diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..23531973a --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,24 @@ +# As of git 2.23, git-blame supports ignoring specific commits. This is useful +# with commits that make bulk formatting changes without truly changing any +# code. +# +# This file lists ignorable pgindent, pgperltidy, and reformat-dat-files +# related commits only. Please don't add commits that are not in this +# category. +# +# You can use the ignore list file by running: +# +# $ git config blame.ignoreRevsFile .git-blame-ignore-revs +# +# Add new entries by adding the output of the following to the top of the file: +# +# $ git log --pretty=format:"%H # %cd%n# %s" $PGINDENTGITHASH -1 --date=iso + +89288109a11bff5ea62f39355d2a6a7efc856b6a # 2025-12-08 16:43:12 +0900 +# Run pgindent. + +a48d72c1682294386fb21b4d17689ac4afde738b # 2025-07-18 15:39:40 +0900 +# Fix indentation. + +468573ad3d19bee5634e362d17df357298d4b51a # 2025-07-17 19:15:48 +0900 +# Run pgindent. diff --git a/.gitignore b/.gitignore index ed9637468..5f3128df9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ .libs/ Makefile TAGS +tags autom4te.cache/ config.h config.log @@ -35,3 +36,23 @@ pgpool.8 sql/pgpool-recovery/pgpool-recovery.sql sql/pgpool-regclass/pgpool-regclass.sql stamp-h1 +Makefile.in +src/include/config.h.in + +# Local excludes in root directory +/aclocal.m4 +/compile +/configure +/config.guess +/config.sub +/depcomp +/install-sh +/ltmain.sh +/missing +/mkinstalldirs +/ylwrap +/m4/libtool.m4 +/m4/ltoptions.m4 +/m4/ltsugar.m4 +/m4/ltversion.m4 +/m4/lt~obsolete.m4 diff --git a/COPYING b/COPYING index e73d19575..94658cae4 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2003-2016 PgPool Global Development Group +Copyright (c) 2003-2021 PgPool Global Development Group Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby diff --git a/Makefile.am b/Makefile.am index 9088c8223..306127b12 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS = subdir-objects ACLOCAL_AMFLAGS = -I m4 docs: - $(MAKE) -C doc all && $(MAKE) -C doc.ja all + $(MAKE) -C doc all && $(MAKE) -C doc.ja all && $(MAKE) .PHONY: docs SUBDIRS = src diff --git a/Makefile.in b/Makefile.in deleted file mode 100644 index 70c2e6b7d..000000000 --- a/Makefile.in +++ /dev/null @@ -1,809 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = . -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) mkinstalldirs \ - AUTHORS COPYING ChangeLog INSTALL NEWS README TODO compile \ - config.guess config.sub depcomp install-sh missing ylwrap \ - ltmain.sh -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -#AM_CPPFLAGS = -D_GNU_SOURCE -I @PGSQL_INCLUDE_DIR@ -AUTOMAKE_OPTIONS = subdir-objects - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src -DIST_SUBDIRS = src doc doc.ja -all: all-recursive - -.SUFFIXES: -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign --ignore-deps'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign --ignore-deps \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool config.lt - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-libtool \ - distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ - am--refresh check check-am clean clean-cscope clean-generic \ - clean-libtool cscope cscopelist-am ctags ctags-am dist \ - dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ - dist-xz dist-zip distcheck distclean distclean-generic \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am - - -docs: - $(MAKE) -C doc all && $(MAKE) -C doc.ja all -.PHONY: docs - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/NEWS b/NEWS index b475d644e..9fc51978f 100644 --- a/NEWS +++ b/NEWS @@ -95,7 +95,7 @@ table, allow_sql_comments, client_idle_limit, log_error_verbosity, client_min_messages, log_min_messages, client_idle_limit_in_recovery. - - Sync inconsitent status of PostgreSQL nodes in Pgpool-II instances + - Sync inconsistent status of PostgreSQL nodes in Pgpool-II instances after restart. (Muhammad Usama) - At the Pgpool-II startup, the status of each configured backend node @@ -155,7 +155,7 @@ and secondly the routing of the query containing pg_terminate_backend also needs a new logic so that the query should be sent to the correct PostgreSQL node that hosts the backend with the PID referred by - the pg_terminate_bakend() + the pg_terminate_backend() So how does this commit handles pg_terminate_backend()?? In the SimpleQuery() function which is the work horse of simple query @@ -215,7 +215,7 @@ make sure that we do not declare the timer expire due to some other signal arrived while waiting for data for health check in pool_check_fd(). - - Add new script called "watchdog_setup". (Tatstuo Ishii) + - Add new script called "watchdog_setup". (Tatsuo Ishii) watchdog_setup is a command to create a temporary installation of Pgpool-II clusters with watchdog for mainly testings. @@ -234,7 +234,7 @@ - Do not update status file if all backend nodes are in down status. (Chris Pacejo, Tatsuo Ishii) - This commit tries to remove the data inconsitency in replication + This commit tries to remove the data inconsistency in replication mode found in [pgpool-general: 3918] by not recording the status file when all backend nodes are in down status. This surprisingly simple but smart solution was provided by Chris Pacejo. @@ -267,7 +267,7 @@ * Changes - Change the default value of search_primary_node_timeout from 10 to - 300. (Tatstuo Ishii) + 300. (Tatsuo Ishii) Prior default value 10 seconds is sometimes too short for a standby to be promoted. @@ -429,7 +429,7 @@ the watchdog master/coordinator node at the time of startup. - Fix Pgpool-II doesn't escalate ip in case of another node - inavailability. (bug 215) (Muhammad Usama) + unavailability. (bug 215) (Muhammad Usama) The heartbeat receiver fails to identify the heartbeat sender watchdog node when the heartbeat destination is specified in terms of an IP address @@ -521,12 +521,12 @@ The reason was a missing command timeout handling in the function that sends the IPC commands to watchdog. - - Fix a posible hang during health checking. (bug 204) (Yugo Nagata) + - Fix a possible hang during health checking. (bug 204) (Yugo Nagata) - Helath checking was hang when any data wasn't sent from + Health checking was hang when any data wasn't sent from backend after connect(2) succeeded. To fix this, pool_check_fd() returns 1 when select(2) exits with EINTR due to SIGALRM while - health checkking is performed. + health checking is performed. - Deal with the case when the primary is not node 0 in streaming replication mode. (Tatsuo Ishii) @@ -576,9 +576,9 @@ - Fix confusing comments in pgpool.conf. (Tatsuo Ishii) - - Fix Japanese and Chinese documetation bug about raw mode. (Yugo Nagata, Bo Peng) + - Fix Japanese and Chinese documentation bug about raw mode. (Yugo Nagata, Bo Peng) - Connection pool is avalilable in raw mode. + Connection pool is available in raw mode. - Fix is_set_transaction_serializable() when SET default_transaction_isolation TO 'serializable'. (bug 191) (Bo Peng) @@ -648,18 +648,18 @@ - Fix pgpool hung after receiving error state from backend. (bug #169) (Tatsuo Ishii) - This could happend if we execute an extended protocol query + This could happen if we execute an extended protocol query and it fails. After an error is received the "ignore till sync flag" - is set and remained even if sync message was actually received. + is set and retained even if sync message was actually received. Thus any subsequent query (in the case above "DEALLOCATE message") - is not procesed and pgpool waits for message from frontend and backend, - and pgpool stucks here because no message will arrive from both side. + is not processed and pgpool waits for message from frontend and backend, + and pgpool sticks here because no message will arrive from both side. To fix this, unconditionally reset the "ignore till sync flag" in ReadyforQuery(). This is safe because apparently we already received the ready for query message. - - Fix query stack problems in extended protocol case. (bug 167, 168) (Tatstuo Ishii) + - Fix query stack problems in extended protocol case. (bug 167, 168) (Tatsuo Ishii) - Fix [pgpool-hackers: 1440] yet another reset query stuck problem. (Tatsuo Ishii) @@ -688,7 +688,7 @@ - Add some warning messages for wd_authkey hash calculation failure. (Yugo Nagata) Sometimes wd_authkey calculation fails for some reason other - than authkey mismatch. The additional messages make these distingushable + than authkey mismatch. The additional messages make these distinguishable for each other. =============================================================================== @@ -750,7 +750,7 @@ - doc : Fixing a typo in english doc (Muhammad Usama) - - Fix for bun 215 that pgpool doesn't escalate ip in case of another node inavailability. + - Fix for bun 215 that pgpool doesn't escalate ip in case of another node unavailability. (Muhammad Usama) The heartbeat receiver fails to identify the heartbeat sender watchdog node when @@ -863,8 +863,8 @@ See bug 191 for related info. - - Fix Chinese documetation bug about raw mode (Yugo Nagata, Bo Peng) - Connection pool is avalilable in raw mode. + - Fix Chinese documentation bug about raw mode (Yugo Nagata, Bo Peng) + Connection pool is available in raw mode. - Fix confusing comments in pgpool.conf (Tatsuo Ishii) @@ -921,12 +921,12 @@ either load balance node or primary node, the primary node id is returned. - - Fix a posible hang during health checking (Yugo Nagata) + - Fix a possible hang during health checking (Yugo Nagata) - Helath checking was hang when any data wasn't sent + Health checking was hang when any data wasn't sent from backend after connect(2) succeeded. To fix this, pool_check_fd() returns 1 when select(2) exits with - EINTR due to SIGALRM while health checkking is performed. + EINTR due to SIGALRM while health checking is performed. Reported and patch provided by harukat and some modification by Yugo. @@ -1048,7 +1048,7 @@ (Yugo Nagata) Sometimes wd_authkey calculation fails for some reason other than - authkey mismatch. The additional messages make these distingushable + authkey mismatch. The additional messages make these distinguishable for each other. - test: Fix regression test to check timeout of each test (Yugo Nagata) @@ -1066,7 +1066,7 @@ - test: Fix test/regression/clean.sh to remove binary files of 010.rewrite_timestamp test (Yugo Nagata) - - Fix memorry leak reported by Coverity (CID 1350095) (Yugo Nagata) + - Fix memory leak reported by Coverity (CID 1350095) (Yugo Nagata) - Fixing pgpool-recovery module compilation issue with PostgreSQL 9.6 (Muhammad Usama) @@ -1118,7 +1118,7 @@ - Fix pgpool hung after receiving error state from backend (Tatsuo Ishii) - This could happend if we execute an extended protocol query and it + This could happened if we execute an extended protocol query and it fails. Per bug #169. @@ -1234,7 +1234,7 @@ * Enhancements - - Performance improvement in extened query protocol (Tatsuo Ishii) + - Performance improvement in extended query protocol (Tatsuo Ishii) Unnecessary "flush" messages which used to be sent in each step of extended protocol messages (parse, bind, describe and execute) and @@ -1290,7 +1290,7 @@ Long command line options can be used now. -- PCP password is safe: Don't pass password via command line, which causes security risks. - -- Mutiple concurrent execution of pcp commands: + -- Multiple concurrent execution of pcp commands: Allow to execute a pcp command while running pcp_recovery_node which takes sometime to finish. @@ -1348,7 +1348,7 @@ caching the PostgreSQL connection if the connection to frontend was not properly terminated. - - test: Fix false alerm of regression tset 062 (Yugo Nagata) + - test: Fix false alarm of regression tset 062 (Yugo Nagata) - test: Fix broken regression test for native replication (Yugo Nagata) @@ -1363,7 +1363,7 @@ When a schema name was provided, the table name was quoted wrongly as like "public.mytbl" instead of "public"."mytbl". So, pool_regclass - and to_regclass couldn't find right talbe oid and insert lock was + and to_regclass couldn't find right table oid and insert lock was never executed. This caused inconsistency between DB nodes. - test: Fix complication error and segfault of timestamp rewrite test (Yugo Nagata) @@ -1384,9 +1384,9 @@ - doc: Fix wrong description in documents about log_standby_delay (Yugo Nagata) - - Fix segfalut that occurs when function is used in FROM clause (Yugo Nagata) + - Fix segfault that occurs when function is used in FROM clause (Yugo Nagata) - PRPARE statements in streaming-reaplication mode and INSERT/UPDATE + PREPARE statements in streaming-reapplication mode and INSERT/UPDATE with SELECT in native-replication mode were affected. For example: - prepare p as select * from generate_series(1,1); @@ -1395,7 +1395,7 @@ - doc: Add caution about JDBC driver version regarding app_name_redirect_preference_list (Tatsuo Ishii) - - Fix hang problmen reported in bug #145. (Tatsuo Ishii) + - Fix hang problem reported in bug #145. (Tatsuo Ishii) The problem occurs when all the condition below are met: @@ -1469,7 +1469,7 @@ backend nodes. The function assumed that the node was also invalid when its connection status was down. However, that is not always right. - - Fix white/black_memqcache_table_list not to require quotaion (Yugo Nagata) + - Fix white/black_memqcache_table_list not to require quotation (Yugo Nagata) The tables and schemas name specified in *_memqcache_table_list were needed to be quoted by double quotation. @@ -1624,8 +1624,8 @@ See bug 191 for related info. - - Fix Chinese documetation bug about raw mode (Yugo Nagata, Bo Peng) - Connection pool is avalilable in raw mode. + - Fix Chinese documentation bug about raw mode (Yugo Nagata, Bo Peng) + Connection pool is available in raw mode. - Fix confusing comments in pgpool.conf (Tatsuo Ishii) @@ -1656,12 +1656,12 @@ See bug 194 for related info. - - Fix a posible hang during health checking (Yugo Nagata) + - Fix a possible hang during health checking (Yugo Nagata) - Helath checking was hang when any data wasn't sent + Health checking was hang when any data wasn't sent from backend after connect(2) succeeded. To fix this, pool_check_fd() returns 1 when select(2) exits with - EINTR due to SIGALRM while health checkking is performed. + EINTR due to SIGALRM while health checking is performed. Reported and patch provided by harukat and some modification by Yugo. @@ -1769,7 +1769,7 @@ - test: Fix test/regression/clean.sh to remove binary files of 010.rewrite_timestamp test (Yugo Nagata) - - Fix memorry leak reported by Coverity (CID 1350095) (Yugo Nagata) + - Fix memory leak reported by Coverity (CID 1350095) (Yugo Nagata) - Fixing pgpool-recovery module compilation issue with PostgreSQL 9.6 (Muhammad Usama) @@ -1855,7 +1855,7 @@ caching the PostgreSQL connection if the connection to frontend was not properly terminated. - - test: Fix false alerm of regression tset 062 (Yugo Nagata) + - test: Fix false alarm of regression tset 062 (Yugo Nagata) - test: Fix broken regression test for native replication (Yugo Nagata) @@ -1870,7 +1870,7 @@ When a schema name was provided, the table name was quoted wrongly as like "public.mytbl" instead of "public"."mytbl". So, pool_regclass - and to_regclass couldn't find right talbe oid and insert lock was + and to_regclass couldn't find right table oid and insert lock was never executed. This caused inconsistency between DB nodes. - test: Fix complication error and segfault of timestamp rewrite test @@ -1968,7 +1968,7 @@ The expected result of 'show pool_nodes' is fixed to use PGSOCKET_DIR in hostname column. - - Fix white/black_memqcache_table_list not require quotaion (Yugo Nagata) + - Fix white/black_memqcache_table_list not require quotation (Yugo Nagata) The tables and schemas name specified in *_memqcache_table_list were needed to be quoted by double quotation. @@ -2006,7 +2006,7 @@ (Yugo Nagata) Sometimes wd_authkey calculation fails for some reason other than - authkey mismatch. The additional messages make these distingushable + authkey mismatch. The additional messages make these distinguishable for each other. - test: Fix regression test to check timeout of each test (Yugo Nagata) @@ -2022,9 +2022,9 @@ Per bug #153. - - Fix segfalut that occurs when function is used in FROM clause (Yugo Nagata) + - Fix segfault that occurs when function is used in FROM clause (Yugo Nagata) - PRPARE statements in streaming-reaplication mode and INSERT/UPDATE + PREPARE statements in streaming-reapplication mode and INSERT/UPDATE with SELECT in native-replication mode were affected. For example: - prepare p as select * from generate_series(1,1); @@ -2144,7 +2144,7 @@ ERROR: failed to make persistent db connection DETAIL: connection to host:"x.x.x.x:5432 failed - However, the healthchek triggers neither fail over nor retrying. So, + However, the healthcheck triggers neither fail over nor retrying. So, except the annoying messages above, everything goes well. This could occur more easily if 1) num_init_children is big and 2) pgpool children go into idle state (no query arrived from client for @@ -2262,7 +2262,7 @@ ERROR: failed to make persistent db connection DETAIL: connection to host:"x.x.x.x:5432 failed - However, the healthchek triggers neither fail over nor retrying. So, + However, the healthcheck triggers neither fail over nor retrying. So, except the annoying messages above, everything goes well. This could occur more easily if 1) num_init_children is big and 2) pgpool children go into idle state (no query arrived from client for @@ -2336,7 +2336,7 @@ Rather, it is harmful, and due to this it was regarded that ping command exited abnormally in error even when this succeeded. - - Fix to use waitpid instead of wait in exec_ifconifg (Yugo Nagata) + - Fix to use waitpid instead of wait in exec_ifconfig (Yugo Nagata) - Remove an unnecessary include directive (Yugo Nagata) @@ -2346,7 +2346,7 @@ parameter description. Unfortunately recovery_timeout description is 64 chars, which is 1 byte longer than former definition of the macro. - - doc: Update document of condition for load balancig (Yugo Nagata) + - doc: Update document of condition for load balancing (Yugo Nagata) Load balancing is possible in an explicit transaction block even in replication mode since 3.3.0. @@ -2424,7 +2424,7 @@ The node id should be lower than NUM_BACKENDS. Probably harmless since callers never pass node ids greater or equal to NUM_BACKENDS. - - Fix occasional stuck that occures when a NOTIFY message is sent from + - Fix occasional stuck that occurs when a NOTIFY message is sent from a backend. (Muhammad Usama) The issue happens in master slave mode with load balancing when the @@ -2458,12 +2458,12 @@ - Fix a memory leak with long-lived connections (Muhammad Usama) - Problem reporeted in [pgpool-general: 3325]. + Problem reported in [pgpool-general: 3325]. - Change the log level of "Frontend Terminated" message to DEBUG1 from LOG (Muhammad Usama) - - Fix ill signal befavior of SIGCHLD in exec_ifconfig() (Tatsuo Ishii) + - Fix ill signal behavior of SIGCHLD in exec_ifconfig() (Tatsuo Ishii) For some reason SIGCHLD was set to SIG_IGN *and* tries to wait child process which always fails because SIGCHLD is never delivered. @@ -2505,7 +2505,7 @@ - Fix pgpool main process to shutdown in case of child process start-up failures (Muhammad Usama) - Problem rported in [pgpool-general: 3358]. + Problem reported in [pgpool-general: 3358]. - Fix a segmentation fault that could happen in child process error (Muhammad Usama) @@ -2639,7 +2639,7 @@ - Rename all occurrence of "on memory query cache" to "in memory query cache" because latter is more correct in English (Tatsuo Ishii) - - Add 4th paramter "master node port number" to recovery script + - Add 4th parameter "master node port number" to recovery script (Tatsuo Ishii) - Allow to handle more than 3 database nodes in pgpool_setup @@ -2765,8 +2765,8 @@ See bug 191 for related info. - - Fix Chinese documetation bug about raw mode (Yugo Nagata, Bo Peng) - Connection pool is avalilable in raw mode. + - Fix Chinese documentation bug about raw mode (Yugo Nagata, Bo Peng) + Connection pool is available in raw mode. - Fix confusing comments in pgpool.conf (Tatsuo Ishii) @@ -2817,12 +2817,12 @@ - change the Makefile under the directory src/sql/, that is proposed (Bo Peng) by [pgpool-hackers: 1611] - - Fix a posible hang during health checking (Yugo Nagata) + - Fix a possible hang during health checking (Yugo Nagata) - Helath checking was hang when any data wasn't sent + Health checking was hang when any data wasn't sent from backend after connect(2) succeeded. To fix this, pool_check_fd() returns 1 when select(2) exits with - EINTR due to SIGALRM while health checkking is performed. + EINTR due to SIGALRM while health checking is performed. Reported and patch provided by harukat and some modification by Yugo. Per bug #204. @@ -2900,7 +2900,7 @@ - test: Fix test/regression/clean.sh to remove binary files of 010.rewrite_timestamp test (Yugo Nagata) - - Fix memorry leak reported by Coverity (CID 1350095) (Yugo Nagata) + - Fix memory leak reported by Coverity (CID 1350095) (Yugo Nagata) - Fixing pgpool-recovery module compilation issue with PostgreSQL 9.6 (Muhammad Usama) @@ -2969,7 +2969,7 @@ This ensures that pgpool_status is saved to permanent storage and allow to survive after system crash. - - test: Fix false alerm of regression tset 062 (Yugo Nagata) + - test: Fix false alarm of regression tset 062 (Yugo Nagata) - test: Fix broken regression test for native replication (Yugo Nagata) @@ -2984,7 +2984,7 @@ When a schema name was provided, the table name was quoted wrongly as like "public.mytbl" instead of "public"."mytbl". So, pool_regclass - and to_regclass couldn't find right talbe oid and insert lock was + and to_regclass couldn't find right table oid and insert lock was never executed. This caused inconsistency between DB nodes. - test: Fix complication error and segfault of timestamp rewrite test @@ -3048,7 +3048,7 @@ The expected result of 'show pool_nodes' is fixed to use PGSOCKET_DIR in hostname column. - - Fix white/black_memqcache_table_list not require quotaion (Yugo Nagata) + - Fix white/black_memqcache_table_list not require quotation (Yugo Nagata) The tables and schemas name specified in *_memqcache_table_list were needed to be quoted by double quotation. @@ -3073,7 +3073,7 @@ (Yugo Nagata) Sometimes wd_authkey calculation fails for some reason other than - authkey mismatch. The additional messages make these distingushable + authkey mismatch. The additional messages make these distinguishable for each other. - test: Fix regression test to check timeout of each test (Yugo Nagata) @@ -3167,7 +3167,7 @@ ERROR: failed to make persistent db connection DETAIL: connection to host:"x.x.x.x:5432 failed - However, the healthchek triggers neither fail over nor retrying. So, + However, the healthcheck triggers neither fail over nor retrying. So, except the annoying messages above, everything goes well. This could occur more easily if 1) num_init_children is big and 2) pgpool children go into idle state (no query arrived from client for @@ -3232,7 +3232,7 @@ parameter description. Unfortunately recovery_timeout description is 64 chars, which is 1 byte longer than former definition of the macro. - - doc: Update document of condition for load balancig (Yugo Nagata) + - doc: Update document of condition for load balancing (Yugo Nagata) Load balancing is possible in an explicit transaction block even in replication mode since 3.3.0. @@ -3278,7 +3278,7 @@ - doc: Describe explicitly that the number of slave nodes is not necessarily 1 (Tatsuo Ishii) - - Fix occasinal deadlock in failover with watchdog enabled + - Fix occasional deadlock in failover with watchdog enabled (Muhammad Usama) per bug #105 @@ -3320,7 +3320,7 @@ - test: Add memory leak regression test (Tatsuo Ishii) - - Fix ill signal befavior of SIGCHLD in exec_ifconfig() (Tatsuo Ishii) + - Fix ill signal behavior of SIGCHLD in exec_ifconfig() (Tatsuo Ishii) For some reason SIGCHLD was set to SIG_IGN *and* tries to wait child process which always fails because SIGCHLD is never delivered. @@ -3427,7 +3427,7 @@ (Yugo Nagata) When executing command such as ifconfig or ping by execv() in a forked - child proess, wait() can fails with an error code ECHILD, although the + child process, wait() can fails with an error code ECHILD, although the process exists exactly, if SIGCHLD is set to SIG_IGN in Linux. We should ignore this and not treat as failure of the command. @@ -3504,7 +3504,7 @@ This problem is reported by Qian Peng in [pgpool-hackers: 520]. - - Disbale statement_timeout of PostgreSQL while executing online recovery + - Disable statement_timeout of PostgreSQL while executing online recovery (Tatsuo Ishii) Online recovery may take very long time and user may enable statement @@ -3550,7 +3550,7 @@ Coverity issue #1111419, #1111420, #1111422. - - replacing strcpy() with much safer and recomended call strlcpy() + - replacing strcpy() with much safer and recommended call strlcpy() (Muhammad Usama) Coverity issue #1111480. @@ -3670,7 +3670,7 @@ - Fix query cache bug with extended protocol. (Tatsuo Ishii) - SELECT retrieves outdated cache even DML was executed in an expilicit + SELECT retrieves outdated cache even DML was executed in an explicit transaction. The bug had been there since in memory query cache was born. Per [pgpool-general-jp: 1252]. @@ -3700,7 +3700,7 @@ Replace strcpy() with strlcpy(). Per Coverity report 1111478, 1111480, 1111481. - - Add dubug messages for analyzing errors in if_up_cmd (Yugo Nagata) + - Add debug messages for analyzing errors in if_up_cmd (Yugo Nagata) - Fix freeing NULL. (Tatsuo Ishii) @@ -3729,7 +3729,7 @@ With JDBC, when a prepared statement is executed more than PrepareThreshold times, the statement is named and Describe message is sent after Parse. With named statement, pgpool rewrite now() to - parameter in replication mode. Hence, rewritten query has additonal + parameter in replication mode. Hence, rewritten query has additional parameter than original. In this case, ParameterDescription message sent to frontend (response of Describe) should include OIDs of the same number os original query's parameters. Otherwize, JDBC throws @@ -3737,12 +3737,12 @@ This is reported in [pgpool-general-jp: 1192]. - - Fix backend error of prepared statement about table which has column whoes + - Fix backend error of prepared statement about table which has column whose default value is now() in replication mode (Yugo Nagata) When pgpool parses a named prepared statement with default now(), timestamps are replaced to additional parameters. So, Bind message also - should inclued additional parameter format codes. However, when the + should included additional parameter format codes. However, when the number of original parameter was one, pgpool didn't handle this. This caused a error like "incorrect binary data format in bind parameter 2". @@ -3807,7 +3807,7 @@ Per bug#74. http://www.pgpool.net/mantisbt/view.php?id=74 - doc: Modify descriptions about restrictions of parallel mode - Muliple rows INSERT using VALUES are not supported in parallel mode. + Multiple rows INSERT using VALUES are not supported in parallel mode. (Yugo Nagata) - Avoid calling find_primary_node_repeatedly() when standby node goes @@ -3897,7 +3897,7 @@ unnecessary 4 bytes, which did nothing bd for the execution of program. But a bug is a bug. - Per covery report "1111476 Wrong sizeof argument" + Per coverity report "1111476 Wrong sizeof argument" - Fix "show pool_status" always shows memqcache_auto_cache_invalidation as 0. (Tatsuo Ishii) @@ -4004,12 +4004,12 @@ string than the buffer. Per Coverity report 1111426 "Out-of-bounds access". - - RPM: Improved to specify the versions of pgool-II and PostgreSQL in the. + - RPM: Improved to specify the versions of pgpool-II and PostgreSQL in the. spec file. (Nozomi Anzai) - - Fix resource leak in make_persistent_db_connection. (Tatsio Ishii) + - Fix resource leak in make_persistent_db_connection. (Tatsuo Ishii) - For this pupose, new static function free_persisten_db_connection_memory + For this purpose, new static function free_persisten_db_connection_memory is added. Per Coverity report #1111468. @@ -4096,7 +4096,7 @@ * Incompatible changes - - All the follwing are about watchdog. + - All the following are about watchdog. See "New features" section below for details of these changes. - Default monitoring method was changed from query mode to heartbeat mode. @@ -4106,7 +4106,7 @@ - In default, all the query caches on shared memory are cleared when standby pgpool-II escalates to active. - - Database name, user name, and password used for monitring other + - Database name, user name, and password used for monitoring other pgpool-II by query are specified by dedicated parameters. Previously, template1, recovery_user, and recovery_password are used. @@ -4116,7 +4116,7 @@ ** Watchdog - - Add a new monitring method using heartbeat signal of UDP packet in + - Add a new monitoring method using heartbeat signal of UDP packet in lifecheck. (Yugo Nagata) You can select a method from either of two methods, "heartbeat" mode or @@ -4182,7 +4182,7 @@ used in query mode lifecheck of watchdog . Previously, these are hard coded to use template1, recovery_user, and recovery_password. - - When delegate_IP parameter is emply, viertual IP is neither brought up + - When delegate_IP parameter is empty, virtual IP is neither brought up nor switched. (Yugo Nagata) This allows multi-master like configuration without virtual IP. @@ -4213,13 +4213,13 @@ - Support installation method using CREATE EXTENSION for pgpool-recovery and pgpool-regclass. (Tatsuo Ishii) - Older installtion method is still preserved. + Older installation method is still preserved. Note: extension names are "pgpool_recovery" and "pgpool_regclass", not - "pgpool-recovery" and "pgpool-regclass" because latters are not + "pgpool-recovery" and "pgpool-regclass" because letters are not convenient in using CREATE EXTENSION command (requires double quotes). - - Add a function "pgpool_pgctl()" which enebles to execute + - Add a function "pgpool_pgctl()" which enables to execute pg_ctl stop/restart/reload (except for start) by SQL. (Nozomi Anzai) $ psql sales -c "select pgpool_pgctl('reload', 'fast')"; @@ -4262,7 +4262,7 @@ * Bug fixes - - Consider timeout waiting for compeletion of failback request in on line + - Consider timeout waiting for completion of failback request in on line recovery. (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever @@ -4298,7 +4298,7 @@ The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and - kill the existig connection. This is not gentle but at this point I + kill the existing connection. This is not gentle but at this point I believe this is the best solution. - Fix possible deadlock during failover with watchdog enabled. @@ -4310,7 +4310,7 @@ - Fix unnecessary degeneration caused by error on commit. (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other - slaves are normal at commit, we don't need to degenrate any backend + slaves are normal at commit, we don't need to degenerate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. @@ -4337,9 +4337,9 @@ SELECT * FROM t1; - At commit pgpool tries to delete cache for t2 but failes because + At commit pgpool tries to delete cache for t2 but fails because there's no oid table entry for t2. Problem is, it fails to check oid - table for t1. So cahce for t1 remains and the last SELECT incorrectly + table for t1. So cache for t1 remains and the last SELECT incorrectly returns cached data. Fix is, continuing to check oid table entries. This is reported in Bug track #58 by wms @@ -4401,7 +4401,7 @@ of recovery script, and this causes a malfunction. In especially, rsync may delete unrelated files in basebackup scripts. - - Fix a segmentation fault on main process that could occures after backend + - Fix a segmentation fault on main process that could occurs after backend error detection (Tatsuo Ishii) This is reported in Bug track #62 by tuomas. @@ -4448,7 +4448,7 @@ snprintf and strlcpy respectively. (Yugo Nagata) - Replace "sticky bit" to "setuid bit" in log message, comments and - funcation names. (Yugo Nagata) + function names. (Yugo Nagata) These words were used mistakenly and caused confusion. @@ -4577,8 +4577,8 @@ See bug 191 for related info. - - Fix Chinese documetation bug about raw mode (Yugo Nagata, Bo Peng) - Connection pool is avalilable in raw mode. + - Fix Chinese documentation bug about raw mode (Yugo Nagata, Bo Peng) + Connection pool is available in raw mode. - Fix confusing comments in pgpool.conf (Tatsuo Ishii) @@ -4629,12 +4629,12 @@ - change the Makefile under the directory src/sql/, that is proposed (Bo Peng) by [pgpool-hackers: 1611] - - Fix a posible hang during health checking (Yugo Nagata) + - Fix a possible hang during health checking (Yugo Nagata) - Helath checking was hang when any data wasn't sent + Health checking was hang when any data wasn't sent from backend after connect(2) succeeded. To fix this, pool_check_fd() returns 1 when select(2) exits with - EINTR due to SIGALRM while health checkking is performed. + EINTR due to SIGALRM while health checking is performed. Reported and patch provided by harukat and some modification by Yugo. Per bug #204. @@ -5018,7 +5018,7 @@ Per bug #104. http://www.pgpool.net/mantisbt/view.php?id=104 - - Disbale statement_timeout of PostgreSQL while executing online recovery + - Disable statement_timeout of PostgreSQL while executing online recovery (Tatsuo Ishii) Online recovery may take very long time and user may enable statement @@ -5103,7 +5103,7 @@ - Fix query cache bug with extended protocol. (Tatsuo Ishii) - SELECT retrieves outdated cache even DML was executed in an expilicit + SELECT retrieves outdated cache even DML was executed in an explicit transaction. The bug had been there since in memory query cache was born. Per [pgpool-general-jp: 1252]. @@ -5156,7 +5156,7 @@ With JDBC, when a prepared statement is executed more than PrepareThreshold times, the statement is named and Describe message is sent after Parse. With named statement, pgpool rewrite now() to - parameter in replication mode. Hence, rewritten query has additonal + parameter in replication mode. Hence, rewritten query has additional parameter than original. In this case, ParameterDescription message sent to frontend (response of Describe) should include OIDs of the same number os original query's parameters. Otherwize, JDBC throws @@ -5164,12 +5164,12 @@ This is reported in [pgpool-general-jp: 1192]. - - Fix backend error of prepared statement about table which has column whoes + - Fix backend error of prepared statement about table which has column whose default value is now() in replication mode (Yugo Nagata) When pgpool parses a named prepared statement with default now(), timestamps are replaced to additional parameters. So, Bind message also - should inclued additional parameter format codes. However, when the + should included additional parameter format codes. However, when the number of original parameter was one, pgpool didn't handle this. This caused a error like "incorrect binary data format in bind parameter 2". @@ -5219,7 +5219,7 @@ Per bug#74. http://www.pgpool.net/mantisbt/view.php?id=74 - doc: Modify descriptions about restrictions of parallel mode - Muliple rows INSERT using VALUES are not supported in parallel mode. + Multiple rows INSERT using VALUES are not supported in parallel mode. (Yugo Nagata) - Avoid calling find_primary_node_repeatedly() when standby node goes @@ -5306,7 +5306,7 @@ unnecessary 4 bytes, which did nothing bd for the execution of program. But a bug is a bug. - Per covery report "1111476 Wrong sizeof argument" + Per coverity report "1111476 Wrong sizeof argument" - Fix "show pool_status" always shows memqcache_auto_cache_invalidation as 0. (Tatsuo Ishii) @@ -5400,9 +5400,9 @@ string than the buffer. Per Coverity report 1111426 "Out-of-bounds access". - - Fix resource leak in make_persistent_db_connection. (Tatsio Ishii) + - Fix resource leak in make_persistent_db_connection. (Tatsuo Ishii) - For this pupose, new static function free_persisten_db_connection_memory + For this purpose, new static function free_persisten_db_connection_memory is added. Per Coverity report #1111468. @@ -5424,7 +5424,7 @@ * Bug fixes - - Fix a segmentation fault on main process that could occures after backend + - Fix a segmentation fault on main process that could occurs after backend error detection (Tatsuo Ishii) This is reported in Bug track #62 by tuomas. @@ -5491,7 +5491,7 @@ - Add mention about "-D" option to the man page. (Tatsuo Ishii) - - Consider timeout waiting for compeletion of failback request in on line + - Consider timeout waiting for completion of failback request in on line recovery (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever @@ -5524,7 +5524,7 @@ The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and - kill the existig connection. This is not gentle but at this point I + kill the existing connection. This is not gentle but at this point I believe this is the best solution. - Fix possible deadlock during failover with watchdog enabled @@ -5548,7 +5548,7 @@ - Fix unnecessary degeneration caused by error on commit (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other - slaves are normal at commit, we don't need to degenrate any backend + slaves are normal at commit, we don't need to degenerate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. @@ -5565,9 +5565,9 @@ SELECT * FROM t1; - At commit pgpool tries to delete cache for t2 but failes because + At commit pgpool tries to delete cache for t2 but fails because there's no oid table entry for t2. Problem is, it fails to check oid - table for t1. So cahce for t1 remains and the last SELECT incorrectly + table for t1. So cache for t1 remains and the last SELECT incorrectly returns cached data. Fix is, continuing to check oid table entries. This is reported in Bug track #58 by wms @@ -5654,7 +5654,7 @@ interrupted by alarm. (Tatsuo Ishii) This confuses health checking because connect_inet_domain_socket_by_port() - returns unsable fd. This makes detecting errors in health checking longer. + returns usable fd. This makes detecting errors in health checking longer. See the following for more details: @@ -5669,7 +5669,7 @@ message. Problem is, the rewritten message was kept in the data which is managed by pool_create_sent_message() etc. The function assumes that all the data is in session context memory. However, palloc() - allocates memory in query context of course, and gets freeed later on + allocates memory in query context of course, and gets freed later on when the query context disappears. And the function tries to free the memory as well, which causes various problems, including segfault and double free. To fix this, memory to store rewritten message is @@ -5691,7 +5691,7 @@ http://www.pgpool.net/pipermail/pgpool-general/2013-March/001551.html - Fix to calculate replication delay only if standby server is behind from - the primay server. (Yugo Nagata) + the primary server. (Yugo Nagata) When the primary server is behind from standby server, negative value of delay is calculated and the value is assigned to unsigned variable. It @@ -5723,7 +5723,7 @@ The problem is reported in bugtrack #53. - #53 pgpool_regclas hangs all connections + #53 pgpool_regclass hangs all connections Date: 2013-04-04 13:35 Reporter: tmandke http://www.pgpool.net/mantisbt/view.php?id=53 @@ -5768,7 +5768,7 @@ health checking. If all of following conditions are met, pgpool main process disappeared and all client connections to pgpool-II hang forever when failover happens. And the only way to recover - from it is, manualy killing the pgpool child process and restart + from it is, manually killing the pgpool child process and restart pgpool-II. - health checking is enabled @@ -5856,11 +5856,11 @@ - Fix segfault due to bug with query cache array handling. (Tatsuo Ishii) - The cache arrary is used to keep temporary cache results in a transaction. + The cache array is used to keep temporary cache results in a transaction. If there are more than 128 SELECTs in a transaction, the module expands - cache_arrary by using realloc. However it does not record the new pointer + cache_array by using realloc. However it does not record the new pointer returned by realloc. So the module keeps on using the old pointer which is - absoleted. + obsoleted. This problem is reported in bug track #31 by jgentsch. @@ -5869,10 +5869,10 @@ Date: 2012-10-23 06:25 http://www.pgpool.net/mantisbt/view.php?id=31 - - Fix hung up while repeating pcp_attach_node and pcp_detatch_node + - Fix hung up while repeating pcp_attach_node and pcp_detach_node (Tatsuo Ishii) - When node status is changed by pcp_attach_node and pcp_detatch_node, + When node status is changed by pcp_attach_node and pcp_detach_node, failover() sends SIGUSR1 to pcp_child process expecting it exits to refresh node status. In this situation lots of pgpool children exit and produce SIGCHLD as well. The SIGCHLD handler reaper() tries catch all @@ -5890,7 +5890,7 @@ - Fix pool_send_severity_message() not to use uninitialized memory. (Tatsuo Ishii) - It cause a segmentaion fault. + It cause a segmentation fault. Reported in Bug #33's attached valgrind output by dudee. #33 pgpool-II 3.2.1 segfault @@ -5909,7 +5909,7 @@ 4) CREATE TEMP TABLE t1(i int); -- create a temp table 5) SELECT * FROM t1; -- query cache entry mistakenly created! - Problem is #3 creates relcache entry for t1, and #5 incorrecly uses it + Problem is #3 creates relcache entry for t1, and #5 incorrectly uses it and believes that temp table t1 is not a temp table. - Add a description about "-f" to help message. (Tatsuo Ishii) @@ -5948,7 +5948,7 @@ http://www.sraoss.jp/pipermail/pgpool-general/2012-December/001237.html - Fix health_check() to check the health check timer before retrying - with template1 database. (Tatuo Ishii) + with template1 database. (Tatsuo Ishii) Without this, the retry with node 0 always fails because health check timer may be already expired. @@ -5988,7 +5988,7 @@ - Fix child_exit() to not call send_frontend_exits() if there's no connection pool. (Tatsuo Ishii) - Otherwise, it segfaults because send_frontend_exits() referes to objects + Otherwise, it segfaults because send_frontend_exits() refers to objects pointed to by pool_connection_pool. Per bug track #44 by tuomas. #44 pgpool went haywire after slave shutdown triggering master failover @@ -6050,7 +6050,7 @@ stack and pop out when it is convenient. For this purpose, new functions pool_push(), pool_pop() and pool_stacklen() are added. - This probmel is reported in but grack #45 by rpashin. + This problem is reported in but grack #45 by rpashin. #45 LISTEN/NOTIFY doesn't work if cluster contains more then 1 node in streaming replication mode @@ -6083,7 +6083,7 @@ See [pgpool-general: 1330] for more details. - [pgpool-general: 1330] WatchDog and pgool sudden stop working + [pgpool-general: 1330] WatchDog and pgpool sudden stop working From: Tomas Halgas Date: Fri, 18 Jan 2013 14:47:23 +0100 http://www.sraoss.jp/pipermail/pgpool-general/2013-January/001350.html @@ -6133,7 +6133,7 @@ sends a packet to other pgpools. However, the packet sometimes is sent before the virtual IP is brought down completely. In this case the packet sender is set to this IP. When the IP is brought down before other pgpools - respond, the active pgpool can not recieve the response, and hang up. + respond, the active pgpool can not receive the response, and hang up. In this fix, the active pgpool confirms that the virtual IP is brought down before sending the packet. @@ -6222,7 +6222,7 @@ (Tatsuo Ishii) If one of bind parameter < 0, it was possible to produce more than 2 - byte string for "%02X" due to sign extention. + byte string for "%02X" due to sign extension. Also use snprintf, rather than sprintf to prevent from possible buffer overrun in the future. @@ -6241,7 +6241,7 @@ - Fix typo in cache_reporting(). (Tatsuo Ishii) - - Fix inifinit loop in SSL mode. (Tatsuo Ishii) + - Fix infinite loop in SSL mode. (Tatsuo Ishii) When there's pending data in SSL layer of frontend, pool_process_query() checks pending data in backend. If there's non, it loops again and checks @@ -6301,7 +6301,7 @@ modules. So this fix is not Parse() only, rather for other modules. For this purpose ProcessFrontendResponse() is changed. - See bugtrack in detai. + See bugtrack in detail. #21 pgpool-II 3.2.0 cannot execute sql through jdbc Date: 2012-08-17 16:31 @@ -6311,7 +6311,7 @@ - Fix to set unix domain socket path for pgpool PCP communication before setting up signal handlers. (Yugo Nagata) - Previously, unlink of the socket in exitting process was failed because + Previously, unlink of the socket in exiting process was failed because the path of the socket was not set. Patch contributed by Gilles Darold @@ -6374,12 +6374,12 @@ On memory cache saves pair of SELECT statements (with its Bind parameters if the SELECT is an extended query). If the same SELECTs comes in, it returns the value from cache. Since no SQL parsing nor access to - PostgreSQL are involed, it's extremely fast. + PostgreSQL are involved, it's extremely fast. On the other hand, it might be slower than the normal path because it adds some overhead to store cache. Moreover when a table is updated, pgpool automatically deletes all the caches related to the table. So the - prformace will be degraded by a system with a lot of updates. If the + performance will be degraded by a system with a lot of updates. If the cache_hit_ratio is lower than 70%, you might want to disable onl memory cache. @@ -6397,7 +6397,7 @@ - On memory query cache deletes the all cache of an updated table automatically with monitoring if the executed query is UPDATE, INSERT, ALTER TABLE and so on. But pgpool-II isn't able to recognize implicit - updates due to trigers, foreign keys and DROP TABLE CASCADE. + updates due to triggers, foreign keys and DROP TABLE CASCADE. You can avoid this problem with memqcache_expire by which pgpool deletes old cache in a fixed time automatically, or with black_memqcache_table_list by which pgpool's memory cache flow ignores the tables. @@ -6410,7 +6410,7 @@ New parameters: - - Add parameters for on memoey query cache as follows: + - Add parameters for on memory query cache as follows: memory_cache_enabled, memqcache_method, memqcache_expire, memqcache_maxcache, memqcache_oiddir. (Tatsuo Ishii) @@ -6518,7 +6518,7 @@ * Enhancements - - Retry if health check faied rather than immediately do failover. For + - Retry if health check failed rather than immediately do failover. For this purpose new directives "health_check_max_retries" and "health_check_retry_delay" were added. (Tatsuo Ishii) Patch contributed by Matt Solnit. @@ -6528,9 +6528,9 @@ Date: Fri, 18 Nov 2011 16:28:44 -0500 - Log client IP and port number when pgpool failed to parse given query. - (Tasuo) + (Tatsuo) - This is usefull to identify which client gives wrong query without + This is useful to identify which client gives wrong query without enabling log_connections, which produces too many log entries on busy web systems. @@ -6563,14 +6563,14 @@ pgpool-II. Patch contributed by Gurjeet Singh. - Remove unused parameter "query" from is_set_transaction_serializable(). - (Tastuo Ishii) + (Tatsuo Ishii) - Fix on memory query cache section's comments in pgpool.com in the way - which other sections employ. (Tastuo Ishii) + which other sections employ. (Tatsuo Ishii) - Add missing health_check_max_retries and health_check_retry_delay directives to pgpool.conf.sample-master-slave, pgpool.conf.sample-replication - pgpool.conf.sample-stream. (Tastuo Ishii) + pgpool.conf.sample-stream. (Tatsuo Ishii) - Fix pool_ssl_write. It seems someone forgot to do retrying when SSL returns SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. @@ -6621,7 +6621,7 @@ - Fix segfault of pcp_systemdb_info not in parallel mode. (Nozomi Anzai) - - Fix "unnamed prepared statment does not exist" error. (Tatsuo Ishii) + - Fix "unnamed prepared statement does not exist" error. (Tatsuo Ishii) This is caused by pgpool's internal query, which breaks client's unnamed statements. To fix this, if extended query is used, named @@ -6730,7 +6730,7 @@ - If frontend terminates while reading large number of query results from backend, pgpool continues to read from backend and write to - frontend until all query results consumued. (Tatsuo Ishii) + frontend until all query results consumed. (Tatsuo Ishii) This will take very long time if query results is huge. To finish pgpool session as soon as possible, modify pool_flush_it to returns error if @@ -6816,8 +6816,8 @@ See bug 191 for related info. - - Fix Chinese documetation bug about raw mode (Yugo Nagata, Bo Peng) - Connection pool is avalilable in raw mode. + - Fix Chinese documentation bug about raw mode (Yugo Nagata, Bo Peng) + Connection pool is available in raw mode. - Fix confusing comments in pgpool.conf (Tatsuo Ishii) @@ -6868,12 +6868,12 @@ - change the Makefile under the directory src/sql/, that is proposed (Bo Peng) by [pgpool-hackers: 1611] - - Fix a posible hang during health checking (Yugo Nagata) + - Fix a possible hang during health checking (Yugo Nagata) - Helath checking was hang when any data wasn't sent + Health checking was hang when any data wasn't sent from backend after connect(2) succeeded. To fix this, pool_check_fd() returns 1 when select(2) exits with - EINTR due to SIGALRM while health checkking is performed. + EINTR due to SIGALRM while health checking is performed. Reported and patch provided by harukat and some modification by Yugo. Per bug #204. @@ -7175,7 +7175,7 @@ See [pgpool-hackers: 239][pgpool-hackers: 512]. - - Disbale statement_timeout of PostgreSQL while executing online recovery + - Disable statement_timeout of PostgreSQL while executing online recovery (Tatsuo Ishii) Online recovery may take very long time and user may enable statement @@ -7297,7 +7297,7 @@ With JDBC, when a prepared statement is executed more than PrepareThreshold times, the statement is named and Describe message is sent after Parse. With named statement, pgpool rewrite now() to - parameter in replication mode. Hence, rewritten query has additonal + parameter in replication mode. Hence, rewritten query has additional parameter than original. In this case, ParameterDescription message sent to frontend (response of Describe) should include OIDs of the same number os original query's parameters. Otherwize, JDBC throws @@ -7305,12 +7305,12 @@ This is reported in [pgpool-general-jp: 1192]. - - Fix backend error of prepared statement about table which has column whoes + - Fix backend error of prepared statement about table which has column whose default value is now() in replication mode (Yugo Nagata) When pgpool parses a named prepared statement with default now(), timestamps are replaced to additional parameters. So, Bind message also - should inclued additional parameter format codes. However, when the + should included additional parameter format codes. However, when the number of original parameter was one, pgpool didn't handle this. This caused a error like "incorrect binary data format in bind parameter 2". @@ -7361,7 +7361,7 @@ Per bug#74. http://www.pgpool.net/mantisbt/view.php?id=74 - doc: Modify descriptions about restrictions of parallel mode - Muliple rows INSERT using VALUES are not supported in parallel mode. + Multiple rows INSERT using VALUES are not supported in parallel mode. (Yugo Nagata) - Avoid calling find_primary_node_repeatedly() when standby node goes @@ -7465,9 +7465,9 @@ will access out of array. Per Coverity report 1111413 "Memory - illegal accesses". - - Fix resource leak in make_persistent_db_connection. (Tatsio Ishii) + - Fix resource leak in make_persistent_db_connection. (Tatsuo Ishii) - For this pupose, new static function free_persisten_db_connection_memory + For this purpose, new static function free_persisten_db_connection_memory is added. Per Coverity report #1111468. @@ -7515,7 +7515,7 @@ - Add mention about "-D" option to the man page. (Tatsuo Ishii) - - Consider timeout waiting for compeletion of failback request in on line + - Consider timeout waiting for completion of failback request in on line recovery (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever @@ -7531,7 +7531,7 @@ The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and - kill the existig connection. This is not gentle but at this point I + kill the existing connection. This is not gentle but at this point I believe this is the best solution. - Fix bug with do_query which causes hung in extended protocol @@ -7547,7 +7547,7 @@ - Fix unnecessary degeneration caused by error on commit (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other - slaves are normal at commit, we don't need to degenrate any backend + slaves are normal at commit, we don't need to degenerate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. @@ -7612,7 +7612,7 @@ message. Problem is, the rewritten message was kept in the data which is managed by pool_create_sent_message() etc. The function assumes that all the data is in session context memory. However, palloc() - allocates memory in query context of course, and gets freeed later on + allocates memory in query context of course, and gets freed later on when the query context disappears. And the function tries to free the memory as well, which causes various problems, including segfault and double free. To fix this, memory to store rewritten message is @@ -7634,7 +7634,7 @@ http://www.pgpool.net/pipermail/pgpool-general/2013-March/001551.html - Fix to calculate replication delay only if standby server is behind from - the primay server. (Yugo Nagata) + the primary server. (Yugo Nagata) When the primary server is behind from standby server, negative value of delay is calculated and the value is assigned to unsigned variable. It @@ -7666,7 +7666,7 @@ The problem is reported in bugtrack #53. - #53 pgpool_regclas hangs all connections + #53 pgpool_regclass hangs all connections Date: 2013-04-04 13:35 Reporter: tmandke http://www.pgpool.net/mantisbt/view.php?id=53 @@ -7703,10 +7703,10 @@ Date: Sun, 28 Oct 2012 01:12:52 -0400 http://www.sraoss.jp/pipermail/pgpool-general/2012-October/001160.html - - Fix hung up while repeating pcp_attach_node and pcp_detatch_node + - Fix hung up while repeating pcp_attach_node and pcp_detach_node (Tatsuo Ishii) - When node status is changed by pcp_attach_node and pcp_detatch_node, + When node status is changed by pcp_attach_node and pcp_detach_node, failover() sends SIGUSR1 to pcp_child process expecting it exits to refresh node status. In this situation lots of pgpool children exit and produce SIGCHLD as well. The SIGCHLD handler reaper() tries catch all @@ -7724,7 +7724,7 @@ - Fix pool_send_severity_message() not to use uninitialized memory. (Tatsuo Ishii) - It cause a segmentaion fault. + It cause a segmentation fault. Reported in Bug #33's attached valgrind output by dudee. #33 pgpool-II 3.2.1 segfault @@ -7769,7 +7769,7 @@ - Fix child_exit() to not call send_frontend_exits() if there's no connection pool. (Tatsuo Ishii) - Otherwise, it segfaults because send_frontend_exits() referes to objects + Otherwise, it segfaults because send_frontend_exits() refers to objects pointed to by pool_connection_pool. Per bug track #44 by tuomas. #44 pgpool went haywire after slave shutdown triggering master failover @@ -7828,7 +7828,7 @@ - Remove unnecessary/confusing debug log from s_do_auth.(Tatsuo Ishii) - - Fix inifinit loop in SSL mode. When there's pending data in SSL layer + - Fix infinite loop in SSL mode. When there's pending data in SSL layer of frontend, pool_process_query() checks pending data in backend. (Tatsuo Ishii) @@ -7909,13 +7909,13 @@ - Fix segfault of pcp_systemdb_info not in parallel mode. (Nozomi Anzai) - - Fix "unnamed prepared statment does not exist" error. (Tatsuo Ishii) + - Fix "unnamed prepared statement does not exist" error. (Tatsuo Ishii) This is caused by pgpool's internal query, which breaks client's unnamed statements. To fix this, if extended query is used, named statement/portal for internal are used for internal query. - - Fix is_system_catalog(). Its relcach was accidently defined as + - Fix is_system_catalog(). Its relcache was accidently defined as "session local". (Tatsuo Ishii) - Fix hangup when query conflict occurs in Hot-Standby mode. @@ -8018,7 +8018,7 @@ From 3.1 transactional statements such as "BEGIN" are sent to not only primary but also standbys. This brings an unfortunate side effect: if the multi statement is "BEGIN;DELETE FROM table;END", this will be - sent to standy as well and cause an error because standby does notallow + sent to standby as well and cause an error because standby does notallow write SQL. So fix is, if a query is a multi statement one, then send it to primary only. @@ -8035,7 +8035,7 @@ Real master node could be changed while pgpool is running in streaming replication mode. Previously it is assigned REAL_MASTER_NODE_ID, which - could have no connections after fail over and cause segafult. + could have no connections after fail over and cause segfault. - Fix pool_setall_node_to_be_sent() to use private_backend_status instead of BACKEND_INFO macro. (Tatsuo Ishii) @@ -8127,7 +8127,7 @@ - Major cleanup for strncpy(Tatsuo Ishii). There are several places where strncpy() is used. Problem is some of them do not - consider the case when copy lengh == buffer size. In this case + consider the case when copy length == buffer size. In this case copied buffer is not null terminated and may cause tons of problems later. To fix this, most of them are replaced by strlcpy(). @@ -8142,7 +8142,7 @@ - Fix buffer overrun problem when pcp password is longer than 32(Tatsuo Ishii). - - Remove PGDLLIMPORTI which is only neccessary for Windows + - Remove PGDLLIMPORTI which is only necessary for Windows and cause a problem for non gcc. Patch contributed by Ibrar Ahmed. =============================================================================== @@ -8310,8 +8310,8 @@ Now restarting pgpool-II children is avoided when recovery finished. So existing sessions can be continued while doing online recovery(Tatsuo Ishii) - - pcp_attach_node does not diconnect existing sessions in - streaming replication mode. In other mode, pcp_attache_node + - pcp_attach_node does not disconnect existing sessions in + streaming replication mode. In other mode, pcp_attach_node still disconnects existing sessions(Tatsuo Ishii). - Import PostgreSQL 9.0 parser. This allows to use CREATE INDEX with @@ -8564,7 +8564,7 @@ See [pgpool-hackers: 239][pgpool-hackers: 512]. - - Disbale statement_timeout of PostgreSQL while executing online recovery + - Disable statement_timeout of PostgreSQL while executing online recovery (Tatsuo Ishii) Online recovery may take very long time and user may enable statement @@ -8660,7 +8660,7 @@ With JDBC, when a prepared statement is executed more than PrepareThreshold times, the statement is named and Describe message is sent after Parse. With named statement, pgpool rewrite now() to - parameter in replication mode. Hence, rewritten query has additonal + parameter in replication mode. Hence, rewritten query has additional parameter than original. In this case, ParameterDescription message sent to frontend (response of Describe) should include OIDs of the same number os original query's parameters. Otherwize, JDBC throws @@ -8668,12 +8668,12 @@ This is reported in [pgpool-general-jp: 1192]. - - Fix backend error of prepared statement about table which has column whoes + - Fix backend error of prepared statement about table which has column whose default value is now() in replication mode (Yugo Nagata) When pgpool parses a named prepared statement with default now(), timestamps are replaced to additional parameters. So, Bind message also - should inclued additional parameter format codes. However, when the + should included additional parameter format codes. However, when the number of original parameter was one, pgpool didn't handle this. This caused a error like "incorrect binary data format in bind parameter 2". @@ -8724,7 +8724,7 @@ Per bug#74. http://www.pgpool.net/mantisbt/view.php?id=74 - doc: Modify descriptions about restrictions of parallel mode - Muliple rows INSERT using VALUES are not supported in parallel mode. + Multiple rows INSERT using VALUES are not supported in parallel mode. (Yugo Nagata) - Avoid calling find_primary_node_repeatedly() when standby node goes @@ -8797,9 +8797,9 @@ string than the buffer. Per Coverity report 1111426 "Out-of-bounds access". - - Fix resource leak in make_persistent_db_connection. (Tatsio Ishii) + - Fix resource leak in make_persistent_db_connection. (Tatsuo Ishii) - For this pupose, new static function free_persisten_db_connection_memory + For this purpose, new static function free_persisten_db_connection_memory is added. Per Coverity report #1111468. @@ -8847,7 +8847,7 @@ - Add mention about "-D" option to the man page. (Tatsuo Ishii) - - Consider timeout waiting for compeletion of failback request in on line + - Consider timeout waiting for completion of failback request in on line recovery (Tatsuo Ishii) This will prevent the situation that recovery operation continues forever @@ -8859,7 +8859,7 @@ The typical symptom is "I see SELECT is keep on running according to pg_stat_activity". To fix this pgpool-II just exits the process and - kill the existig connection. This is not gentle but at this point I + kill the existing connection. This is not gentle but at this point I believe this is the best solution. - Fix bug with do_query which causes hung in extended protocol @@ -8875,7 +8875,7 @@ - Fix unnecessary degeneration caused by error on commit (Tatsuo Ishii) In master slave mode, if master gets an error at commit, while other - slaves are normal at commit, we don't need to degenrate any backend + slaves are normal at commit, we don't need to degenerate any backend because it is likely that the "kind mismatch error" was caused by a deferred trigger. @@ -8961,7 +8961,7 @@ message. Problem is, the rewritten message was kept in the data which is managed by pool_create_sent_message() etc. The function assumes that all the data is in session context memory. However, palloc() - allocates memory in query context of course, and gets freeed later on + allocates memory in query context of course, and gets freed later on when the query context disappears. And the function tries to free the memory as well, which causes various problems, including segfault and double free. To fix this, memory to store rewritten message is @@ -8983,7 +8983,7 @@ http://www.pgpool.net/pipermail/pgpool-general/2013-March/001551.html - Fix to calculate replication delay only if standby server is behind from - the primay server. (Yugo Nagata) + the primary server. (Yugo Nagata) When the primary server is behind from standby server, negative value of delay is calculated and the value is assigned to unsigned variable. It @@ -9015,7 +9015,7 @@ The problem is reported in bugtrack #53. - #53 pgpool_regclas hangs all connections + #53 pgpool_regclass hangs all connections Date: 2013-04-04 13:35 Reporter: tmandke http://www.pgpool.net/mantisbt/view.php?id=53 @@ -9055,7 +9055,7 @@ - Fix pool_send_severity_message() not to use uninitialized memory. (Tatsuo Ishii) - It cause a segmentaion fault. + It cause a segmentation fault. Reported in Bug #33's attached valgrind output by dudee. #33 pgpool-II 3.2.1 segfault @@ -9098,7 +9098,7 @@ - Fix child_exit() to not call send_frontend_exits() if there's no connection pool. (Tatsuo Ishii) - Otherwise, it segfaults because send_frontend_exits() referes to objects + Otherwise, it segfaults because send_frontend_exits() refers to objects pointed to by pool_connection_pool. Per bug track #44 by tuomas. #44 pgpool went haywire after slave shutdown triggering master failover @@ -9159,7 +9159,7 @@ - Remove unnecessary/confusing debug log from s_do_auth.(Tatsuo Ishii) - - Fix inifinit loop in SSL mode. When there's pending data in SSL layer + - Fix infinite loop in SSL mode. When there's pending data in SSL layer of frontend, pool_process_query() checks pending data in backend. (Tatsuo Ishii) @@ -9230,13 +9230,13 @@ - Fix segfault of pcp_systemdb_info not in parallel mode. (Nozomi Anzai) - - Fix "unnamed prepared statment does not exist" error. (Tatsuo Ishii) + - Fix "unnamed prepared statement does not exist" error. (Tatsuo Ishii) This is caused by pgpool's internal query, which breaks client's unnamed statements. To fix this, if extended query is used, named statement/portal for internal are used for internal query. - - Fix is_system_catalog(). Its relcach was accidently defined as + - Fix is_system_catalog(). Its relcache was accidently defined as "session local". (Tatsuo Ishii) - Improve reading and writing pid_file. (Tatsuo Ishii) @@ -9412,7 +9412,7 @@ - Fix bug with pcp_connect() which causes double free. Patch contributed by Jehan-Guillaume (ioguix) de Rorthais(Tatsuo Ishii) - - Fix bug with start_recoery() which is apparently wrong usage of + - Fix bug with start_recovery() which is apparently wrong usage of PQfinish()(Tatsuo Ishii) - Fix incorrect error message which is sent to the frontend when @@ -9617,7 +9617,7 @@ executes on master(primary) Also many new features are added and major refactoring has been - made to the internal structure of pgpoo-II. For example, in + made to the internal structure of pgpool-II. For example, in replication mode, SELECTs calling functions possibly write to database will not allow to load balance. @@ -9652,8 +9652,8 @@ connection pool or not are added to pcp_proc_info's output(Tatsuo Ishii) - - "Gracefuly detach" option is added to pcp_detatch_node. With - this option, pcp_detatch_node waits until all frontends + - "Gracefully detach" option is added to pcp_detach_node. With + this option, pcp_detach_node waits until all frontends disconnected(Tatsuo Ishii) - New directive "white_function_list" and "black_function_list" @@ -9724,7 +9724,7 @@ - Fix bug with timeout handling in pcp commands(Tatsuo Ishii) - - Fix SSL hang when large amount of data transfered(Tatsuo Ishii) + - Fix SSL hang when large amount of data transferred(Tatsuo Ishii) - Fix failover when there's only one DB node(Tatsuo Ishii) @@ -9903,7 +9903,7 @@ - Fix possible crash during creating "kind mismatch" error message. This used to work but was broken in 2.3.2(Tatsuo Ishii) - - Fix bug with healh checking. If a network problem such as + - Fix bug with health checking. If a network problem such as unplugged wire happens while calling connect(), health checking does not work since connect_unix_domain_socket()/connect_inet_domain_socket() do @@ -9916,7 +9916,7 @@ SimpleForwardToBackend. Per bug report from Bugtrack #1010771. Report from Peter Pramberge(Tatsuo Ishii) - - Fix rewriting "*" in paralell query. Patch conributed by + - Fix rewriting "*" in parallel query. Patch contributed by sho-san(Toshihiro Kitagawa) - Fix connect_inet_domain_socket_by_port() so that it print out @@ -9949,7 +9949,7 @@ * Version 2.3.2.1 - This version fixes bug in 2.3.x. It is identfied that + This version fixes bug in 2.3.x. It is identified that pgpool-II 2.3.x has a problem with erroneous query processing(Akio Ishida). @@ -9976,9 +9976,9 @@ later, however(Tatsuo Ishii) - Emit statement log when error or notice message comes from - query parsing process. This is usefull because PostgreSQL does + query parsing process. This is useful because PostgreSQL does not log particular statement if the error was detected - *before* raw parser get executed. This typlically happens + *before* raw parser get executed. This typically happens when encoding error was found(Tatsuo Ishii) - Display original query to log if kind mismatch error was @@ -9994,7 +9994,7 @@ * Bug fixes - - Fix errors in timestamp rewriting which occasionaly cause + - Fix errors in timestamp rewriting which occasionally cause broken packet sentto slave nodes(Tatsuo Ishii) - Fix errors when timestamp rewriting is used with V2 @@ -10007,7 +10007,7 @@ when smart shutdown signal has been sent. This has been used to work in 2.2(Toshihiro Kitagawa) - - Fix ProcessFrontendResponse not to accept invalid frotend + - Fix ProcessFrontendResponse not to accept invalid frontend packet(Xavier Noguer) - Use %dz for sizeof in fprintf for more portability(Tatsuo Ishii) @@ -10040,7 +10040,7 @@ - INSERT or UPDATE are used which explicitly include now(), - CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME. Or the target - Table's default value use above functions - - The SQL statement inclludes out of 32bit + - The SQL statement includes out of 32bit integer value(-2147483648 to 2147483647 in decimal) Example SQL: INSERT INTO t1(id, regdate) VALUES(98887776655, @@ -10060,7 +10060,7 @@ This version enhances replication, especially CURRENT_TIMESTAMP, CURRENT_DATE, now() etc. now can be properly replicated. Also - perforance of replication when num_init_children == 1 is + performance of replication when num_init_children == 1 is enhanced. Pgpool-II now records the status of down nodes, and remember when it restarts to ensure that keep the node status as before. Also some logs are enhanced and more fine fail over @@ -10082,7 +10082,7 @@ - Enable proper replication of results of temporal functions (CURRENT_TIMESTAMP, CURRENT_DATE, now() etc.). Now applications can execute INSERT/UPDATE tables which include - defaut values using those temporal functions. There are small + default values using those temporal functions. There are small limitations. See restriction sections of docs for more details (Akio Ishida) @@ -10096,7 +10096,7 @@ it easier which query is sent to which DB node(Tatsuo Ishii) - Add new directive fail_over_on_backend_error to control the - behaviro of fail over(Tatsuo Ishii) + behavior of fail over(Tatsuo Ishii) - Record DB node status and remember when pgpool-II restarts(Tatsuo Ishii) @@ -10218,11 +10218,11 @@ - In master/slave mode, execute Parse message on only master node. In previous versions Parse executed on all nodes, which - grabbed unneccessary lock(Tatsuo Ishii) + grabbed unnecessary lock(Tatsuo Ishii) - Remove init script from all runlevels before uninstall(Devrim) - - Fix pgpoo.spec(Devrim) + - Fix pgpool.spec(Devrim) - Do not execute REINDEX DATABASE or SYSTEM, CREATE/DROP TABLE SPACE inside a transaction block(Tatsuo Ishii) @@ -10231,14 +10231,14 @@ * Enhancements - - Allow to change weight by reloading pgool.conf. This will take + - Allow to change weight by reloading pgpool.conf. This will take effect for next client sessions(Tatsuo Ishii) - - Reply with usefull error messages, rather than "server closed + - Reply with useful error messages, rather than "server closed the connection unexpectedly" when authentication fails(Glyn Astill) - - Add info to logs when writing to sockets falis to know if it + - Add info to logs when writing to sockets fails to know if it was for backend or frontend(Tatsuo Ishii) - Do not complain when writing to socket of frontend @@ -10271,7 +10271,7 @@ other cases such as internal locks are issued and Parse (Tatsuo Ishii) - - Fix inifinit loop in reset_backend(Xavier Noguer, Tatsuo) + - Fix infinite loop in reset_backend(Xavier Noguer, Tatsuo) - Fix Parse() to print actual query when it detects kind mismatch error(Tatsuo Ishii) @@ -10295,9 +10295,9 @@ DML/DDL call might sent to only master node(Tatsuo Ishii) - Send NOTICE message to frontend periodically if V2 protocol is - used. This is ifdef out since it affectes visible change to - applications. 2.2.3 unconditionaly sends param packet to - client even it uses version 2 protocol, which is apparentlt + used. This is ifdef out since it affects visible change to + applications. 2.2.3 unconditionally sends param packet to + client even it uses version 2 protocol, which is apparently wrong. Also tweak checking period from 1 second to 30 seconds since 1 second seems too aggressive(Tatsuo Ishii) @@ -10325,7 +10325,7 @@ - Fix message corruption for kid mismatch error(Akio Ishida) - - Now stetmemt_time works(Tatsuo Ishii) + - Now statement_time works(Tatsuo Ishii) - Enhance health checking to detect postmaster stopping by SIGSTOP(Tatsuo Ishii) @@ -10355,8 +10355,8 @@ * Version 2.2.2 This version fixes various bugs in 2.2.1 or before. Please note - that an importan fix is made to avoid data incositency risk, - which could happen when client does not exit gracely(without + that an important fix is made to avoid data inconsistency risk, + which could happen when client does not exit gracefully(without sending "X" packet) while pgpool is trying to send data to it. This could happen with all version of pgpool-II. @@ -10366,7 +10366,7 @@ - Ignore write error on frontend connection. This is needed to continue processing with backend, otherwise we risk data - incositency(Tatsuo Ishii) + inconsistency(Tatsuo Ishii) - Fix bug introduced in 2.2.1 (In master slave mode, sometimes DEALLOCATE fails). If prepared statement reused, pgpool @@ -10396,7 +10396,7 @@ - Update pgpool.spec along with related files(Devrim) - - Fix inser_lock so that it is ignored when protocol version is + - Fix insert_lock so that it is ignored when protocol version is 2(Tatsuo Ishii) - Remove excessive log messages regarding parameter change notice(Tatsuo Ishii) @@ -10437,7 +10437,7 @@ - Add -d option to pcp commands(Jun Kuriyama) - - Enahnce kind mismatch error message to include originarl + - Enhance kind mismatch error message to include original query string(Tatsuo Ishii) __________________________________________________________________ @@ -10489,7 +10489,7 @@ M: <-- error S: <-- ok since no previous SELECT is sent. kind mismatch error occurs! - - Process status display has extra space on FreeeBSD(Jun Kuriyama) + - Process status display has extra space on FreeBSD(Jun Kuriyama) - Fix incorrect kind mismatch detection case. e.g: BEGIN; BEGIN; (Tatsuo Ishii) @@ -10500,7 +10500,7 @@ return ReadyForQuery. This due to a wrong assumption for the client/server protocol(Tatsuo Ishii) - - Fix the case when sending an erronous query to abort + - Fix the case when sending an erroneous query to abort transaction. It assumed that after sending an error query, always ReadyForQuery came right after that. If some debugging or logging verboseness is set, PostgreSQL might @@ -10621,7 +10621,7 @@ - Fix INSERT failure. (Yoshiharu Mori) - Fix syntax error when a query contains "AS" in FROM clause. (sho) - - Fix Hung up when two or more statment was executed + - Fix Hung up when two or more statement was executed in parallel mode (Yoshiharu Mori) - Fix Query rewriting of Join Expression and DISTINCT ON (Yoshiharu Mori) @@ -10656,7 +10656,7 @@ * General - Allow to reload pgpool.conf(Yoshiyuki Asaba) - - The paraser is now compatible with PostgreSQL 8.3(Yoshiyuki Asaba) + - The parser is now compatible with PostgreSQL 8.3(Yoshiyuki Asaba) - Add new directive "failover_command" to specify command when a node is detached(Yoshiyuki Asaba) - Add new directive "client_idle_limit" to specify the time out since @@ -10667,12 +10667,12 @@ * Replication - Always start a new transaction even if the query is not in - an explicit transaction to enhance the reliabilty of + an explicit transaction to enhance the reliability of replication(Yoshiyuki Asaba) - Enhance the performance of replication for write queries. Now the worst case is 1/2 compared with single DB node regardless the number of DB nodes. Previous release - tends to degrade according to the numer of DB + tends to degrade according to the number of DB nodes(Yoshiyuki Asaba) - Add "online recovery" which allows to add a DB node and sync with other DB nodes without stopping the pgpool @@ -10741,7 +10741,7 @@ - If it is true, SELECT query is replicated. This behavior is same as V3.2 or earlier. * Improve signal handling. (Yoshiyuki Asaba) - - Occasionaly, zombie processes were remained. Or processes + - Occasionally, zombie processes were remained. Or processes were unstable. * Fix hang up when SELECT was error inside a transaction block. The bug was introduced in V3.3. (Yoshiyuki Asaba) @@ -10784,7 +10784,7 @@ * Improve replication. SELECT nextval() and SELECT setval() are now replicated. (Yoshiyuki Asaba) * Change SELECT query is only sent to the master node. (Yoshiyuki Asaba) - - Use /*REPLICATION*/ comment to repliate a SELECT query. + - Use /*REPLICATION*/ comment to replicate a SELECT query. * Fix unexpected failover error due to receiving an interrupt signal while connecting to the backend. (Yoshiyuki Asaba) * Add "pgpool.pam" file, for PAM configuration file, to be diff --git a/README.build b/README.build index f96d29096..0b7544aa5 100644 --- a/README.build +++ b/README.build @@ -1,6 +1,6 @@ This memo explains the rule how to build pgpool-II source tree using autotools and need to push derived files such as Makefile.in into -pgpool-II official source reporsitory. +pgpool-II official source repository. So the rule does not apply to: diff --git a/README.online-recovery b/README.online-recovery index efdc3dcb0..5b9aeb92f 100644 --- a/README.online-recovery +++ b/README.online-recovery @@ -19,7 +19,7 @@ * */ -How does online reconvery work? +How does online recovery work? pcp_recovery_node calls pcp_recovery_node() API @@ -31,7 +31,7 @@ pcp_recovery_node(int node_id) does: pcp_child calls start_recovery() and waits for its completion start_recovery() sets Req_info->kind to NODE_RECOVERY_REQUEST - start_recovery calls execute_checkpoint() execute CHEKPOINT + start_recovery calls execute_checkpoint() execute CHECKPOINT command start_recovery calls exec_recovery exec_recovery executes SELECT pgpool_recovery() @@ -40,7 +40,7 @@ pcp_recovery_node(int node_id) does: /* start 2nd stage */ sets InRecovery to 1 wait_connection_closed() to wait for all frontend exits - calls execute_checkpoint() execute CHEKPOINT + calls execute_checkpoint() execute CHECKPOINT calls exec_recovery to execute 2nd stage script calls exec_remote_start to start postmaster calls check_postmaster_started to wait for postmaster starts diff --git a/TODO b/TODO index 9028c3f3e..c109dcb80 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,7 @@ $Header$ * General -- Reset application name to "pgppol" when client disconnects(3.1. why +- Reset application name to "pgpool" when client disconnects(3.1. why not use set command?) -> Done. - Use reset_query_list to reset to "pgpool" for client disconnection - Reset to client specified application name when reusing existing @@ -55,11 +55,11 @@ $Header$ - Cache invalidation -- More effcient cache (memcache?) +- More efficient cache (memcache?) * Log -- Mutiple log levels(3.1, but low priority) +- Multiple log levels(3.1, but low priority) - Multiple log destinations(3.1, but low priority) @@ -91,7 +91,7 @@ LINE 1: SELECT pool_parallel("SELECT d1.id, d1.aaaa, d1.bbbb... - Allow to run pgpoolAdmin on a host different from a host which pgpool-II is running on(3.2?) -- Allow to stop PostgeSQL from pgpoolAdmin to make the on-line +- Allow to stop PostgreSQL from pgpoolAdmin to make the on-line recovery more convenient(pgpool_stop()?) * Docs diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index 27b03b797..000000000 --- a/aclocal.m4 +++ /dev/null @@ -1,845 +0,0 @@ -# generated automatically by aclocal 1.13.4 -*- Autoconf -*- - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.13' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.13.4], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.13.4])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Copyright (C) 1998-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_LEX -# ----------- -# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a -# "missing" invocation, for better error output. -AC_DEFUN([AM_PROG_LEX], -[AC_PREREQ([2.50])dnl -AC_REQUIRE([AM_MISSING_HAS_RUN])dnl -AC_REQUIRE([AC_PROG_LEX])dnl -if test "$LEX" = :; then - LEX=${am_missing_run}flex -fi]) - -# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- -# From Jim Meyering - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAINTAINER_MODE([DEFAULT-MODE]) -# ---------------------------------- -# Control maintainer-specific portions of Makefiles. -# Default is to disable them, unless 'enable' is passed literally. -# For symmetry, 'disable' may be passed as well. Anyway, the user -# can override the default with the --enable/--disable switch. -AC_DEFUN([AM_MAINTAINER_MODE], -[m4_case(m4_default([$1], [disable]), - [enable], [m4_define([am_maintainer_other], [disable])], - [disable], [m4_define([am_maintainer_other], [enable])], - [m4_define([am_maintainer_other], [enable]) - m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) -AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode's default is 'disable' unless 'enable' is passed - AC_ARG_ENABLE([maintainer-mode], - [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], - am_maintainer_other[ make rules and dependencies not useful - (and sometimes confusing) to the casual installer])], - [USE_MAINTAINER_MODE=$enableval], - [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) - AC_MSG_RESULT([$USE_MAINTAINER_MODE]) - AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST([MAINT])dnl -] -) - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_CC_C_O -# -------------- -# Like AC_PROG_CC_C_O, but changed for automake. -AC_DEFUN([AM_PROG_CC_C_O], -[AC_REQUIRE([AC_PROG_CC_C_O])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -dnl Make sure AC_PROG_CC is never called again, or it will override our -dnl setting of CC. -m4_define([AC_PROG_CC], - [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# -*- Autoconf -*- -# Obsolete and "removed" macros, that must however still report explicit -# error messages when used, to smooth transition. -# -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -AC_DEFUN([AM_CONFIG_HEADER], -[AC_DIAGNOSE([obsolete], -['$0': this macro is obsolete. -You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl -AC_CONFIG_HEADERS($@)]) - -AC_DEFUN([AM_PROG_CC_STDC], -[AC_PROG_CC -am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc -AC_DIAGNOSE([obsolete], -['$0': this macro is obsolete. -You should simply use the 'AC][_PROG_CC' macro instead. -Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', -but upon 'ac_cv_prog_cc_stdc'.])]) - -AC_DEFUN([AM_C_PROTOTYPES], - [AC_FATAL([automatic de-ANSI-fication support has been removed])]) -AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([m4/docbook.m4]) -m4_include([m4/libtool.m4]) -m4_include([m4/ltoptions.m4]) -m4_include([m4/ltsugar.m4]) -m4_include([m4/ltversion.m4]) -m4_include([m4/lt~obsolete.m4]) diff --git a/c-compiler.m4 b/c-compiler.m4 index 70ed5c6f4..71b645839 100644 --- a/c-compiler.m4 +++ b/c-compiler.m4 @@ -1,5 +1,5 @@ # Macros to detect C compiler features -# $PostgreSQL: pgsql/config/c-compiler.m4,v 1.19 2008/06/27 00:36:16 tgl Exp $ +# config/c-compiler.m4 # PGAC_C_SIGNED @@ -7,8 +7,8 @@ # Check if the C compiler understands signed types. AC_DEFUN([PGAC_C_SIGNED], [AC_CACHE_CHECK(for signed types, pgac_cv_c_signed, -[AC_TRY_COMPILE([], -[signed char c; signed short s; signed int i;], +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], +[signed char c; signed short s; signed int i;])], [pgac_cv_c_signed=yes], [pgac_cv_c_signed=no])]) if test x"$pgac_cv_c_signed" = xno ; then @@ -17,6 +17,42 @@ fi])# PGAC_C_SIGNED +# PGAC_C_PRINTF_ARCHETYPE +# ----------------------- +# 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 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) # ------------------------- # Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to @@ -25,7 +61,7 @@ AC_DEFUN([PGAC_TYPE_64BIT_INT], [define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar], -[AC_TRY_RUN( +[AC_RUN_IFELSE([AC_LANG_SOURCE( [typedef $1 ac_int64; /* @@ -49,9 +85,11 @@ int does_int64_work() return 0; return 1; } + +int main() { - exit(! does_int64_work()); -}], + return (! does_int64_work()); +}])], [Ac_cachevar=yes], [Ac_cachevar=no], [# If cross-compiling, check the size reported by the compiler and @@ -69,6 +107,78 @@ undefine([Ac_cachevar])dnl ])# PGAC_TYPE_64BIT_INT +# PGAC_TYPE_128BIT_INT +# --------------------- +# Check if __int128 is a working 128 bit integer type, and if so +# define PG_INT128_TYPE to that typename, and define ALIGNOF_PG_INT128_TYPE +# as its alignment requirement. +# +# This currently only detects a GCC/clang extension, but support for other +# environments may be added in the future. +# +# For the moment we only test for support for 128bit math; support for +# 128bit literals and snprintf is not required. +AC_DEFUN([PGAC_TYPE_128BIT_INT], +[AC_CACHE_CHECK([for __int128], [pgac_cv__128bit_int], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([ +/* + * We don't actually run this test, just link it to verify that any support + * functions needed for __int128 are present. + * + * These are globals to discourage the compiler from folding all the + * arithmetic tests down to compile-time constants. We do not have + * convenient support for 128bit literals at this point... + */ +__int128 a = 48828125; +__int128 b = 97656250; +],[ +__int128 c,d; +a = (a << 12) + 1; /* 200000000001 */ +b = (b << 12) + 5; /* 400000000005 */ +/* try the most relevant arithmetic ops */ +c = a * b; +d = (c + b) / b; +/* must use the results, else compiler may optimize arithmetic away */ +if (d != a+1) + return 1; +])], +[pgac_cv__128bit_int=yes], +[pgac_cv__128bit_int=no])]) +if test x"$pgac_cv__128bit_int" = xyes ; then + # Use of non-default alignment with __int128 tickles bugs in some compilers. + # If not cross-compiling, we can test for bugs and disable use of __int128 + # with buggy compilers. If cross-compiling, hope for the best. + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83925 + AC_CACHE_CHECK([for __int128 alignment bug], [pgac_cv__128bit_int_bug], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([ +/* This must match the corresponding code in c.h: */ +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__) +#define pg_attribute_aligned(a) __attribute__((aligned(a))) +#endif +typedef __int128 int128a +#if defined(pg_attribute_aligned) +pg_attribute_aligned(8) +#endif +; +int128a holder; +void pass_by_val(void *buffer, int128a par) { holder = par; } +],[ +long int i64 = 97656225L << 12; +int128a q; +pass_by_val(main, (int128a) i64); +q = (int128a) i64; +if (q != holder) + return 1; +])], + [pgac_cv__128bit_int_bug=ok], + [pgac_cv__128bit_int_bug=broken], + [pgac_cv__128bit_int_bug="assuming ok"])]) + if test x"$pgac_cv__128bit_int_bug" != xbroken ; then + AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.]) + AC_CHECK_ALIGNOF(PG_INT128_TYPE) + fi +fi])# PGAC_TYPE_128BIT_INT + # PGAC_C_FUNCNAME_SUPPORT # ----------------------- @@ -76,8 +186,8 @@ undefine([Ac_cachevar])dnl # Define HAVE_FUNCNAME__FUNC or HAVE_FUNCNAME__FUNCTION accordingly. AC_DEFUN([PGAC_C_FUNCNAME_SUPPORT], [AC_CACHE_CHECK(for __func__, pgac_cv_funcname_func_support, -[AC_TRY_COMPILE([#include ], -[printf("%s\n", __func__);], +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], +[printf("%s\n", __func__);])], [pgac_cv_funcname_func_support=yes], [pgac_cv_funcname_func_support=no])]) if test x"$pgac_cv_funcname_func_support" = xyes ; then @@ -85,8 +195,8 @@ AC_DEFINE(HAVE_FUNCNAME__FUNC, 1, [Define to 1 if your compiler understands __func__.]) else AC_CACHE_CHECK(for __FUNCTION__, pgac_cv_funcname_function_support, -[AC_TRY_COMPILE([#include ], -[printf("%s\n", __FUNCTION__);], +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], +[printf("%s\n", __FUNCTION__);])], [pgac_cv_funcname_function_support=yes], [pgac_cv_funcname_function_support=no])]) if test x"$pgac_cv_funcname_function_support" = xyes ; then @@ -97,22 +207,284 @@ fi])# PGAC_C_FUNCNAME_SUPPORT +# PGAC_C_STATIC_ASSERT +# -------------------- +# Check if the C compiler understands _Static_assert(), +# and define HAVE__STATIC_ASSERT if so. +# +# We actually check the syntax ({ _Static_assert(...) }), because we need +# gcc-style compound expressions to be able to wrap the thing into macros. +AC_DEFUN([PGAC_C_STATIC_ASSERT], +[AC_CACHE_CHECK(for _Static_assert, pgac_cv__static_assert, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], +[({ _Static_assert(1, "foo"); })])], +[pgac_cv__static_assert=yes], +[pgac_cv__static_assert=no])]) +if test x"$pgac_cv__static_assert" = xyes ; then +AC_DEFINE(HAVE__STATIC_ASSERT, 1, + [Define to 1 if your compiler understands _Static_assert.]) +fi])# PGAC_C_STATIC_ASSERT + + + +# PGAC_C_TYPEOF +# ------------- +# Check if the C compiler understands typeof or a variant. Define +# HAVE_TYPEOF if so, and define 'typeof' to the actual key word. +# +AC_DEFUN([PGAC_C_TYPEOF], +[AC_CACHE_CHECK(for typeof, pgac_cv_c_typeof, +[pgac_cv_c_typeof=no +for pgac_kw in typeof __typeof__ decltype; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], +[int x = 0; +$pgac_kw(x) y; +y = x; +return y;])], +[pgac_cv_c_typeof=$pgac_kw]) + test "$pgac_cv_c_typeof" != no && break +done]) +if test "$pgac_cv_c_typeof" != no; then + AC_DEFINE(HAVE_TYPEOF, 1, + [Define to 1 if your compiler understands `typeof' or something similar.]) + if test "$pgac_cv_c_typeof" != typeof; then + AC_DEFINE_UNQUOTED(typeof, $pgac_cv_c_typeof, [Define to how the compiler spells `typeof'.]) + fi +fi])# PGAC_C_TYPEOF + + + +# PGAC_C_TYPES_COMPATIBLE +# ----------------------- +# Check if the C compiler understands __builtin_types_compatible_p, +# and define HAVE__BUILTIN_TYPES_COMPATIBLE_P if so. +# +# We check usage with __typeof__, though it's unlikely any compiler would +# have the former and not the latter. +AC_DEFUN([PGAC_C_TYPES_COMPATIBLE], +[AC_CACHE_CHECK(for __builtin_types_compatible_p, pgac_cv__types_compatible, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], +[[ int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)]; ]])], +[pgac_cv__types_compatible=yes], +[pgac_cv__types_compatible=no])]) +if test x"$pgac_cv__types_compatible" = xyes ; then +AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1, + [Define to 1 if your compiler understands __builtin_types_compatible_p.]) +fi])# PGAC_C_TYPES_COMPATIBLE + + +# PGAC_C_BUILTIN_CONSTANT_P +# ------------------------- +# Check if the C compiler understands __builtin_constant_p(), +# and define HAVE__BUILTIN_CONSTANT_P if so. +# We need __builtin_constant_p("string literal") to be true, but some older +# compilers don't think that, so test for that case explicitly. +AC_DEFUN([PGAC_C_BUILTIN_CONSTANT_P], +[AC_CACHE_CHECK(for __builtin_constant_p, pgac_cv__builtin_constant_p, +[AC_COMPILE_IFELSE([AC_LANG_SOURCE( +[[static int x; + static int y[__builtin_constant_p(x) ? x : 1]; + static int z[__builtin_constant_p("string literal") ? 1 : x]; +]] +)], +[pgac_cv__builtin_constant_p=yes], +[pgac_cv__builtin_constant_p=no])]) +if test x"$pgac_cv__builtin_constant_p" = xyes ; then +AC_DEFINE(HAVE__BUILTIN_CONSTANT_P, 1, + [Define to 1 if your compiler understands __builtin_constant_p.]) +fi])# PGAC_C_BUILTIN_CONSTANT_P + + + +# PGAC_C_BUILTIN_OP_OVERFLOW +# ------------------------- +# Check if the C compiler understands __builtin_$op_overflow(), +# and define HAVE__BUILTIN_OP_OVERFLOW if so. +# +# Check for the most complicated case, 64 bit multiplication, as a +# proxy for all of the operations. To detect the case where the compiler +# knows the function but library support is missing, we must link not just +# compile, and store the results in global variables so the compiler doesn't +# optimize away the call. +AC_DEFUN([PGAC_C_BUILTIN_OP_OVERFLOW], +[AC_CACHE_CHECK(for __builtin_mul_overflow, pgac_cv__builtin_op_overflow, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([ +PG_INT64_TYPE a = 1; +PG_INT64_TYPE b = 1; +PG_INT64_TYPE result; +int oflo; +], +[oflo = __builtin_mul_overflow(a, b, &result);])], +[pgac_cv__builtin_op_overflow=yes], +[pgac_cv__builtin_op_overflow=no])]) +if test x"$pgac_cv__builtin_op_overflow" = xyes ; then +AC_DEFINE(HAVE__BUILTIN_OP_OVERFLOW, 1, + [Define to 1 if your compiler understands __builtin_$op_overflow.]) +fi])# PGAC_C_BUILTIN_OP_OVERFLOW + + + +# PGAC_C_BUILTIN_UNREACHABLE +# -------------------------- +# Check if the C compiler understands __builtin_unreachable(), +# and define HAVE__BUILTIN_UNREACHABLE if so. +# +# NB: Don't get the idea of putting a for(;;); or such before the +# __builtin_unreachable() call. Some compilers would remove it before linking +# and only a warning instead of an error would be produced. +AC_DEFUN([PGAC_C_BUILTIN_UNREACHABLE], +[AC_CACHE_CHECK(for __builtin_unreachable, pgac_cv__builtin_unreachable, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], +[__builtin_unreachable();])], +[pgac_cv__builtin_unreachable=yes], +[pgac_cv__builtin_unreachable=no])]) +if test x"$pgac_cv__builtin_unreachable" = xyes ; then +AC_DEFINE(HAVE__BUILTIN_UNREACHABLE, 1, + [Define to 1 if your compiler understands __builtin_unreachable.]) +fi])# PGAC_C_BUILTIN_UNREACHABLE + + + +# PGAC_C_COMPUTED_GOTO +# ----------------------- +# Check if the C compiler knows computed gotos (gcc extension, also +# available in at least clang). If so, define HAVE_COMPUTED_GOTO. +# +# Checking whether computed gotos are supported syntax-wise ought to +# be enough, as the syntax is otherwise illegal. +AC_DEFUN([PGAC_C_COMPUTED_GOTO], +[AC_CACHE_CHECK(for computed goto support, pgac_cv_computed_goto, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], +[[void *labeladdrs[] = {&&my_label}; + goto *labeladdrs[0]; + my_label: + return 1; +]])], +[pgac_cv_computed_goto=yes], +[pgac_cv_computed_goto=no])]) +if test x"$pgac_cv_computed_goto" = xyes ; then +AC_DEFINE(HAVE_COMPUTED_GOTO, 1, + [Define to 1 if your compiler handles computed gotos.]) +fi])# PGAC_C_COMPUTED_GOTO + + + +# 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 + + + +# PGAC_PROG_VARCC_VARFLAGS_OPT +# ----------------------- +# Given a compiler, variable name and a string, check if the compiler +# supports the string as a command-line option. If it does, add the +# string to the given variable. +AC_DEFUN([PGAC_PROG_VARCC_VARFLAGS_OPT], +[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_$1_cflags_$3])])dnl +AC_CACHE_CHECK([whether ${$1} supports $3, for $2], [Ac_cachevar], +[pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${$1} +CFLAGS="${$2} $3" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [Ac_cachevar=yes], + [Ac_cachevar=no]) +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC"]) +if test x"$Ac_cachevar" = x"yes"; then + $2="${$2} $3" +fi +undefine([Ac_cachevar])dnl +])# PGAC_PROG_VARCC_VARFLAGS_OPT + + + # PGAC_PROG_CC_CFLAGS_OPT # ----------------------- # Given a string, check if the compiler supports the string as a # command-line option. If it does, add the string to CFLAGS. -AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT], -[AC_MSG_CHECKING([if $CC supports $1]) -pgac_save_CFLAGS=$CFLAGS -CFLAGS="$pgac_save_CFLAGS $1" -_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], - AC_MSG_RESULT(yes), - [CFLAGS="$pgac_save_CFLAGS" - AC_MSG_RESULT(no)]) +AC_DEFUN([PGAC_PROG_CC_CFLAGS_OPT], [ +PGAC_PROG_VARCC_VARFLAGS_OPT(CC, CFLAGS, $1) ])# PGAC_PROG_CC_CFLAGS_OPT +# PGAC_PROG_CC_VAR_OPT +# ----------------------- +# Given a variable name and a string, check if the compiler supports +# the string as a command-line option. If it does, add the string to +# the given variable. +AC_DEFUN([PGAC_PROG_CC_VAR_OPT], +[PGAC_PROG_VARCC_VARFLAGS_OPT(CC, $1, $2) +])# PGAC_PROG_CC_VAR_OPT + + + +# PGAC_PROG_VARCXX_VARFLAGS_OPT +# ----------------------- +# Given a compiler, variable name and a string, check if the compiler +# supports the string as a command-line option. If it does, add the +# string to the given variable. +AC_DEFUN([PGAC_PROG_VARCXX_VARFLAGS_OPT], +[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_$1_cxxflags_$3])])dnl +AC_CACHE_CHECK([whether ${$1} supports $3, for $2], [Ac_cachevar], +[pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${$1} +CXXFLAGS="${$2} $3" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +AC_LANG_PUSH(C++) +_AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [Ac_cachevar=yes], + [Ac_cachevar=no]) +AC_LANG_POP([]) +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX"]) +if test x"$Ac_cachevar" = x"yes"; then + $2="${$2} $3" +fi +undefine([Ac_cachevar])dnl +])# PGAC_PROG_VARCXX_VARFLAGS_OPT + + + +# PGAC_PROG_CXX_CFLAGS_OPT +# ----------------------- +# Given a string, check if the compiler supports the string as a +# command-line option. If it does, add the string to CXXFLAGS. +AC_DEFUN([PGAC_PROG_CXX_CFLAGS_OPT], +[PGAC_PROG_VARCXX_VARFLAGS_OPT(CXX, CXXFLAGS, $1) +])# PGAC_PROG_CXX_VAR_OPT + + + # PGAC_PROG_CC_LDFLAGS_OPT # ------------------------ # Given a string, check if the compiler supports the string as a @@ -121,14 +493,179 @@ _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], # you can link to a particular function, not just whether you can link. # In fact, we must actually check that the resulting program runs :-( AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT], -[AC_MSG_CHECKING([if $CC supports $1]) -pgac_save_LDFLAGS=$LDFLAGS +[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_ldflags_$1])])dnl +AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar], +[pgac_save_LDFLAGS=$LDFLAGS LDFLAGS="$pgac_save_LDFLAGS $1" AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])], - AC_MSG_RESULT(yes), - [LDFLAGS="$pgac_save_LDFLAGS" - AC_MSG_RESULT(no)], - [LDFLAGS="$pgac_save_LDFLAGS" - AC_MSG_RESULT(assuming no)]) + [Ac_cachevar=yes], + [Ac_cachevar=no], + [Ac_cachevar="assuming no"]) +LDFLAGS="$pgac_save_LDFLAGS"]) +if test x"$Ac_cachevar" = x"yes"; then + LDFLAGS="$LDFLAGS $1" +fi +undefine([Ac_cachevar])dnl ])# PGAC_PROG_CC_LDFLAGS_OPT +# PGAC_HAVE_GCC__SYNC_CHAR_TAS +# ------------------------- +# Check if the C compiler understands __sync_lock_test_and_set(char), +# and define HAVE_GCC__SYNC_CHAR_TAS +# +# NB: There are platforms where test_and_set is available but compare_and_swap +# is not, so test this separately. +# NB: Some platforms only do 32bit tas, others only do 8bit tas. Test both. +AC_DEFUN([PGAC_HAVE_GCC__SYNC_CHAR_TAS], +[AC_CACHE_CHECK(for builtin __sync char locking functions, pgac_cv_gcc_sync_char_tas, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], + [char lock = 0; + __sync_lock_test_and_set(&lock, 1); + __sync_lock_release(&lock);])], + [pgac_cv_gcc_sync_char_tas="yes"], + [pgac_cv_gcc_sync_char_tas="no"])]) +if test x"$pgac_cv_gcc_sync_char_tas" = x"yes"; then + AC_DEFINE(HAVE_GCC__SYNC_CHAR_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(char *) and friends.]) +fi])# PGAC_HAVE_GCC__SYNC_CHAR_TAS + +# PGAC_HAVE_GCC__SYNC_INT32_TAS +# ------------------------- +# Check if the C compiler understands __sync_lock_test_and_set(), +# and define HAVE_GCC__SYNC_INT32_TAS +AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_TAS], +[AC_CACHE_CHECK(for builtin __sync int32 locking functions, pgac_cv_gcc_sync_int32_tas, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], + [int lock = 0; + __sync_lock_test_and_set(&lock, 1); + __sync_lock_release(&lock);])], + [pgac_cv_gcc_sync_int32_tas="yes"], + [pgac_cv_gcc_sync_int32_tas="no"])]) +if test x"$pgac_cv_gcc_sync_int32_tas" = x"yes"; then + AC_DEFINE(HAVE_GCC__SYNC_INT32_TAS, 1, [Define to 1 if you have __sync_lock_test_and_set(int *) and friends.]) +fi])# PGAC_HAVE_GCC__SYNC_INT32_TAS + +# PGAC_HAVE_GCC__SYNC_INT32_CAS +# ------------------------- +# Check if the C compiler understands __sync_compare_and_swap() for 32bit +# types, and define HAVE_GCC__SYNC_INT32_CAS if so. +AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_CAS], +[AC_CACHE_CHECK(for builtin __sync int32 atomic operations, pgac_cv_gcc_sync_int32_cas, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], + [int val = 0; + __sync_val_compare_and_swap(&val, 0, 37);])], + [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_val_compare_and_swap(int *, int, int).]) +fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS + +# PGAC_HAVE_GCC__SYNC_INT64_CAS +# ------------------------- +# Check if the C compiler understands __sync_compare_and_swap() for 64bit +# types, and define HAVE_GCC__SYNC_INT64_CAS if so. +AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS], +[AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], + [PG_INT64_TYPE lock = 0; + __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])], + [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_val_compare_and_swap(int64 *, int64, int64).]) +fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS + +# PGAC_HAVE_GCC__ATOMIC_INT32_CAS +# ------------------------- +# Check if the C compiler understands __atomic_compare_exchange_n() for 32bit +# types, and define HAVE_GCC__ATOMIC_INT32_CAS if so. +AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT32_CAS], +[AC_CACHE_CHECK(for builtin __atomic int32 atomic operations, pgac_cv_gcc_atomic_int32_cas, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], + [int val = 0; + int expect = 0; + __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])], + [pgac_cv_gcc_atomic_int32_cas="yes"], + [pgac_cv_gcc_atomic_int32_cas="no"])]) +if test x"$pgac_cv_gcc_atomic_int32_cas" = x"yes"; then + AC_DEFINE(HAVE_GCC__ATOMIC_INT32_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int).]) +fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS + +# PGAC_HAVE_GCC__ATOMIC_INT64_CAS +# ------------------------- +# Check if the C compiler understands __atomic_compare_exchange_n() for 64bit +# types, and define HAVE_GCC__ATOMIC_INT64_CAS if so. +AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS], +[AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([], + [PG_INT64_TYPE val = 0; + PG_INT64_TYPE expect = 0; + __atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])], + [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 *, int64 *, int64).]) +fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS + +# PGAC_SSE42_CRC32_INTRINSICS +# ----------------------- +# Check if the compiler supports the x86 CRC instructions added in SSE 4.2, +# using the _mm_crc32_u8 and _mm_crc32_u32 intrinsic functions. (We don't +# test the 8-byte variant, _mm_crc32_u64, but it is assumed to be present if +# the other ones are, on x86-64 platforms) +# +# An optional compiler flag can be passed as argument (e.g. -msse4.2). If the +# intrinsics are supported, sets pgac_sse42_crc32_intrinsics, and CFLAGS_SSE42. +AC_DEFUN([PGAC_SSE42_CRC32_INTRINSICS], +[define([Ac_cachevar], [AS_TR_SH([pgac_cv_sse42_crc32_intrinsics_$1])])dnl +AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=$1], [Ac_cachevar], +[pgac_save_CFLAGS=$CFLAGS +CFLAGS="$pgac_save_CFLAGS $1" +AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [unsigned int crc = 0; + crc = _mm_crc32_u8(crc, 0); + crc = _mm_crc32_u32(crc, 0); + /* return computed value, to prevent the above being optimized away */ + return crc == 0;])], + [Ac_cachevar=yes], + [Ac_cachevar=no]) +CFLAGS="$pgac_save_CFLAGS"]) +if test x"$Ac_cachevar" = x"yes"; then + CFLAGS_SSE42="$1" + pgac_sse42_crc32_intrinsics=yes +fi +undefine([Ac_cachevar])dnl +])# PGAC_SSE42_CRC32_INTRINSICS + + +# PGAC_ARMV8_CRC32C_INTRINSICS +# ----------------------- +# Check if the compiler supports the CRC32C instructions using the __crc32cb, +# __crc32ch, __crc32cw, and __crc32cd intrinsic functions. These instructions +# were first introduced in ARMv8 in the optional CRC Extension, and became +# mandatory in ARMv8.1. +# +# An optional compiler flag can be passed as argument (e.g. +# -march=armv8-a+crc). If the intrinsics are supported, sets +# pgac_armv8_crc32c_intrinsics, and CFLAGS_ARMV8_CRC32C. +AC_DEFUN([PGAC_ARMV8_CRC32C_INTRINSICS], +[define([Ac_cachevar], [AS_TR_SH([pgac_cv_armv8_crc32c_intrinsics_$1])])dnl +AC_CACHE_CHECK([for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=$1], [Ac_cachevar], +[pgac_save_CFLAGS=$CFLAGS +CFLAGS="$pgac_save_CFLAGS $1" +AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [unsigned int crc = 0; + crc = __crc32cb(crc, 0); + crc = __crc32ch(crc, 0); + crc = __crc32cw(crc, 0); + crc = __crc32cd(crc, 0); + /* return computed value, to prevent the above being optimized away */ + return crc == 0;])], + [Ac_cachevar=yes], + [Ac_cachevar=no]) +CFLAGS="$pgac_save_CFLAGS"]) +if test x"$Ac_cachevar" = x"yes"; then + CFLAGS_ARMV8_CRC32C="$1" + pgac_armv8_crc32c_intrinsics=yes +fi +undefine([Ac_cachevar])dnl +])# PGAC_ARMV8_CRC32C_INTRINSICS diff --git a/c-library.m4 b/c-library.m4 index 74754b20e..482d250f6 100644 --- a/c-library.m4 +++ b/c-library.m4 @@ -230,6 +230,9 @@ AC_DEFUN([PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT], AC_CACHE_VAL(pgac_cv_snprintf_long_long_int_format, [for pgac_format in '%lld' '%qd' '%I64d'; do AC_TRY_RUN([#include +#include +#include + typedef long long int ac_int64; #define INT64_FORMAT "$pgac_format" diff --git a/compile b/compile deleted file mode 100644 index e69de29bb..000000000 diff --git a/config.guess b/config.guess deleted file mode 100755 index d622a44e5..000000000 --- a/config.guess +++ /dev/null @@ -1,1530 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. - -timestamp='2012-02-10' - -# 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 -# the Free Software Foundation; either version 2 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. -# -# You should have received a copy of the GNU General Public License -# 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 -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# 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;hb=HEAD - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -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." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - 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 -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# 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= ;' - -# 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 - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -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 - -# Note: order is significant - the case branches are not exclusive. - -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*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - 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 ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # 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 - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - 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}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # 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'` - # 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 - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - 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/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $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. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - 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/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - 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 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - 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 - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # 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} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - 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); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - 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` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - 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 - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - 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 - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - 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 - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - 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 - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - 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 ;; - 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 - 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 - 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 - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (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" ] - then - eval $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 - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - 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} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $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:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - 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/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - 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/ /_/'` - 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/ /_/'` - 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} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - 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 - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`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 '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $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-gnu - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - 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-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # 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} - 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 - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86: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} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V: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} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - 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 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - 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 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - 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; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { 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; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - 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; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { 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; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - 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} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - 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} - 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} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - 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 - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - 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} - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - 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. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $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 (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#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 (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; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 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} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/config.sub b/config.sub deleted file mode 100755 index c894da455..000000000 --- a/config.sub +++ /dev/null @@ -1,1773 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012 Free Software Foundation, Inc. - -timestamp='2012-02-10' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# 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 -# the Free Software Foundation; either version 2 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. -# -# You should have received a copy of the GNU General Public License -# 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 -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# 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;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 -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." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - 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-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - 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 - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -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) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -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 | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | 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 \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 \ - | ns16k | ns32k \ - | open8 \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | 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 \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | 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 - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-unknown - ;; - - # 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-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ - | 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-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | 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-* \ - | 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 - ;; - 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 - ;; - 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 - ;; - 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 - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-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 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - 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 - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-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 - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-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 - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - 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 - ;; - mingw32) - basic_machine=i386-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 - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i386-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-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 - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - 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 - ;; - 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 - ;; - 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 - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - 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/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - 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 | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-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 - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - 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 - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - 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 - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - 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) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -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 - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First 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* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -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* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -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*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - 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 $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/configure b/configure deleted file mode 100755 index c39d7d657..000000000 --- a/configure +++ /dev/null @@ -1,17203 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for pgpool-II 4.1devel. -# -# Report bugs to . -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 - - test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ - || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: pgpool-hackers@pgpool.net 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." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - -SHELL=${CONFIG_SHELL-/bin/sh} - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='pgpool-II' -PACKAGE_TARNAME='pgpool-II' -PACKAGE_VERSION='4.1devel' -PACKAGE_STRING='pgpool-II 4.1devel' -PACKAGE_BUGREPORT='pgpool-hackers@pgpool.net' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -enable_rpath_FALSE -enable_rpath_TRUE -MEMCACHED_DIR -PGSQL_LIB_DIR -PGSQL_INCLUDE_DIR -MEMCACHED_RPATH_OPT -MEMCACHED_LINK_OPT -MEMCACHED_INCLUDE_OPT -PGCONFIG -use_repl_snprintf_FALSE -use_repl_snprintf_TRUE -LIBOBJS -STYLE_ENV_SET_FALSE -STYLE_ENV_SET_TRUE -STYLE -XSLTPROC_HTML_FLAGS -LYNX -PERL -OSX -XMLLINT -XSLTPROC -COLLATEINDEX -CATALOG -DOCBOOKSTYLE -have_docbook -can_build_docs_FALSE -can_build_docs_TRUE -JADE -NSGMLS -YFLAGS -YACC -LEXLIB -LEX_OUTPUT_ROOT -LEX -CPP -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -MANIFEST_TOOL -RANLIB -ac_ct_AR -AR -DLLTOOL -OBJDUMP -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -LIBTOOL -MAINT -MAINTAINER_MODE_FALSE -MAINTAINER_MODE_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -enable_maintainer_mode -enable_shared -enable_static -with_pic -enable_fast_install -with_gnu_ld -with_sysroot -enable_libtool_lock -enable_float4_byval -enable_float8_byval -with_pgsql -with_pgsql_includedir -with_pgsql_libdir -with_openssl -with_pam -with_memcached -enable_rpath -enable_sequence_lock -enable_table_lock -enable_cassert -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP -YACC -YFLAGS -DOCBOOKSTYLE' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -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 pgpool-II 4.1devel to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/pgpool-II] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of pgpool-II 4.1devel:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --disable-maintainer-mode - disable make rules and dependencies not useful (and - sometimes confusing) to the casual installer - --enable-shared[=PKGS] build shared libraries [default=yes] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - --disable-float4-byval disable float4 passed by value - --disable-float8-byval disable float8 passed by value - --disable-rpath do not embed shared library search path in executables - --enable-sequence-lock insert_lock compatible with pgpool-II 3.0 series - (until 3.0.4) - --enable-table-lock insert_lock compatible with pgpool-II 2.2 and 2.3 - series - --enable-cassert build with assertion checks - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use - both] - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot=DIR Search for dependent libraries within DIR - (or the compiler's sysroot if not specified). - --with-pgsql=DIR site header files for PostgreSQL in DIR - --with-pgsql-includedir=DIR site header files for PostgreSQL in DIR - --with-pgsql-libdir=DIR site library files for PostgreSQL in DIR - --with-openssl build with OpenSSL support - --with-pam build with PAM support - --with-memcached=DIR site header files for libmemcached in DIR - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - YACC The `Yet Another Compiler Compiler' implementation to use. - Defaults to the first program found out of: `bison -y', `byacc', - `yacc'. - YFLAGS The list of arguments that will be passed by default to $YACC. - This script will default YFLAGS to the empty string to avoid a - default value of `-d' given by some make applications. - DOCBOOKSTYLE - location of DocBook stylesheets - -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 . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -pgpool-II configure 4.1devel -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. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_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_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* 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 $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext 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_func - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&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;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$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 pgpool-hackers@pgpool.net ## -## ---------------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -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_type - -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- -# Tries to find the compile-time value of EXPR in a program that includes -# INCLUDES, setting VAR accordingly. Returns whether the value could be -# computed -ac_fn_c_compute_int () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=0 ac_mid=0 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid; break -else - as_fn_arith $ac_mid + 1 && ac_lo=$as_val - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=-1 ac_mid=-1 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=$ac_mid; break -else - as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - ac_lo= ac_hi= -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid -else - as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in #(( -?*) eval "$3=\$ac_lo"; ac_retval=0 ;; -'') ac_retval=1 ;; -esac - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (($2) < 0) - { - long int i = longval (); - if (i != ($2)) - return 1; - fprintf (f, "%ld", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ($2)) - return 1; - fprintf (f, "%lu", i); - } - /* Do not output a trailing newline, as this causes \r\n confusion - on some platforms. */ - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - echo >>conftest.val; read $3 &5 -$as_echo_n "checking for $2.$3... " >&6; } -if eval \${$4+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (sizeof ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - eval "$4=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$4 - { $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_member -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 pgpool-II $as_me 4.1devel, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; 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_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # 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_CC="${ac_tool_prefix}gcc" - $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 -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; 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_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_ac_ct_CC="gcc" - $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 -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; 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_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # 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_CC="${ac_tool_prefix}cc" - $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 -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; 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_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -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 - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $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 - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$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_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # 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_CC="$ac_tool_prefix$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 -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -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_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_ac_ct_CC="$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 -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -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 compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - 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 run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $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 compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" 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_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 - - -am__api_version='1.13' - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; 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_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip" - $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 -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; 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_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_ac_ct_STRIP="strip" - $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 -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $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 - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -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 whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='pgpool-II' - VERSION='4.1devel' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } - # Check whether --enable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then : - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=yes -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 -$as_echo "$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - - -# AC_PROG_RANLIB -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.4.2' -macro_revision='1.3337' - - - - - - - - - - - - - -ltmain="$ac_aux_dir/ltmain.sh" - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -$as_echo_n "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case "$ECHO" in - printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -$as_echo "printf" >&6; } ;; - print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -$as_echo "print -r" >&6; } ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -$as_echo "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -{ $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 - 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 - - $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_path_SED=$SED -fi - -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 - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ $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 fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_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 fgrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_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 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "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_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_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_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# 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 $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&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. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname 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 ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - if test -n "$ac_tool_prefix"; then - for ac_prog in dumpbin "link -dump" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$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_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # 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_DUMPBIN="$ac_tool_prefix$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 -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in dumpbin "link -dump" -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_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # 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_ac_ct_DUMPBIN="$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 -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 -$as_echo_n "checking how to convert $build file names to $host format... " >&6; } -if ${lt_cv_to_host_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac - -fi - -to_host_file_cmd=$lt_cv_to_host_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 -$as_echo "$lt_cv_to_host_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 -$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } -if ${lt_cv_to_tool_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - #assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac - -fi - -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 -$as_echo "$lt_cv_to_tool_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_reload_flag='-r' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then - reload_cmds=false - fi - ;; - darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; 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_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # 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_OBJDUMP="${ac_tool_prefix}objdump" - $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 -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; 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_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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_ac_ct_OBJDUMP="objdump" - $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 -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; 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_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # 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_DLLTOOL="${ac_tool_prefix}dlltool" - $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 -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; 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_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # 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_ac_ct_DLLTOOL="dlltool" - $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 -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 -$as_echo_n "checking how to associate runtime and link libraries... " >&6; } -if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 -$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - - - - - - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$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_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # 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_AR="$ac_tool_prefix$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 -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar -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_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_ac_ct_AR="$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 -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} -: ${AR_FLAGS=cru} - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 -$as_echo_n "checking for archiver @FILE support... " >&6; } -if ${lt_cv_ar_at_file+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ar_at_file=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 -$as_echo "$lt_cv_ar_at_file" >&6; } - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; 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_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip" - $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 -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; 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_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_ac_ct_STRIP="strip" - $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 -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; 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_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # 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_RANLIB="${ac_tool_prefix}ranlib" - $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 -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; 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_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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_ac_ct_RANLIB="ranlib" - $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 -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } - -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; -else - with_sysroot=no -fi - - -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 -$as_echo "${with_sysroot}" >&6; } - as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 - ;; -esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 -$as_echo "${lt_sysroot:-no}" >&6; } - - - - - -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; -fi - -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_cc_needs_belf=yes -else - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. -set dummy ${ac_tool_prefix}mt; 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_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MANIFEST_TOOL"; then - ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # 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_MANIFEST_TOOL="${ac_tool_prefix}mt" - $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 -MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL -if test -n "$MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 -$as_echo "$MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_MANIFEST_TOOL"; then - ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL - # Extract the first word of "mt", so it can be a program name with args. -set dummy mt; 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_ac_ct_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_MANIFEST_TOOL"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # 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_ac_ct_MANIFEST_TOOL="mt" - $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 -ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL -if test -n "$ac_ct_MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 -$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_MANIFEST_TOOL" = x; then - MANIFEST_TOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL - fi -else - MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" -fi - -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 -$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if ${lt_cv_path_mainfest_tool+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&5 - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -$as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi - - - - - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; 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_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # 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_DSYMUTIL="${ac_tool_prefix}dsymutil" - $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 -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; 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_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # 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_ac_ct_DSYMUTIL="dsymutil" - $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 -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; 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_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # 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_NMEDIT="${ac_tool_prefix}nmedit" - $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 -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; 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_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # 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_ac_ct_NMEDIT="nmedit" - $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 -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; 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_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # 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_LIPO="${ac_tool_prefix}lipo" - $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 -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; 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_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # 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_ac_ct_LIPO="lipo" - $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 -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; 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_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # 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_OTOOL="${ac_tool_prefix}otool" - $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 -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; 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_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # 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_ac_ct_OTOOL="otool" - $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 -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; 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_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # 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_OTOOL64="${ac_tool_prefix}otool64" - $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 -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; 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_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # 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_ac_ct_OTOOL64="otool64" - $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 -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&5 - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_ld_exported_symbols_list=yes -else - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 -$as_echo_n "checking for -force_load linker flag... " >&6; } -if ${lt_cv_ld_force_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 - echo "$RANLIB libconftest.a" >&5 - $RANLIB libconftest.a 2>&5 - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&5 - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&5 - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 -$as_echo "$lt_cv_ld_force_load" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -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 $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 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. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=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 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF - -fi - -done - - - - - -# Set options - - - - enable_dlopen=no - - - enable_win32_dll=no - - - # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=yes -fi - - - - - - - - - - # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : - withval=$with_pic; lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for lt_pkg in $withval; do - IFS="$lt_save_ifs" - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - pic_mode=default -fi - - -test -z "$pic_mode" && pic_mode=default - - - - - - - - # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi - - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; - *) - lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - lt_prog_compiler_wl='-Xlinker ' - if test -n "$lt_prog_compiler_pic"; then - lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - *Sun\ F* | *Sun*Fortran*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - *Intel*\ [CF]*Compiler*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - *Portland\ Group*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic=$lt_prog_compiler_pic -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 -$as_echo "$lt_cv_prog_compiler_pic" >&6; } -lt_prog_compiler_pic=$lt_cv_prog_compiler_pic - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } - -if test x"$lt_cv_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu | gnu*) - link_all_deplibs=no - ;; - esac - - ld_shlibs=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; - *\ \(GNU\ Binutils\)\ [3-9]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='${wl}--export-all-symbols' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - link_all_deplibs=yes - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = no; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - link_all_deplibs=no - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - fi - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - always_export_symbols=yes - file_list_spec='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, )='true' - enable_shared_with_static_runtimes=yes - exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - old_postinstall_cmds='chmod 644 $oldlib' - postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - enable_shared_with_static_runtimes=yes - ;; - esac - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - - else - whole_archive_flag_spec='' - fi - link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 -$as_echo_n "checking if $CC understands -b... " >&6; } -if ${lt_cv_prog_compiler__b+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler__b=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -b" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler__b=yes - fi - else - lt_cv_prog_compiler__b=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 -$as_echo "$lt_cv_prog_compiler__b" >&6; } - -if test x"$lt_cv_prog_compiler__b" = xyes; then - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' -fi - - ;; - esac - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 -$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } -if ${lt_cv_irix_exported_symbol+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo (void) { return 0; } -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_irix_exported_symbol=yes -else - lt_cv_irix_exported_symbol=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 -$as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test "$lt_cv_irix_exported_symbol" = yes; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' - ;; - esac - fi - fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc+:} false; then : - $as_echo_n "(cached) " >&6 -else - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } - archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([A-Za-z]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[23].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } - -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $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 dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $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 shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_shl_load=yes -else - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $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 dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $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 dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_svld_dlopen=yes -else - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $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 dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_dld_link=yes -else - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 - -CC="$lt_save_CC" - - - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - - -for ac_prog in flex lex -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_LEX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LEX"; then - ac_cv_prog_LEX="$LEX" # 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_LEX="$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 -LEX=$ac_cv_prog_LEX -if test -n "$LEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 -$as_echo "$LEX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$LEX" && break -done -test -n "$LEX" || LEX=":" - -if test "x$LEX" != "x:"; then - cat >conftest.l <<_ACEOF -%% -a { ECHO; } -b { REJECT; } -c { yymore (); } -d { yyless (1); } -e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ - yyless ((input () != 0)); } -f { unput (yytext[0]); } -. { BEGIN INITIAL; } -%% -#ifdef YYTEXT_POINTER -extern char *yytext; -#endif -int -main (void) -{ - return ! yylex () + ! yywrap (); -} -_ACEOF -{ { ac_try="$LEX conftest.l" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$LEX conftest.l") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 -$as_echo_n "checking lex output file root... " >&6; } -if ${ac_cv_prog_lex_root+:} false; then : - $as_echo_n "(cached) " >&6 -else - -if test -f lex.yy.c; then - ac_cv_prog_lex_root=lex.yy -elif test -f lexyy.c; then - ac_cv_prog_lex_root=lexyy -else - as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 -$as_echo "$ac_cv_prog_lex_root" >&6; } -LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root - -if test -z "${LEXLIB+set}"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 -$as_echo_n "checking lex library... " >&6; } -if ${ac_cv_lib_lex+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ac_save_LIBS=$LIBS - ac_cv_lib_lex='none needed' - for ac_lib in '' -lfl -ll; do - LIBS="$ac_lib $ac_save_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -`cat $LEX_OUTPUT_ROOT.c` -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lex=$ac_lib -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - test "$ac_cv_lib_lex" != 'none needed' && break - done - LIBS=$ac_save_LIBS - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 -$as_echo "$ac_cv_lib_lex" >&6; } - test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 -$as_echo_n "checking whether yytext is a pointer... " >&6; } -if ${ac_cv_prog_lex_yytext_pointer+:} false; then : - $as_echo_n "(cached) " >&6 -else - # POSIX says lex can declare yytext either as a pointer or an array; the -# default is implementation-dependent. Figure out which it is, since -# not all implementations provide the %pointer and %array declarations. -ac_cv_prog_lex_yytext_pointer=no -ac_save_LIBS=$LIBS -LIBS="$LEXLIB $ac_save_LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #define YYTEXT_POINTER 1 -`cat $LEX_OUTPUT_ROOT.c` -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_prog_lex_yytext_pointer=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_save_LIBS - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 -$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } -if test $ac_cv_prog_lex_yytext_pointer = yes; then - -$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h - -fi -rm -f conftest.l $LEX_OUTPUT_ROOT.c - -fi -if test "$LEX" = :; then - LEX=${am_missing_run}flex -fi -for ac_prog in 'bison -y' byacc -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_YACC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$YACC"; then - ac_cv_prog_YACC="$YACC" # 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_YACC="$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 -YACC=$ac_cv_prog_YACC -if test -n "$YACC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 -$as_echo "$YACC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$YACC" && break -done -test -n "$YACC" || YACC="yacc" - -if test "x$CC" != xcc; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 -$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 -$as_echo_n "checking whether cc understands -c and -o together... " >&6; } -fi -set dummy $CC; ac_cc=`$as_echo "$2" | - sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -# Make sure it works both with $CC and with simple cc. -# We do the test twice because some compilers refuse to overwrite an -# existing .o file with -o, though they will create one. -ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' -rm -f conftest2.* -if { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && - test -f conftest2.$ac_objext && { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; -then - eval ac_cv_prog_cc_${ac_cc}_c_o=yes - if test "x$CC" != xcc; then - # Test first that cc exists at all. - if { ac_try='cc -c conftest.$ac_ext >&5' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' - rm -f conftest2.* - if { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && - test -f conftest2.$ac_objext && { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; - then - # cc works too. - : - else - # cc exists but doesn't like -o. - eval ac_cv_prog_cc_${ac_cc}_c_o=no - fi - fi - fi -else - eval ac_cv_prog_cc_${ac_cc}_c_o=no -fi -rm -f core conftest* - -fi -if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h - -fi - -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi - - - - -# Check for docbook -for ac_prog in onsgmls nsgmls -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_NSGMLS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NSGMLS"; then - ac_cv_prog_NSGMLS="$NSGMLS" # 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_NSGMLS="$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 -NSGMLS=$ac_cv_prog_NSGMLS -if test -n "$NSGMLS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NSGMLS" >&5 -$as_echo "$NSGMLS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$NSGMLS" && break -done - -for ac_prog in openjade jade -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_JADE+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$JADE"; then - ac_cv_prog_JADE="$JADE" # 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_JADE="$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 -JADE=$ac_cv_prog_JADE -if test -n "$JADE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JADE" >&5 -$as_echo "$JADE" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$JADE" && break -done - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DocBook V4.2" >&5 -$as_echo_n "checking for DocBook V4.2... " >&6; } -if ${pgac_cv_check_docbook+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.sgml < - - test - - random - - testsect - text - - - -EOF - -pgac_cv_check_docbook=no - -if test -n "$NSGMLS"; then - $NSGMLS -s conftest.sgml 1>&5 2>&1 - if test $? -eq 0; then - pgac_cv_check_docbook=yes - fi -fi -rm -f conftest.sgml -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_check_docbook" >&5 -$as_echo "$pgac_cv_check_docbook" >&6; } - -have_docbook=$pgac_cv_check_docbook - if test "$pgac_cv_check_docbook" = "yes"; then - can_build_docs_TRUE= - can_build_docs_FALSE='#' -else - can_build_docs_TRUE='#' - can_build_docs_FALSE= -fi - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DocBook stylesheets" >&5 -$as_echo_n "checking for DocBook stylesheets... " >&6; } -if ${pgac_cv_path_stylesheets+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DOCBOOKSTYLE"; then - pgac_cv_path_stylesheets=$DOCBOOKSTYLE -else - for pgac_prefix in /usr /usr/local /opt /sw; do - for pgac_infix in share lib; do - for pgac_postfix in \ - sgml/stylesheets/nwalsh-modular \ - sgml/stylesheets/docbook \ - sgml/stylesheets/dsssl/docbook \ - sgml/docbook-dsssl \ - sgml/docbook/dsssl/modular \ - sgml/docbook/stylesheet/dsssl/modular \ - sgml/docbook/dsssl-stylesheets \ - sgml/dsssl/docbook-dsssl-nwalsh - do - pgac_candidate=$pgac_prefix/$pgac_infix/$pgac_postfix - if test -r "$pgac_candidate/html/docbook.dsl" \ - && test -r "$pgac_candidate/print/docbook.dsl" - then - pgac_cv_path_stylesheets=$pgac_candidate - break 3 - fi - done - done - done -fi -fi - -DOCBOOKSTYLE=$pgac_cv_path_stylesheets - -if test -n "$DOCBOOKSTYLE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOCBOOKSTYLE" >&5 -$as_echo "$DOCBOOKSTYLE" >&6; } - CATALOG="-c ${DOCBOOKSTYLE}/catalog" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - CATALOG= -fi - - -if test -n "$DOCBOOKSTYLE" -a -r "$DOCBOOKSTYLE/bin/collateindex.pl"; then - COLLATEINDEX="$DOCBOOKSTYLE/bin/collateindex.pl" - -else - # Extract the first word of "collateindex.pl", so it can be a program name with args. -set dummy collateindex.pl; 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_path_COLLATEINDEX+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $COLLATEINDEX in - [\\/]* | ?:[\\/]*) - ac_cv_path_COLLATEINDEX="$COLLATEINDEX" # Let the user override the test with a path. - ;; - *) - 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_path_COLLATEINDEX="$as_dir/$ac_word$ac_exec_ext" - $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 - - ;; -esac -fi -COLLATEINDEX=$ac_cv_path_COLLATEINDEX -if test -n "$COLLATEINDEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $COLLATEINDEX" >&5 -$as_echo "$COLLATEINDEX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -for ac_prog in xsltproc -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_XSLTPROC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$XSLTPROC"; then - ac_cv_prog_XSLTPROC="$XSLTPROC" # 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_XSLTPROC="$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 -XSLTPROC=$ac_cv_prog_XSLTPROC -if test -n "$XSLTPROC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XSLTPROC" >&5 -$as_echo "$XSLTPROC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$XSLTPROC" && break -done - -for ac_prog in xmllint -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_XMLLINT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$XMLLINT"; then - ac_cv_prog_XMLLINT="$XMLLINT" # 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_XMLLINT="$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 -XMLLINT=$ac_cv_prog_XMLLINT -if test -n "$XMLLINT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XMLLINT" >&5 -$as_echo "$XMLLINT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$XMLLINT" && break -done - -for ac_prog in osx sgml2xml sx -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_OSX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OSX"; then - ac_cv_prog_OSX="$OSX" # 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_OSX="$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 -OSX=$ac_cv_prog_OSX -if test -n "$OSX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OSX" >&5 -$as_echo "$OSX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$OSX" && break -done - -for ac_prog in perl -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_PERL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$PERL"; then - ac_cv_prog_PERL="$PERL" # 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_PERL="$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 -PERL=$ac_cv_prog_PERL -if test -n "$PERL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 -$as_echo "$PERL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$PERL" && break -done - -for ac_prog in lynx -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_LYNX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LYNX"; then - ac_cv_prog_LYNX="$LYNX" # 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_LYNX="$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 -LYNX=$ac_cv_prog_LYNX -if test -n "$LYNX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LYNX" >&5 -$as_echo "$LYNX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$LYNX" && break -done - - - - - if test ! -z "$STYLE"; then - STYLE_ENV_SET_TRUE= - STYLE_ENV_SET_FALSE='#' -else - STYLE_ENV_SET_TRUE='#' - STYLE_ENV_SET_FALSE= -fi - - -OLD_CFLAGS=$CFLAGS -CFLAGS="$CFLAGS -Wall" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wall option" >&5 -$as_echo_n "checking for -Wall option... " >&6; } -if ${ac_cv_wall+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -char a; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_wall=yes -else - ac_cv_wall=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -echo $ac_cv_wall -if test $ac_cv_wall = no; then - CFLAGS=$OLD_CFLAGS -fi - -OLD_CFLAGS=$CFLAGS -CFLAGS="$CFLAGS -Wmissing-prototypes" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wmissing-prototypes option" >&5 -$as_echo_n "checking for -Wmissing-prototypes option... " >&6; } -if ${ac_cv_wmissing_prototypes+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -char a; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_wmissing_prototypes=yes -else - ac_cv_wmissing_prototypes=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -echo $ac_cv_wmissing_prototypes -if test $ac_cv_wmissing_prototypes = no; then - CFLAGS=$OLD_CFLAGS -fi - - -OLD_CFLAGS=$CFLAGS -CFLAGS="$CFLAGS -Wmissing-declarations" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wmissing-declarations option" >&5 -$as_echo_n "checking for -Wmissing-declarations option... " >&6; } -if ${ac_cv_wmissing_declarations+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -char a; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_wmissing_declarations=yes -else - ac_cv_wmissing_declarations=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -echo $ac_cv_wmissing_declarations -if test $ac_cv_wmissing_declarations = no; then - CFLAGS=$OLD_CFLAGS -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5 -$as_echo_n "checking for main in -lm... " >&6; } -if ${ac_cv_lib_m_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_m_main=yes -else - ac_cv_lib_m_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5 -$as_echo "$ac_cv_lib_m_main" >&6; } -if test "x$ac_cv_lib_m_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBM 1 -_ACEOF - - LIBS="-lm $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5 -$as_echo_n "checking for main in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nsl_main=yes -else - ac_cv_lib_nsl_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5 -$as_echo "$ac_cv_lib_nsl_main" >&6; } -if test "x$ac_cv_lib_nsl_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBNSL 1 -_ACEOF - - LIBS="-lnsl $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsocket" >&5 -$as_echo_n "checking for main in -lsocket... " >&6; } -if ${ac_cv_lib_socket_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_main=yes -else - ac_cv_lib_socket_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" >&5 -$as_echo "$ac_cv_lib_socket_main" >&6; } -if test "x$ac_cv_lib_socket_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSOCKET 1 -_ACEOF - - LIBS="-lsocket $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lipc" >&5 -$as_echo_n "checking for main in -lipc... " >&6; } -if ${ac_cv_lib_ipc_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lipc $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ipc_main=yes -else - ac_cv_lib_ipc_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_main" >&5 -$as_echo "$ac_cv_lib_ipc_main" >&6; } -if test "x$ac_cv_lib_ipc_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBIPC 1 -_ACEOF - - LIBS="-lipc $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lIPC" >&5 -$as_echo_n "checking for main in -lIPC... " >&6; } -if ${ac_cv_lib_IPC_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lIPC $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_IPC_main=yes -else - ac_cv_lib_IPC_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_IPC_main" >&5 -$as_echo "$ac_cv_lib_IPC_main" >&6; } -if test "x$ac_cv_lib_IPC_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBIPC 1 -_ACEOF - - LIBS="-lIPC $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -llc" >&5 -$as_echo_n "checking for main in -llc... " >&6; } -if ${ac_cv_lib_lc_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llc $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lc_main=yes -else - ac_cv_lib_lc_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lc_main" >&5 -$as_echo "$ac_cv_lib_lc_main" >&6; } -if test "x$ac_cv_lib_lc_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLC 1 -_ACEOF - - LIBS="-llc $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lBSD" >&5 -$as_echo_n "checking for main in -lBSD... " >&6; } -if ${ac_cv_lib_BSD_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lBSD $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_BSD_main=yes -else - ac_cv_lib_BSD_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_BSD_main" >&5 -$as_echo "$ac_cv_lib_BSD_main" >&6; } -if test "x$ac_cv_lib_BSD_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBBSD 1 -_ACEOF - - LIBS="-lBSD $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgen" >&5 -$as_echo_n "checking for main in -lgen... " >&6; } -if ${ac_cv_lib_gen_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgen $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gen_main=yes -else - ac_cv_lib_gen_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_main" >&5 -$as_echo "$ac_cv_lib_gen_main" >&6; } -if test "x$ac_cv_lib_gen_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGEN 1 -_ACEOF - - LIBS="-lgen $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lPW" >&5 -$as_echo_n "checking for main in -lPW... " >&6; } -if ${ac_cv_lib_PW_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lPW $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_PW_main=yes -else - ac_cv_lib_PW_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_PW_main" >&5 -$as_echo "$ac_cv_lib_PW_main" >&6; } -if test "x$ac_cv_lib_PW_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPW 1 -_ACEOF - - LIBS="-lPW $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lresolv" >&5 -$as_echo_n "checking for main in -lresolv... " >&6; } -if ${ac_cv_lib_resolv_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lresolv $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_resolv_main=yes -else - ac_cv_lib_resolv_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_main" >&5 -$as_echo "$ac_cv_lib_resolv_main" >&6; } -if test "x$ac_cv_lib_resolv_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBRESOLV 1 -_ACEOF - - LIBS="-lresolv $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lcrypt" >&5 -$as_echo_n "checking for main in -lcrypt... " >&6; } -if ${ac_cv_lib_crypt_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcrypt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypt_main=yes -else - ac_cv_lib_crypt_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_main" >&5 -$as_echo "$ac_cv_lib_crypt_main" >&6; } -if test "x$ac_cv_lib_crypt_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBCRYPT 1 -_ACEOF - - LIBS="-lcrypt $LIBS" - -fi - - -for ac_func in strlcat, strlcpy -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" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -{ $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. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=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 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 -$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } -if ${ac_cv_header_sys_wait_h+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) -#endif -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -int -main () -{ - int s; - wait (&s); - s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_sys_wait_h=yes -else - ac_cv_header_sys_wait_h=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 -$as_echo "$ac_cv_header_sys_wait_h" >&6; } -if test $ac_cv_header_sys_wait_h = yes; then - -$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h - -fi - -for ac_header in fcntl.h unistd.h getopt.h netinet/tcp.h netinet/in.h netdb.h sys/param.h sys/types.h sys/socket.h sys/un.h sys/time.h sys/sem.h sys/shm.h sys/select.h crypt.h sys/pstat.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" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default" -if test "x$ac_cv_header_termios_h" = xyes; then : - -$as_echo "#define HAVE_TERMIOS_H 1" >>confdefs.h - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - -#ifndef __cplusplus - /* Ultrix mips cc rejects this sort of thing. */ - typedef int charset[2]; - const charset cs = { 0, 0 }; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this sort of thing. */ - char tx; - char *t = &tx; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; } bx; - struct s *b = &bx; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" -if test "x$ac_cv_type_pid_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define pid_t int -_ACEOF - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if ${ac_cv_header_time+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time=yes -else - ac_cv_header_time=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h - -fi - - - -# Macros to detect C compiler features -# $PostgreSQL: pgsql/config/c-compiler.m4,v 1.19 2008/06/27 00:36:16 tgl Exp $ - - -# PGAC_C_SIGNED -# ------------- -# Check if the C compiler understands signed types. -# PGAC_C_SIGNED - - - -# PGAC_TYPE_64BIT_INT(TYPE) -# ------------------------- -# Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to -# yes or no respectively, and define HAVE_TYPE_64 if yes. -# PGAC_TYPE_64BIT_INT - - - -# PGAC_C_FUNCNAME_SUPPORT -# ----------------------- -# Check if the C compiler understands __func__ (C99) or __FUNCTION__ (gcc). -# Define HAVE_FUNCNAME__FUNC or HAVE_FUNCNAME__FUNCTION accordingly. -# PGAC_C_FUNCNAME_SUPPORT - - - -# PGAC_PROG_CC_CFLAGS_OPT -# ----------------------- -# Given a string, check if the compiler supports the string as a -# command-line option. If it does, add the string to CFLAGS. -# PGAC_PROG_CC_CFLAGS_OPT - - - -# PGAC_PROG_CC_LDFLAGS_OPT -# ------------------------ -# Given a string, check if the compiler supports the string as a -# command-line option. If it does, add the string to LDFLAGS. -# For reasons you'd really rather not know about, this checks whether -# you can link to a particular function, not just whether you can link. -# In fact, we must actually check that the resulting program runs :-( -# PGAC_PROG_CC_LDFLAGS_OPT - - -# Macros that test various C library quirks -# $PostgreSQL: pgsql/config/c-library.m4,v 1.33 2008/08/21 13:53:28 petere Exp $ - - -# PGAC_VAR_INT_TIMEZONE -# --------------------- -# Check if the global variable `timezone' exists. If so, define -# HAVE_INT_TIMEZONE. -# PGAC_VAR_INT_TIMEZONE - - -# PGAC_STRUCT_TIMEZONE -# ------------------ -# Figure out how to get the current timezone. If `struct tm' has a -# `tm_zone' member, define `HAVE_TM_ZONE'. Also, if the -# external array `tzname' is found, define `HAVE_TZNAME'. -# This is the same as the standard macro AC_STRUCT_TIMEZONE, except that -# tzname[] is checked for regardless of whether we find tm_zone. -# PGAC_STRUCT_TIMEZONE - - -# PGAC_FUNC_GETTIMEOFDAY_1ARG -# --------------------------- -# Check if gettimeofday() has only one arguments. (Normal is two.) -# If so, define GETTIMEOFDAY_1ARG. -# PGAC_FUNC_GETTIMEOFDAY_1ARG - - -# PGAC_FUNC_GETPWUID_R_5ARG -# --------------------------- -# Check if getpwuid_r() takes a fifth argument (later POSIX standard, not draft version) -# If so, define GETPWUID_R_5ARG -# PGAC_FUNC_GETPWUID_R_5ARG - - -# 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 -# PGAC_FUNC_STRERROR_R_INT - - -# PGAC_UNION_SEMUN -# ---------------- -# Check if `union semun' exists. Define HAVE_UNION_SEMUN if so. -# If it doesn't then one could define it as -# union semun { int val; struct semid_ds *buf; unsigned short *array; } -# PGAC_UNION_SEMUN - - -# PGAC_STRUCT_SOCKADDR_UN -# ----------------------- -# If `struct sockaddr_un' exists, define HAVE_UNIX_SOCKETS. -# (Requires test for !) -# PGAC_STRUCT_SOCKADDR_UN - - -# PGAC_STRUCT_SOCKADDR_STORAGE -# ---------------------------- -# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE. -# If it is missing then one could define it. -# PGAC_STRUCT_SOCKADDR_STORAGE - -# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS -# -------------------------------------- -# Check the members of `struct sockaddr_storage'. We need to know about -# ss_family and ss_len. (Some platforms follow RFC 2553 and call them -# __ss_family and __ss_len.) We also check struct sockaddr's sa_len; -# if we have to define our own `struct sockaddr_storage', this tells us -# whether we need to provide an ss_len field. -# PGAC_STRUCT_SOCKADDR_STORAGE_MEMBERS - - -# PGAC_STRUCT_ADDRINFO -# ----------------------- -# If `struct addrinfo' exists, define HAVE_STRUCT_ADDRINFO. -# PGAC_STRUCT_ADDRINFO - - -# PGAC_FUNC_POSIX_SIGNALS -# ----------------------- -# Check to see if the machine has the POSIX signal interface. Define -# HAVE_POSIX_SIGNALS if so. Also set the output variable HAVE_POSIX_SIGNALS -# to yes or no. -# -# Note that this test only compiles a test program, it doesn't check -# whether the routines actually work. If that becomes a problem, make -# a fancier check. -# PGAC_FUNC_POSIX_SIGNALS - - -# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT -# --------------------------------------- -# Determine which format snprintf uses for long long int. We handle -# %lld, %qd, %I64d. The result is in shell variable -# LONG_LONG_INT_FORMAT. -# -# MinGW uses '%I64d', though gcc throws an warning with -Wall, -# while '%lld' doesn't generate a warning, but doesn't work. -# -# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT - - -# PGAC_FUNC_PRINTF_ARG_CONTROL -# --------------------------------------- -# Determine if printf supports %1$ argument selection, e.g. %5$ selects -# the fifth argument after the printf print string. -# This is not in the C99 standard, but in the Single Unix Specification (SUS). -# It is used in our language translation strings. -# -# PGAC_FUNC_PRINTF_ARG_CONTROL - - -# backport from Autoconf 2.61a -# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=f0c325537a22105536ac8c4e88656e50f9946486 - -# AC_FUNC_FSEEKO -# -------------- - - -# AC_FUNC_FSEEKO - -# $PostgreSQL: pgsql/config/general.m4,v 1.10 2008/10/29 09:27:24 petere Exp $ - -# This file defines new macros to process configure command line -# arguments, to replace the brain-dead AC_ARG_WITH and AC_ARG_ENABLE. -# The flaw in these is particularly that they only differentiate -# between "given" and "not given" and do not provide enough help to -# process arguments that only accept "yes/no", that require an -# argument (other than "yes/no"), etc. -# -# The point of this implementation is to reduce code size and -# redundancy in configure.in and to improve robustness and consistency -# in the option evaluation code. - - -# Convert type and name to shell variable name (e.g., "enable_long_strings") - - - -# PGAC_ARG(TYPE, NAME, HELP-STRING-LHS-EXTRA, HELP-STRING-RHS, -# [ACTION-IF-YES], [ACTION-IF-NO], [ACTION-IF-ARG], -# [ACTION-IF-OMITTED]) -# ------------------------------------------------------------ -# This is the base layer. TYPE is either "with" or "enable", depending -# on what you like. NAME is the rest of the option name. -# HELP-STRING-LHS-EXTRA is a string to append to the option name on -# the left-hand side of the help output, e.g., an argument name. If -# set to "-", append nothing, but let the option appear in the -# negative form (disable/without). HELP-STRING-RHS is the option -# description, for the right-hand side of the help output. -# ACTION-IF-YES is executed if the option is given without an argument -# (or "yes", which is the same); similar for ACTION-IF-NO. - -# PGAC_ARG - -# PGAC_ARG_CHECK() -# ---------------- -# Checks if the user passed any --with/without/enable/disable -# arguments that were not defined. Just prints out a warning message, -# so this should be called near the end, so the user will see it. - -# PGAC_ARG_CHECK - -# PGAC_ARG_BOOL(TYPE, NAME, DEFAULT, HELP-STRING-RHS, -# [ACTION-IF-YES], [ACTION-IF-NO]) -# --------------------------------------------------- -# Accept a boolean option, that is, one that only takes yes or no. -# ("no" is equivalent to "disable" or "without"). DEFAULT is what -# should be done if the option is omitted; it should be "yes" or "no". -# (Consequently, one of ACTION-IF-YES and ACTION-IF-NO will always -# execute.) - -# PGAC_ARG_BOOL - - -# PGAC_ARG_REQ(TYPE, NAME, HELP-ARGNAME, HELP-STRING-RHS, -# [ACTION-IF-GIVEN], [ACTION-IF-NOT-GIVEN]) -# ------------------------------------------------------- -# This option will require an argument; "yes" or "no" will not be -# accepted. HELP-ARGNAME is a name for the argument for the help output. - -# PGAC_ARG_REQ - - -# PGAC_ARG_OPTARG(TYPE, NAME, HELP-ARGNAME, HELP-STRING-RHS, -# [DEFAULT-ACTION], [ARG-ACTION], -# [ACTION-ENABLED], [ACTION-DISABLED]) -# ---------------------------------------------------------- -# This will create an option that behaves as follows: If omitted, or -# called with "no", then set the enable_variable to "no" and do -# nothing else. If called with "yes", then execute DEFAULT-ACTION. If -# called with argument, set enable_variable to "yes" and execute -# ARG-ACTION. Additionally, execute ACTION-ENABLED if we ended up with -# "yes" either way, else ACTION-DISABLED. -# -# The intent is to allow enabling a feature, and optionally pass an -# additional piece of information. - -# PGAC_ARG_OPTARG - - -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 - - -{ $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; } -if ${pgac_cv_type_long_int_64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - # If cross-compiling, check the size reported by the compiler and -# trust that the arithmetic works. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -static int test_array [1 - 2 * !(sizeof(long int) == 8)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv_type_long_int_64=yes -else - pgac_cv_type_long_int_64=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -typedef long int ac_int64; - -/* - * These are globals to discourage the compiler from folding all the - * arithmetic tests down to compile-time constants. - */ -ac_int64 a = 20000001; -ac_int64 b = 40000005; - -int does_int64_work() -{ - ac_int64 c,d; - - if (sizeof(ac_int64) != 8) - return 0; /* definitely not the right size */ - - /* Do perfunctory checks to see if 64-bit arithmetic seems to work */ - c = a * b; - d = (c + b) / b; - if (d != a+1) - return 0; - return 1; -} -main() { - exit(! does_int64_work()); -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_type_long_int_64=yes -else - pgac_cv_type_long_int_64=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_type_long_int_64" >&5 -$as_echo "$pgac_cv_type_long_int_64" >&6; } - -HAVE_LONG_INT_64=$pgac_cv_type_long_int_64 -if test x"$pgac_cv_type_long_int_64" = xyes ; then - -$as_echo "#define HAVE_LONG_INT_64 1" >>confdefs.h - -fi - - -if test x"$HAVE_LONG_INT_64" = x"no" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long long int is 64 bits" >&5 -$as_echo_n "checking whether long long int is 64 bits... " >&6; } -if ${pgac_cv_type_long_long_int_64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - # If cross-compiling, check the size reported by the compiler and -# trust that the arithmetic works. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -static int test_array [1 - 2 * !(sizeof(long long int) == 8)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv_type_long_long_int_64=yes -else - pgac_cv_type_long_long_int_64=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -typedef long long int ac_int64; - -/* - * These are globals to discourage the compiler from folding all the - * arithmetic tests down to compile-time constants. - */ -ac_int64 a = 20000001; -ac_int64 b = 40000005; - -int does_int64_work() -{ - ac_int64 c,d; - - if (sizeof(ac_int64) != 8) - return 0; /* definitely not the right size */ - - /* Do perfunctory checks to see if 64-bit arithmetic seems to work */ - c = a * b; - d = (c + b) / b; - if (d != a+1) - return 0; - return 1; -} -main() { - exit(! does_int64_work()); -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_type_long_long_int_64=yes -else - pgac_cv_type_long_long_int_64=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_type_long_long_int_64" >&5 -$as_echo "$pgac_cv_type_long_long_int_64" >&6; } - -HAVE_LONG_LONG_INT_64=$pgac_cv_type_long_long_int_64 -if test x"$pgac_cv_type_long_long_int_64" = xyes ; then - -$as_echo "#define HAVE_LONG_LONG_INT_64 1" >>confdefs.h - -fi - -fi - - -if test x"$HAVE_LONG_LONG_INT_64" = xyes ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define INT64CONST(x) x##LL -long long int foo = INT64CONST(0x1234567890123456); - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -$as_echo "#define HAVE_LL_CONSTANTS 1" >>confdefs.h - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -# 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 format for long long int" >&5 -$as_echo_n "checking snprintf format for long long int... " >&6; } -if ${pgac_cv_snprintf_long_long_int_format+:} false; then : - $as_echo_n "(cached) " >&6 -else - for pgac_format in '%lld' '%qd' '%I64d'; do -if test "$cross_compiling" = yes; then : - pgac_cv_snprintf_long_long_int_format=cross; break -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -typedef long long int ac_int64; -#define INT64_FORMAT "$pgac_format" - -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; -} -main() { - exit(! does_int64_snprintf_work()); -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_snprintf_long_long_int_format=$pgac_format; 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_FORMAT='' - -case $pgac_cv_snprintf_long_long_int_format 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_format" >&5 -$as_echo "$pgac_cv_snprintf_long_long_int_format" >&6; } - LONG_LONG_INT_FORMAT=$pgac_cv_snprintf_long_long_int_format;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; };; -esac - if test "$LONG_LONG_INT_FORMAT" = ""; then - # Force usage of our own snprintf, since system snprintf is broken - pgac_need_repl_snprintf=yes - LONG_LONG_INT_FORMAT='%lld' - fi - else - # Here if we previously decided we needed to use our own snprintf - LONG_LONG_INT_FORMAT='%lld' - fi - LONG_LONG_UINT_FORMAT=`echo "$LONG_LONG_INT_FORMAT" | sed 's/d$/u/'` - INT64_FORMAT="\"$LONG_LONG_INT_FORMAT\"" - UINT64_FORMAT="\"$LONG_LONG_UINT_FORMAT\"" -else - # Here if we are not using 'long long int' at all - INT64_FORMAT='"%ld"' - UINT64_FORMAT='"%lu"' -fi - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - - - -cat >>confdefs.h <<_ACEOF -#define INT64_FORMAT $INT64_FORMAT -_ACEOF - - - -cat >>confdefs.h <<_ACEOF -#define UINT64_FORMAT $UINT64_FORMAT -_ACEOF - - -# 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 - if test $pgac_need_repl_snprintf = yes; then - use_repl_snprintf_TRUE= - use_repl_snprintf_FALSE='#' -else - use_repl_snprintf_TRUE='#' - use_repl_snprintf_FALSE= -fi - -# Need a #define for the size of Datum (unsigned long) -# 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]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 -$as_echo_n "checking size of unsigned long... " >&6; } -if ${ac_cv_sizeof_unsigned_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_unsigned_long" = yes; 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 77 "cannot compute sizeof (unsigned long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_unsigned_long=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 -$as_echo "$ac_cv_sizeof_unsigned_long" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long -_ACEOF - - - -# And check size of void *, size_t (enables tweaks for > 32bit address space) -# 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]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 -$as_echo_n "checking size of void *... " >&6; } -if ${ac_cv_sizeof_void_p+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_void_p" = yes; 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 77 "cannot compute sizeof (void *) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_void_p=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 -$as_echo "$ac_cv_sizeof_void_p" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_VOID_P $ac_cv_sizeof_void_p -_ACEOF - - -# 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]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 -$as_echo_n "checking size of size_t... " >&6; } -if ${ac_cv_sizeof_size_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_size_t" = yes; 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 77 "cannot compute sizeof (size_t) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_size_t=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 -$as_echo "$ac_cv_sizeof_size_t" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t -_ACEOF - - - -# Decide whether float4 is passed by value: user-selectable, enabled by default -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with float4 passed by value" >&5 -$as_echo_n "checking whether to build with float4 passed by value... " >&6; } - -pgac_args="$pgac_args enable_float4_byval" - -# Check whether --enable-float4-byval was given. -if test "${enable_float4_byval+set}" = set; then : - enableval=$enable_float4_byval; - case $enableval in - yes) - -$as_echo "#define USE_FLOAT4_BYVAL 1" >>confdefs.h - - float4passbyval=true - ;; - no) - float4passbyval=false - ;; - *) - as_fn_error $? "no argument expected for --enable-float4-byval option" "$LINENO" 5 - ;; - esac - -else - enable_float4_byval=yes - -$as_echo "#define USE_FLOAT4_BYVAL 1" >>confdefs.h - - float4passbyval=true -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_float4_byval" >&5 -$as_echo "$enable_float4_byval" >&6; } - -cat >>confdefs.h <<_ACEOF -#define FLOAT4PASSBYVAL $float4passbyval -_ACEOF - - -# Decide whether float8 is passed by value. -# Note: this setting also controls int8 and related types such as timestamp. -# If sizeof(Datum) >= 8, this is user-selectable, enabled by default. -# If not, trying to select it is an error. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with float8 passed by value" >&5 -$as_echo_n "checking whether to build with float8 passed by value... " >&6; } -if test $ac_cv_sizeof_unsigned_long -ge 8 ; then - -pgac_args="$pgac_args enable_float8_byval" - -# Check whether --enable-float8-byval was given. -if test "${enable_float8_byval+set}" = set; then : - enableval=$enable_float8_byval; - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - as_fn_error $? "no argument expected for --enable-float8-byval option" "$LINENO" 5 - ;; - esac - -else - enable_float8_byval=yes - -fi - - -else - -pgac_args="$pgac_args enable_float8_byval" - -# Check whether --enable-float8-byval was given. -if test "${enable_float8_byval+set}" = set; then : - enableval=$enable_float8_byval; - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - as_fn_error $? "no argument expected for --enable-float8-byval option" "$LINENO" 5 - ;; - esac - -else - enable_float8_byval=no - -fi - - - if test "$enable_float8_byval" = yes ; then - as_fn_error $? "--enable-float8-byval is not supported on 32-bit platforms." "$LINENO" 5 - fi -fi -if test "$enable_float8_byval" = yes ; then - -$as_echo "#define USE_FLOAT8_BYVAL 1" >>confdefs.h - - float8passbyval=true -else - float8passbyval=false -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_float8_byval" >&5 -$as_echo "$enable_float8_byval" >&6; } - -cat >>confdefs.h <<_ACEOF -#define FLOAT8PASSBYVAL $float8passbyval -_ACEOF - - - - - -# $PostgreSQL: pgsql/config/ac_func_accept_argtypes.m4,v 1.6 2003/11/29 19:51:17 pgsql Exp $ -# This comes from the official Autoconf macro archive at -# -# (I removed the $ before the Id CVS keyword below.) - - - -# PostgreSQL local changes: In the original version ACCEPT_TYPE_ARG3 -# is a pointer type. That's kind of useless because then you can't -# use the macro to define a corresponding variable. We also make the -# reasonable(?) assumption that you can use arg3 for getsocktype etc. -# as well (i.e., anywhere POSIX.2 has socklen_t). -# -# arg2 can also be `const' (e.g., RH 4.2). Change the order of tests -# for arg3 so that `int' is first, in case there is no prototype at all. -# -# Solaris 7 and 8 have arg3 as 'void *' (disguised as 'Psocklen_t' -# which is *not* 'socklen_t *'). If we detect that, then we assume -# 'int' as the result, because that ought to work best. -# -# On Win32, accept() returns 'unsigned int PASCAL' - - - -ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -" -if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 -_ACEOF - - -fi - -ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_family" "ac_cv_member_struct_sockaddr_storage_ss_family" "#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -" -if test "x$ac_cv_member_struct_sockaddr_storage_ss_family" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1 -_ACEOF - - -fi -ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "__ss_family" "ac_cv_member_struct_sockaddr_storage___ss_family" "#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -" -if test "x$ac_cv_member_struct_sockaddr_storage___ss_family" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY 1 -_ACEOF - - -fi -ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "ss_len" "ac_cv_member_struct_sockaddr_storage_ss_len" "#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -" -if test "x$ac_cv_member_struct_sockaddr_storage_ss_len" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 -_ACEOF - - -fi -ac_fn_c_check_member "$LINENO" "struct sockaddr_storage" "__ss_len" "ac_cv_member_struct_sockaddr_storage___ss_len" "#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -" -if test "x$ac_cv_member_struct_sockaddr_storage___ss_len" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN 1 -_ACEOF - - -fi -ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -" -if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_SA_LEN 1 -_ACEOF - - -fi - - -ac_fn_c_check_type "$LINENO" "union semun" "ac_cv_type_union_semun" "#include -#include -#include -" -if test "x$ac_cv_type_union_semun" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UNION_SEMUN 1 -_ACEOF - - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 -$as_echo_n "checking return type of signal handlers... " >&6; } -if ${ac_cv_type_signal+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include - -int -main () -{ -return *(signal (0, 0)) (0) == 1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_type_signal=int -else - ac_cv_type_signal=void -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 -$as_echo "$ac_cv_type_signal" >&6; } - -cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE $ac_cv_type_signal -_ACEOF - - -for ac_func in vprintf -do : - ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" -if test "x$ac_cv_func_vprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VPRINTF 1 -_ACEOF - -ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" -if test "x$ac_cv_func__doprnt" = xyes; then : - -$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h - -fi - -fi -done - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wait3 that fills in rusage" >&5 -$as_echo_n "checking for wait3 that fills in rusage... " >&6; } -if ${ac_cv_func_wait3_rusage+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_wait3_rusage=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -#include -#include -#include -/* HP-UX has wait3 but does not fill in rusage at all. */ -int -main () -{ - struct rusage r; - int i; - /* Use a field that we can force nonzero -- - voluntary context switches. - For systems like NeXT and OSF/1 that don't set it, - also use the system CPU time. And page faults (I/O) for Linux. */ - r.ru_nvcsw = 0; - r.ru_stime.tv_sec = 0; - r.ru_stime.tv_usec = 0; - r.ru_majflt = r.ru_minflt = 0; - switch (fork ()) - { - case 0: /* Child. */ - sleep(1); /* Give up the CPU. */ - _exit(0); - break; - case -1: /* What can we do? */ - _exit(0); - break; - default: /* Parent. */ - wait3(&i, 0, &r); - /* Avoid "text file busy" from rm on fast HP-UX machines. */ - sleep(2); - return (r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0 - && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0); - } -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_wait3_rusage=yes -else - ac_cv_func_wait3_rusage=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: $ac_cv_func_wait3_rusage" >&5 -$as_echo "$ac_cv_func_wait3_rusage" >&6; } -if test $ac_cv_func_wait3_rusage = yes; then - -$as_echo "#define HAVE_WAIT3 1" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for accept()" >&5 -$as_echo_n "checking types of arguments for accept()... " >&6; } - if ${ac_cv_func_accept_return+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ${ac_cv_func_accept_arg1+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ${ac_cv_func_accept_arg2+:} false; then : - $as_echo_n "(cached) " >&6 -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'; do - for ac_cv_func_accept_arg1 in 'int' '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 -/* end confdefs.h. */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -extern $ac_cv_func_accept_return accept ($ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *); -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_not_found=no; break 4 -else - ac_not_found=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done - done - done - done - if test "$ac_not_found" = yes; then - as_fn_error $? "could not determine argument types" "$LINENO" 5 - fi - if test "$ac_cv_func_accept_arg3" = "void"; then - ac_cv_func_accept_arg3=int - fi - -fi - -fi - -fi - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_accept_return, $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&5 -$as_echo "$ac_cv_func_accept_return, $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&6; } - -cat >>confdefs.h <<_ACEOF -#define ACCEPT_TYPE_RETURN $ac_cv_func_accept_return -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define ACCEPT_TYPE_ARG1 $ac_cv_func_accept_arg1 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define ACCEPT_TYPE_ARG2 $ac_cv_func_accept_arg2 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define ACCEPT_TYPE_ARG3 $ac_cv_func_accept_arg3 -_ACEOF - - -for ac_func in setsid select socket sigprocmask strdup strerror strftime strtok asprintf vasprintf gai_strerror hstrerror pstat setproctitle vsyslog -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" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -for ac_prog in pg_config -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_PGCONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$PGCONFIG"; then - ac_cv_prog_PGCONFIG="$PGCONFIG" # 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_PGCONFIG="$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 -PGCONFIG=$ac_cv_prog_PGCONFIG -if test -n "$PGCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PGCONFIG" >&5 -$as_echo "$PGCONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$PGCONFIG" && break -done - - -if test -z $PGCONFIG -then - PGSQL_INCLUDE_DIR=/usr/local/pgsql/include - PGSQL_LIB_DIR=/usr/local/pgsql/lib -else - PGSQL_INCLUDE_DIR=`pg_config --includedir` - PGSQL_LIB_DIR=`pg_config --libdir` -fi - - -# Check whether --with-pgsql was given. -if test "${with_pgsql+set}" = set; then : - withval=$with_pgsql; - case "$withval" in - "" | y | ye | yes | n | no) - as_fn_error $? "*** You must supply an argument to the --with-pgsql option." "$LINENO" 5 - ;; - esac - PGSQL_INCLUDE_DIR="$withval"/include - PGSQL_LIB_DIR="$withval"/lib - -fi - - - -# Check whether --with-pgsql-includedir was given. -if test "${with_pgsql_includedir+set}" = set; then : - withval=$with_pgsql_includedir; - case "$withval" in - "" | y | ye | yes | n | no) - as_fn_error $? "*** You must supply an argument to the --with-pgsql-includedir option." "$LINENO" 5 - ;; - esac - PGSQL_INCLUDE_DIR="$withval" - -fi - - - -# Check whether --with-pgsql-libdir was given. -if test "${with_pgsql_libdir+set}" = set; then : - withval=$with_pgsql_libdir; - case "$withval" in - "" | y | ye | yes | n | no) - as_fn_error $? "*** You must supply an argument to the --with-pgsql-libdir option." "$LINENO" 5 - ;; - esac - PGSQL_LIB_DIR="$withval" - -fi - - - - -# Check whether --with-openssl was given. -if test "${with_openssl+set}" = set; then : - withval=$with_openssl; -else - openssl=no -fi - - -if test "$with_openssl" = yes || test "$with_openssl" = auto; then - for ac_header in openssl/ssl.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_SSL_H 1 -_ACEOF - -$as_echo "#define USE_SSL 1" >>confdefs.h - -else - - if test "$with_openssl" = yes; then - as_fn_error $? "header file is required for SSL" "$LINENO" 5 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: header file is required for SSL" >&5 -$as_echo "$as_me: WARNING: header file is required for SSL" >&2;} - fi - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_new_ex_data in -lcrypto" >&5 -$as_echo_n "checking for CRYPTO_new_ex_data in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_CRYPTO_new_ex_data+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcrypto $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 CRYPTO_new_ex_data (); -int -main () -{ -return CRYPTO_new_ex_data (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_CRYPTO_new_ex_data=yes -else - ac_cv_lib_crypto_CRYPTO_new_ex_data=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CRYPTO_new_ex_data" >&5 -$as_echo "$ac_cv_lib_crypto_CRYPTO_new_ex_data" >&6; } -if test "x$ac_cv_lib_crypto_CRYPTO_new_ex_data" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBCRYPTO 1 -_ACEOF - - LIBS="-lcrypto $LIBS" - -else - as_fn_error $? "library 'crypto' is required for OpenSSL" "$LINENO" 5 -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5 -$as_echo_n "checking for SSL_new in -lssl... " >&6; } -if ${ac_cv_lib_ssl_SSL_new+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lssl $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 SSL_new (); -int -main () -{ -return SSL_new (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ssl_SSL_new=yes -else - ac_cv_lib_ssl_SSL_new=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5 -$as_echo "$ac_cv_lib_ssl_SSL_new" >&6; } -if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSSL 1 -_ACEOF - - LIBS="-lssl $LIBS" - -else - as_fn_error $? "library 'ssl' is required for OpenSSL" "$LINENO" 5 -fi - -fi - - -# Check whether --with-pam was given. -if test "${with_pam+set}" = set; then : - withval=$with_pam; -$as_echo "#define USE_PAM 1" >>confdefs.h - -fi - -if test "$with_pam" = yes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5 -$as_echo_n "checking for pam_start in -lpam... " >&6; } -if ${ac_cv_lib_pam_pam_start+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpam $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 pam_start (); -int -main () -{ -return pam_start (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pam_pam_start=yes -else - ac_cv_lib_pam_pam_start=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5 -$as_echo "$ac_cv_lib_pam_pam_start" >&6; } -if test "x$ac_cv_lib_pam_pam_start" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPAM 1 -_ACEOF - - LIBS="-lpam $LIBS" - -else - as_fn_error $? "library 'pam' is required for PAM" "$LINENO" 5 -fi - - for ac_header in security/pam_appl.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" -if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SECURITY_PAM_APPL_H 1 -_ACEOF - -else - for ac_header in pam/pam_appl.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "pam/pam_appl.h" "ac_cv_header_pam_pam_appl_h" "$ac_includes_default" -if test "x$ac_cv_header_pam_pam_appl_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_PAM_PAM_APPL_H 1 -_ACEOF - -else - as_fn_error $? "header file or is required for PAM." "$LINENO" 5 -fi - -done - -fi - -done - -fi - - -# Check whether --with-memcached was given. -if test "${with_memcached+set}" = set; then : - withval=$with_memcached; - case "$withval" in - "" | y | ye | yes | n | no) - as_fn_error $? "*** You must supply an argument to the --with-memcached option." "$LINENO" 5 - ;; - *) - - MEMCACHED_INCLUDE_DIR="$withval"/include - MEMCACHED_LIB_DIR="$withval"/lib - OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -I$MEMCACHED_INCLUDE_DIR" - for ac_header in libmemcached/memcached.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "libmemcached/memcached.h" "ac_cv_header_libmemcached_memcached_h" "$ac_includes_default" -if test "x$ac_cv_header_libmemcached_memcached_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBMEMCACHED_MEMCACHED_H 1 -_ACEOF - -$as_echo "#define USE_MEMCACHED 1" >>confdefs.h - -else - as_fn_error $? "header file is required for memcached support" "$LINENO" 5 -fi - -done - - CFLAGS=$OLD_CFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memcached_create in -lmemcached" >&5 -$as_echo_n "checking for memcached_create in -lmemcached... " >&6; } -if ${ac_cv_lib_memcached_memcached_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lmemcached $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 memcached_create (); -int -main () -{ -return memcached_create (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_memcached_memcached_create=yes -else - ac_cv_lib_memcached_memcached_create=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_memcached_memcached_create" >&5 -$as_echo "$ac_cv_lib_memcached_memcached_create" >&6; } -if test "x$ac_cv_lib_memcached_memcached_create" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBMEMCACHED 1 -_ACEOF - - LIBS="-lmemcached $LIBS" - -else - as_fn_error $? "libmemcached is not installed" "$LINENO" 5 -fi - - MEMCACHED_INCLUDE_OPT="-I $MEMCACHED_INCLUDE_DIR" - MEMCACHED_LINK_OPT="-L$MEMCACHED_LIB_DIR" - MEMCACHED_RPATH_OPT="-rpath $MEMCACHED_LIB_DIR" - ;; - esac - -fi - - -CFLAGS="$CFLAGS -fno-strict-aliasing" - - - - - -OLD_LDFLAGS="$LDFLAGS" -LDFLAGS="-L$PGSQL_LIB_DIR" -OLD_LIBS="$LIBS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQexecPrepared in -lpq" >&5 -$as_echo_n "checking for PQexecPrepared in -lpq... " >&6; } -if ${ac_cv_lib_pq_PQexecPrepared+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpq $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 PQexecPrepared (); -int -main () -{ -return PQexecPrepared (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pq_PQexecPrepared=yes -else - ac_cv_lib_pq_PQexecPrepared=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQexecPrepared" >&5 -$as_echo "$ac_cv_lib_pq_PQexecPrepared" >&6; } -if test "x$ac_cv_lib_pq_PQexecPrepared" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPQ 1 -_ACEOF - - LIBS="-lpq $LIBS" - -else - as_fn_error $? "libpq is not installed or libpq is old" "$LINENO" 5 -fi - -for ac_func in PQprepare -do : - ac_fn_c_check_func "$LINENO" "PQprepare" "ac_cv_func_PQprepare" -if test "x$ac_cv_func_PQprepare" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_PQPREPARE 1 -_ACEOF - -fi -done - -LDFLAGS="$OLD_LDFLAGS" -LIBS="$OLD_LIBS" - - - - - -# --enable(disable)-rpath option -# Check whether --enable-rpath was given. -if test "${enable_rpath+set}" = set; then : - enableval=$enable_rpath; case "${enableval}" in - yes) rpath=yes ;; - no) rpath=no ;; - esac -else - rpath=yes - -fi - - if test x$rpath = xyes; then - enable_rpath_TRUE= - enable_rpath_FALSE='#' -else - enable_rpath_TRUE='#' - enable_rpath_FALSE= -fi - - -# Decide whether to use row lock against the sequence table for insert_lock. -# This lock method is compatible with pgpool-II 3.0 series(until 3.0.4). -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use row lock against the sequence table for insert_lock" >&5 -$as_echo_n "checking whether to use row lock against the sequence table for insert_lock... " >&6; } - -pgac_args="$pgac_args enable_sequence_lock" - -# Check whether --enable-sequence-lock was given. -if test "${enable_sequence_lock+set}" = set; then : - enableval=$enable_sequence_lock; - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - as_fn_error $? "no argument expected for --enable-sequence-lock option" "$LINENO" 5 - ;; - esac - -else - enable_sequence_lock=no - -fi - - -if test "$enable_sequence_lock" = yes && test "$enable_table_lock" = yes ; then - as_fn_error $? "--enable-table-lock cannot be enabled at the same time." "$LINENO" 5 -fi -if test "$enable_sequence_lock" = yes ; then - -$as_echo "#define USE_SEQUENCE_LOCK 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_sequence_lock" >&5 -$as_echo "$enable_sequence_lock" >&6; } - -# Decide whether to use table lock against the target table for insert_lock. -# This lock method is compatible with pgpool-II 2.2 and 2.3 series. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use table lock against the target table for insert_lock" >&5 -$as_echo_n "checking whether to use table lock against the target table for insert_lock... " >&6; } - -pgac_args="$pgac_args enable_table_lock" - -# Check whether --enable-table-lock was given. -if test "${enable_table_lock+set}" = set; then : - enableval=$enable_table_lock; - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - as_fn_error $? "no argument expected for --enable-table-lock option" "$LINENO" 5 - ;; - esac - -else - enable_table_lock=no - -fi - - -if test "$enable_table_lock" = yes && test "$enable_sequence_lock" = yes ; then - as_fn_error $? "--enable-sequence-lock cannot be enabled at the same time." "$LINENO" 5 -fi -if test "$enable_table_lock" = yes ; then - -$as_echo "#define USE_TABLE_LOCK 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_table_lock" >&5 -$as_echo "$enable_table_lock" >&6; } - - -pgac_args="$pgac_args enable_cassert" - -# Check whether --enable-cassert was given. -if test "${enable_cassert+set}" = set; then : - enableval=$enable_cassert; - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - as_fn_error $? "no argument expected for --enable-cassert option" "$LINENO" 5 - ;; - esac - -else - enable_cassert=no - -fi - - -if test "$enable_cassert" = yes ; then - -$as_echo "#define USE_ASSERT_CHECKING 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: enable cassert = $enable_cassert" >&5 -$as_echo "enable cassert = $enable_cassert" >&6; } - -ac_config_headers="$ac_config_headers src/include/config.h" - - -ac_config_files="$ac_config_files Makefile doc/Makefile doc/src/Makefile doc/src/sgml/Makefile doc.ja/Makefile doc.ja/src/Makefile doc.ja/src/sgml/Makefile src/Makefile src/include/Makefile src/parser/Makefile src/libs/Makefile src/libs/pcp/Makefile src/tools/Makefile src/tools/pgmd5/Makefile src/tools/pgenc/Makefile src/tools/pcp/Makefile src/tools/pgproto/Makefile src/watchdog/Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${can_build_docs_TRUE}" && test -z "${can_build_docs_FALSE}"; then - as_fn_error $? "conditional \"can_build_docs\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${STYLE_ENV_SET_TRUE}" && test -z "${STYLE_ENV_SET_FALSE}"; then - as_fn_error $? "conditional \"STYLE_ENV_SET\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${use_repl_snprintf_TRUE}" && test -z "${use_repl_snprintf_FALSE}"; then - as_fn_error $? "conditional \"use_repl_snprintf\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${enable_rpath_TRUE}" && test -z "${enable_rpath_FALSE}"; then - as_fn_error $? "conditional \"enable_rpath\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by pgpool-II $as_me 4.1devel, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -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="\\ -pgpool-II config.status 4.1devel -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in SHELL \ -ECHO \ -PATH_SEPARATOR \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -OBJDUMP \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -DLLTOOL \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -nm_file_list_spec \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "src/include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "doc/src/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/Makefile" ;; - "doc/src/sgml/Makefile") CONFIG_FILES="$CONFIG_FILES doc/src/sgml/Makefile" ;; - "doc.ja/Makefile") CONFIG_FILES="$CONFIG_FILES doc.ja/Makefile" ;; - "doc.ja/src/Makefile") CONFIG_FILES="$CONFIG_FILES doc.ja/src/Makefile" ;; - "doc.ja/src/sgml/Makefile") CONFIG_FILES="$CONFIG_FILES doc.ja/src/sgml/Makefile" ;; - "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; - "src/include/Makefile") CONFIG_FILES="$CONFIG_FILES src/include/Makefile" ;; - "src/parser/Makefile") CONFIG_FILES="$CONFIG_FILES src/parser/Makefile" ;; - "src/libs/Makefile") CONFIG_FILES="$CONFIG_FILES src/libs/Makefile" ;; - "src/libs/pcp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libs/pcp/Makefile" ;; - "src/tools/Makefile") CONFIG_FILES="$CONFIG_FILES src/tools/Makefile" ;; - "src/tools/pgmd5/Makefile") CONFIG_FILES="$CONFIG_FILES src/tools/pgmd5/Makefile" ;; - "src/tools/pgenc/Makefile") CONFIG_FILES="$CONFIG_FILES src/tools/pgenc/Makefile" ;; - "src/tools/pcp/Makefile") CONFIG_FILES="$CONFIG_FILES src/tools/pcp/Makefile" ;; - "src/tools/pgproto/Makefile") CONFIG_FILES="$CONFIG_FILES src/tools/pgproto/Makefile" ;; - "src/watchdog/Makefile") CONFIG_FILES="$CONFIG_FILES src/watchdog/Makefile" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "libtool":C) - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool 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 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="" - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The PATH separator for the build system. -PATH_SEPARATOR=$lt_PATH_SEPARATOR - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# An object symbol dumper. -OBJDUMP=$lt_OBJDUMP - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and in which our libraries should be installed. -lt_sysroot=$lt_sysroot - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - diff --git a/configure.ac b/configure.ac index c7f8e0dd5..8e9dbb3de 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,15 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([pgpool-II], [4.1devel], [pgpool-hackers@pgpool.net], [pgpool-II]) +AC_INIT([pgpool-II], [4.8devel], [pgpool-hackers@lists.postgresql.org], [pgpool-II]) dnl Checks for programs. AC_PROG_CC +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 AM_INIT_AUTOMAKE([foreign no-dependencies subdir-objects]) @@ -10,6 +17,8 @@ dnl Disallow to rebuild configure. AM_MAINTAINER_MODE(enable) # AC_PROG_RANLIB +AR_FLAGS="cr" +AC_SUBST(AR_FLAGS) AC_PROG_LIBTOOL AM_PROG_LEX @@ -29,6 +38,7 @@ AC_CHECK_PROGS(XMLLINT, xmllint) AC_CHECK_PROGS(OSX, [osx sgml2xml sx]) AC_CHECK_PROGS(PERL, perl) AC_CHECK_PROGS(LYNX, lynx) +AC_CHECK_PROGS(SUNIFDEF, sunifdef) AC_SUBST([XSLTPROC_HTML_FLAGS]) AC_SUBST([STYLE]) @@ -95,7 +105,7 @@ dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_PID_T AC_HEADER_TIME - +AC_C_BIGENDIAN dnl ===== Copied from PostgreSQL's configure start ===== dnl @@ -166,6 +176,16 @@ else UINT64_FORMAT='"%lu"' fi +# 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 +PGAC_PROG_CC_VAR_OPT(NOT_THE_CFLAGS, [-Wstringop-truncation]) +if test -n "$NOT_THE_CFLAGS"; then + CFLAGS="$CFLAGS -Wno-stringop-truncation" +fi AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) @@ -258,7 +278,9 @@ AC_TYPE_SIGNAL AC_FUNC_VPRINTF AC_FUNC_WAIT3 AC_FUNC_ACCEPT_ARGTYPES -AC_CHECK_FUNCS(setsid select socket sigprocmask strdup strerror strftime strtok asprintf vasprintf gai_strerror hstrerror pstat setproctitle vsyslog) +AC_CHECK_FUNCS(setsid select socket sigprocmask strdup strerror strftime strtok asprintf vasprintf gai_strerror hstrerror pstat setproctitle syslog) + +PGAC_C_TYPES_COMPATIBLE dnl Checks for pg_config command. AC_CHECK_PROGS(PGCONFIG, pg_config) @@ -267,9 +289,11 @@ if test -z $PGCONFIG then PGSQL_INCLUDE_DIR=/usr/local/pgsql/include PGSQL_LIB_DIR=/usr/local/pgsql/lib + PGSQL_BIN_DIR=/usr/local/pgsql/bin else PGSQL_INCLUDE_DIR=`pg_config --includedir` PGSQL_LIB_DIR=`pg_config --libdir` + PGSQL_BIN_DIR=`pg_config --bindir` fi AC_ARG_WITH(pgsql, @@ -282,6 +306,7 @@ AC_ARG_WITH(pgsql, esac PGSQL_INCLUDE_DIR="$withval"/include PGSQL_LIB_DIR="$withval"/lib + PGSQL_BIN_DIR="$withval"/bin ]) AC_ARG_WITH(pgsql-includedir, @@ -306,6 +331,27 @@ AC_ARG_WITH(pgsql-libdir, PGSQL_LIB_DIR="$withval" ]) +AC_ARG_WITH(pgsql-bindir, + [ --with-pgsql-bindir=DIR site executable files for PostgreSQL in DIR], + [ + case "$withval" in + "" | y | ye | yes | n | no) + AC_MSG_ERROR([*** You must supply an argument to the --with-pgsql-bindir option.]) + ;; + esac + PGSQL_BIN_DIR="$withval" + ]) + +AC_ARG_WITH(sunifdef, + [ --with-sunifdef=DIR install path for sunifdef utility ], + [ + case "$withval" in + "" | y | ye | yes | n | no) + AC_MSG_ERROR([*** You must supply an argument to the --with-sunifdef option.]) + ;; + esac + SUNIFDEF="$withval"/sunifdef + ]) AC_ARG_WITH(openssl, [ --with-openssl build with OpenSSL support], @@ -313,6 +359,10 @@ AC_ARG_WITH(openssl, [openssl=no]) if test "$with_openssl" = yes || test "$with_openssl" = auto; then + # Minimum required OpenSSL version is 1.0.2 + AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + AC_CHECK_HEADERS(openssl/ssl.h, [AC_DEFINE([USE_SSL], 1, [Define to 1 to build with SSL support. (--with-openssl)])], @@ -328,6 +378,18 @@ if test "$with_openssl" = yes || test "$with_openssl" = auto; then AC_CHECK_LIB(ssl, SSL_new, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) fi +AC_ARG_WITH(ldap, + [ --with-ldap build with LDAP support], + [AC_DEFINE([USE_LDAP], 1, [Define to 1 to build with LDAP support. (--with-ldap)])]) +if test "$with_ldap" = yes ; then + AC_CHECK_LIB(ldap, ldap_bind, [], + [AC_MSG_ERROR([library 'ldap' is required for LDAP])], + [$EXTRA_LDAP_LIBS]) + AC_CHECK_HEADERS(ldap.h, [], + [AC_MSG_ERROR([header file is required for LDAP])]) + AC_CHECK_FUNCS([ldap_initialize]) +fi + AC_ARG_WITH(pam, [ --with-pam build with PAM support], [AC_DEFINE([USE_PAM], 1, [Define to 1 to build with PAM support. (--with-pam)])]) @@ -338,6 +400,7 @@ if test "$with_pam" = yes ; then [AC_MSG_ERROR([header file or is required for PAM.])])]) fi + AC_ARG_WITH(memcached, [ --with-memcached=DIR site header files for libmemcached in DIR], [ @@ -371,15 +434,17 @@ AC_SUBST(MEMCACHED_LINK_OPT) AC_SUBST(MEMCACHED_RPATH_OPT) OLD_LDFLAGS="$LDFLAGS" -LDFLAGS="-L$PGSQL_LIB_DIR" +LDFLAGS="-L$PGSQL_LIB_DIR $LDFLAGS" OLD_LIBS="$LIBS" AC_CHECK_LIB(pq, PQexecPrepared, [], [AC_MSG_ERROR(libpq is not installed or libpq is old)]) AC_CHECK_FUNCS(PQprepare) +AC_CHECK_FUNCS(PQpingParams) LDFLAGS="$OLD_LDFLAGS" LIBS="$OLD_LIBS" AC_SUBST(PGSQL_INCLUDE_DIR) AC_SUBST(PGSQL_LIB_DIR) +AC_SUBST(PGSQL_BIN_DIR) AC_SUBST(MEMCACHED_DIR) # --enable(disable)-rpath option @@ -428,4 +493,4 @@ AC_MSG_RESULT([enable cassert = $enable_cassert]) AM_CONFIG_HEADER(src/include/config.h) -AC_OUTPUT([Makefile doc/Makefile doc/src/Makefile doc/src/sgml/Makefile doc.ja/Makefile doc.ja/src/Makefile doc.ja/src/sgml/Makefile src/Makefile src/include/Makefile src/parser/Makefile src/libs/Makefile src/libs/pcp/Makefile src/tools/Makefile src/tools/pgmd5/Makefile src/tools/pgenc/Makefile src/tools/pcp/Makefile src/tools/pgproto/Makefile src/watchdog/Makefile]) +AC_OUTPUT([Makefile doc/Makefile doc/src/Makefile doc/src/sgml/Makefile doc.ja/Makefile doc.ja/src/Makefile doc.ja/src/sgml/Makefile src/Makefile src/include/Makefile src/parser/Makefile src/libs/Makefile src/libs/pcp/Makefile src/tools/Makefile src/tools/pgmd5/Makefile src/tools/pgenc/Makefile src/tools/pcp/Makefile src/tools/pgproto/Makefile src/tools/watchdog/Makefile src/watchdog/Makefile]) diff --git a/depcomp b/depcomp deleted file mode 100755 index bd0ac0895..000000000 --- a/depcomp +++ /dev/null @@ -1,688 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2011-12-04.11; # UTC - -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, -# 2011 Free Software Foundation, Inc. - -# 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 2, 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. - -# You should have received a copy of the GNU General Public License -# 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 -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputting dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -cygpath_u="cygpath -u -f -" -if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp -fi - -if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. hp depmode also adds that space, but also prefixes the VPATH -## to the object. Take care to not repeat it in the output. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" - echo >> "$depfile" - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. - sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -msvc7) - if test "$libtool" = yes; then - showIncludes=-Wc,-showIncludes - else - showIncludes=-showIncludes - fi - "$@" $showIncludes > "$tmpdepfile" - stat=$? - grep -v '^Note: including file: ' "$tmpdepfile" - if test "$stat" = 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The first sed program below extracts the file names and escapes - # backslashes for cygpath. The second sed program outputs the file - # name when reading, but also accumulates all include files in the - # hold buffer in order to output them again at the end. This only - # works with sed implementations that can handle large buffers. - sed < "$tmpdepfile" -n ' -/^Note: including file: *\(.*\)/ { - s//\1/ - s/\\/\\\\/g - p -}' | $cygpath_u | sort -u | sed -n ' -s/ /\\ /g -s/\(.*\)/ \1 \\/p -s/.\(.*\) \\/\1:/ -H -$ { - s/.*/ / - G - p -}' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvc7msys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no eat=no - for arg - do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - if test $eat = yes; then - eat=no - continue - fi - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -arch) - eat=yes ;; - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix=`echo "$object" | sed 's/^.*\././'` - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - # makedepend may prepend the VPATH from the source file name to the object. - # No need to regex-escape $object, excess matching of '.' is harmless. - sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - IFS=" " - for arg - do - case "$arg" in - -o) - shift - ;; - $object) - shift - ;; - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E 2>/dev/null | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvcmsys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/doc.ja/Makefile.in b/doc.ja/Makefile.in deleted file mode 100644 index 8cb6a9777..000000000 --- a/doc.ja/Makefile.in +++ /dev/null @@ -1,635 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = doc.ja -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src -all: all-recursive - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps doc.ja/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps doc.ja/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool cscopelist-am ctags \ - ctags-am distclean distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/doc.ja/src/Makefile.in b/doc.ja/src/Makefile.in deleted file mode 100644 index 86485c087..000000000 --- a/doc.ja/src/Makefile.in +++ /dev/null @@ -1,638 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = doc.ja/src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = figures/process-diagram.gif figures/process-diagram.odp \ - figures/cluster.gif figures/cluster.odp - -SUBDIRS = sgml -all: all-recursive - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps doc.ja/src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps doc.ja/src/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool cscopelist-am ctags \ - ctags-am distclean distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/doc.ja/src/figures/cluster_40.gif b/doc.ja/src/figures/cluster_40.gif new file mode 100644 index 000000000..47b2352a4 Binary files /dev/null and b/doc.ja/src/figures/cluster_40.gif differ diff --git a/doc.ja/src/figures/cluster_40.odp b/doc.ja/src/figures/cluster_40.odp new file mode 100644 index 000000000..a1dcf4190 Binary files /dev/null and b/doc.ja/src/figures/cluster_40.odp differ diff --git a/doc.ja/src/figures/detach_false_primary.gif b/doc.ja/src/figures/detach_false_primary.gif index 6e8765163..a5c51492c 100644 Binary files a/doc.ja/src/figures/detach_false_primary.gif and b/doc.ja/src/figures/detach_false_primary.gif differ diff --git a/doc.ja/src/figures/detach_false_primary.odp b/doc.ja/src/figures/detach_false_primary.odp index 8dc358c56..0a1352d6a 100644 Binary files a/doc.ja/src/figures/detach_false_primary.odp and b/doc.ja/src/figures/detach_false_primary.odp differ diff --git a/doc.ja/src/figures/process-diagram.gif b/doc.ja/src/figures/process-diagram.gif index 0bf7ec2df..ae6b3bd27 100644 Binary files a/doc.ja/src/figures/process-diagram.gif and b/doc.ja/src/figures/process-diagram.gif differ diff --git a/doc.ja/src/figures/process-diagram.odp b/doc.ja/src/figures/process-diagram.odp index aa61834eb..41a074ab7 100644 Binary files a/doc.ja/src/figures/process-diagram.odp and b/doc.ja/src/figures/process-diagram.odp differ diff --git a/doc.ja/src/sgml/Makefile.am b/doc.ja/src/sgml/Makefile.am index 210f85fdd..7baa45955 100644 --- a/doc.ja/src/sgml/Makefile.am +++ b/doc.ja/src/sgml/Makefile.am @@ -5,8 +5,7 @@ DEFS = @DEFS@ \ all: html man1 man8 -GENERATED_SGML = bookindex.sgml version.sgml \ - features-supported.sgml features-unsupported.sgml errcodes-table.sgml +GENERATED_SGML = bookindex.sgml version.sgml ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML) diff --git a/doc.ja/src/sgml/Makefile.in b/doc.ja/src/sgml/Makefile.in deleted file mode 100644 index 0d28a1862..000000000 --- a/doc.ja/src/sgml/Makefile.in +++ /dev/null @@ -1,622 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@STYLE_ENV_SET_TRUE@am__append_1 = -V website-stylesheet -@STYLE_ENV_SET_TRUE@am__append_2 = --param website.stylesheet 1 -subdir = doc.ja/src/sgml -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ $(am__append_2) -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -GENERATED_SGML = bookindex.sgml version.sgml \ - features-supported.sgml features-unsupported.sgml errcodes-table.sgml - -ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML) - -# Sometimes we don't want this one. -ALMOSTALLSGML := $(filter-out %bookindex.sgml,$(ALLSGML)) -SPFLAGS = -wall -wno-unused-param -wno-empty -wfully-tagged -OUTDIR = html - -#jade -G -t sgml -i html -d stylesheet.dsl#html -o abas pgpool-en.sgm -#JADE.html.call = $(JADE) $(JADEFLAGS) $(SPFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t sgml -i output-html -JADE.html.call = SP_CHARSET_FIXED=1 SP_ENCODING=UTF-8 $(JADE) \ - $(JADEFLAGS) $(SPFLAGS) $(SGMLINCLUDE) $(CATALOG) -d \ - stylesheet.dsl -t sgml -i output-html $(am__append_1) -JADE.tex.call = $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t tex -V tex-backend -i output-print -i include-index -JADE.rtf.call = $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t rtf -V rtf-backend -i output-print -i include-index -JADE_html = $(JADE) $(SPFLAGS) -d stylesheet.dsl\#html -t sgml -i html -V website-stylesheet -EXTRA_DIST = $(ALLSGML) html man1 man8 stylesheet.dsl stylesheet.css stylesheet-man.xsl stylesheet-common.xsl -FOP = fop -CLEANFILES = *.html *.tex-pdf pgpool-en.rtf pgpool-en.txt html/* HTML.index bookindex.sgml man-stamp man1/* man3/* pgpool.xml -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps doc.ja/src/sgml/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps doc.ja/src/sgml/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - - -all: html man1 man8 - -#if DOCBOOKSTYLE -#CATALOG = -c $(DOCBOOKSTYLE)/catalog -#endif - -#override XSLTPROCFLAGS += --stringparam pgpool.version '$(VERSION)' -override XSLTPROCFLAGS += --stringparam pg.version '$(VERSION)' - -man1 man8 distprep-man: man-stamp - -man-stamp: stylesheet-man.xsl pgpool.xml - $(XMLLINT) --noout --valid pgpool.xml - $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_MAN_FLAGS) $^ - touch $@ - -# The draft target creates HTML output in draft mode, without index (for faster build). -draft: pgpool.sgml $(ALMOSTALLSGML) stylesheet.dsl - $(MKDIR_P) html - $(JADE.html.call) -V draft-mode $< - cp $(srcdir)/stylesheet.css html/ - -html: html-stamp - -html-stamp: pgpool.sgml $(ALLSGML) stylesheet.dsl - $(MKDIR_P) html - $(JADE.html.call) -i include-index $< - cp $(srcdir)/stylesheet.css html/ - cp ../figures/*.gif html - -# single-page HTML -pgpool.html: pgpool.sgml $(ALLSGML) stylesheet.dsl - $(JADE.html.call) -V nochunks -V rootchunk -V '(define %root-filename% #f)' -V '(define use-output-dir #f)' -i include-index $< - -# single-page text -pgpool.txt: pgpool.html - $(LYNX) -force_html -dump -nolist $< > $@ - -HTML.index: pgpool.sgml $(ALMOSTALLSGML) stylesheet.dsl - $(MKDIR_P) html - $(JADE.html.call) -V html-index $< - -bookindex.sgml: HTML.index - LC_ALL=C $(PERL) $(COLLATEINDEX) -f -g -i 'bookindex' -o $@ $< - -# single-page text -#pgpool-en.txt: pgpool-en.html -# $(LYNX) -force_html -dump -nolist $< > $@ - -# single-page HTML -#pgpool-en.html: pgpool-en.sgml $(ALLSGML) stylesheet.dsl -# $(JADE.html.call) -V nochunks -V rootchunk -i include-index $< >$@ - -%.rtf: %.sgml $(ALLSGML) - $(JADE.rtf.call) $< - -%-A4.tex-ps: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texdvi-output -V '%paper-type%'=A4 -o $@ $< - -%-US.tex-ps: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texdvi-output -V '%paper-type%'=USletter -o $@ $< - -%-A4.tex-pdf: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texpdf-output -V '%paper-type%'=A4 -o $@ $< - -%-US.tex-pdf: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texpdf-output -V '%paper-type%'=USletter -o $@ $< - -%.pdf: %.tex-pdf - @rm -f $*.aux $*.log $*.out -# multiple runs are necessary to create proper intra-document links - pdfjadetex $< - pdfjadetex $< - pdfjadetex $< - -#pgpool-en.pdf: pgpool-en-A4.tex-pdf pgpool-en-US.tex-pdf - -# This generates an XML version of the flow-object tree. It's useful -# # for debugging DSSSL code, and possibly to interface to some other -# # tools that can make use of this. -%.fot: %.sgml $(ALLSGML) - $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t fot -i output-print -i include-index -o $@ $< - -%.ps: %.dvi - dvips -o $@ $< - -pgpool-en.xml: $(ALLSGML) - $(OSX) -D. -x lower -i include-xslt-index $< >pgpool-en.xmltmp - $(PERL) -p -e 's/\[(aacute|acirc|aelig|agrave|amp|aring|atilde|auml|bull|copy|eacute|egrave|gt|iacute|lt|mdash|nbsp|ntilde|oacute|ocirc|oslash|ouml|pi|quot|scaron|uuml) *\]/\&\1;/gi;' \ - -e '$$_ .= qq{\n} if $$. == 1;' \ - $@ - rm pgpool-en.xmltmp - -pgpool.xml: $(srcdir)/pgpool.sgml $(ALMOSTALLSGML) - SP_CHARSET_FIXED=1 SP_ENCODING=UTF-8 \ - $(OSX) -D. -x lower -i include-xslt-index $< >pgpool.xmltmp - $(PERL) -p -e 's/\[(aacute|acirc|aelig|agrave|amp|aring|atilde|auml|bull|copy|eacute|egrave|gt|iacute|lt|mdash|nbsp|ntilde|oacute|ocirc|oslash|ouml|pi|quot|scaron|uuml) *\]/\&\1;/gi;' \ - -e '$$_ .= qq{\n} if $$. == 1;' \ - $@ - rm pgpool.xmltmp - -.PHONY: xslthtml-stamp - -xslthtml: xslthtml-stamp - -xslthtml: xslthtml-stamp - -xslthtml-stamp: stylesheet.xsl pgpool.xml - $(XMLLINT) --noout --valid pgpool.xml - $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $^ - cp $(srcdir)/stylesheet.css html/ - -htmlhelp: stylesheet-hh.xsl pgpool.xml - $(XMLLINT) --noout --valid pgpool.xml - $(XSLTPROC) $(XSLTPROCFLAGS) $^ - -%-A4.fo.tmp: stylesheet-fo.xsl %.xml - $(XMLLINT) --noout --valid $*.xml - $(XSLTPROC) $(XSLTPROCFLAGS) --stringparam paper.type A4 -o $@ $^ - -%-US.fo.tmp: stylesheet-fo.xsl %.xml - $(XMLLINT) --noout --valid $*.xml - $(XSLTPROC) $(XSLTPROCFLAGS) --stringparam paper.type USletter -o $@ $^ - -#xslthtml-stamp: stylesheet.xsl pgpool-en.xml -# $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $^ -# cp $(srcdir)/stylesheet.css html/ - -# reformat FO output so that locations of errors are easier to find -%.fo: %.fo.tmp - $(XMLLINT) --format --output $@ $^ - -epub: pgpool.epub - pgpool.epub: pgpool.xml - $(XMLLINT) --noout --valid $< - $(DBTOEPUB) $< - -version.sgml: $(top_srcdir)/configure - { \ - echo ""; \ - } > $@ - -# tabs are harmless, but it is best to avoid them in SGML files -check-tabs: - @( ! grep ' ' $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml $(srcdir)/*.dsl $(srcdir)/*.xsl) ) || (echo "Tabs appear in SGML/XML files" 1>&2; exit 1) - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/doc.ja/src/sgml/advanced.sgml b/doc.ja/src/sgml/advanced.sgml index 769162374..79407e016 100644 --- a/doc.ja/src/sgml/advanced.sgml +++ b/doc.ja/src/sgml/advanced.sgml @@ -1,1117 +1,1122 @@ - Watchdog + Watchdog - - - はじめに + + + はじめに - -Watchdogは、高可用性のためのPgpool-IIのサブプロセスです。 -Watchdogは、単一障害点を除くために複数のPgpool-IIを使用する際に使用されます。 -Watchdogは、最初にPgpool-II V3.2で導入され、Pgpool-II V3.5で常にクォーラムを保つように大きく改善されました。 -この機能追加により、watchdogはより対障害性が増し、スプリットブレイン障害とネットワーク分割に対する対処および防止が強固になりました。 -ただし、クォーラム機構を正しく動かすためには、pgpool-IIノードの数は奇数であり、かつ3以上でなければなりません。 + + Watchdogは、高可用性のためのPgpool-IIのサブプロセスです。 + Watchdogは、単一障害点を除くために複数のPgpool-IIを使用する際に使用されます。 + Watchdogは、最初にPgpool-II V3.2で導入され、Pgpool-II V3.5で常にクォーラムを保つように大きく改善されました。 + この機能追加により、watchdogはより対障害性が増し、スプリットブレイン障害とネットワーク分割に対する対処および防止が強固になりました。 + また、V3.7ではクォーラムフェイルオーバ (参照)が導入され、PostgreSQLサーバの故障誤検知によるフェイルオーバが起こりにくくなりました。 + クォーラム機構を正しく動かすためには、Pgpool-IIノードの数は奇数であり、かつ3以上でなければなりません。 - + --> 複数<productname>Pgpool-II</productname>ノードを協調させる WATCHDOG - - -watchdogは、お互いに情報をやり取りすることにより、複数のPgpool-IIノードを協調させます。 - - - -もしwatchdogが有効なら、Pgpool-IIノードは起動時にマスターwatchdogノードの情報を使ってバックエンドの状態の同期を取ります。 -そのノードが自分自身をマスターに昇格中であれば、バックエンド状態をローカルに初期化します。 -フェイルオーバなどでバックエンドの状態が変更したら、watchdogは他のPgpool-IIノードに通知し、同期を取ります。 -オンラインリカバリを実行すると、バックエンドの不整合を防ぐために、watchdogはクライアントが他のPgpool-IIノードに接続するのを防ぎます。 - - - - -また、watchdogは、接続したすべてのPgpool-IIノードを調停し、フェイルバック、フェイルオーバ、フォローマスターコマンドがただひとつのPgpool-IIで実行されるようにします。 - + + + watchdogは、お互いに情報をやり取りすることにより、複数のPgpool-IIノードを協調させます。 + + + + もしwatchdogが有効なら、Pgpool-IIノードは起動時にリーダーwatchdogノードの情報を使ってバックエンドの状態の同期を取ります。 + そのノードが自分自身をリーダーに昇格中であれば、バックエンド状態をローカルに初期化します。 + フェイルオーバなどでバックエンドの状態が変更したら、watchdogは他のPgpool-IIノードに通知し、同期を取ります。 + オンラインリカバリを実行すると、バックエンドの不整合を防ぐために、watchdogはクライアントが他のPgpool-IIノードに接続するのを防ぎます。 + + + + + また、watchdogは、接続したすべてのPgpool-IIノードを調停し、フェイルバック、フェイルオーバ、フォロープライマリコマンドがただひとつのPgpool-IIで実行されるようにします。 + - + --> 他の<productname>Pgpool-II</productname>ノードの死活監視 WATCHDOG - - -watchdog死活監視は、高可用性のために、watchdogクラスタに所属するPgpool-IIノードの健全性を監視するための下位コンポーネントです。 -伝統的に、Pgpool-II watchdogは2種類のリモートの死活監視方法を提供しています。 -"heartbeat""query"モードです。 -Pgpool-II V3.5で、に新しく"external"が追加され、Pgpool-II watchdogが外部サードパーティのシステムを呼び出すことが可能になりました。 - - - -リモートノードの死活監視の他に、watchdog死活監視は、上位サーバへの接続を監視することにより、稼働しているノードの健全性をチェックすることができます。 -監視がエラーを返したら、watchdogはローカルPgpool-IIノードの障害として扱います。 - - - - -heartbeatモードでは、watchdogは他のPgpool-IIプロセスをheartbeat信号で監視します。 -watchdogは、定期的に他のPgpool-IIから送られたハートビート信号を受信します。 -一定期間信号が受信されなければ、watchdogはそのPgpool-IIに障害が起こったとみなします。 -冗長性のためにPgpool-IIノード間で取り交わされるハートビート通信のためのネットワーク接続を複数使うことができます。 -これがデフォルトかつ推奨される死活監視のモードです。 - - - - -queryモードでは、watchdogはPgpool-IIのプロセスではなく、サービスを監視します。 -このモードでは、watchdogは他のPgpool-IIにクエリを送り、結果をチェックします。 - - - -この方法では、他のPgpool-IIからの接続が必要で、が十分に大きくないと失敗します。 -このモードは非推奨で、後方互換性のために残されています。 - - - - - - -externalモードは、Pgpool-II V3.5で導入されました。 -このモードでは、基本的にPgpool-II watchdogの組み込み死活監視は無効になり、watchdogは外部システムがローカルと、watchdogクラスタに所属しているすべてのリモートノードの健全性について報告することを期待します。 - + + + watchdog死活監視は、高可用性のために、watchdogクラスタに所属するPgpool-IIノードの健全性を監視するための下位コンポーネントです。 + 伝統的に、Pgpool-II watchdogは2種類のリモートの死活監視方法を提供しています。 + "heartbeat""query"モードです。 + Pgpool-II V3.5で、に新しく"external"が追加され、Pgpool-II watchdogが外部サードパーティのシステムを呼び出すことが可能になりました。 + + + + リモートノードの死活監視の他に、watchdog死活監視は、上位サーバへの接続を監視することにより、稼働しているノードの健全性をチェックすることができます。 + 監視がエラーを返したら、watchdogはローカルPgpool-IIノードの障害として扱います。 + + + + + heartbeatモードでは、watchdogは他のPgpool-IIプロセスをハートビート信号で監視します。 + watchdogは、定期的に他のPgpool-IIから送られたハートビート信号を受信します。 + 一定期間信号が受信されなければ、watchdogはそのPgpool-IIに障害が起こったとみなします。 + 冗長性のためにPgpool-IIノード間で取り交わされるハートビート通信のためのネットワーク接続を複数使うことができます。 + これがデフォルトかつ推奨される死活監視のモードです。 + + + + + queryモードでは、watchdogはPgpool-IIのプロセスではなく、サービスを監視します。 + このモードでは、watchdogは他のPgpool-IIにクエリを送り、結果をチェックします。 + + + + この方法では、他のPgpool-IIからの接続が必要で、が十分に大きくないと失敗します。 + このモードは非推奨で、後方互換性のために残されています。 + + + + + + + externalモードは、Pgpool-II V3.5で導入されました。 + このモードでは、基本的にPgpool-II watchdogの組み込み死活監視は無効になり、watchdogは外部システムがローカルと、watchdogクラスタに所属しているすべてのリモートノードの健全性について報告することを期待します。 + - + --> すべての<productname>Pgpool-II</productname>ノードの設定パラメータの一貫性 WATCHDOG - - -起動時に、watchdogはローカルノードのPgpool-IIの設定パラメータを、マスターノードのwatchdog上の設定パラメータとの一貫性を確認し、違いがあれば警告を出します。 -これにより、異なるPgpool-IIノードにおける設定パラメータの違いによる好ましくない振る舞いが起きる可能性を減らします。 - + + + 起動時に、watchdogはローカルノードのPgpool-IIの設定パラメータを、リーダーノードのwatchdog上の設定パラメータとの一貫性を確認し、違いがあれば警告を出します。 + これにより、異なるPgpool-IIノードにおける設定パラメータの違いによる好ましくない振る舞いが起きる可能性を減らします。 + - - 障害が検出された際のアクティブ/スタンバイ状態の切換 + --> + 障害が検出された際のリーダー/スタンバイ状態の切換 WATCHDOG - - -Pgpool-IIの障害が検出されると、watchdogは他のwatchdogにそのことを通知します。 -障害が起きたのがアクティブなPgpool-IIであれば、watchdogは投票によって新しいアクティブPgpool-IIを決定し、active/standby状態を変更します - + + + Pgpool-IIの障害が検出されると、watchdogは他のwatchdogにそのことを通知します。 + 障害が起きたのがリーダーPgpool-IIであれば、watchdogは投票によって新しいリーダーPgpool-IIを決定し、active/standby状態を変更します + - + --> 自動仮想IP切換 WATCHDOG - - -スタンバイPgpool-IIサーバが昇格すると、新しいアクティブサーバは仮想IPインターフェスを立ち上げます。 -一方、以前のアクティブサーバは、仮想IPインターフェイスを停止します。 -これにより、サーバが切り替わってもPgpool-IIは同じIPアドレスを使うことができます。 - + + + スタンバイPgpool-IIサーバが昇格すると、新しいリーダーサーバは仮想IPインターフェイスを立ち上げます。 + 一方、以前のリーダーサーバは、仮想IPインターフェイスを停止します。 + これにより、サーバが切り替わってもPgpool-IIは同じIPアドレスを使うことができます。 + - + --> リカバリ時にサーバをスタンバイとして自動的に登録 WATCHDOG - - -故障したサーバが復帰あるいは新しいサーバが追加されると、watchdogプロセスは新しいサーバの情報と共に、クラスタ内の他のwatchdogに通知します。 -アクティブサーバとそれ以外のサーバ上のwatchdogはその情報を受けとります。 -そして、復帰したサーバはスタンバイとして登録されます。 - + + + 故障したサーバが復帰あるいは新しいサーバが追加されると、watchdogプロセスは新しいサーバの情報と共に、クラスタ内の他のwatchdogに通知します。 + アクティブサーバとそれ以外のサーバ上のwatchdogはその情報を受けとります。 + そして、復帰したサーバはスタンバイとして登録されます。 + - + --> watchdogの起動と停止 WATCHDOG + + -watchdogは、Pgpool-IIの下位プロセスとして自動的に起動、停止されます。 -したがって、専用の起動、停止コマンドはありません。 - - -watchdogは仮想IPインターフェイスを制御します。 -VIPを起動、停止するために実行されるコマンドにはroot権限が必要です。 -watchdogが委任IPを伴って起動される際には、Pgpool-IIは、Pgpool-IIを実行しているユーザがroot権限を持つことを要求します。 -しかし、Pgpool-IIをrootユーザで実行するのは良いセキュリティの実践とは言えません。 -別の推奨する方法は、Pgpool-IIを通常のユーザとして起動し、sudoを使ってにカスタムコマンドを設定するか、if_*コマンドにsetuid("set user ID upon execution")することです。 - - -死活監視プロセスはwatchdogの下位コンポーネントです。 -その仕事は、watchdogクラスタに参加しているPgpool-IIノードの健全さを監視することです。 -死活監視プロセスは、組み込みの死活監視を使用するようにwatchdogが設定されている場合、自動的に起動されます。 -死活監視プロセスは、watchdogのメインプロセスの初期化が完了した後に起動します。 -watchdogの組み込み死活監視は、すべてのPgpool-IIノードが起動してから始まります。 -ただし、死活監視プロセスは、設定されているすべてのwatchdogノードがクラスタに参加し、アクティブになった時にだけ起動されます。 -死活監視がアクティブになる前にリモートノードに障害が起こると、その障害が死活監視によって捕捉されません。 - + Lifecheck process is a sub-component of watchdog, its job is to monitor the + health of Pgpool-II nodes participating in + the watchdog cluster. The Lifecheck process is started automatically + when the watchdog is configured to use the built-in life-checking, + it starts after the watchdog main process initialization is complete. + However lifecheck process only kicks in when all configured watchdog + nodes join the cluster and becomes active. If some remote node fails + before the Lifecheck become active that failure will not get caught by the lifecheck. + --> + watchdogは、Pgpool-IIの下位プロセスとして自動的に起動、停止されます。 + したがって、専用の起動、停止コマンドはありません。 + + + watchdogは仮想IPインターフェイスを制御します。 + VIPを起動、停止するために実行されるコマンドにはroot権限が必要です。 + watchdogが仮想IPを伴って起動される際には、Pgpool-IIは、Pgpool-IIを実行しているユーザがroot権限を持つことを要求します。 + しかし、Pgpool-IIをrootユーザで実行するのは良いセキュリティの実践とは言えません。 + 別の推奨する方法は、Pgpool-IIを通常のユーザとして起動し、sudoを使ってにカスタムコマンドを設定するか、if_*コマンドにsetuid("set user ID upon execution")することです。 + + + 死活監視プロセスはwatchdogの下位コンポーネントです。 + その仕事は、watchdogクラスタに参加しているPgpool-IIノードの健全さを監視することです。 + 死活監視プロセスは、組み込みの死活監視を使用するようにwatchdogが設定されている場合、自動的に起動されます。 + 死活監視プロセスは、watchdogのメインプロセスの初期化が完了した後に起動します。 + watchdogの組み込み死活監視は、すべてのPgpool-IIノードが起動してから始まります。 + ただし、死活監視プロセスは、設定されているすべてのwatchdogノードがクラスタに参加し、アクティブになった時にだけ起動されます。 + 死活監視がアクティブになる前にリモートノードに障害が起こると、その障害が死活監視によって捕捉されません。 + - + - - - watchdogに外部死活監視を組み込む + + + watchdogに外部死活監視を組み込む - - -Pgpool-II watchdogプロセスは、すべてのPgpool-IIプロセスとBSDソケットを使って通信します。 -そのBSDソケットは、ローカルとリモートのPgpool-II watchdogノードをサードパーティのシステムが死活監視するために使用することができます。 -IPCのためのBSDソケットの名前は、"s.PGPOOLWD_CMD."文字列の後にPgpool-IIのwd_portを付けたもので、そのソケットファイルはディレクトリに置かれます。 - + + + Pgpool-II watchdogプロセスは、すべてのPgpool-IIプロセスとBSDソケットを使って通信します。 + そのBSDソケットは、ローカルとリモートのPgpool-II watchdogノードをサードパーティのシステムが死活監視するために使用することができます。 + IPCのためのBSDソケットの名前は、"s.PGPOOLWD_CMD."文字列の後にPgpool-IIのwd_portを付けたもので、そのソケットファイルはディレクトリに置かれます。 + - + --> watchdogのIPCコマンドパケットフォーマット WATCHDOG - - -watchdogのIPCコマンドパケットは3つのフィールドから構成されます。 -以下のテーブルはメッセージフィールドの詳細な説明です。 - - - - - - watchdogのIPCコマンドパケットフォーマット - - - - - フィールド - - 説明 - - - - - - - TYPE - BYTE1 - コマンド型 - - - LENGTH - ネットワークバイトオーダーのINT32 - データ部の長さ - - - DATA - JSONフォーマットのデータ - JSONフォーマットのコマンドデータ - - - - -
+ + + watchdogのIPCコマンドパケットは3つのフィールドから構成されます。 + 以下のテーブルはメッセージフィールドの詳細な説明です。 + + + + + + watchdogのIPCコマンドパケットフォーマット + + + + + フィールド + + 説明 + + + + + + + TYPE + BYTE1 + コマンド型 + + + LENGTH + ネットワークバイトオーダーのINT32 + データ部の長さ + + + DATA + JSONフォーマットのデータ + JSONフォーマットのコマンドデータ + + + + +
- + --> watchdogのIPC結果パケットフォーマット WATCHDOG - - -watchdogのIPCコマンド結果パケットは3つのフィールドから構成されます。 -以下のテーブルはメッセージフィールドの詳細な説明です。 - - - - - watchdogのIPC結果パケットフォーマット - - - - - フィールド - - 説明 - - - - - - - TYPE - BYTE1 - コマンド型 - - - LENGTH - ネットワークバイトオーダーのINT32 - データ部の長さ - - - DATA - JSONフォーマットのデータ - JSONフォーマットのコマンドデータ - - - - -
+ + + watchdogのIPCコマンド結果パケットは3つのフィールドから構成されます。 + 以下のテーブルはメッセージフィールドの詳細な説明です。 + + + + + watchdogのIPC結果パケットフォーマット + + + + + フィールド + + 説明 + + + + + + + TYPE + BYTE1 + コマンド型 + + + LENGTH + ネットワークバイトオーダーのINT32 + データ部の長さ + + + DATA + JSONフォーマットのデータ + JSONフォーマットのコマンド結果データ + + + + +
- + --> watchdogのIPCコマンドパケット型 WATCHDOG - - -watchdogプロセスに送られ、またwatchdogプロセスから返却されるIPCコマンドのパケットの最初のバイトは、コマンドまたはコマンド結果型と認識されます。 - - - - Watchdog IPC command packet types - - - - - 名前 - バイト値 - - 説明 - - - - - - - REGISTER FOR NOTIFICATIONS - '0' - コマンドパケット - 現在の接続をwatchdog通知を受け取るために登録するコマンド - - - NODE STATUS CHANGE - '2' - コマンドパケット - watchdogノードの状態変化をwatchdogに通知するためのコマンド - - - GET NODES LIST - '3' - コマンドパケット - Command to get the list of all configured watchdog nodes - - - NODES LIST DATA - '4' - 結果パケット - パケット中のJSONデータにすべてのwatchdogノードのリストが含まれます - - - CLUSTER IN TRANSITION - '7' - 結果パケット - クラスタが遷移中なのでコマンドを処理できないときにwatchdogはこのパケットを返します - - - RESULT BAD - '8' - 結果パケット - IPCコマンドが失敗すると、watchdogはこのパケット型を返します - - - RESULT OK - '9' - 結果パケット - IPCコマンドが成功すると、watchdogはこのパケット型を返します - - - - -
+ + + watchdogプロセスに送られ、またwatchdogプロセスから返却されるIPCコマンドのパケットの最初のバイトは、コマンドまたはコマンド結果型と認識されます。 + + + + Watchdog IPC command packet types + + + + + 名前 + バイト値 + + 説明 + + + + + + + REGISTER FOR NOTIFICATIONS + '0' + コマンドパケット + 現在の接続をwatchdog通知を受け取るために登録するコマンド + + + NODE STATUS CHANGE + '2' + コマンドパケット + watchdogノードの状態変化をwatchdogに通知するためのコマンド + + + GET NODES LIST + '3' + コマンドパケット + 全ての設定済み watchdog ノードのリストを要求します + + + NODES LIST DATA + '4' + 結果パケット + パケット中のJSONデータにすべてのwatchdogノードのリストが含まれます + + + CLUSTER IN TRANSITION + '7' + 結果パケット + クラスタが遷移中なのでコマンドを処理できないときにwatchdogはこのパケットを返します + + + RESULT BAD + '8' + 結果パケット + IPCコマンドが失敗すると、watchdogはこのパケット型を返します + + + RESULT OK + '9' + 結果パケット + IPCコマンドが成功すると、watchdogはこのパケット型を返します + + + + +
- + --> 外部死活監視のIPCパケットとデータ WATCHDOG - - -watchdogの"GET NODES LIST"、"NODES LIST DATA"、"NODE STATUS CHANGE"IPCメッセージは、外部死活監視システムを統合するために使用できます。 -pgpoolの組み込み死活監視も同じチャンネルと技術を使っていることに注意してください。 - - - - - 構成されているwatchdogノードのリストの取得 + + + watchdogの"GET NODES LIST"、"NODES LIST DATA"、"NODE STATUS CHANGE"IPCメッセージは、外部死活監視システムを統合するために使用できます。 + pgpoolの組み込み死活監視も同じチャンネルと技術を使っていることに注意してください。 + + + + + 構成されているwatchdogノードのリストの取得 - WATCHDOG + WATCHDOG - - -サードパーティの死活監視システムは、が設定されている時は認証キーとデータを含むJSONデータを、が設定されていない時は空のパケットデータを含む"GET NODES LIST"パケットをwatchdogのIPCソケットに送ることにより、"NODES LIST DATA"結果パケットを入手できます。 - - - -"GET NODES LIST"に対するwatchdogに返却される結果パケットは、死活監視を実施する対象となる、構成されているすべてのwatchdogノードのリストを含むJSONフォーマットです。 - - - - -- The example JSON data contained in "NODES LIST DATA" + + + サードパーティの死活監視システムは、が設定されている時は認証キーとデータを含むJSONデータを、が設定されていない時は空のパケットデータを含む"GET NODES LIST"パケットをwatchdogのIPCソケットに送ることにより、"NODES LIST DATA"結果パケットを入手できます。 + + + + "GET NODES LIST"に対するwatchdogに返却される結果パケットは、死活監視を実施する対象となる、構成されているすべてのwatchdogノードのリストを含むJSONフォーマットです。 + + + + -- The example JSON data contained in "NODES LIST DATA" { "NodeCount":3, "WatchdogNodes": - [ - { - "ID":0, - "State":1, - "NodeName":"Linux_ubuntu_9999", - "HostName":"watchdog-host1", - "DelegateIP":"172.16.5.133", - "WdPort":9000, - "PgpoolPort":9999 - }, - { - "ID":1, - "State":1, - "NodeName":"Linux_ubuntu_9991", - "HostName":"watchdog-host2", - "DelegateIP":"172.16.5.133", - "WdPort":9000, - "PgpoolPort":9991 - }, - { - "ID":2, - "State":1, - "NodeName":"Linux_ubuntu_9992", - "HostName":"watchdog-host3", - "DelegateIP":"172.16.5.133", - "WdPort":9000, - "PgpoolPort":9992 - } - ] + [ + { + "ID":0, + "State":1, + "NodeName":"Linux_ubuntu_9999", + "HostName":"watchdog-host1", + "DelegateIP":"172.16.5.133", + "WdPort":9000, + "PgpoolPort":9999 + }, + { + "ID":1, + "State":1, + "NodeName":"Linux_ubuntu_9991", + "HostName":"watchdog-host2", + "DelegateIP":"172.16.5.133", + "WdPort":9000, + "PgpoolPort":9991 + }, + { + "ID":2, + "State":1, + "NodeName":"Linux_ubuntu_9992", + "HostName":"watchdog-host3", + "DelegateIP":"172.16.5.133", + "WdPort":9000, + "PgpoolPort":9992 + } + ] + } + + -- Note that ID 0 is always reserved for local watchdog node + + + + + + 構成されているwatchdogノード情報をwatchdogから入手したら、外部死活監視システムはwatchdogノードの死活監視を実施できます。 + ノードの状態変化を検知したら、watchdogの"NODE STATUS CHANGE"IPCメッセージを使って、watchdogに通知できます。 + メッセージには、状態変化したノードIDとノードの新しい状態を伴うJSONでデータを格納してください(ノードIDは、watchdogから返却されたWatchdogNodesリスト中のノードと同じノードIDを使わなければなりません)。 + + + + -- The example JSON to inform pgpool-II watchdog about health check + failed on node with ID 1 will look like + + { + "NodeID":1, + "NodeStatus":1, + "Message":"optional message string to log by watchdog for this event" + "IPCAuthKey":"wd_authkey configuration parameter value" } - -- Note that ID 0 is always reserved for local watchdog node - - - - - -構成されているwatchdogノード情報をwatchdogから入手したら、外部死活監視システムはwatchdogノードの死活監視を実施できます。 -ノードの状態変化を検知したら、watchdogの"NODE STATUS CHANGE"IPCメッセージを使って、watchdogに通知できます。 -メッセージには、状態変化したノードIDとノードの新しい状態を伴うJSONでデータを格納してください(ノードIDは、watchdogから返却されたWatchdogNodesリスト中のノードと同じノードIDを使わなければなりません)。 - - - - -- The example JSON to inform pgpool-II watchdog about health check - failed on node with ID 1 will look like - - { - "NodeID":1, - "NodeStatus":1, - "Message":"optional message string to log by watchdog for this event" - "IPCAuthKey":"wd_authkey configuration parameter value" - } - - -- NodeStatus values meanings are as follows - NODE STATUS DEAD = 1 - NODE STATUS ALIVE = 2 - - - - + -- NodeStatus values meanings are as follows + NODE STATUS DEAD = 1 + NODE STATUS ALIVE = 2 + + + + + +
+ + + watchdogの制限事項 + + + WATCHDOG + + + + + クエリモードの死活監視におけるwatchdogの制限事項 + + WATCHDOG + + + + + クエリモードでは、PostgreSQLサーバの障害やpcp_detach_nodeによってすべてのDBノードがPgpool-IIから切り離されると、watchdogはPgpool-IIサービスが停止状態にあるとみなし、watchdogに割り当てられた仮想IPを停止します。 + ですので、Pgpool-IIのクライアントは仮想IPを使ってPgpool-IIに接続できなくなります。 + これは、複数のリーダーPgpool-IIが存在するスプリットブレインを回避するために必要です。 + + + + + + watchdogが停止している<productname>Pgpool-II</productname>に接続する + + WATCHDOG + + + + watchdog が停止状態のPgpool-IIに実IPで接続しないでください。 + なぜなら、watchdog がダウン状態のPgpool-IIは、他のPgpool-II watchdogから情報を受け取れないので、他のPgpool-IIから、バックエンドの状態がずれるかもしれないからです。 + - - - - watchdogの制限事項 - - + + + + watchdogが停止している<productname>Pgpool-II</productname>は再起動が必要です + WATCHDOG + + + watchdog が停止状態のPgpool-IIは、アクティブのPgpool-IIにもスタンバイのPgpool-IIにもなれません。 + 停止状態からの復帰にはPgpool-IIの再起動が必要です。 + + + + + + watchdogの昇格には数秒を要します + + WATCHDOG + + + + 停止通知パケットが他のPgpool-IIに送られる前に、以前の仮想IPが停止したことを確認するので、リーダーPgpool-IIが停止してからスタンバイPgpool-IIが新しいリーダーに昇格するまでには数秒を要します。 + + + - - - クエリモードの死活監視におけるwatchdogの制限事項 - - WATCHDOG - - - - -クエリモードでは、PostgreSQLサーバの障害やpcp_detach_nodeによってすべてのDBノードがPgpool-IIから切り離されると、watchdogはPgpool-IIサービスが停止状態にあるとみなし、watchdogに割り当てあられた仮想IPを停止します。 -ですので、Pgpool-IIのクライアントは仮想IPを使ってPgpool-IIに接続できなくなります。 -これは、複数のアクティブPgpool-IIが存在するスプリットブレインを回避するために必要です。 - - - - - - watchdogが停止している<productname>Pgpool-II</productname>に接続する - - WATCHDOG - - - -watchdog が停止状態のPgpool-IIに実IPで接続しないでください。 -なぜなら、watchdog がダウン状態のPgpool-IIは、他のPgpool-II watchdogから情報を受け取れないので、他のPgpool-IIから、バックエンドの状態がずれるかもしれないからです。 - - - - - - watchdogが停止している<productname>Pgpool-II</productname>は再起動が必要です - - WATCHDOG - - - -watchdog が停止状態のPgpool-IIは、アクティブのPgpool-IIにもスタンバイのPgpool-IIにもなれません。 -停止状態からの復帰にはPgpool-IIの再起動が必要です。 - - - - - - watchdogの昇格には数秒を要します - - WATCHDOG - - - -停止通知パケットが他のPgpool-IIに送られる前に、以前の仮想IPが停止したことを確認するので、アクティブPgpool-IIが停止してからスタンバイPgpool-IIが新しいアクティブに昇格するまでには数秒を要します。 - - -
- - - - watchdogの構造 + + + watchdogの構造 + + + watchdogはPgpool-IIの下位プロセスで、複数のPgpool-IIを調整して、高可用性を追加し、単一障害点を除きます。 + (もし有効なら)watchdogプロセスはPgpool-IIが起動した際に自動的に起動されます。 + watchdogは、コアシステムと死活監視システムの2つの主なコンポーネントから構成されます。 + + + + + watchdogコア + + + "watchdog"として参照されるwatchdogコアは、クラスタに存在するPgpool-IIノードとのwatchdog関連の通信を管理します。 + また、Pgpool-II親プロセスと死活監視プロセスとも通信します。 + + + + watchdogプロセスの中心はステートマシンで、初期状態(WD_LOADING)から出発し、スタンバイ状態(WD_STANDBY)かリーダー/コーディネーター状態(WD_COORDINATOR)へと遷移します。 + スタンバイ状態もリーダー/コーディネーター状態も、watchdogステートマシンとしては安定状態です。 + ローカルのPgpool-IIノードに問題が起きるか、リモートのPgpool-IIノードがクラスタから切り離されるまでその状態を保ちます。 + + + + watchdogプロセスは以下のタスクを実行します。 + + + + + + + ローカルノードのwatchdog状態の管理と調停 + + + + + + + ローカルあるいはリモートのPgpool-IIを対象とする組み込みあるいは外部死活監視との通信 + + + + + + + watchdogチャンネルを通じてPgpool-II親プロセスがクラスタコマンドを実行するための機構を提供するために、Pgpool-IIメインプロセスと通信する + + + + + + + 参加しているすべてのPgpool-IIノードと通信し、リーダー/コーディネーターノードの選択を調停し、クラスタのクォーラムを確実にする + + + + + + + リーダー/コーディネーターノード上の仮想IPを管理し、ユーザが昇格と降格用のカスタムスクリプトを書けるようにする + + + + + + + watchdogクラスタ中のPgpool-IIノードの設定の一貫性を検証する + + + + + + + 起動時にすべてのPostgreSQLバックエンドの状態を同期する + + + + + + + 複数のフェイルオーバコマンドを直列化するためにPgpool-IIメインプロセスに対して分散ロック機能を提供する + + + + + + + + クラスタの他のノードとの通信 + + + watchdogはほかのすべてのノードとの通信にTCP/IPソケットを使っています。 + 各々のwatchdogノードはそれぞれのノードに2つのソケットを開くことができます。 + ひとつはこのノードが作った出て行く(クライアント)ソケットで、他のノードとの通信を開始します。 + 2つ目は、リモートwatchdogノードが開いた通信から入ってくるのを待ち受けるソケットです。 + リモートノードとのソケット接続が成功すると、直ちにwatchdogはADD NODE (WD_ADD_NODE_MESSAGE)メッセージをそのソケットに送ります。 + ADD NODEメッセージを受信したwatchdogノードは、メッセージにカプセル化されたノード情報をそのノードのPgpool-II設定と照合し、照合テストが成功すればノードをクラスタに追加します。 + 照合テストが失敗すると、接続は切断されます。 + + + + + + IPCとデータフォーマット - -watchdogはPgpool-IIの下位プロセスで、複数のPgpool-IIを調整して、高可用性を追加し、単一障害点を除きます。 -(もし有効なら)watchdogプロセスはPgpool-IIが起動した際に自動的に起動されます。 -watchdogは、コアシステムと死活監視システムの2つの主なコンポーネントから構成されます。 + + watchdogプロセスはIPC通信のためにUNIXドメインソケットを公開し、JSON形式のデータを受付、また提供します。 + Pgpool-IIの組み込み死活監視とメインプロセスも含めて、すべてのPgpool-IIの内部プロセスは、このIPCソケットを使ってwatchdogと通信します。 + IPCソケットは、watchdogと通信する外部/サードパーティシステムも利用することができます。 + + + 外部/サードパーティシステムと統合するための、watchdog IPCインターフェイスの使い方の詳細はをご覧ください。 + + + + + + + Watchdogにおける死活監視 + + + Watchdogにおける死活監視は、watchdogクラスタに参加しているPgpool-IIノードの健全性を監視するwatchdogの下位コンポーネントです。 + Pgpool-II watchdogは、リモートノードの健全性をチェックする3つの方法、"heartbeat"と"query"と"external"モードを提供します。 + + + + "heartbeat"モードでは、死活監視プロセスはUDPを使ってリモートノードにアクセスできるかどうか確認します。 + 各ノード毎に死活監視の親プロセスは2つの子プロセスを起動します。 + ひとつはハートビート信号の送信のため、もうひとつはハートビートの受信のためです。 + "query"モードでは、死活監視プロセスはPostgreSQLのlibpqインターフェイスを使ってリモートのPgpool-IIに問い合わせを送ります。 + このモードでは、各死活監視プロセスは、死活監視のために新しくスレッドを作成します。 + クエリが終了すると、直ちにそのスレッドは破棄されます。 + "external"モードでは、Pgpool-IIの死活監視は無効になり、代わりに外部システムがローカルノードとリモートノードを監視することを期待します。 + + + + リモートノードの死活監視以外にも、watchdogの死活監視は、上位サーバへの接続を監視することにより、インストールされたノードの健全性をチェックできます。 + 上位サーバへの接続を監視するために、Pgpool-IIの死活監視はexecv()を使って'ping -q -c3 hostname'コマンドを実行します。 + 各pingコマンドを実行するために新しい子プロセスが生成されます。 + つまり、各々の死活監視のサイクルごとに、それぞれの上位サーバのために子プロセスが作られ、破棄されます。 + たとえば、死活監視の設定で2つの上位サーバがあり、10秒ごとに死活監視を行うとすると、死活監視は10秒ごとに2つの子プロセスを起動し、各上位サーバ用に1個ずつプロセスが割り当てられます。 + それぞれのプロセスは、pingコマンドが完了するまで生存します。 + + - - - watchdogコア - - -"watchdog"として参照されるwatchdogコアは、クラスタに存在するPgpool-IIノードとのwatchdog関連の通信を管理します。 -また、Pgpool-II親プロセスと死活監視プロセスとも通信します。 - - - -watchdogプロセスの中心はステートマシンで、初期状態(WD_LOADING)から出発し、スタンバイ状態(WD_STANDBY)かマスター/コーディネーター状態(WD_COORDINATOR)へと遷移します。 -スタンバイ状態もマスター/コーディネーター状態も、watchdogステートマシンとしては安定状態です。 -ローカルのPgpool-IIノードに問題が起きるか、リモートのPgpool-IIノードがクラスタから切り離されるまでその状態を保ちます。 - - - -watchdogプロセスは以下のタスクを実行します。 - - - - - - -ローカルノードのwatchdog状態の管理と調停 - - - - - - -ローカルあるいはリモートのPgpool-IIを対象とする組み込みあるいは外部死活監視との通信 - - - - - - -watchdogチャンネルを通じてPgpool-II親プロセスがクラスタコマンドを実行するための機構を提供するために、Pgpool-IIメインプロセスと通信する - - - - - - -参加しているすべてのPgpool-IIノードと通信し、マスター/コーディネーターノードの選択を調停し、クラスタのクォーラムを確実にする - - - - - - -マスター/コーディネーターノード上の仮想IPを管理し、ユーザが昇格と降格用のカスタムスクリプトを書けるようにする - - - - - - -watchdogクラスタ中のPgpool-IIノードの設定の一貫性を検証する - - - - - - -起動時にすべてのPostgreSQLバックエンドの状態を同期する - - - - - - -複数のフェイルオーバコマンドを直列化するためにPgpool-IIメインプロセスに対して分散ロック機能を提供する - - - - - - - - クラスタの他のノードとの通信 - - -watchdogはほかのすべてのノードとの通信にTCP/IPソケットを使っています。 -各々のwatchdogノードはそれぞれのノードに2つのソケットを開くことができます。 -ひとつはこのノードが作った出て行く(クライアント)ソケットで、他のノードとの通信を開始します。 -2つ目は、リモートwatchdogノードが開いた通信から入ってくるのを待ち受けるソケットです。 -リモートノードとのソケット接続が成功すると、直ちにwatchdogはADD NODE (WD_ADD_NODE_MESSAGE)メッセージをそのソケットに送ります。 -ADD NODEメッセージを受信したwatchdogノードは、メッセージにカプセル化されたノード情報をそのノードのPgpool-II設定と照合し、照合テストが成功すればノードをクラスタに追加します。 -照合テストが失敗すると、接続は切断されます。 - - - - - - IPCとデータフォーマット - - -watchdogプロセスはIPC通信のためにUNIXドメインソケットを公開し、JSON形式のデータを受付、また提供します。 -Pgpool-IIの組み込み死活監視とメインプロセスも含めて、すべてのPgpool-IIの内部プロセスは、このIPCソケットを使ってwatchdogと通信します。 -IPCソケットは、watchdogと通信する外部/サードパーティシステムも利用することができます。 - - - -外部/サードパーティシステムと統合するための、watchdog IPCインターフェイスの使い方の詳細はをご覧ください。 - - - - - - - Watchdogにおける死活監視 - - -Watchdogにおける死活監視は、watchdogクラスタに参加しているPgpool-IIノードの健全性を監視するwatchdogの下位コンポーネントです。 -Pgpool-II watchdogは、リモートノードの健全性をチェックする2つの方法、"heartbeat"と"query"モードを提供します。 - - - -"heartbeat"モードでは、死活監視プロセスはUDPを使ってリモートノードにアクセスできるかどうか確認します。 -各ノード毎に死活監視の親プロセスは2つの子プロセスを起動します。 -ひとつはハートビート信号の送信のため、もうひとつはハートビートの受信のためです。 -"query"モードでは、死活監視プロセスはPostgreSQLのlibpqインターフェイスを使ってリモートのPgpool-IIに問い合わせを送ります。 -このモードでは、各死活監視プロセスは、死活監視のために新しくスレッドを作成します。 -クエリが終了すると、直ちにそのスレッドは破棄されます。 - - - -リモートノードの死活監視以外にも、watchdogの死活監視は、上位サーバへの接続を監視することにより、インストールされたノードの健全性をチェックできます。 -上位サーバへの接続を監視するために、Pgpool-IIの死活監視はexecv()を使って'ping -q -c3 hostname'コマンドを実行します。 -つまり、各々の死活監視のサイクルごとに、それぞれの上位サーバのために子プロセスが作られ、破棄されます。 -たとえば、死活監視の設定で2つの上位サーバがあり、10秒ごとに死活監視を行うとすると、死活監視は10秒ごとに2つの子プロセスを起動し、各上位サーバ用に1個ずつプロセスが割り当てられます。 -それぞれのプロセスは、pingコマンドが完了するまで生存します。 - - - - +
diff --git a/doc.ja/src/sgml/basic-config-example.sgml b/doc.ja/src/sgml/basic-config-example.sgml deleted file mode 100644 index 57ccd0265..000000000 --- a/doc.ja/src/sgml/basic-config-example.sgml +++ /dev/null @@ -1,258 +0,0 @@ - - Basic Configuration Example - - - In this tutorial, I explain how to create a simple streaming - replication setting using pgpool-II step by step. You need three - Linux boxes: one is for pgpool-II itself and pgpoolAdmin, and the - others for PostgreSQL. Needless to say you could use virtual - machines to simulate those three servers. - - - Though the setting is simple, it makes possible to implement - important functionalities which PostgreSQL lacks: - - - - - Automated failover. If one of the two PostgreSQL goes down, - pgpool-II will automatically let remaining node take over and - keep on providing database service to applications. - - - - - - Query dispatching and load balancing. In streaming replication - mode, applications need to carefully chose queries to be sent - to standby node. Pgpool-II checks the query and automatically - chose primary or standby node in sending queries. So - applications need not to worry about it. - - - - - - Online recovery. Recover failed node without stopping - pgpool-II and PostgreSQL. - - - - - - In this configuration, if the host where pgool-II is running on, - you cannot access database via pgpool-II anymore. To overcome - the problem, you can create a high availabilty configuration by - using watchdog. - - - Here is the overall picture of the installation. - - - - Please note that in this figure the server #1(hostname is - "osspc16") is assigned to pgpool-II and pgpoolAdmin. The server - #2 (hostname is "osspc17") is for the primary PostgreSQL - server. The server #3 (hostname is "osspc18") is for the standby - PostgreSQL server. Please note that this is just a initial - setting and afterward you can interchange the role of each - PostgreSQL by using online recovery. - - - - Installig PostgreSQL - - - The easiest way is downloading Linux package from PostgreSQL - official site. Another way to install PostgreSQL is from the - source code. This is surprisingly easy actually. Just unpack - the tar ball and configure;make;make install. See the - PostgreSQL manual for more details. - -From now on, I assume that database clusters are located at /home/postgres/data and are owned by postgres user: - -$ initdb -D /home/postgres/data - -Next add followings to /home/postgres/data/postgresql.conf. "logging_collector" and below are not really relevant to Streaming replication but they are my favorites to make my life easier. You might want to remove "log_statement = 'all'" in production environment however. - -listen_address = '*' -hot_standby = on -wal_level = hot_standby -max_wal_senders = 1 -logging_collector = on -log_filename = '%A.log' -log_line_prefix = '%p %t ' -log_truncate_on_rotation = on -log_statement = 'all' - -Put pg_hba.conf to /home/postgres/data. Of course you need to replace "/some/where/" with actual directory where you downloaded the scripts. Caution: settings here allows to access from any IP address. Please apply appropreate setting for your real world systems. - -$ cp /some/where/pg_hba.conf" /home/postgres/data" - -Start PostgreSQL server on occp17 and osspc18. At this poing those PostgreSQL servers will run as primary server, thus no streaming replication is working). - -$ pg_ctl -D /home/postgres/data start - -Next you need to allow postgres user on osspc17 and osspc18 can acceess each other without password. Execute ssh-keygen command as postgres and append the contents of /home/postgres/.ssh/id_rsa.pub to /home/postgres/.ssh/authorized_keys of other server. After this we recommend to test the setting by executing ls command via ssh, for example. - -$ ssh osspc17 ls - -Installing pgpool-II - -Install pgpool-II onto osspc16. In this configuration explained here you need pgpool-II 3.3.3 or later. - -$ tar xfz /some/where/pgpool-II-3.3.3.tar.gz -$ cd pgpool-II-3.3.3 -$ ./configure -$ make -$ sudo make install -$ cp /some/where/install-functions.sh . -$ sh install-functions.sh - -Next install user defined functions used by pgpool-II onto PostgreSQL. Execute followings as postgres user on occp17 and osspc18. "install-functions.sh" can be downloaded here. Of course you need to replace "/some/where/" with actual directory where you downloaded the scripts. - -Next you need to install pgpool-II configuration files onto occp16. The main configuration file is pgpool.conf. The other one is the pcp.conf. You will need to execute followings as root. - -# cp /some/where/pgpool.conf /usr/local/etc -# chown apache /usr/local/etc/pgpool.conf -# cp /some/where/pcp.conf /usr/local/etc -# chown apache /usr/local/etc/pcp.conf - -The reason why we execute chown is, pgpoolAdmin need to modify those files. pgpoolAdmin is a PHP script thus executed by Apache. If you have no plan to use pgpoolAdmin(that measn you want to use pcp command line admin tools only), you do not need to execute chown. - -The initial password for "postgres" in the pcp.conf is "pgpoolAdmin". I strongly recommend to change the password immediately after finishing the installation. The new password string can be obtained using pg_md5 command. See the pgpool-II doc for more details. - -Install basebackup.sh and pgpool_remote_start, neccessary for online recovery onto osspc17 and osspc18. Note that in pgpool_remote_start the path to pg_ctl command is specified. You might want to change it to an appropreate path according to your PostgreSQL installation. - -$ cp /some/where/baseback.sh /home/postgres/data -$ chmod 755 basebackup.sh -$ cp /some/where/pgpool_remote_start /home/postgres/data -$ chmod 755 pgpool_remote_start - -Install failover.sh for automatic failover onto osspc16. - -$ sudo cp /some/where/failover.sh /usr/local/etc -$ chmod 755 failover.sh - -Create neccessary directories on osspc16. Execute followings as root. The reason why we use chown is, pgpool-II is started by pgpoolAdmin. If you do not have a plan to use pgpoolAdmin, you need to change "apache" to the user you want to invoke pgpool-II. - -# mkdir /var/run/pgpool -# chown apache /var/run/pgpool -# mkdir /var/log/pgpool -# chown apache /var/log/pgpool - -Create neccessary directories on osspc17 and osspc18. Execute followings as root. - -# mkdir /var/log/pgpool/trigger -# chown postgres /var/log/pgpool/trigger - -If you plan to use pgpoolAdmin, you need to allow apache user on osspc16 accesses postgres uer on osspc17 and postgres user on osspc18. In most systems, login to the system as apache user is prohibited. - -apache:x:48:48:Apache:/var/www:/sbin/nologin - -Change temporarily /sbin/nologin to /bin/bash for example, to allow login. Create /var/www/.ssh and execute ssh-keygen. - -# mkdir /var/www/.ssh -# chown apache /var/www/.ssh -# su - apache -$ ssh-keygen -: -: - -Add /var/www/.ssh/id_rsa.pub to /home/postggres/.ssh/authorized_keys on osspc17 and osspc18. After this we recommend to test the setting by executing ls command via ssh, for example do followings as apache user. - -$ ssh postgres@osspc17 ls -$ ssh postgres@osspc18 ls - -Revert /etc/passwd. In the real world system it is recommended that you create an account solely used fro pgpoolAdmin and start its own apache. - -Create apache user on osspc17 and osspc18. - -$ createuser apache -Shall the new role be a superuser? (y/n) n -Shall the new role be allowed to create databases? (y/n) n -Shall the new role be allowed to create more new roles? (y/n) n - -Stop PostgreSQL on osspc18 and execute followings on osspc18. - -$ pg_ctl -D /home/postgres/data -m f stop - -Installing pgpoolAdmin - -pgpoolAdmin is a management tool for pgpool-II written in PHP. pgpoolAdmin must be executed on the same host which pgpool-II is running on. This effectively means that pgpoolAdmin does not work on Windows platform. pgpoolAdmin runs on PHP 4.2 or higher. It also needs PostgreSQL extention. If you plan to build PHP, please include --with-pgsql option. If you plan to install PHP from rpm. you may need to install PostgreSQL extension as well. Some distributions have built-in support for PostgreSQL extention, but most distributions do not. - -pgpoolAdmin has its own installer thus it is pretty easy to install pgpoolAdmin. In this configuration you need to install pgpoolAdmin 3.3.1 or later(or CVS HEAD). Unpack it under Apache document directory(for example, /var/www/html/). Follow the install instruction, located at doc/install/install.html. Here are several key points before installing pgpoolAdmin by using Web installer. - -# cd /var/www/html/pgpoolAdmin-3.3.1 -# chmod 777 templates_c -# chown apache conf/pgmgt.conf.php -# chmod 644 conf/pgmgt.conf.php - -Once you are prepared, brows the pgpoolAdmin install using your favorite Web browser. In this example, the URL will be http://localhost/pgpoolAdmin-3.3.1/install/index.php. You will see this page. Click "Next" and you will see this this page. Please make sure that all items are checked by green. This indicates that everytyhing is good. Click "Next". This is the main setting page. Several points you want to change from default values: - - Check "Discard pgpol_status". pgpool_status is a file to remember previous status of PostgreSQL when pgpool-II started. pgpool-II recognizes the healthiness of PostgreSQL by looking at the file. This will prevent pgpool-II from recognizing PostgreSQL has been up since pgpool started last time. Otherwise pgpool-II believies that PostgreSQL continues to be up, which cause data consistency among PostgreSQL nodes. However in an experiment environment, this is not convenient because you want to up down PostgreSQL frequently. - Check "don't run in daemon mode". This is neccessary to get pgpool log. - Chose stop mode "fast". The default value "smart" will not allow you to stop pgpool until all clients are disconnected and I feel this is annoying for test envrionment. - set "pgpool Logfile" to "|/usr/sbin/rotatelogs2 -l -f /var/log/pgpool/pgpool.log.%A 86400". This allows to place pgpool log files under /var/log/pgpool/ and rotate them once a day by using rotatelogs2 coming with apache2. - Set "Refresh Time" to 10. PgpoolAdmin will check pgpool-II status every 10 seconds and refresh pages. This is extremly convenient for test enverionments. - -Once you've done, the page should look like this. You finished to install pgpoolAdmin. Conguratulations! -Starting pgpool-II - -Login to pgpoolAdmin and start pgpool-II from "pgpool status" menu. You see osspc17 port 5432 PostgreSQL is running as a primary server. You should be able to connect to osspc16 port 5432 by using psql. Let's try to create a table. - -$ createdb -h osspc16 test -$ psql -h osspc16 test -test=# create table t1(i int); -CREATE TABLE -test=# - -You will find something like this in the pgpool log. - -$ tail /var/log/pgpool/pgpool.log.Friday -2014-04-04 15:17:20 LOG: pid 5716: DB node id: 0 backend pid: 6036 statement: create table t1(i int); - -You will see same thing in the PostgreSQL log as well. - -$ tail /home/postgres/data/pg_log/Friday.log -6036 2014-04-04 15:17:22 JST LOG: statement: create table t1(i int); - -Starting standby server - -At this point standby server is not running. To start standby server, just click "Recovery" button. "basebackup.sh" will be executed and the standby server will be automatically started. - -Once standby server is running, streaming replication starts. Let's insert some data into t1. - --- insert into t1 via pgpool-II. --- it will be executed on primary server -psql -h osspc16 test -test=# insert into t1 values(1); -test=# \q -psql -h osspc18 test --- now connected to standby server -test=# select * from t1; - i ---- - 1 -(1 row) - -What if standby server goes down? - -If standby goes down, it is disconnected from pgpool-II. Users can issue SQL via pgpool-II as usual. Just streaming replication is stopped. To recover standby server, click "Recovery" button. -What if primary server goes down? - -Don't panic. Standby server is there for this situation. Let the current primary server be osspc17. Login to osspc17 and stop PostgreSQL. - -$ pg_ctl -D /home/postgres/data -m f stop - -As you can see, osspc17 PostgreSQL goes down and osspc18 PostgreSQL takes over the primary role. When pgpool-II finds that primary is going down it executes failover script(failover.sh). The script creates trigger file as osspc18:/var/log/pgpool/trigger/trigger1. Standby server on osspc18 finds the file and decides to promote to primary. If you click the "Recovery" button osspc17 PostgreSQL, the former primary server will be recovered as standby server. -Summary - -PostgreSQL 9.3 supports simple and easy to use built-in replication system. Adding pgpool-II on top of the replication system it is possible to build a high availability(HA) system. - -If you have questions and/or comments, please post to pgpool-general mailing list. - -Tatsuo Ishii -ishii at sraoss.co.jp - - diff --git a/doc.ja/src/sgml/biblio.sgml b/doc.ja/src/sgml/biblio.sgml index e2cd69d27..24558b719 100644 --- a/doc.ja/src/sgml/biblio.sgml +++ b/doc.ja/src/sgml/biblio.sgml @@ -3,537 +3,30 @@ Bibliography - - Selected references and readings for SQL - and PostgreSQL. - - - - Some white papers and technical reports from the original - POSTGRES development team - are available at the University of California, Berkeley, Computer Science - Department - web site. - - - - <acronym>SQL</acronym> Reference Books - Reference texts for SQL features. - - - The Practical <acronym>SQL</acronym> Handbook - Bowman et al, 2001 - Using SQL Variants - Fourth Edition - - - Judith - Bowman - - - Sandra - Emerson - - - Marcy - Darnovsky - - - 0-201-70309-2 - 2001 - - Addison-Wesley Professional - - - 2001 - - - - - A Guide to the <acronym>SQL</acronym> Standard - Date and Darwen, 1997 - A user's guide to the standard database language SQL - Fourth Edition - - - C. J. - Date - - - Hugh - Darwen - - - 0-201-96426-0 - 1997 - - Addison-Wesley - - - 1997 - Addison-Wesley Longman, Inc. - - - - - An Introduction to Database Systems - Date, 2004 - Eighth Edition - - - C. J. - Date - - - 0-321-19784-4 - 2003 - - Addison-Wesley - - - 2004 - Pearson Education, Inc. - - - - - Fundamentals of Database Systems - Fourth Edition - - - Ramez - Elmasri - - - Shamkant - Navathe - - - 0-321-12226-7 - 2003 - - Addison-Wesley - - - 2004 - - - - - Understanding the New <acronym>SQL</acronym> - Melton and Simon, 1993 - A complete guide - - - Jim - Melton - - - Alan R. - Simon - - - 1-55860-245-3 - 1993 - - Morgan Kaufmann - - - 1993 - Morgan Kaufmann Publishers, Inc. - - - - - Principles of Database and Knowledge - Base Systems - Ullman, 1988 - - - Jeffrey D. - Ullman - - - Volume 1 - - Computer Science Press - - 1988 - - - - - - PostgreSQL-specific Documentation - This section is for related documentation. - - - Enhancement of the ANSI SQL Implementation of PostgreSQL - Simkovics, 1998 - - - Stefan - Simkovics - - - - - - - Discusses SQL history and syntax, and describes the addition of - INTERSECT and EXCEPT constructs into - PostgreSQL. Prepared as a Master's - Thesis with the support of O. Univ. Prof. Dr. Georg Gottlob and - Univ. Ass. Mag. Katrin Seyr at Vienna University of Technology. - - - - November 29, 1998 - - Department of Information Systems, Vienna University of Technology -
Vienna, Austria
-
-
- - - The <productname>Postgres95</productname> User Manual - Yu and Chen, 1995 - - - A. - Yu - - - J. - Chen - - - - - The POSTGRES Group - - - - Sept. 5, 1995 - - University of California -
Berkeley, California
-
-
- - - - <ulink url="http://db.cs.berkeley.edu/papers/UCB-MS-zfong.pdf"> - The design and implementation of the <productname>POSTGRES</productname> query optimizer - </ulink> - - Zelaine - Fong - - - University of California, Berkeley, Computer Science Department - - - -
- Proceedings and Articles - This section is for articles and newsletters. - - Partial indexing in POSTGRES: research project - Olson, 1993 - - - Nels - Olson - - - 1993 - UCB Engin T7.49.1993 O676 - - University of California -
Berkeley, California
-
-
- - + - A Unified Framework for Version Modeling Using Production Rules in a Database System - Ong and Goh, 1990 + <ulink + url="http://www.vldb.org/pvldb/vol2/vldb09-694.pdf">Pangea: An + Eager Database Replication Middleware guaranteeing Snapshot + Isolation without modification of Database Servers</ulink> - L. - Ong + Takeshi + Mishima - J. - Goh - - - - - ERL Technical Memorandum M90/33 - April, 1990 - - University of California -
Berkely, California
-
-
-
- - - - <ulink url="http://db.cs.berkeley.edu/papers/ERL-M87-13.pdf"> - The <productname>POSTGRES</productname> data model - </ulink> - Rowe and Stonebraker, 1987 - - - L. - Rowe - - - M. - Stonebraker + Hiroshi + Nakamura VLDB Conference - Sept. 1987 -
Brighton, England
-
-
- - - - Generalized Partial Indexes - <ulink url="http://citeseer.ist.psu.edu/seshadri95generalized.html">(cached version) -<!-- - Original URL: http://citeseer.ist.psu.edu/seshadri95generalized.html ---> - </ulink> - - Seshardri, 1995 - - - P. - Seshadri - - - A. - Swami - - - - - Eleventh International Conference on Data Engineering - 6-10 March 1995 -
Taipeh, Taiwan
-
- 1995 - Cat. No.95CH35724 - - IEEE Computer Society Press -
Los Alamitos, California
-
- 420-7 -
- - - - <ulink url="http://db.cs.berkeley.edu/papers/ERL-M85-95.pdf"> - The design of <productname>POSTGRES</productname> - </ulink> - Stonebraker and Rowe, 1986 - - - M. - Stonebraker - - - L. - Rowe - - - - - ACM-SIGMOD Conference on Management of Data - May 1986 -
Washington, DC
-
-
- - - - The design of the <productname>POSTGRES</productname> rules system - Stonebraker, Hanson, Hong, 1987 - - - M. - Stonebraker - - - E. - Hanson - - - C. H. - Hong - - - - - IEEE Conference on Data Engineering - Feb. 1987 -
Los Angeles, California
-
-
- - - - <ulink url="http://db.cs.berkeley.edu/papers/ERL-M87-06.pdf"> - The design of the <productname>POSTGRES</productname> storage system - </ulink> - Stonebraker, 1987 - - - M. - Stonebraker - - - - - VLDB Conference - Sept. 1987 -
Brighton, England
-
-
- - - - <ulink url="http://db.cs.berkeley.edu/papers/ERL-M89-82.pdf"> - A commentary on the <productname>POSTGRES</productname> rules system - </ulink> - Stonebraker et al, 1989 - - - M. - Stonebraker - - - M. - Hearst - - - S. - Potamianos - - - - - SIGMOD Record 18(3) - Sept. 1989 - - - - - - <ulink url="http://db.cs.berkeley.edu/papers/ERL-M89-17.pdf"> - The case for partial indexes - </ulink> - Stonebraker, M, 1989b - - - M. - Stonebraker - - - - - SIGMOD Record 18(4) - 4-11 - Dec. 1989 - - - - - - <ulink url="http://db.cs.berkeley.edu/papers/ERL-M90-34.pdf"> - The implementation of <productname>POSTGRES</productname> - </ulink> - Stonebraker, Rowe, Hirohama, 1990 - - - M. - Stonebraker - - - L. A. - Rowe - - - M. - Hirohama - - - - - Transactions on Knowledge and Data Engineering 2(1) - - IEEE - - March 1990 - - - - - - <ulink url="http://db.cs.berkeley.edu/papers/ERL-M90-36.pdf"> - On Rules, Procedures, Caching and Views in Database Systems - </ulink> - Stonebraker et al, ACM, 1990 - - - M. - Stonebraker - - - A. - Jhingran - - - J. - Goh - - - S. - Potamianos - - - - - ACM-SIGMOD Conference on Management of Data - June 1990 + Aug. 2009 +
Lyon, France
diff --git a/doc.ja/src/sgml/client-auth.sgml b/doc.ja/src/sgml/client-auth.sgml index 3bc324de3..571c0c65c 100644 --- a/doc.ja/src/sgml/client-auth.sgml +++ b/doc.ja/src/sgml/client-auth.sgml @@ -1,24 +1,24 @@ - + --> クライアント認証 - + --> クライアント認証 - -Pgpool-IIPostgreSQLサーバとPostgreSQLデータベースクライアントの間で動作するミドルウェアであるため、クライアントアプリケーションがPgpool-IIに接続したときには、今度はPgpool-IIがクライアントが提供したのと同じ認証情報を使ってPostgreSQLサーバに接続します。 -したがって、PostgreSQLのユーザに対し定義された全てのアクセス権限と制約が、自動的に全てのPgpool-IIクライアントに適用されます。 -例外はクライアントのIPアドレスやホスト名に依存するPostgreSQL側での認証です。 -それは、PostgreSQLサーバへの接続はPgpool-IIによって作られ、PostgreSQLサーバは実際のクライアントではなくPgpool-IIのIPアドレスしか見ることができないからです。 -このため、クライアントホストに基づく認証のため、Pgpool-IIpg_hbaと同様にクライアント接続の認証処理を行うpool_hbaのメカニズムを持っています。 + authenticating the incoming client connections. + --> + Pgpool-IIPostgreSQLサーバとPostgreSQLデータベースクライアントの間で動作するミドルウェアであるため、クライアントアプリケーションがPgpool-IIに接続したときには、今度はPgpool-IIがクライアントが提供したのと同じ認証情報を使ってPostgreSQLサーバに接続します。 + したがって、PostgreSQLのユーザに対し定義された全てのアクセス権限と制約が、自動的に全てのPgpool-IIクライアントに適用されます。 + 例外はクライアントのIPアドレスやホスト名に依存するPostgreSQL側での認証です。 + それは、PostgreSQLサーバへの接続はPgpool-IIによって作られ、PostgreSQLサーバは実際のクライアントではなくPgpool-IIのIPアドレスしか見ることができないからです。 + このため、クライアントホストに基づく認証のため、Pgpool-IIpg_hbaと同様にクライアント接続の認証処理を行うpool_hbaのメカニズムを持っています。 + + + + クライアントがPgpool-IIに接続する際の認証用のパスワードを管理するのがpool_passwdファイルです(詳細はをご覧ください。) + pool_passwdに登録されるパスワードは、PostgreSQLに登録されるパスワードと一致している必要があります。 + PostgreSQLに登録されたパスワードを変更しても、pool_passwdのパスワードは自動変更されないことに注意してください。 + scram-shar-256認証とMD5認証では、pool_passwdにユーザ名とパスワードを登録するのが必須ですが、clear text password認証、あるいはが有効である場合では必須ではありません。 + このため、pool_passwdのパスワードの保守を避けたい場合には、clear text password認証あるいはの検討をお勧めします。 - + --> <filename>pool_hba.conf</filename>ファイル @@ -47,24 +55,32 @@ - -PostgreSQLのpg_hba.confと同じようにPgpool-IIでもpool_hba.confとよばれる設定ファイルを使った同様のクライアント認証機能をサポートしています。 -Pgpool-IIをインストールするとデフォルトインストール先の設定ファイルディレクトリ("/usr/local/etc")にサンプルのpool_hba.conf.sampleが含まれています。 -デフォルトではpool_hbaによる認証は無効になっており、enable_pool_hbaonに設定することで有効になります。 -設定パラメータをご覧ください。 + + PostgreSQLpg_hba.confと同じようにPgpool-IIでもpool_hba.confとよばれる設定ファイルを使った同様のクライアント認証機能をサポートしています。 + Pgpool-IIをソースコードからインストールした場合、デフォルトインストール先の設定ファイルディレクトリ("/usr/local/etc")にサンプルのpool_hba.conf.sampleが含まれています。 + デフォルトではpool_hbaによる認証は無効になっており、enable_pool_hbaonに設定することで有効になります。 + 設定パラメータをご覧ください。 + + + PostgreSQLの数が1台のみ、あるいはraw mode(参照)では、pool_hba.confは必要なく、enable_pool_hbaはoffのままで構いません。 + この場合、クライアントの認証方式はPostgreSQLに完全に任されます。 + PostgreSQLの数が複数台、あるいはraw mode以外の場合でも、PostgreSQLでの認証方式がtrustなら、やはりpool_hba.confは必要なく、enable_pool_hbaはoffのままで構いません。 + + + - -pool_hba.confのフォーマットはPostgreSQLのpg_hba.confのものとほとんど同じです。 -pool_hba.confファイルの一般的な書式は、1行につき1つのレコードというレコードの集合です。 -空行はコメント用の#文字以降の文字と同じく無視されます。 -レコードは行をまたいで続けることはできません。 -レコードはスペースもしくはタブ、もしくはその両方で区切られた、複数のフィールドで構成されています。 -フィールドには、フィールド値が二重引用符付きの場合空白文字を含むことができます。 -データベース、ユーザもしくはアドレスフィールド内のキーワード(例:allまたはreplication)の一つを引用するとその特別な意味が失われ、その名称のデータベース、ユーザもしくはホストと一致するようになります。 + --> + pool_hba.confのフォーマットはPostgreSQLのpg_hba.confのものとほとんど同じです。 + pool_hba.confファイルの一般的な書式は、1行につき1つのレコードというレコードの集合です。 + 空行はコメント用の#文字以降の文字と同じく無視されます。 + レコードは行をまたいで続けることはできません。 + レコードはスペースもしくはタブ、もしくはその両方で区切られた、複数のフィールドで構成されています。 + フィールドには、フィールド値が二重引用符付きの場合空白文字を含むことができます。 + データベース、ユーザもしくはアドレスフィールド内のキーワード(例:allまたはreplication)の一つを引用符で囲むとその特別な意味が失われ、その名称のデータベース、ユーザもしくはホストと一致するようになります。 - -それぞれのレコードは接続形式、(接続形式に対して意味を持つのであれば)クライアントのIPアドレス範囲、データベースの名前、ユーザ名およびこれらのパラメータに一致する接続で使用される認証方法を指定します。 -接続形式、クライアントアドレス、要求されたデータベース、およびユーザ名に一致する最初のレコードが認証処理に使用されます。 -「失敗時の継続」や、 あるいは「バックアップ」はありません。 -これは、もしあるレコードが選択されて認証に失敗した場合、後続のレコードは考慮されないということです。 -どのレコードも一致しない時はアクセスが拒否されます。 + --> + それぞれのレコードは接続形式、(接続形式に対して意味を持つのであれば)クライアントのIPアドレス範囲、データベースの名前、ユーザ名およびこれらのパラメータに一致する接続で使用される認証方法を指定します。 + 接続形式、クライアントアドレス、要求されたデータベース、およびユーザ名に一致する最初のレコードが認証処理に使用されます。 + 「失敗時の継続」や、 あるいは「バックアップ」はありません。 + これは、もしあるレコードが選択されて認証に失敗した場合、後続のレコードは考慮されないということです。 + どのレコードも一致しない時はアクセスが拒否されます。 - -レコードは以下の書式のうちの1つの形式を取ります。 - -local database user auth-method auth-options - -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 - -host database user address auth-method auth-options -hostssl database user address auth-method auth-options -hostnossl database user address auth-method auth-options - - + レコードは以下の書式のうちの1つの形式を取ります。 + + local database user auth-method auth-options + + 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 + + host database user address auth-method auth-options + hostssl database user address auth-method auth-options + hostnossl database user address auth-method auth-options + + -フィールドの意味は以下のようになっています。 + --> + フィールドの意味は以下のようになっています。 local - -このレコードはUnixドメインソケットを使用する接続に対応します。 -この種類のレコードを使用しないと、Unixドメインソケット経由の接続は拒否されます + --> + このレコードはUnixドメインソケットを使用する接続に対応します。 + この種類のレコードを使用しないと、Unixドメインソケット経由の接続は拒否されます @@ -147,28 +163,28 @@ hostnossl database user host - -このレコードは、TCP/IPを使用した接続に対応します。 -hostレコードは、SSLもしくは非SSL接続のいずれかに対応します。 - - - - -サーバのデフォルトの動作は、ローカルループバックアドレスであるlocalhostのみTCP/IP接続を監視しています。 -よってサーバにおいてパラメータが適切な値に設定された状態で起動されていない限り、リモートのTCP/IP接続はできません。 + --> + このレコードは、TCP/IPを使用した接続に対応します。 + hostレコードは、SSLもしくは非SSL接続のいずれかに対応します。 - + + + + サーバのデフォルトの動作は、ローカルループバックアドレスであるlocalhostのみTCP/IP接続を監視しています。 + よってサーバにおいてパラメータが適切な値に設定された状態で起動されていない限り、リモートのTCP/IP接続はできません。 + + @@ -176,21 +192,21 @@ hostnossl database user hostssl - -このレコードは、接続がSSLで暗号化されている場合にのみTCP/IPを使用する接続に対応します。 + + このレコードは、接続がSSLで暗号化されている場合にのみTCP/IPを使用する接続に対応します。 - -このオプションを使用するには、Pgpool-IISSLサポートでビルドする必要があります。 -また、SSL設定パラメータを設定することによって有効にする必要があります。 -そうしなければ、hostsslレコードは無視されます。 + + このオプションを使用するには、Pgpool-IISSLサポートでビルドする必要があります。 + また、SSL設定パラメータを設定することによって有効にする必要があります。 + そうしなければ、hostsslレコードは無視されます。 @@ -199,11 +215,11 @@ hostnossl database user hostnossl - -このレコードは、hostsslと反対の動作で、SSLを使用していないTCP/IPの接続のみに対応します。 + + このレコードは、hostsslと反対の動作で、SSLを使用していないTCP/IPの接続のみに対応します。 @@ -212,28 +228,28 @@ hostnossl database user database - -このレコードで対応するデータベース名を指定します。 -allという値は、全てのデータベースと対応することを指定します。 - - - -databaseフィールド値として"samegroup"はサポートされません - - - -Pgpool-IIPostgreSQLバックエンドサーバにあるユーザ情報を事前に知る事ができないため、データベース名はpool_hba.confにあるdatabaseフィールドの項目のみと比較されます。 - - + --> + このレコードで対応するデータベース名を指定します。 + allという値は、全てのデータベースと対応することを指定します。 + + + + databaseフィールド値として"samegroup"はサポートされません + + + + Pgpool-IIPostgreSQLバックエンドサーバにあるユーザ情報を事前に知る事ができないため、データベース名はpool_hba.confにあるdatabaseフィールドの項目のみと比較されます。 + + @@ -242,32 +258,32 @@ databaseフィールド値として"samegroup"はサポート user - -このレコードで対応するデータベースユーザ名を指定します。 -allという値は、すべてのユーザが対応することを指定します。 -それ以外の場合には特定のデータベースユーザの名前となります。 + --> + このレコードで対応するデータベースユーザ名を指定します。 + allという値は、すべてのユーザが対応することを指定します。 + それ以外の場合には特定のデータベースユーザの名前となります。 - - -userフィールド値として"+"を使ったグループ指定はサポートされません + + + userフィールド値として"+"を使ったグループ指定はサポートされません - - - -上記の"samegroup"と同じ理由で、ユーザ名は単純にpool_hba.confにあるuserフィールドの項目のみ対してチェックされます。 - - + + + + 上記の"samegroup"と同じ理由で、ユーザ名は単純にpool_hba.confにあるuserフィールドの項目のみ対してチェックされます。 + + @@ -276,130 +292,130 @@ userフィールド値として"+"を使ったグループ指定はサポート address - -このレコードに対応しているクライアントマシンのアドレスを指定します。 -このフィールドはホスト名、IPアドレスの範囲、もしくは下記の特別なキーワードのいずれかを含むことができます。 + + このレコードに対応しているクライアントマシンのアドレスを指定します。 + このフィールドはホスト名、IPアドレスの範囲、もしくは下記の特別なキーワードのいずれかを含むことができます。 - -IPアドレスの範囲は、範囲の開始アドレス、スラッシュ (/) およびCIDRマスク長という標準数値表記を使用して指定します。 -CIDRマスク長は、クライアントIPアドレスが一致しなければならない、上位のビット数を表すものです。 -指定するIPアドレスの右側のビットには、0を指定しなければなりません。 -IPアドレス、 /、およびCIDRマスク長の間に空白を入れてはいけません。 + + IPアドレスの範囲は、範囲の開始アドレス、スラッシュ (/) およびCIDRマスク長という標準数値表記を使用して指定します。 + CIDRマスク長は、クライアントIPアドレスが一致しなければならない、上位のビット数を表すものです。 + 指定するIPアドレスの右側のビットには、0を指定しなければなりません。 + IPアドレス、 /、およびCIDRマスク長の間に空白を入れてはいけません。 - -典型的なIPv4アドレス範囲の例は、単一のホストの場合は172.20.143.89/32、小規模ネットワークの場合は172.20.143.0/24、大規模ネットワークの場合は10.6.0.0/16です。 -IPv6アドレスの範囲は、単一のホストの場合は::1/128(この場合はIPv6ループバックアドレス)、小規模ネットワークの場合はfe80::7a31:c1ff:0000:0000/96です。 -0.0.0.0/0はすべてのIPv4アドレス、::0/0はすべてのIPv6アドレスを意味しています。 -単一ホストを指定するには、IPv4の場合は32、IPv6の場合は128のマスク長を使用します。ネットワークアドレスでは、末尾の0を省略できません。 + + 典型的なIPv4アドレス範囲の例は、単一のホストの場合は172.20.143.89/32、小規模ネットワークの場合は172.20.143.0/24、大規模ネットワークの場合は10.6.0.0/16です。 + IPv6アドレスの範囲は、単一のホストの場合は::1/128(この場合はIPv6ループバックアドレス)、小規模ネットワークの場合はfe80::7a31:c1ff:0000:0000/96です。 + 0.0.0.0/0はすべてのIPv4アドレス、::0/0はすべてのIPv6アドレスを意味しています。 + 単一ホストを指定するには、IPv4の場合は32、IPv6の場合は128のマスク長を使用します。ネットワークアドレスでは、末尾の0を省略できません。 - -IPv4書式で指定されたエントリは、IPv4接続のみに対応し、IPv6書式で指定されたエントリは、たとえそのアドレスがIPv6内のIPv4の範囲内であったとしてもIPv6接続のみに対応します。 -IPv6書式のエントリは、システムのCライブラリがIPv6アドレスをサポートしていない場合拒否されることに注意してください。 + + IPv4書式で指定されたエントリは、IPv4接続のみに対応し、IPv6書式で指定されたエントリは、たとえそのアドレスがIPv6内のIPv4の範囲内であったとしてもIPv6接続のみに対応します。 + IPv6書式のエントリは、システムのCライブラリがIPv6アドレスをサポートしていない場合拒否されることに注意してください。 - -すべてのIPアドレスに一致するようにallと書くこともできますし、サーバ自身のどのIPアドレスにも一致するようにsamehostと書くこともできます。 -もしくは、サーバが直接接続されているサブネット内のどのアドレスにも一致するようにsamenetと書くこともできます。 + + すべてのIPアドレスに一致するようにallと書くこともできますし、サーバ自身のどのIPアドレスにも一致するようにsamehostと書くこともできます。 + もしくは、サーバが直接接続されているサブネット内のどのアドレスにも一致するようにsamenetと書くこともできます。 - -もし、ホスト名が指定されている場合 (IPアドレス範囲以外の場合、もしくはホスト名として処理される特別なキーワード)、その名前は、クライアントのIPアドレスの逆引き名前解決の結果 (例えば、もしDNSが使用されている場合は、逆引きDNS検索により解決されるもの) と比較されます。 -ホスト名の比較では、大文字と小文字を区別しません。 -もし一致するものがあった場合は、ホスト名に対して正引き解決 (例えば正引きDNS検索) が実行され、解決されたアドレスのいずれかがクライアントのIPアドレスと等しいかどうかがチェックされます。 -もし両方が一致した場合、エントリは一致するものとみなされます。 -(pool_hba.confで使用されているホスト名は、クライアントのIPアドレスの正引き名前解決が返すホスト名の1つでなければなりません。 -そうでなければ、この行は一致しません。 -1つのIPアドレスを複数のホスト名に関連付けるホスト名データベースもありますが、IPアドレスの解決を要求された場合にオペレーティングシステムは1つのホスト名のみを返します。) + + もし、ホスト名が指定されている場合 (IPアドレス範囲以外の場合、もしくはホスト名として処理される特別なキーワード)、その名前は、クライアントのIPアドレスの逆引き名前解決の結果 (例えば、もしDNSが使用されている場合は、逆引きDNS検索により解決されるもの) と比較されます。 + ホスト名の比較では、大文字と小文字を区別しません。 + もし一致するものがあった場合は、ホスト名に対して正引き解決 (例えば正引きDNS検索) が実行され、解決されたアドレスのいずれかがクライアントのIPアドレスと等しいかどうかがチェックされます。 + もし両方が一致した場合、エントリは一致するものとみなされます。 + (pool_hba.confで使用されているホスト名は、クライアントのIPアドレスの正引き名前解決が返すホスト名の1つでなければなりません。 + そうでなければ、この行は一致しません。 + 1つのIPアドレスを複数のホスト名に関連付けるホスト名データベースもありますが、IPアドレスの解決を要求された場合にオペレーティングシステムは1つのホスト名のみを返します。) - -ドット (.) で始まるホスト名の指定は実際のホスト名のサフィックスに一致します。 -したがって、.example.comfoo.example.comに一致します (example.comだけでは一致しません)。 + + ドット (.) で始まるホスト名の指定は実際のホスト名のサフィックスに一致します。 + したがって、.example.comfoo.example.comに一致します (example.comだけでは一致しません)。 - -pool_hba.confにホスト名が指定されている場合は、名前解決が十分に高速であることを確認する必要があります。 -nscdのようなローカル名前解決のキャッシュを設定することは有利かもしれません。 + + pool_hba.confにホスト名が指定されている場合は、名前解決が十分に高速であることを確認する必要があります。 + nscdのようなローカル名前解決のキャッシュを設定することは有利かもしれません。 - -このフィールドはhosthostsslhostnosslレコードにのみ適用されます。 + + このフィールドはhosthostsslhostnosslレコードにのみ適用されます。 - -アドレスフィールドにホスト名を指定することは、 Pgpool-II V3.7より前では利用できません。 + + アドレスフィールドにホスト名を指定することは、 Pgpool-II V3.7より前では利用できません。 @@ -409,24 +425,24 @@ IPv6書式のエントリは、システムのCライブラリがIPv6アドレ IP-mask - -この2つのフィールドはIP-address/mask-length表記の代替として使用可能です。 -マスク長を指定する代わりに、実際のマスクを分離した列で指定します。 -例えば、255.0.0.0はIPv4のCIDRマスク長8を意味し、255.255.255.255CIDRマスク長32を意味しています。 + + この2つのフィールドはIP-address/mask-length表記の代替として使用可能です。 + マスク長を指定する代わりに、実際のマスクを分離した列で指定します。 + 例えば、255.0.0.0はIPv4のCIDRマスク長8を意味し、255.255.255.255CIDRマスク長32を意味しています。 - -このフィールドはhosthostsslhostnosslレコードにのみ適用されます。 + + このフィールドはhosthostsslhostnosslレコードにのみ適用されます。 @@ -436,160 +452,182 @@ IPv6書式のエントリは、システムのCライブラリがIPv6アドレ auth-method - -接続がこのレコードに一致する場合に使用する認証方式を指定します。 -使用できる選択肢は以下にまとめていますが、詳しくを参照してください。 - - - - trust - - - -接続を無条件で許可します。 -この方式は、Pgpool-IIに接続できる全てのユーザを許可します。 - - - - - - reject - - - -接続を無条件に拒否します。 -特定のホストをあるグループから「除外」するために便利です。 -例えば、1行のrejectは特定のホストが接続することを拒否します。 - - - - - - md5 - - - -クライアントに対して認証時に二重MD5ハッシュ化パスワードを要求します。 - - - - -md5認証を使うには、ユーザ名とパスワードをというパスワードファイルに登録する必要があります。 -詳細はを参照してください。 - - - - - - - - scram-sha-256 - - - -ユーザのパスワードを確認するため、SCRAM-SHA-256認証を行います。 + --> + 接続がこのレコードに一致する場合に使用する認証方式を指定します。 + 使用できる選択肢は以下にまとめていますが、詳しくを参照してください。 + + + + trust + + + + 接続を無条件で許可します。 + この方式は、Pgpool-IIに接続できる全てのユーザを許可します。 + + + + + + reject + + + + 接続を無条件に拒否します。 + 特定のホストをあるグループから「除外」するために便利です。 + 例えば、1行のrejectは特定のホストが接続することを拒否します。 + + + + + + md5 + + + + クライアントに対して認証時に二重MD5ハッシュ化パスワードを要求します。 + + + + + md5認証を使うには、ユーザ名とパスワードをというパスワードファイルに登録する必要があります。 + 詳細はを参照してください。 + なお、pool_passwdでパスワードを管理したくない場合は、を使うこともできます。 + + + + + + + + scram-sha-256 + + + + ユーザのパスワードを確認するため、SCRAM-SHA-256認証を行います。 - - -scram-sha-256認証を使用するためには、ファイルにユーザ名とパスワードを登録する必要があります。 -詳細はを参照してください。 - + + + scram-sha-256認証を使用するためには、ファイルにユーザ名とパスワードを登録する必要があります。 + 詳細はを参照してください。 + なお、pool_passwdでパスワードを管理したくない場合は、を使うこともできます。 + - - - - - - cert - - - -SSLクライアント証明書を使って認証します。 -詳細はを参照してください。 - - - - - - - pam - - - -オペレーティングシステムによって提供されるPAM(Pluggable Authentication Modules)サービスを使用した認証です。 -詳細はを参照してください - - - -Pgpool-IIが稼働するホスト上のユーザ情報を使ったPAM認証を利用することができます。 -PAMサポートを有効にするには、Pgpool-II"--with-pam"をつけてconfigureされていなければなりません。 - - - -PAM認証を有効にするには、Pgpool-IIのサービス設定ファイルをシステムのPAM設定ディレクトリ(通常は"/etc/pam.d"にあります)に作成しなければなりません。 -サービス設定ファイルのサンプルはインストールディレクトリ下に"share/pgpool.pam"としてインストールされています。 - - - - - - - - + + + + + + cert + + + + SSLクライアント証明書を使って認証します。 + 詳細はを参照してください。 + + + + + + + pam + + + + オペレーティングシステムによって提供されるPAM(Pluggable Authentication Modules)サービスを使用した認証です。 + 詳細はを参照してください + + + + Pgpool-IIが稼働するホスト上のユーザ情報を使ったPAM認証を利用することができます。 + PAMサポートを有効にするには、Pgpool-II"--with-pam"をつけてconfigureされていなければなりません。 + + + + PAM認証を有効にするには、Pgpool-IIのサービス設定ファイルをシステムのPAM設定ディレクトリ(通常は"/etc/pam.d"にあります)に作成しなければなりません。 + サービス設定ファイルのサンプルはインストールディレクトリ下に"share/pgpool.pam"としてインストールされています。 + + + + + + ldap + + + + LDAPサーバを使って認証します。 + 詳細はを参照してください。 + + + + LDAPサポートを有効にするには、Pgpool-II"--with-ldap"をつけてconfigureされていなければなりません。 + + + + + + + auth-options - -auth-methodフィールドの後ろに、認証方式のオプションを指定する、name=valueの形式のフィールドが存在する可能性があります。 + --> + auth-methodフィールドの後ろに、認証方式のオプションを指定する、name=valueの形式のフィールドが存在する可能性があります。 @@ -597,7 +635,7 @@ PAM認証を有効にするには、Pgpool-IIのサ - -pool_hba.confレコードは接続が試みられる度に順番に検査されますので、レコードの順序はとても大切です。 -典型的には、始めの方のレコードには厳しい接続照合パラメータと緩い認証方式があるのに対し、終わりの方のレコードにはより緩い照合パラメータとより厳しい認証方式があります。 -例えば、ローカルTCP接続ではtrust認証方式、リモートTCP接続に対してはパスワードを要求したいとします。 -この場合、広範囲にわたって許可されるクライアントのIPアドレスに対するパスワード認証を指定するレコードの前に127.0.0.1からの接続に対するtrust認証指定のレコードが置かれなければなりません。 + --> + pool_hba.confレコードは接続が試みられる度に順番に検査されますので、レコードの順序はとても大切です。 + 典型的には、始めの方のレコードには厳しい接続照合パラメータと緩い認証方式があるのに対し、終わりの方のレコードにはより緩い照合パラメータとより厳しい認証方式があります。 + 例えば、ローカルTCP接続ではtrust認証方式、リモートTCP接続に対してはパスワードを要求したいとします。 + この場合、広範囲にわたって許可されるクライアントのIPアドレスに対するパスワード認証を指定するレコードの前に127.0.0.1からの接続に対するtrust認証指定のレコードが置かれなければなりません。 - - -ここで説明された全てのpool_hba認証のオプションはクライアントとPgpool-IIの間についてだということに注意してください。 -クラインアントは依然として、PostgreSQLによる認証を通過しなければなりませんし、バックエンドPostgreSQLサーバ上のデータベースに対してCONNECT権限を持っていなければなりません。 - - - -pool_hbaにとってはクライアントに指定されたユーザ名やデータベース名(例. psql -U testuser testdb)が実際にバックエンド上に存在するかどうかは問題ではありません。 -pool_hbaはpool_hba.confの値とマッチするかどうかのみを気にします。 - + + + ここで説明された全てのpool_hba認証のオプションはクライアントとPgpool-IIの間についてだということに注意してください。 + クラインアントは依然として、PostgreSQLによる認証を通過しなければなりませんし、バックエンドPostgreSQLサーバ上のデータベースに対してCONNECT権限を持っていなければなりません。 + + + + pool_hbaにとってはクライアントに指定されたユーザ名やデータベース名(例. psql -U testuser testdb)が実際にバックエンド上に存在するかどうかは問題ではありません。 + pool_hbaはpool_hba.confの値とマッチするかどうかのみを気にします。 + - -pool_hba.confファイルの例をいくつか以下に示します。 -各種認証方式の詳細については次の節をご覧ください。 + --> + pool_hba.confファイルの例をいくつか以下に示します。 + 各種認証方式の詳細については次の節をご覧ください。 - - - <filename>pool_hba.conf</filename>の項目の例 - -# Allow any user on the local system to connect to any database with -# any database user name using Unix-domain sockets (the default for local -# connections). -# -# TYPE DATABASE USER ADDRESS METHOD -local all all trust - -# The same using local loopback TCP/IP connections. -# -# TYPE DATABASE USER ADDRESS METHOD -host all all 127.0.0.1/32 trust - -# Allow any user from host 192.168.12.10 to connect to database -# "postgres" if the user's password is correctly supplied. -# -# TYPE DATABASE USER ADDRESS METHOD -host postgres all 192.168.12.10/32 md5 - - + + + <filename>pool_hba.conf</filename>の項目の例 + + # Allow any user on the local system to connect to any database with + # any database user name using Unix-domain sockets (the default for local + # connections). + # + # TYPE DATABASE USER ADDRESS METHOD + local all all trust + + # The same using local loopback TCP/IP connections. + # + # TYPE DATABASE USER ADDRESS METHOD + host all all 127.0.0.1/32 trust + + # Allow any user from host 192.168.12.10 to connect to database + # "postgres" if the user's password is correctly supplied. + # + # TYPE DATABASE USER ADDRESS METHOD + host postgres all 192.168.12.10/32 md5 + + - + --> 認証方式 - -以下の小節では、認証方式について詳細に説明します。 + --> + 以下の小節では、pool_hba.confで指定する認証方式について詳細に説明します。 - + --> trust認証 - + trust認証が指定されるとPgpool-IIは、サーバに接続できる全ての人に対してその人が指定する任意のデータベースユーザ名としてのアクセス権限が付与されていると想定します + + + + + Clear Text Password Authentication + + + + password方式は、パスワードを平文で送信するので、パスワード盗聴攻撃に対して脆弱です。 + 可能ならば、常に避けるようにしてください。 + しかし、接続がSSL暗号で保護されていれば、passwordは安全に使用できます。 + クライアントがSSL暗号を使うことを強制するために、pool_hba.confhostsslを指定することをおすすめします。 + + + -trust認証が指定されるとPgpool-IIは、サーバに接続できる全ての人に対してその人が指定する任意のデータベースユーザ名としてのアクセス権限が付与されていると想定します + この方式を使う利点は、認証のためのパスワードがクライアント側から提供され、pool_passwdは使われないことです。 + ですからpool_passwdの保守を避けることができます。 + + + + を使ってもpool_passwdの保守を避けることができますが、SSL暗号を強制することはできません。pool_hba.confをこのパラメータと一緒に使うことができないからです。 - + --> MD5パスワード認証 @@ -718,7 +797,7 @@ host postgres all 192.168.12.10/32 md5 - -この認証方法はMD-5ハッシュ化されたパスワードがクライアントから送信されるパスワードベースの認証方法です。 -Pgpool-IIPostgreSQLデータベースユーザパスワードを見ることができず、クライアントプリケーションはMD5ハッシュ化されたパスワードを送るのみです。 -そのため、Pgpool-IImd5認証は認証ファイルを使ってサポートしています。 + --> + この認証方法はMD-5ハッシュ化されたパスワードがクライアントから送信されるパスワードベースの認証方法です。 + Pgpool-IIPostgreSQLデータベースユーザパスワードを見ることができず、クライアントプリケーションはMD5ハッシュ化されたパスワードを送るのみです。 + そのため、Pgpool-IImd5認証は認証ファイルを使ってサポートしています。 - - - -Pgpool-IIをrawモードで使用している場合、あるいはバックエンドが1つしかない場合は、を設定する必要はありません。 - - - - - + --> 認証ファイル形式 - -md5認証を使用するには、認証ファイルに平文、md5またはAES暗号化形式のいずれかのユーザのパスワード -が含まれている必要があります。 + + md5認証を使用するには、認証ファイルに平文、AESmd5暗号化形式のいずれかのユーザのパスワード + が含まれている必要があります。 - -pool_passwdファイルは以下の形式の行を含みます。 - - "username:plain_text_passwd" - - - "username:encrypted_passwd" - + + pool_passwdファイルは以下の形式の行を含みます。 + + "username:TEXT_plain_text_passwd" + + + "username:AES_encrypted_passwd" + + + "username:md5_encrypted_passwd" + + (実際には、"TEXT"、"AES"、"md5"の後の"_"は存在しません。) - + - - + --> md5認証の設定 - MD5 + MD5 - -以下がmd5認証を有効にする手順です。 + + 以下がmd5認証を有効にする手順です。 - -1. データベースのOSユーザとしてログインし、"pg_md5 --md5auth --username=ユーザ名 パスワード" を実行します。 -がまだ存在していなかった場合は、pg_md5コマンドが自動的にこれを生成します。 - - - + 1. データベースのOSユーザとしてログインし、"pg_md5 --config-file=pgpool.confへのパス --md5auth --username=ユーザ名 パスワード" を実行します。 + がまだ存在していなかった場合は、pg_md5コマンドが自動的にこれを生成します。 + + + -ユーザ名とパスワードは、PostgreSQLに登録したものと完全に同じでなければなりません。 - - + --> + ユーザ名とパスワードは、PostgreSQLに登録したものと完全に同じでなければなりません。 + + - -2. pool_hba.confにmd5認証のエントリを作成します。 -詳細についてはを参照してください。 + + 2. pool_hba.confにmd5認証のエントリを作成します。 + 詳細についてはを参照してください。 + pool_hba.confを有効にしない場合は、PostgreSQLpg_hba.confでmd5認証が指定されていることを確認してください。 - -3. (もちろんpool_passwdとPostgreSQLの両方で)md5パスワードを変更したら、Pgpool-II設定の再読み込みを実行してください。 + + 3. (もちろんpool_passwdとPostgreSQLの両方で)md5パスワードを変更したら、Pgpool-II設定の再読み込みを実行してください。 - + - - - scram-sha-256認証 + + + scram-sha-256認証 - + SCRAM - + - - -SCRAMとも呼ばれるこの認証方式は、信頼できない接続におけるパスワードの盗聴を防ぐチャレンジレスポンス認証です。 -Pgpool-IIは、PostgreSQLデータベースユーザのパスワードの可視性を持たないため、SCRAM認証は認証ファイルを使用してサポートされています。 - + + + SCRAMとも呼ばれるこの認証方式は、信頼できない接続におけるパスワードの盗聴を防ぐチャレンジレスポンス認証です。 + Pgpool-IIは、PostgreSQLデータベースユーザのパスワードの可視性を持たないため、SCRAM認証は認証ファイルを使用してサポートされています。 + - - + --> SCRAMの認証ファイルエントリ - -SCRAM認証を使用する場合、認証ファイルは平文もしくはAES暗号化ファーマットのユーザパスワードを含んでる必要があります。 + + SCRAM認証を使用する場合、認証ファイルは平文もしくはAES暗号化ファーマットのユーザパスワードを含んでる必要があります。 - "username:plain_text_passwd" + "username:TEXT_plain_text_passwd" - "username:AES_encrypted_passwd" + "username:AES_encrypted_passwd" + (実際には、"TEXT"あるいは"AES"の後の"_"は存在しません。) - - -ファイル内のmd5形式のユーザパスワードはSCRAM認証に使用できません。 - + + + ファイル内のmd5形式のユーザパスワードはSCRAM認証に使用できません。 + - + - - + --> scram-sha-256認証の設定 - SCRAM + SCRAM - -以下がscram-sha-256認証を有効にする手順です。 + + 以下がscram-sha-256認証を有効にする手順です。 - -1- 平文またはAES暗号化フォーマットのデータベースユーザとパスワードのファイルエントリを作成します。 -Pgpool-II付属のコマンドでファイル内にAES暗号化パスワードエントリを作成することができます。 - - - -ユーザ名とパスワードはPostgreSQLサーバに登録されているものと一致している必要があります。 - - + + 1- 平文またはAES暗号化フォーマットのデータベースユーザとパスワードのファイルエントリを作成します。 + Pgpool-II付属のコマンドでファイル内にAES暗号化パスワードエントリを作成することができます。 + + + + ユーザ名とパスワードはPostgreSQLサーバに登録されているものと一致している必要があります。 + + - -2- pool_hba.confに適切なscram-sha-256エントリを追加します。 -詳細はを参照してください。 + + 2- pool_hba.confに適切なscram-sha-256エントリを追加します。 + 詳細はを参照してください。 + pool_hba.confを有効にしない場合は、PostgreSQLpg_hba.confでscram-sha-256認証が指定されていることを確認してください。 - -3- (もちろんpool_passwdとPostgreSQLの両方で)SCRAMパスワードを変更したら、Pgpool-IIの設定の再読み込みを実行してください。 + + 3- (もちろんpool_passwdとPostgreSQLの両方で)SCRAMパスワードを変更したら、Pgpool-IIの設定の再読み込みを実行してください。 - + - + - - - 証明書認証 + + + 証明書認証 - + Certificate - - - - -この認証方式は認証を実施するためにSSLクライアント証明書を使用します。 -この認証方式を使っている場合、Pgpool-IIはクライアントが提供する有効な証明書を要求します。 -パスワードプロンプトがクライアントに送信されません。 + -証明書のcn(コモンネーム)の属性は要求されたデータベースユーザ名と比較され、一致した場合ログインが許可されます。 - + + + この認証方式は認証を実施するためにSSLクライアント証明書を使用します。 + この認証方式を使っている場合、Pgpool-IIはクライアントが提供する有効な証明書を要求します。 + パスワードプロンプトがクライアントに送信されません。 + + 証明書のcn(コモンネーム)の属性は要求されたデータベースユーザ名と比較され、一致した場合ログインが許可されます。 + - + - -証明書認証はクライアントとPgpool-IIの間で使用され、バックエンド認証にはその他の認証方式を使用できます。 + + 証明書認証はクライアントとPgpool-IIの間でのみ使用できます。 + 証明書認証はPgpool-IIPostgreSQLの間では使用できません。 + バックエンド認証にはその他の認証方式を使用できます。 - + - + - + --> PAM認証 @@ -994,7 +1074,7 @@ SCRAMとも呼ばれるこの認証方式は、信頼できない接続におけ - -この認証方式は認証機構としてPAM(Pluggable Authentication Modules)を使用します。 -デフォルトのPAMサービス名はpgpoolです。 -Pgpool-IIが稼働するホスト上のユーザ情報を使ったPAM認証を利用することができます。 -PAMについての詳細はLinux-PAMページを読んでください + --> + この認証方式は認証機構としてPAM(Pluggable Authentication Modules)を使用します。 + デフォルトのPAMサービス名はpgpoolです。 + Pgpool-IIが稼働するホスト上のユーザ情報を使ったPAM認証を利用することができます。 + PAMについての詳細はLinux-PAMページを読んでください - -PAM認証を有効にするには、Pgpool-IIのサービス設定ファイルをシステムのPAM設定ディレクトリ(通常は"/etc/pam.d"にあります)に作成しなければなりません。 -サービス設定ファイルのサンプルはインストールディレクトリ下に"share/pgpool-II/pgpool.pam"としてインストールされています。 + --> + PAM認証を有効にするには、Pgpool-IIのサービス設定ファイルをシステムのPAM設定ディレクトリ(通常は"/etc/pam.d"にあります)に作成しなければなりません。 - -PAMサポートを有効にするには、Pgpool-II"--with-pam"をつけてconfigureされていなければなりません。 + --> + PAMサポートを有効にするには、Pgpool-II"--with-pam"をつけてconfigureされていなければなりません。 - - - - フロンエンドとバックエンド認証に対する異なる認証方式の使用 + + + LDAP認証 - - AUTH - + + LDAP + - - -Pgpool-IIV4.0以降では、クライアントアプリケーションとバックエンドのPostgreSQLサーバに対して異なる認証を使用することが可能です。 -例えば、クライアントアプリケーションはPgpool-IIへの接続にscram-sha-256を使用し、次に同じセッションのPostgreSQLバックエンドへの接続にtrustまたはmd5認証を使用できます。 + + +この認証方式はパスワード確認にLDAPを使用します。 +LDAPはユーザの名前とパスワードの組み合わせのみに使用されます。 +そのため、LDAPを使用して認証を行うようにする前に、ユーザはデータベースに存在しなければなりません。 + - - + + +LDAP認証は2つのモードで動作します。1つ目のモードでは、それは単なるバインド・モードを呼び出すものですが、サーバはprefix username suffixとして区別された名前にバインドします。 +一般的に、prefixパラメータはActive Directory環境でのcn=DOMAIN\を特定するために使用されます。 +suffixは、Active Directory環境ではない場合でのDNの残りの部分を特定するために使用されます。 + - - - pool_passwdにおけるAES256暗号化パスワードの使用 + + +2つ目のモードでは、それはsearch/bindモードを呼び出すもので、サーバは最初にldapbinddnldapbindpasswdで指定された、固定されたユーザ名とパスワードを使用してLDAPディレクトリにバインドします。 +それからデータベースにログインしようとしているユーザを検索します。 +もしユーザとパスワードが指定されていなかった場合、ディレクトリに対して匿名でバインドします。 +検索はldapbasednのサブツリーまで行われ、ldapsearchattributeで指定された属性に正確に一致するかどうかまで行われます。 +この検索において、一度ユーザが見つかるとサーバは切断して、クライアントで指定されたパスワードを使用してこのユーザとして再度ディレクトリにバインドします。 +これはそのログインが正しいかどうかを検証するためです。 +このモードはApache mod_authzn_heapおよびpam_ldapのように他のソフトウェアと同じように、LDAP認証の仕組みで使用されるものと同じです。 +この方法は、ユーザオブジェクトがディレクトリに配置されている場合に、かなりの柔軟性があります。 +しかし、LDAPサーバへの2つの分離した接続が作成されます。 + - - AUTH - + + +次の設定オプションは両方のモードで使用されます。 + + + ldapserver + + + +接続するLDAPサーバの名称もしくはIPアドレスの名称。空白で区切ることで複数のサーバを指定できます。 + + + + + ldapport + + + +LDAPサーバに接続するためのポート番号。 +もしポートが指定されていない場合はLDAPライブラリ内のデフォルトポート設定が使用されます。 + + + + + ldapscheme + + + +ldapsに設定するとLDAPSを使用します。 +これはいくつかのLDAPサーバーの実装でサポートされている、SSL経由のLDAPを使用する非標準の方法です。 +代替方法については、ldaptlsオプションを参照してください。 + + + + + ldaptls + + + +1に設定すると、Pgpool-IIとLDAPサーバ間の接続にTLSによる暗号化を使用します。 +これはRFC 4513のStartTLS操作を使用します。 +代替方法については、ldapschemeオプションを参照して下さい。 + + + + + + + +ldapschemeldaptlsを使うときにはPgpool-IIサーバとLDAPサーバ間のトラフィックのみが暗号化されることに注意して下さい。 +SSLがそこでも使用されていない限り、Pgpool-IIサーバとクライアントとの接続は、暗号化されません。 + + + + +以下のオプションは単純バインド・モードのみで使用されます。 + + + ldapprefix + + + +単純なバインド認証を行う場合のDNを生成する際にユーザ名の前に追加する文字列 + + + + + ldapsuffix + + + +単純なバインド認証を行う場合のDNを生成する際にユーザ名の後に追加する文字列 + + + + + + + + +以下のオプションはsearch/bindモードのみで使用されます。 + + + ldapbasedn + + + +検索とバインドの認証を行う場合のユーザ名がログインするための検索を始めるためのルートDN + + + + + ldapbinddn + + + +検索とバインドの認証を行う場合のディレクトリと検索をバインドするためのユーザのDN + + + + + ldapbindpasswd + + + +検索とバインドの認証を行う場合のディレクトリと検索をバインドするためのユーザのパスワード + + + + + ldapsearchattribute + + + +検索とバインドの認証を行う場合の検索時のユーザ名に対して一致させる属性。 +属性が指定されない場合、属性uidが使用されます。 + + + + + ldapsearchfilter + + + +search/bind認証を行うときに使用する検索フィルタです。 +$usernameの出現はユーザ名に置き換えられます。 +これによりldapsearchattributeよりも柔軟な検索フィルタが可能になります。 + + + + + ldapurl + + + +RFC 4516 LDAP URL。これはその他いくつかのLDAPオプションをより簡潔、かつ一般的な形式で記述する別の方法です。 +フォーマットは以下のようになっています。 + +ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] + + +scopebaseonesubのいずれかでなくてはならず、一般的には最後のものです。 + (デフォルトはbaseです。これは通常このアプリケーションでは役に立ちません。) +attributeは単一の属性を指定できます。その場合、それはldapsearchattributeの値として使用されます。 +もしattributeが空の場合は、ldapsearchfilterの値としてfilterを使用することができます。 + + + + + URLスキームldapsは、ldapscheme=ldapsを使用するのと同じ、SSL上のLDAP接続をするLDAPS方式を選択します。 +StartTLS操作による暗号化されたLDAP接続を使用するには、通常のURLスキームldapを使用し、ldapurlに加えldaptlsオプションを使用しなければなりません。 + + + + +非匿名バインド(non-anonymous bind)に対し、ldapbinddnおよびldapbindpasswdは個別のオプションとして指定されなければなりません。 + + + + + backend_use_passwd + + + +1に設定すると、LDAP認証で使用されたパスワードをPgpool-IIとバックエンド間の認証に使用します。 + + + + + + + + +search/bindオプションと単純バインドに対するオプションの設定を混在させるのはエラーです。 + + + + +search/bindモードを使用するときは、ldapsearchattributeで指定される単一の属性を使って、あるいはldapsearchfilterで指定されるカスタム検索フィルターを使って、検索を実行できます。 +ldapsearchattribute=fooの指定は、ldapsearchfilter="(foo=$username)"と同等です。 +どちらのオプションもない場合は、ldapsearchattribute=uidがデフォルトです。 + + + + +Pgpool-IIが、LDAPクライアントライブラリとしてOpenLDAPを使用するようにコンパイルされていた場合、ldapserverの設定は省略出来ます。 +その場合、ホスト名とポート番号のリストは、RFC 2782 DNS SRVレコードを使用して検索されます。 +_ldap._tcp.DOMAINという名前が検索され、ldapbasednからDOMAINが抽出されます。 + + + + +以下に単純バインドLDAP設定の例を示します。 + +host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" + + +データベースのユーザ、fooからデータベースサーバに接続を要求された場合、Pgpool-IIはDN cn=foo, dc=example, dc=netおよびクライアントから提供されたパスワードを用いてLDAPサーバにバインドを試みます。 +その接続が成功すればデータベースへのアクセスが認められます。 + + + + +以下はsearch/bind設定の例です。 + +host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid + + +データベースユーザfooとしてデータベースに接続するとき、Pgpool-IIは(ldapbinddnが指定されていないので)匿名的にバインドを試み、指定されたベースDNの基で(uid=foo)の検索を行います。あるエントリが見つかると、見つかった情報とクライアントから与えられたパスワードを用いて、その結果バインドを試みます。その二番目の接続が成功するとデータベースアクセスが認められます。 + + + + +URLとして記述した同じsearch/bind設定の例です。 + +host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" + + +LDAPに対し認証をサポートする幾つかの他のソフトウェアは同じURLフォーマットを使用します。 +従って、設定をより簡易に共有することができます。 + + + + +ldapsearchattributeの代わりにldapsearchfilterを使用してユーザーIDまたは電子メールアドレスによる認証を可能にするsearch/bind設定の例です。 + +host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))" + + + + + +DNS SRV検出を使用してドメイン名example.netのLDAPサービスのホスト名とポート番号を検索する、search/bind設定の例です。 + +host ... ldap ldapbasedn="dc=example,dc=net" + + + + - -SCRAM認証は中間者攻撃から保護します。 -そのため、Pgpool-IIPostgreSQLバックエンドの認証のためにユーザパスワードを要求します。 + +LDAPはDNの異なる構成要素を区別するため往々にしてコンマとスペースを使用します。 +例で示されたように、LDAPオプションを設定する場合、二重引用符で括られたパラメータ値を使用することが必須となることがしばしば必須となります。 + + - -しかしながら、"pool_passwd"ファイルにクリアテキストパスワードを保存するのは良い案ではありません。 + + LDAPサポートを有効にするには、Pgpool-II"--with-ldap"をつけてconfigureされていなければなりません。 + + + + + + GSSAPI認証 + + + GSSAPI + + + + + GSSAPIは、RFC 2743で定義されている安全な認証のための業界標準のプロトコルです。 + 今の所Pgpool-IIはGSSAPIをサポートしていません。 + クライアントはGSSAPI認証要求を行わないようにするか、「可能ならばGSSAPI認証を使う」オプションを選択しなければなりません(これはPostgreSQLクライアントのデフォルト設定です)。 + 後者を選択した場合、Pgpool-IIはGSSAPIを使わない認証方式をクライアントにリクエストし、その結果クライアントはGSSAPIを使わない認証方式を使用するので、通常ユーザはGSSAPI認証方式をPgpool-IIが受け入れないことを意識する必要はありません。 + + + + + + + フロンエンドとバックエンド認証に対する異なる認証方式の使用 + + + AUTH + + + + + Pgpool-IIV4.0以降では、クライアントアプリケーションとバックエンドのPostgreSQLサーバに対して異なる認証を使用することが可能です。 + 例えば、クライアントアプリケーションはPgpool-IIへの接続にscram-sha-256を使用し、次に同じセッションのPostgreSQLバックエンドへの接続にtrustまたはmd5認証を使用できます。 + + + + + + pool_passwdにおけるAES256暗号化パスワードの使用 + + + AUTH + + + + + SCRAM認証は中間者攻撃から保護します。 + そのため、Pgpool-IIPostgreSQLバックエンドの認証のためにユーザパスワードを要求します。 + + + + + しかしながら、"pool_passwd"ファイルにクリアテキストパスワードを保存するのは良い案ではありません。 + + + + 代わりにAES256AES256で暗号化されたパスワードを保存し認証に使用することができます。 + パスワードは、最初にユーザが提供した鍵を使ってAES256暗号で暗号化され、暗号化されたパスワードをbase64でエンコードし、エンコードされた文字列の接頭にAESを追加します。 + - -代わりにAES256で暗号化されたパスワードを保存し認証に使用することができます。 -パスワードは、最初にユーザが提供した鍵を使ってAES暗号で暗号化され、暗号化されたパスワードをbase64でエンコードし、エンコードされた文字列の接頭にAESを追加します。 - - - -適切にフォーマットされたAES256暗号化パスワードを作成するために コマンドを使用できます。 - - + + 適切にフォーマットされたAES256暗号化パスワードを作成するために コマンドを使用できます。 + + - - - 暗号化パスワードエントリの作成 - - -ファイル上にAES暗号化パスワードエントリを作成するために使用できます。 -はパスワードエントリ暗号化のための鍵を要求します。 -その後、認証に使うパスワードを復号化するため、Pgpool-IIで同じ鍵が必要になります。 - - - -暗号化パスワード機能を使うためにSSL(--with-openssl)サポート付でPgpool-IIをビルドする必要があります。 - - - - + + + 暗号化パスワードエントリの作成 + + + ファイル上にAES暗号化パスワードエントリを作成するために使用できます。 + はパスワードエントリ暗号化のための鍵を要求します。 + その後、認証に使うパスワードを復号化するため、Pgpool-IIで同じ鍵が必要になります。 + + + + 暗号化パスワード機能を使うためにSSL(--with-openssl)サポート付でPgpool-IIをビルドする必要があります。 + + + + - - - <productname>Pgpool-II</productname>への復号鍵の提供 + + + <productname>Pgpool-II</productname>への復号鍵の提供 - - -もし、 ファイルにAES暗号化パスワードが保存されていた場合、Pgpool-IIはそれらのパスワードを復号化するために復号鍵が必要となり、Pgpool-IIは起動時に.pgpoolkeyファイルから復号鍵を読み込もうとします。 - - - -デフォルトでは、Pgpool-IIはユーザのホームディレクトリの.pgpoolkeyもしくはPGPOOLKEYFILE環境変数により設定されるファイルを探します。 -コマンドの(-k, --key-file=KEY_FILE)オプションを使用し、鍵ファイルを指定をすることもできます。 -.pgpoolkeyの権限はグループ、他者へのアクセスをすべて拒否しなければなりませんので、chmod 0600 ~/.pgpoolkeyコマンドによって設定します。 - - + + + もし、 ファイルにAES暗号化パスワードが保存されていた場合、Pgpool-IIはそれらのパスワードを復号化するために復号鍵が必要となり、Pgpool-IIは起動時に.pgpoolkeyファイルから復号鍵を読み込もうとします。 + pgpoolkey + PGPOOLKEYFILE + .pgpoolkeyは復号鍵の文字列を格納した単純なテキストファイルです。 + + + + デフォルトでは、Pgpool-IIはユーザのホームディレクトリの.pgpoolkeyもしくはPGPOOLKEYFILE環境変数により設定されるファイルを探します。 + コマンドの(-k, --key-file=KEY_FILE)オプションを使用し、鍵ファイルを指定をすることもできます。 + .pgpoolkeyの権限はグループ、他者へのアクセスをすべて拒否しなければなりませんので、chmod 0600 ~/.pgpoolkeyコマンドによって設定します。 + + - + diff --git a/doc.ja/src/sgml/config.sgml b/doc.ja/src/sgml/config.sgml index 1fd2e142e..8586c83ef 100644 --- a/doc.ja/src/sgml/config.sgml +++ b/doc.ja/src/sgml/config.sgml @@ -1,250 +1,300 @@ - - サーバの設定 - - - - 設定 - サーバの - - - - -Pgpool-IIの動作に影響を与える数多くのパラメータがあります。 -この章の最初の節で、どのように設定パラメータを操作するのかについて説明します。 -引き続く節で、それぞれのパラメータの詳細を説明します。 - - - - - パラメータの設定 - - - - パラメータ名とその値 - - - -全てのパラメータの名前は大文字と小文字を区別しません。 -それぞれのパラメータは、論理値、整数、浮動小数点、文字列、またはenum(列挙型)の5つの型のいずれかの値を取ります。 -型はパラメータをセットするための記法を定義します。 + + サーバの設定 + + + + 設定 + サーバの + + + + + Pgpool-IIの動作に影響を与える数多くのパラメータがあります。 + この章の最初の節で、どのように設定パラメータを操作するのかについて説明します。 + 引き続く節で、それぞれのパラメータの詳細を説明します。 + + + + + パラメータの設定 + + + + パラメータ名とその値 + + + + 全てのパラメータの名前は大文字と小文字を区別しません。 + それぞれのパラメータは、論理値、整数、浮動小数点、文字列、またはenum(列挙型)の5つの型のいずれかの値を取ります。 + 型はパラメータをセットするための記法を定義します。 + + + + + + + 論理型: + + 値は以下のいずれかを取ることができます。 + on, + off, + true, + false, + yes, + no, + 1, + 0 + + (すべて大文字小文字の区別なし) あるいは、曖昧でなければこれらの先頭から数文字を省略して使うこともできます。 + + + + + + + 文字列型: + + 一般に、単一引用符の中に値を入れます。 + 単一引用符を値として使う場合は単一引用符を重ねます。 + なお、値が単純な数字や識別子である場合は、通常引用符は省略できます。 + + + + + + + 数値型(整数型と浮動小数点型): + + 小数点は浮動小数点型のパラメータでのみ使用できます。 + 1000の位取りは使わないでください。 + 引用符は必要ありません。 + + + + + + 単位付きの数値: + メモリの量や時間について記述する数値型のパラメータは暗黙的な単位を持ちます。 + 単位はキロバイト、メガバイト、ミリ秒、秒、分です。 + 例を示します。 + + search_primary_node_timeout = 6min + memqcache_total_size = 64MB + + 修飾無しの数値によるこれらの設定においては、 パラメータごとのデフォルト値が採用されます。 + + + 単位名は大文字小文字を区別し、数値と単位の間に空白があっても構いません。 + 有効なメモリの単位はkB (キロバイト)、MB (メガバイト)、 GB (ギガバイト), TB (テラバイト)です。 + + + 有効な時間の単位はms (ミリ秒)、s (秒)、min (分)、h (時間)、d (日数) です。 + - - - - - 論理型: - -値は以下のいずれかを取ることができます。 - on, - off, - true, - false, - yes, - no, - 1, - 0 - -(すべて大文字小文字の区別なし) あるいは、曖昧でなければこれらの先頭から数文字を省略して使うこともできます。 - - - - - - - 文字列型: - -一般に、単一引用符の中に値を入れます。 -単一引用符を値として使う場合は単一引用符を重ねます。 -なお、値が単純な数字や識別子である場合は、通常引用符は省略できます。 - - - - - - - 数値型(整数型と浮動小数点型): - -小数点は浮動小数点型のパラメータでのみ使用できます。 -1000の位取りは使わないでください。 -引用符は必要ありません。 - - - - - - + --> 列挙型: - -列挙型のパラメータは文字列パラメータと同じように記述します。 -ただ、使用できる文字列の種類が決まっているだけです。 -列挙型の値は大文字小文字を区別しません。 - - - - - - - - 設定ファイルによるパラメータ操作 - - - + 列挙型のパラメータは文字列パラメータと同じように記述します。 + ただ、使用できる文字列の種類が決まっているだけです。 + 列挙型の値は大文字小文字を区別しません。 + + + + + + + + 設定ファイルによるパラメータ操作 + + + -これらのパラメータを設定する最も基本的な方法は、pgpool.confpgpool.confファイルを編集することで、これは通常$prefix/ext/pgpool.confに配置されています。 -このファイルがどういったものかの例を示します。 + which is located in $prefix/etc/pgpool.conf, if it + installed from source code. An example of what this file might look like is: + --> + これらのパラメータを設定する最も基本的な方法は、pgpool.confpgpool.confファイルを編集することです。 + ソースコードからインストールした場合、$prefix/etc/pgpool.confに配置されています。 + このファイルがどういったものかの例を示します。 - # This is a comment - listen_addresses = 'localhost' - port = 9999 - serialize_accept = off - reset_query_list = 'ABORT; DISCARD ALL' + # This is a comment + listen_addresses = 'localhost' + port = 9999 + serialize_accept = off + reset_query_list = 'ABORT; DISCARD ALL' - -1つの行毎に1つのパラメータが指定されます。 -名前と値の間の等号はオプションです。 -引用符の中の空白(white space)を除き、空白は特に意味を持たず、何もない行は無視されます。 -ハッシュ記号(#)はその行の後の表記がコメントであることを意味します。 -単純でない識別子、または数値でないパラメータ値は単一引用符で括られなければなりません。 -パラメータ値の中に単一引用符を埋め込む場合、二重引用符(推奨)もしくはバックスラッシュ-引用符で括ります。 - - - - - -この方法によりクラスタに対してデフォルト値が設定されます。 -上書きされない限り、アクティブなセッションが見るのはこの値です。 -次の節では、管理者やユーザがこれらのデフォルト値を上書きする方法を説明します。 - - - - - SIGHUP - - -設定ファイルはメインサーバプロセスがSIGHUP信号を受け取ると何時でも 再読み込みされます。 -手っ取り早く行なうには、コマンドラインからpgpool reloadを実行します。 -メインpgpoolプロセスは同時にこの信号を、現存のセッションが同様に新しい値を入手できるように、全ての子プロセスに伝播します。 -いくつかのパラメータはサーバの起動時のみ設定されます; -設定ファイル中のそれらのエントリのいかなる変更も、サーバが再起動されるまで無視されます。 -設定ファイル内で無効なパラメータが設定された場合は同様に(ログには残りますが)SIGHUP処理中に無視されます。 - + + 1つの行毎に1つのパラメータが指定されます。 + 名前と値の間の等号はオプションです。 + 引用符の中の空白(white space)を除き、空白は特に意味を持たず、何もない行は無視されます。 + ハッシュ記号(#)はその行の後の表記がコメントであることを意味します。 + 単純でない識別子、または数値でないパラメータ値は単一引用符で括られなければなりません。 + パラメータ値の中に単一引用符を埋め込む場合、単一引用符を二つ(推奨)もしくはバックスラッシュ-引用符で括ります。 + + + + + + この方法によりクラスタに対してデフォルト値が設定されます。 + 上書きされない限り、アクティブなセッションが見るのはこの値です。 + 次の節では、管理者やユーザがこれらのデフォルト値を上書きする方法を説明します。 + + + + + SIGHUP + + + 設定ファイルはメインサーバプロセスがSIGHUP信号を受け取ると何時でも 再読み込みされます。 + 手っ取り早く行なうには、コマンドラインからpgpool reloadを実行します。 + メインpgpoolプロセスは同時にこの信号を、次のセッションが同様に新しい値を入手できるように、全ての子プロセスに伝播します。 + いくつかのパラメータはサーバの起動時のみ設定されます; + 設定ファイル中のそれらのエントリのいかなる変更も、サーバが再起動されるまで無視されます。 + 設定ファイル内で無効なパラメータが設定された場合は同様に(ログには残りますが)SIGHUP処理中に無視されます。 + - - - SQLを通じたパラメータ操作 - - - -Pgpool-IIはまた2つのSQL形式のコマンドを使ってセッションローカルの設定の参照や変更を行うことができます。 - - - + + + 設定ファイルの内容の管理 + + + + Pgpool-IIpgpool.confファイルを複数のファイルに分割して記述する方法を提供しています。 + 機能やサーバ固有のパラメータの設定を分割したい場合に有用です。 + 次のようにincludeディレクティブを追加します。 + + include = 'filename' + + + ファイル名が絶対パスでない場合、参照する設定ファイルを含むディレクトリからの相対パスであると受け取られます。includeコマンドは入れ子にすることができます。 + + + + + + SQLを通じたパラメータ操作 + + + + Pgpool-IIはまた2つのSQL形式のコマンドを使ってセッションローカルの設定の参照や変更を行うことができます。 + + + - - -コマンドを使ってすべてのパラメータの現在の値を調べることができます。 - + + + コマンドを使ってすべてのパラメータの現在の値を調べることができます。 + - - -コマンドを使ってセッション内でローカルに変更できるパラメータの値を変更することができます。 -他のセッションには影響を与えません。 - + + + コマンドを使ってセッション内でローカルに変更できるパラメータの値を変更することができます。 + 他のセッションには影響を与えません。 + - + - + diff --git a/doc.ja/src/sgml/connection-pooling.sgml b/doc.ja/src/sgml/connection-pooling.sgml index cf67c8674..07af0fcd4 100644 --- a/doc.ja/src/sgml/connection-pooling.sgml +++ b/doc.ja/src/sgml/connection-pooling.sgml @@ -1,1105 +1,1613 @@ - - コネクションプーリング - - - -Pgpool-IIは確立されたPostgreSQLサーバへの接続を保存しておき、同じ属性(ユーザ名、データベース、プロトコルバージョン)を持つ新しい接続が来た時にこれらを再利用します。 -これにより接続のオーバヘッドを低減し、システム全体のスループットを向上することができます。 - - - - - コネクションプールの設定 - - - - - connection_cache (boolean) - - - connection_cache 設定パラメータ - - - - - -onに設定されるとバックエンドへの接続をキャッシュします。 -デフォルトはonです。 -ただし、connection_cacheがonでも、template0、template1、postgres、regressionデータベースへの接続はキャッシュされません。 - - - -このパラメータを変更した時にはPgpool-IIを再起動してください。 - - - - - - max_pool (integer) - - - max_pool 設定パラメータ - - - - - -Pgpool-IIの各子プロセスがキャッシュするコネクションの最大数です。 -Pgpool-IIは、受け付けた接続が同じユーザ名で同じデータベースに接続しようとする場合に、キャッシュされたコネクションを再利用します。 -そうでなければPgpool-IIはバックエンドへの新しい接続を生成します。 -もしキャッシュされている接続の数がmax_poolを超えた場合には、一番古いコネクションが廃棄され、そのスロットが新しい接続のために使用されます。 - - - -デフォルト値は4です。 -Pgpool-IIのプロセスからバックエンドへの接続の数は全部で * max_poolに達する可能性があることに注意してください。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - listen_backlog_multiplier (integer) - - - listen_backlog_multiplier 設定パラメータ - - - - - -フロントエンドからPgpool-IIへの接続待ち行列の長さを制御します。 -接続待ち行列の長さ(具体的にはlisten()システムコールのbacklogパラメータ)は、listen_backlog_multiplier * で決まります。 - - - - -システムによってはlisten()システムコールのbacklogパラメータに上限が設定されています。 -詳細はの項を参照してください。 - - - - -デフォルト値は2です。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - serialize_accept (boolean) - - - serialize_accept 設定パラメータ - - - - - -onに設定することで、Pgpool-IIは受け付けるクライアント接続のシリアライズを有効にします。 -シリアライズを行わない場合、OSカーネルはaccept()を実行するために全てのPgpool-II子プロセスを起こし、実際にはそのうちの1つのみが入ってきた接続を処理します。 -ここでの問題は、子プロセスが一度に起こされるために重いコンテキストスイッチングが起こり、性能に影響がでることです。 - - - -この現象は「thundering herd problem(猛獣の暴走)」と呼ばれる古典的な問題です。 -これはaccept()呼び出しのシリアライズを行うことで解決できます。 -入ってきた接続に対してPgpool-IIプロセスのうちひとつだけが起こされてaccept()を実行ようになるためです。 - - - - -しかしシリアライズにはオーバヘッドがあり、が大きい時のみ使用することを推奨します。 -小さいに対しては、シリアライズのオーバヘッドのために性能が低下するかもしれません。 - - - - - -serialize_acceptの相関は環境によって異なるので、serialize_acceptを使うかどうか決める前にベンチマークテストを行ってみることをおすすめします。 - - - - - - serialize_acceptの使用判断のためにpgbenchを利用する - - -以下のコマンドを使ってpgbenchを実行します。 - + + コネクションプーリング + + + + Pgpool-IIは確立されたPostgreSQLサーバへの接続を保存しておき、同じ属性(ユーザ名、データベース、プロトコルバージョン)を持つ新しい接続が来た時にこれらを再利用します。 + これにより接続のオーバヘッドを低減し、システム全体のスループットを向上することができます。 + + + + + コネクションプールの設定 + + + + + connection_cache (boolean) + + + connection_cache 設定パラメータ + + + + + + onに設定されるとバックエンドへの接続をキャッシュします。 + デフォルトはonです。 + ただし、connection_cacheがonでも、template0、template1、postgres、regressionデータベースへの接続はキャッシュされません。 + + + + このパラメータを変更した時にはPgpool-IIを再起動してください。 + + + + + + max_pool (integer) + + + max_pool 設定パラメータ + + + + + + Pgpool-IIの各子プロセスがキャッシュするコネクションの最大数です。 + Pgpool-IIは、受け付けた接続が同じユーザ名かつ同じ実行時パラメータで同じデータベースに接続しようとする場合に、キャッシュされたコネクションを再利用します。 + そうでなければPgpool-IIはバックエンドへの新しい接続を生成します。 + もしキャッシュされている接続の数がmax_poolを超えた場合には、一番古いコネクションが廃棄され、そのスロットが新しい接続のために使用されます。 + + + + デフォルト値は4です。 + Pgpool-IIのプロセスからバックエンドへの接続の数は全部で * max_poolに達する可能性があることに注意してください。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + listen_backlog_multiplier (integer) + + + listen_backlog_multiplier 設定パラメータ + + + + + + フロントエンドからPgpool-IIへの接続待ち行列の長さを制御します。 + 接続待ち行列の長さ(具体的にはlisten()システムコールのbacklogパラメータ)は、listen_backlog_multiplier * で決まります。 + + + + + システムによってはlisten()システムコールのbacklogパラメータに上限が設定されています。 + 詳細はの項を参照してください。 + + + + + デフォルト値は2です。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + serialize_accept (boolean) + + + serialize_accept 設定パラメータ + + + + + + onに設定することで、Pgpool-IIは受け付けるクライアント接続のシリアライズを有効にします。 + シリアライズを行わない場合、OSカーネルはaccept()を実行するために全てのPgpool-II子プロセスを起こし、実際にはそのうちの1つのみが入ってきた接続を処理します。 + ここでの問題は、子プロセスが一度に起こされるために重いコンテキストスイッチングが起こり、性能に影響がでることです。 + + + + この現象は「thundering herd problem(猛獣の暴走)」と呼ばれる古典的な問題です。 + これはaccept()呼び出しのシリアライズを行うことで解決できます。 + 入ってきた接続に対してPgpool-IIプロセスのうちひとつだけが起こされてaccept()を実行するようになるためです。 + + + + + しかしシリアライズにはオーバヘッドがあり、が大きい時のみ使用することを推奨します。 + 小さいに対しては、シリアライズのオーバヘッドのために性能が低下するかもしれません。 + + + + + + serialize_acceptの相関は環境によって異なるので、serialize_acceptを使うかどうか決める前にベンチマークテストを行ってみることをおすすめします。 + + + + + + serialize_acceptの使用判断のためにpgbenchを利用する + + + 以下のコマンドを使ってpgbenchを実行します。 + pgbench -n -S -p 9999 -c 32 -C -S -T 300 test - - -ここで、-Cpgbenchにトランザクション実行の度に毎回データベースに接続することを指示します。 --c 32は、Pgpool-IIへの同時セッション数です。 -これはシステム要件にあわせて変更するのがよいでしょう。 -pgbenchが終了後、"including connections establishing" の数値をチェックします。 - - - - - - -なお、 が有効だと、serialize_acceptは効果がありません。 -serialize_acceptをonにしたい場合は、が0であることを確認してください。 -Pgpool-IIプロセスのメモリーリークなどの潜在的な問題を気にする場合は、代わりにを使ってください。 -この制限は純粋に実装上の問題であり、将来はなくなるかもしれません。 - - - - - -デフォルトはoffです。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - child_life_time (integer) - - - child_life_time 設定パラメータ - - - - - -Pgpool-IIの子プロセスがアイドル状態のままでいるときに、それを強制終了するまでの時間を秒単位で指定します。 -child_life_timeにより終了された時には、すぐに新しい子プロセスがPgpool-IIにより起動されます。 -child_life_timePgpool-II子プロセスのメモリリークやその他の不測のエラーに備えた予防措置です。 - - - - -child_life_timeはまだ一度もコネクションを受け付けていないプロセスには適用されません。 - - - - - -child_life_timeが有効な場合、は無効になります。 - - - - -デフォルト値は300秒(すなわち5分)です。 -0を指定するとこの機能は無効になります。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - client_idle_limit (integer) - - - client_idle_limit 設定パラメータ - - - - - -クライアントが前回のクエリからアイドル状態のままでいるときに、それを切断するまでの時間を秒単位で指定します。 -これは、だらしないクライアントやPgpool-IIの間のTCP/IPコネクションの不調によって、Pgpool-IIの子プロセスが占有されてしまうのを回避するのに役立ちます。 - - - - -client_idle_limitはオンラインリカバリのセカンドステージでは無視されます。 - - - - -デフォルト値は0で、この機能はoffとなります。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - - - - child_max_connections (integer) - - - child_max_connections 設定パラメータ - - - - - -各Pgpool-II子プロセスの寿命を、受付可能なクライアント接続の数で指定します。 -child_max_connections個のクライアント接続を処理した後にPgpool-IIはその子プロセスを終了させ、すぐに代わりの新しい子プロセスを生成します。 - - - -child_max_connectionsが効かないくらい忙しいサーバで有用です。 -またPostgreSQLバックエンドが肥大化するのを防ぐのにも有用です。 - - - -デフォルト値は0で、この機能はoffとなります。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - connection_life_time (integer) - - - connection_life_time 設定パラメータ - - - - - -キャッシュされたPostgreSQLへの接続を切断するまでの時間を秒単位で指定します。 -これはキャッシュされた接続の有効期間として働きます。 - - - -デフォルトは0です。 -これはキャッシュされた接続が切断されないことを意味しています。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - reset_query_list (string) - - - reset_query_list 設定パラメータ - - - - - -ユーザセッションを終了するときにバックエンドコネクションを初期化するために送られるSQLコマンドを指定します。 -複数のコマンドを";"で区切って指定することができます。 - - - - -利用できるコマンドはPostgreSQLのバージョンによって異なります。 -各PostgreSQLバージョンごとの設定は以下です。 -ただし、"ABORT"は必ずコマンドに含めてください。 - - - - - PostgreSQLバージョンごとの<varname>reset_query_list</varname>の推奨設定 - - - - - PostgreSQLバージョン - reset_query_list - - - - - - - 7.1以前 - 'ABORT' - - - - - 7.2から8.2 - 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' - - - - - 8.3以降 - 'ABORT; DISCARD ALL' - - - - -
- - - - - -ABORTは、PostgreSQL 7.4以降ではトランザクションブロックの中にいない場合には発行されません。 - - - - - -デフォルトは'ABORT; DISCARD ALL'です。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - -
-
- -
-
+
+ + ここで、-Cpgbenchにトランザクション実行の度に毎回データベースに接続することを指示します。 + -c 32は、Pgpool-IIへの同時セッション数です。 + これはシステム要件にあわせて変更するのがよいでしょう。 + pgbenchが終了後、"including connections establishing" の数値をチェックします。 +
+
+ + + + + なお、 が有効だと、serialize_acceptは効果がありません。 + serialize_acceptをonにしたい場合は、が0であることを確認してください。 + Pgpool-IIプロセスのメモリーリークなどの潜在的な問題を気にする場合は、代わりにを使ってください。 + この制限は純粋に実装上の問題であり、将来はなくなるかもしれません。 + + + + + + デフォルトはoffです。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + +
+
+ + + child_life_time (integer) + + + child_life_time 設定パラメータ + + + + + + クライアントがPgpool-IIの子プロセスに接続しないアイドル状態のままでいるときに、それを強制終了するまでの時間を秒単位で指定します。 + child_life_timeにより終了された時には、すぐに新しい子プロセスがPgpool-IIにより起動されます。 + child_life_timePgpool-II子プロセスのメモリリークやその他の不測のエラーに備えた予防措置です。 + + + + + child_life_timeはまだ一度もコネクションを受け付けていないプロセスには適用されません。 + + + + + + child_life_timeが有効な場合、は無効になります。 + + + + + デフォルト値は300秒(すなわち5分)です。 + 0を指定するとこの機能は無効になります。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + client_idle_limit (integer) + + + client_idle_limit 設定パラメータ + + + + + + クライアントが前回のクエリからアイドル状態のままでいるときに、それを切断するまでの時間を秒単位で指定します。 + これは、だらしないクライアントやPgpool-IIとクライアントの間のTCP/IPコネクションの不調によって、 + Pgpool-IIの子プロセスが占有されてしまうのを回避するのに役立ちます。 + + + + + client_idle_limitはオンラインリカバリのセカンドステージでは無視されます。 + + + + + デフォルト値は0で、この機能はoffとなります。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + child_max_connections (integer) + + + child_max_connections 設定パラメータ + + + + + + 各Pgpool-II子プロセスの寿命を、受付可能なクライアント接続の数で指定します。 + child_max_connections個のクライアント接続を処理した後にPgpool-IIはその子プロセスを終了させ、すぐに代わりの新しい子プロセスを生成します。 + + + + child_max_connectionsが効かないくらい忙しいサーバで有用です。 + またPostgreSQLバックエンドが肥大化するのを防ぐのにも有用です。 + + + + デフォルト値は0で、この機能はoffとなります。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + connection_life_time (integer) + + + connection_life_time 設定パラメータ + + + + + + キャッシュされたPostgreSQLへの接続を切断するまでの時間を秒単位で指定します。 + これはキャッシュされた接続の有効期間として働きます。 + + + このキャッシュを保持するプロセスに接続中のクライアントがある場合は、その接続が終了するまでconnection_life_timeの有効期間が来たかどうかの計算は行われません。 + したがって、このパラメータの設定値よりも長時間キャッシュされたコネクションが保持されることがあり得ます。 + これを避けたい場合は、を短めに設定することをお勧めします。 + + + + デフォルトは0です。 + これはキャッシュされた接続が切断されないことを意味しています。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + reset_query_list (string) + + + reset_query_list 設定パラメータ + + + + + + ユーザセッションを終了するときにバックエンドコネクションを初期化するために送られるSQLコマンドを指定します。 + 複数のコマンドを";"で区切って指定することができます。 + + + + + 利用できるコマンドはPostgreSQLのバージョンによって異なります。 + 各PostgreSQLバージョンごとの設定は以下です。 + ただし、"ABORT"は必ずコマンドに含めてください。 + + + + + PostgreSQLバージョンごとの<varname>reset_query_list</varname>の推奨設定 + + + + + PostgreSQLバージョン + reset_query_list + + + + + + + 7.1以前 + 'ABORT' + + + + + 7.2から8.2 + 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' + + + + + 8.3以降 + 'ABORT; DISCARD ALL' + + + + +
+ + + + + + ABORTは、PostgreSQL 7.4以降ではトランザクションブロックの中にいない場合には発行されません。 + + + + + + デフォルトは'ABORT; DISCARD ALL'です。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + +
+
+ +
+
- - エラー報告とログ取得 - - - - ログの出力先 - - - - - log_destination (string) - - - log_destination 設定パラメータ - - - - - -Pgpool-IIは、Pgpool-IIのメッセージのログ出力先を2種類サポートします。 -複数のログ出力先を使用したい場合は、希望するログ出力先をカンマで区切ったリストをパラメータに設定することができます。 - + + エラー報告とログ取得 + + + + ログの出力先 + + + + + log_destination (string) + + + log_destination 設定パラメータ + + + + + + Pgpool-IIは、Pgpool-IIのメッセージのログ出力先を2種類サポートします。 + 複数のログ出力先を使用したい場合は、希望するログ出力先をカンマで区切ったリストをパラメータに設定することができます。 + #for example to log on both syslog and stderr log_destination = 'syslog,stderr' - - -デフォルトではstderrのみにログ出力します。 - - - - -log_destinationでsyslogオプションを使用できるようにするために、いくつかのシステムではシステムのsyslogデーモンの設定を変更しなければならないでしょう。 -Pgpool-IIではログをLOCAL0からLOCAL7までのsyslogファシリティで記録することができます(を参照してください)。 -しかし、ほとんどのプラットフォームのデフォルトのsyslog設定ではこれらのメッセージはすべて破棄されます。 -うまく動作させるためにsyslogデーモンの設定に以下のようなものを追加しなければならないでしょう。 - + + + デフォルトではstderrのみにログ出力します。 + + + + + log_destinationでsyslogオプションを使用できるようにするために、いくつかのシステムではシステムのsyslogデーモンの設定を変更しなければならないでしょう。 + Pgpool-IIではログをLOCAL0からLOCAL7までのsyslogファシリティで記録することができます(を参照してください)。 + しかし、ほとんどのプラットフォームのデフォルトのsyslog設定ではこれらのメッセージはすべて破棄されます。 + うまく動作させるためにsyslogデーモンの設定に以下のようなものを追加しなければならないでしょう。 + local0.* /var/log/pgpool.log - - - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - syslog_facility (enum) - - - syslog_facility 設定パラメータ - - - - - -syslogへのログ取得が有効な場合、このパラメータは使用されるsyslogの「facility」を決定します。 -LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、LOCAL5、LOCAL6、LOCAL7の中から選んでください。 -デフォルトはLOCAL0です。 -使用しているシステムのsyslogデーモンの文書を同時に参照してください。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - syslog_ident (string) - - - syslog_ident 設定パラメータ - - - - - -syslogにログ取得が有効な場合、このパラメータはsyslogログ内のPgpool-IIメッセージを特定するのに使用するプログラム名を確定します。 -デフォルトはpgpoolです。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - - - - - いつログを取得するか - - - - - client_min_messages (enum) - - - client_min_messages 設定パラメータ - - - - - -どのメッセージ階層をクライアントに送るかを管理します。 -有効な値は、DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、LOG、NOTICE、WARNING、およびERRORです。 -それぞれの階層はそれに続く全ての階層を包含します。 -デフォルトはNOTICEです。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - - - - log_min_messages (enum) - - - log_min_messages 設定パラメータ - - - - - -どのメッセージ階層をサーバログに書き込むかを管理します。有効な値はDEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、INFO、NOTICE、WARNING、ERROR、LOG、FATAL、およびPANICです。 -それぞれの階層はその下の全ての階層を含みます。 -デフォルトはWARNINGです。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - - - - - - - - 何をログに - - - - - log_statement (boolean) - - - log_statement 設定パラメータ - - - - - -onに設定されている場合、全てのSQL文をログ出力します。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - - - - log_per_node_statement (boolean) - - - log_per_node_statement 設定パラメータ - - - - - -と似ていますが、DBノード単位でログが出力されます。 -レプリケーションや負荷分散が動いていることを確認するのに便利です。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - - - - log_client_messages (boolean) - - - log_client_messages 設定パラメータ - - - - - -onに設定されている場合、クライアントメッセージをログ出力します。 - - - -このパラメータは、Pgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - - - - log_hostname (boolean) - - - log_hostname 設定パラメータ - - - - - -onに設定されている場合、psコマンドの結果、および(がonの場合には)接続時のログに、IPアドレスではなくホスト名を表示します。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - log_connections (boolean) - - - log_connections 設定パラメータ - - - - - -onに設定されている場合、全てのクライアント接続をログへ出力します。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - log_error_verbosity (enum) - - - log_error_verbosity 設定パラメータ - - - - - -ログ取得されるそれぞれのメッセージに対し、サーバログに書き込まれる詳細の量を制御します。 -有効な値は、TERSE、DEFAULT、およびVERBOSEで、それぞれは表示されるメッセージにより多くのフィールドを追加します。 -TERSEはDETAIL、HINT、QUERY、およびCONTEXTエラー情報を除外します。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - - - - log_line_prefix (string) - - - log_line_prefix 設定パラメータ - - - - - -これは、各ログ行の先頭に出力するprintfの書式文字列です。 -%から始まるエスケープシーケンスは、後述の通りのステータス情報で置き換えられます。 -認識できないエスケープは無視されます。 -他の文字はそのままログ行に出力されます。 -デフォルトは '%t: pid %p: 'で、タイムスタンプとプロセスIDを印字します。 -これは、Pgpool-II V3.4より前のバージョンとの互換性を保つためです。 - - - - log_line_prefix escape options - - - - - - エスケープ - 効果 - - - - - - %a - - クライアントのアプリケーション名 - - - - %p - - プロセスID (PID) - - - - %P - - プロセス名 - - - - %t - - タイムスタンプ - - - - %d - - データベース名 - - - - %u - - ユーザ名 - - - - %l - - プロセスごとのログ行番号 - - - - %% - - '%' 文字自身 - - - - -
- - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - -
-
- -
-
+
+ +
+ + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + +
+
+ + + logging_collector (boolean) + + logging_collector設定パラメータ + + + + + + このパラメータはログ収集機構を有効にします。 + それはstderrに送られたログメッセージを捕捉し、ログファイルにリダイレクトするバックグラウンドプロセスです。 + + + + + ログ収集機構を使わずにstderrにログを出力することもできます。 + その場合はログメッセージはサーバのstderrがリダイレクトされたところに単に出力されます。 + しかしこの方法はログの量が少ない場合にのみ適切な方法です。 + ログを巡回させる便利な方法がないからです。 + + + + + このパラメータはサーバ起動時のみ設定可能です。 + + + + logging_collectorPgpool-II V4.2以降でのみ使用可能です。 + + + + + + log_directory (string) + + + log_directory設定パラメータ + + + + + + を有効と設定した場合、このパラメータはログファイルが作成されるディレクトリを確定します。 + + + + デフォルトは/tmp/pgpool_logsです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + + log_filename (string) + + + log_filename設定パラメータ + + + + + + が有効な場合、このパラメータは作成されたログファイルのファイル名を設定します。 + 値はstrftimeパターンとして扱われるため、%エスケープを使用して、時刻によって変動するファイル名を指定することができます。 + サポートされている%-エスケープはstrftime 仕様によく似ています。 + + + + エスケープすることなくファイル名を指定する場合、ディスク全体を使い切ってしまうことを防止するためにログローテーションを行うユーティリティを使用することを計画するべきです。 + + + + デフォルトはpgpool-%Y-%m-%d_%H%M%S.logです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + + log_file_mode (integer) + + + log_file_mode設定パラメータ + + + + + + が有効になっている場合、このパラメータはログファイルのパーミッションを設定します。 + パラメータの値はchmod および umaskシステムコールで許容されるフォーマットで指定される数値モードであると期待されます。 + + + + + + 8進数を使うには、数値を0(ゼロ)で開始してください。 + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_rotation_age (integer) + + + log_rotation_age設定パラメータ + + + + + + が有効な場合、このパラメータは個々のログファイルの最大寿命を決定します。 + この値が単位なしで指定された場合は、分単位であるとみなします。 デフォルトは24時間です。 + + + + ゼロに設定することで、寿命に基づいた新しいログファイルの生成は無効になります。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_rotation_size (integer) + + + log_rotation_size設定パラメータ + + + + + + が有効な場合、このパラメータは個々のログファイルの最大容量を決定します。 + ここでキロバイト単位で指定したデータ量がログファイルに出力された後、新しいログファイルが生成されます。 + + + + ゼロに設定することで、サイズに基づいた新しいログファイルの生成は無効になります。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_truncate_on_rotation (boolean) + + + log_truncate_on_rotation設定パラメータ + + + + + + が有効な場合、PostgreSQLは既存の同名のファイルに追加するのではなく、そのファイルを切り詰める(上書きする)ようになります。 + しかし、切り詰めは時間を基にしたローテーションのために新規にファイルが開かれた時にのみ発生し、サーバ起動時やサイズを基にしたローテーションでは発生しません。 + オフの場合、全ての場合において既存のファイルに追記されます。 + 例えば、この設定をpgpool-%H.logのようなと組み合わせて使用すると、24個の時別のログファイルが生成され、それらは周期的に上書きされることになります。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + syslog_facility (enum) + + + syslog_facility 設定パラメータ + + + + + + syslogへのログ取得が有効な場合、このパラメータは使用されるsyslogの「facility」を決定します。 + LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、LOCAL5、LOCAL6、LOCAL7の中から選んでください。 + デフォルトはLOCAL0です。 + 使用しているシステムのsyslogデーモンの文書を同時に参照してください。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + syslog_ident (string) + + + syslog_ident 設定パラメータ + + + + + + syslogへのログ取得が有効な場合、このパラメータはsyslogログ内のPgpool-IIメッセージを特定するのに使用するプログラム名を確定します。 + デフォルトはpgpoolです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + +
+
+ + + + いつログを取得するか + + + + + client_min_messages (enum) + + + client_min_messages 設定パラメータ + + + + + + どのメッセージ階層をクライアントに送るかを管理します。 + 有効な値は、DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、LOG、NOTICE、WARNING、およびERRORです。 + それぞれの階層はそれに続く全ての階層を包含します。 + デフォルトはNOTICEです。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + log_min_messages (enum) + + + log_min_messages 設定パラメータ + + + + + + どのメッセージ階層をサーバログに書き込むかを管理します。有効な値はDEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、INFO、NOTICE、WARNING、ERROR、LOG、FATAL、およびPANICです。 + それぞれの階層はその下の全ての階層を含みます。 + デフォルトはWARNINGです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + + + + + 何をログに + + + + + log_statement (boolean) + + + log_statement 設定パラメータ + + + + + + onに設定されている場合、全てのSQL文をログ出力します。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + log_per_node_statement (boolean) + + + log_per_node_statement 設定パラメータ + + + + + + と似ていますが、DBノード単位でログが出力されます。 + レプリケーションや負荷分散が動いていることを確認するのに便利です。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + notice_per_node_statement (boolean) + + + notice_per_node_statement 設定パラメータ + + + + + + と似ていますが、NOTICEメッセージとしてDBノード単位でログが出力されます。 + のデフォルト設定(すなわちNOTICE)では、このログメッセージはクライアントの端末にも出力されます。 + クライアントにとっては、Pgpool-IIのログファイルにアクセスする必要がないので便利です。 + と違って、は内部的に発行する問い合わせ(たとえば +システムカタログへの問い合わせ)は出力しないことに注意してください。 + これは、この機能がテストにも使えるように設計されているからです。 + 内部的な問い合わせは非決定論的に発行される傾向があるため、テストに使うには適していません。 + 同じ理由で、バックエンドのプロセスIDも出力されません。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + log_client_messages (boolean) + + + log_client_messages 設定パラメータ + + + + + + onに設定されている場合、クライアントメッセージをログ出力します。 + + + + このパラメータは、Pgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + + log_backend_messages (enum) + + + log_backend_messages 設定パラメータ + + + + + + terseまたはverboseに設定されている場合、バックエンドからのメッセージをログ出力します + terseでは、同じ種類のメッセージが同じバックエンドから送られてくると、その回数を記録し、次に異なる種類のメセージが送られてきた時に繰り返し回数を報告します。 + 出力例を示します。 + + LOG: last DataRow message from backend 0 repeated 10 times + + したがって、繰り返している最中にセッションに対応するプロセスが強制終了すると、その分のログが出力されません。 + この場合でもすべてのログを出力するには、verboseオプションを使用します。 + ただし、このオプションでは繰り返し回数分だけの行のログが出力されるので、大量のメッセージがバックエンドから送られてくる場合は注意が必要です。 + デフォルトはnoneで、バックエンドからのメッセージをログ出力しません。 + + + + このパラメータは、Pgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + log_hostname (boolean) + + + log_hostname 設定パラメータ + + + + + + onに設定されている場合、psコマンドの結果、および(がonの場合には)接続時のログに、IPアドレスではなくホスト名を表示します。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_connections (boolean) + + + log_connections 設定パラメータ + + + + + + onに設定されている場合、全てのクライアント接続をログへ出力します。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_disconnections (boolean) + + + log_disconnections 設定パラメータ + + + + + + onに設定されている場合、全てのクライアント接続終了をログへ出力します。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_pcp_processes (boolean) + + + log_pcp_processes 設定パラメータ + + + + + + onに設定されている場合、PCPプロセスの正常なforkあるいはexitした状態をログに出力します。 + デフォルトはoffです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_error_verbosity (enum) + + + log_error_verbosity 設定パラメータ + + + + + + ログ取得されるそれぞれのメッセージに対し、サーバログに書き込まれる詳細の量を制御します。 + 有効な値は、TERSE、DEFAULT、およびVERBOSEで、それぞれは表示されるメッセージにより多くのフィールドを追加します。 + TERSEはDETAIL、HINT、QUERY、およびCONTEXTエラー情報を除外します。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + log_line_prefix (string) + + + log_line_prefix 設定パラメータ + + + + + + これは、各ログ行の先頭に出力するprintfの書式文字列です。 + %から始まるエスケープシーケンスは、後述の通りのステータス情報で置き換えられます。 + 認識できないエスケープは無視されます。 + 他の文字はそのままログ行に出力されます。 + デフォルトは '%m: %a pid %p: 'で、タイムスタンプ、アプリケーション名、プロセスIDを印字します。 + + + + log_line_prefixのエスケープオプション + + + + + + エスケープ + 効果 + + + + + + %a + + アプリケーション名。 + 子プロセス(セッションプロセス)の初期値は"child"です。 + クライアントがアプリケーション名(スタートアップメッセージあるいはSETコマンドを使って)を設定すると、アプリケーション名は変更されます。 + 他の種類のプロセスでは、アプリケーション名はハードコードされた文字列です。 + を参照してください。 + + + + + %p + + プロセスID (PID) + + + + %P + + プロセス名 + + + + %t + ミリ秒なしのタイムスタンプ + + + + %m + ミリ秒付きのタイムスタンプ + + + + %d + + データベース名 + + + + %u + + ユーザ名 + + + + %l + + プロセスごとのログ行番号 + + + + %% + + '%' 文字自身 + + + + +
+ + + 各プロセスのアプリケーション名 + + + + + プロセスの種類 + アプリケーション名 + + + + + + + main + main + + + + child + child + + + + streaming replication delay check worker + sr_check_worker + + + + watchdog heart beat sender + heart_beat_sender + + + + watchdog heart beat receiver + heart_beat_receiver + + + + watchdog + watchdog + + + + watchdog life check + life_check + + + + follow primary child + follow_child + + + + watchdog utility + watchdog_utility + + + + pcp main + pcp_main + + + + pcp child + pcp_child + + + + health check process + health_check%d (%dはバックエンドノードIDに置換されます) + + + + logger process + logger (loggerプロセスが管理するログファイルに「logger」というアプリケーション名が出力されることはありません) + + + + +
+ + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + +
+
+ +
+
diff --git a/doc.ja/src/sgml/connection-settings.sgml b/doc.ja/src/sgml/connection-settings.sgml index 7e051292f..7f0dd32a8 100644 --- a/doc.ja/src/sgml/connection-settings.sgml +++ b/doc.ja/src/sgml/connection-settings.sgml @@ -1,1707 +1,2075 @@ - - 接続と認証 - - - - 接続設定 - - - - - listen_addresses (string) - - - listen_addresses 設定パラメータ - - + + 接続と認証 + + + + 接続設定 + + + + + listen_addresses (string) + + + listen_addresses 設定パラメータ + + + + + + クライアントアプリケーションからの接続をサーバが監視する TCP/IP アドレスを指定します。 + この値は、ホスト名をコンマで区切ったリスト、そして/もしくは、数値によるIPアドレスです。 + *という特別なエントリは利用可能な全てのIPインタフェースに対応します。 + エントリ0.0.0.0は全てのIPv4アドレスの監視を、そしてエントリ::は全てのIPv6アドレスの監視を許容します。 + リストが空の場合、サーバはいかなるIPインタフェースも全く監視しないで、Unixドメインソケットのみを使用して接続が行われます。 + デフォルトの値はlocalhostで、ローカルなTCP/IP loopback接続のみ許可します。 + クライアント認証()は誰がサーバにアクセス可能かをきめ細かく制御するのに対し、listen_addressesはどのインタフェースが接続を試みるかを制御します。 + これにより、安全でないネットワークインタフェース上において繰り返して行われる悪意のある接続要求の防止に役立ちます。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + port (integer) + + + port 設定パラメータ + + + + + + Pgpool-IIが接続を受け付けるために監視するポート番号です。 + デフォルト値は9999です。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + unix_socket_directories (string) + + + unix_socket_directories 設定パラメータ + + + + + + Pgpool-IIが接続を受け付けるUNIXドメインソケットを置くディレクトリです。 + コンマで区切った複数のディレクトリのリストを設定すると複数のUNIXドメインソケットファイルを作成します。 + 各設定値の先頭と末尾に空白が入っている場合は、自動的に削除されます。 + デフォルト値は/tmpです。 + このソケットは、cron によって削除されることがあるので注意してください。 + /var/runなどのディレクトリに変更することをお勧めします。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + unix_socket_group (string) + + + unix_socket_group 設定パラメータ + + + + + + UNIXドメインソケット(複数も)を所有するグループを設定します(ソケットを所有するユーザは常にサーバを起動するユーザです)。 + unix_socket_permissionsパラメータとの組合せで、UNIXドメインソケット接続の追加的アクセス管理機構として使うことができます。 + デフォルトでは空文字列で、サーバユーザのデフォルトグループを使用します。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + unix_socket_permissions (integer) + + + unix_socket_permissions 設定パラメータ + + + + + + UNIXドメインソケット(複数も)のアクセスパーミッションを設定します。 + UNIXドメインソケットは通常のUNIXファイルシステムパーミッション設定の一式を使用します。 + パラメータ値は、chmodおよびumaskシステムコールが受け付ける数値形式での指定を想定しています。 + (通常使われる8進数形式を使用するのであれば、0(ゼロ)で始まらなければなりません。) + + + + デフォルトのパーミッションは、誰でも接続できる0777になっています。 + 変更するならば0770(ユーザとグループのみです。unix_socket_groupも参照してください)や0700(ユーザのみ)が適切です。 + (UNIXドメインソケットでは書き込み権限だけが問題になるため、読み込みや実行のパーミッションを設定または解除する意味はありません。) + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + pcp_listen_addresses (string) + + + pcp_listen_addresses 設定パラメータ + + + + + + クライアントアプリケーションからの接続をPCPサーバが監視する TCP/IP アドレスを指定します。 + この値は、ホスト名をコンマで区切ったリスト、そして/もしくは、数値によるIPアドレスです。 + *という特別なエントリは利用可能な全てのIPインタフェースに対応します。 + エントリ0.0.0.0は全てのIPv4アドレスの監視を、そしてエントリ::は全てのIPv6アドレスの監視を許容します。 + リストが空の場合、サーバはいかなるIPインタフェースも全く監視しないで、Unixドメインソケットのみを使用して接続が行われます。 + デフォルトの値はlocalhostで、ローカルなTCP/IP loopback接続のみ許可します。 + クライアント認証()は誰がサーバにアクセス可能かをきめ細かく制御するのに対し、pcp_listen_addressesはどのインタフェースが接続を試みるかを制御します。 + これにより、安全でないネットワークインタフェース上において繰り返して行われる悪意のある接続要求の防止に役立ちます。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + pcp_port (integer) + + + pcp_port 設定パラメータ + + + + + + PCPプロセスが接続を受け付けるために監視するポート番号です。 + デフォルト値は9898です。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + pcp_socket_dir (string) + + + pcp_socket_dir 設定パラメータ + + + + + + PCPプロセスが接続を受け付けるUNIXドメインソケットを置くディレクトリです。 + コンマで区切った複数のディレクトリのリストを設定すると複数のUNIXドメインソケットファイルを作成します。 + 各設定値の先頭と末尾に空白が入っている場合は、自動的に削除されます。 + デフォルト値は/tmpです。 + このソケットは、cron によって削除されることがあるので注意してください。 + /var/runなどのディレクトリに変更することをお勧めします。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + num_init_children (integer) + + + num_init_children 設定パラメータ + + + + + + preforkするPgpool-IIのサーバプロセスの数です。 + デフォルト値は32です。 + num_init_childrenはPgpool-IIに対してクライアントが同時に接続できる上限の数でもあります。 + num_init_childrenより多いクライアントがPgpool-IIに接続しようとした場合、が1以上に設定されている場合を除き、それらのクライアントは、Pgpool-IIのどれかのプロセスへの接続が閉じられるまで待たされます(PostgreSQLのように接続拒否エラーにはなりません。)。 + + 待たされる数の上限は、 * num_init_children です。 + + + + 待ち行列は、OS内部に作られ、「listenキュー」と呼ばれます。 + listenキューの長さは「バックログ」と呼ばれます。 + システムによってはバックログの上限が設定されており、*num_init_childrenがこれを越える場合はバックログを大きく設定する必要があります。 + さもないと高負荷時に以下のような問題が発生する可能性があります: + - - -Pgpool-IIがTCP/IP接続を受け付けるホスト名またはIPアドレスを指定します。 -*を指定すると入ってくる全ての接続を受け付けます。 -''を指定するとTCP/IP接続を受け付けません。 -デフォルト値は'localhost'です。 -UNIXドメインソケット経由の接続は常に受け付けます。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - + + + Pgpool-IIへの接続が失敗する。 + - - - - port (integer) - - - port 設定パラメータ - - - - -Pgpool-IIが接続を受け付けるために監視するポート番号です。 -デフォルト値は9999です。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - + + + カーネル内で行われるリトライによりPgpool-IIへの接続が遅くなる。 + - - - - socket_dir (string) - - - socket_dir 設定パラメータ - - - - - -Pgpool-IIが接続を受け付けるUNIXドメインソケットを置くディレクトリです。 -デフォルト値は/tmpです。 -このソケットは、cron によって削除されることがあるので注意してください。 -/var/runなどのディレクトリに変更することをお勧めします。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - pcp_listen_addresses (string) - - - pcp_listen_addresses 設定パラメータ - - - - - -PCPプロセスがTCP/IP接続を受け付けるホスト名またはIPアドレスを指定します。 -*を指定すると入ってくる全ての接続を受け付けます。 -''を指定するとTCP/IP接続を受け付けません。 -デフォルト値は*です。 -UNIXドメインソケット経由のコネクションは常に受け付けます。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - pcp_port (integer) - - - pcp_port 設定パラメータ - - - - - -PCPプロセスが接続を受け付けるために監視するポート番号です。 -デフォルト値は9898です。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - pcp_socket_dir (string) - - - pcp_socket_dir 設定パラメータ - - - - - -PCPプロセスが接続を受け付けるUNIXドメインソケットを置くディレクトリです。 -デフォルト値は/tmpです。 -このソケットは、cron によって削除されることがあるので注意してください。 -/var/runなどのディレクトリに変更することをお勧めします。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - num_init_children (integer) - - - num_init_children 設定パラメータ - - - - - -preforkするPgpool-IIのサーバプロセスの数です。 -デフォルト値は32です。 -num_init_childrenはPgpool-IIに対してクライアントが同時に接続できる上限の数でもあります。 -num_init_childrenより多いクライアントがPgpool-IIに接続しようとした場合、が1以上に設定されている場合を除き、それらのクライアントは、Pgpool-IIのどれかのプロセスへの接続が閉じられるまで待たされます(PostgreSQLのように接続拒否エラーにはなりません。)。 - -待たされる数の上限は、 * num_init_children です。 - - - -待ち行列は、OS内部に作られ、「listenキュー」と呼ばれます。 -listenキューの長さは「バックログ」と呼ばれます。 -システムによってはバックログの上限が設定されており、*num_init_childrenがこれを越える場合はバックログを大きく設定する必要があります。 -さもないと高負荷時に以下のような問題が発生する可能性があります: -1) Pgpool-IIへの接続が失敗する。 -2) カーネル内で行われるリトライによりPgpool-IIへの接続が遅くなる。 -実際にlistenキューが溢れているかどうかは、"netstat -s"コマンドを使って確認できます。 -もし、以下のような出力があった場合、 - -535 times the listen queue of a socket overflowed - - -listenキューが溢れています。 -この場合にはバックログを増やす必要があります(スーパユーザ権限が必要になります)。 - - -# sysctl net.core.somaxconn -net.core.somaxconn = 128 -# sysctl -w net.core.somaxconn = 256 - - -/etc/sysctl.confに以下のように書いても構いません。 - -net.core.somaxconn = 256 - - - - -PostgreSQLへ貼られる接続数は大まかにはmax_pool*num_init_childrenとなります。 - - - - -ただし、問い合わせのキャンセルを行うとバックエンドに対して別の接続が張られます。 -したがって、すべての接続が使用中の場合には問い合わせのキャンセルができなくなります。 -問い合わせのキャンセルを必ず保証したい場合は、想定されるコネクション数の倍の値を設定してください。 - - - -また、PostgreSQLは一般ユーザによる同時接続をmax_connections - superuser_reserved_connections個まで許しています。 - - - -まとめると、max_pool、num_init_children、max_connections、superuser_reserved_connectionsは、以下の式を満たしていなければなりません。 - - -max_pool*num_init_children <= (max_connections - superuser_reserved_connections) (クエリのキャンセルを考慮しない場合) -max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections) (クエリのキャンセルを考慮する場合) - - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - reserved_connections (integer) - - - reserverd_connections設定パラメータ - - - - - -このパラメータが1以上に設定されていると、( - reserved_connections)以上のクライアントからの接続はブロックされるのではなく受け付けられず、"Sorry, too many clients already"というエラーになります。 -たとえば、reserved_connections = 1で、 = 32なら、32番目のクライアントからの接続は拒否されます。 -これは、PostgreSQLと似た挙動で、クライアントからの接続数が多く、各セッションが長時間に渡るようなシステムで有効です。 -この場合、listenキューが非常に長くなる可能性があり、システムを不安定にさせます。 -こうした状況では、このパラメータを0以外にして、listenキューが長くなるのを防ぐのは良い考えです。 - - - -このパラメータを0にすると、クライアントからの接続要求は拒否されなくなります。 -デフォルト値は0です。 -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - - - - - 認証設定 - - - - enable_pool_hba (boolean) - - - enable_pool_hba 設定パラメータ - - - - - -trueの場合、Pgpool-IIはクライアント認証にpool_hba.confを使用します。 -クライアント認証のためpool_hba.confを設定する方法について、詳細はを参照してください。 -デフォルトはfalseです。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - pool_passwd (string) - - - pool_passwd 設定パラメータ - - - - - -認証に用いるパスワードファイルのファイル名を指定します。 -デフォルト値は"pool_passwd"です。 -''(空文字列)を指定すると パスワードファイルの使用は無効になります。 - + + + 実際にlistenキューが溢れているかどうかは、"netstat -s"コマンドを使って確認できます。 + もし、以下のような出力があった場合、 + + 535 times the listen queue of a socket overflowed + + + listenキューが溢れています。 + この場合にはバックログを増やす必要があります(スーパユーザ権限が必要になります)。 + + + # sysctl net.core.somaxconn + net.core.somaxconn = 128 + # sysctl -w net.core.somaxconn = 256 + + + /etc/sysctl.confに以下のように書いても構いません。 + + net.core.somaxconn = 256 + + + + + PostgreSQLへ張られる接続数は大まかにはmax_pool*num_init_childrenとなります。 + + + + + ただし、問い合わせのキャンセルを行うとバックエンドに対して別の接続が張られます。 + したがって、すべての接続が使用中の場合には問い合わせのキャンセルができなくなります。 + 問い合わせのキャンセルを必ず保証したい場合は、想定されるコネクション数の倍の値を設定してください。 + + + + また、PostgreSQLは一般ユーザによる同時接続をmax_connections - superuser_reserved_connections個まで許しています。 + + + + まとめると、max_pool、num_init_children、max_connections、superuser_reserved_connectionsは、以下の式を満たしていなければなりません。 + + + max_pool*num_init_children <= (max_connections - superuser_reserved_connections) (クエリのキャンセルを考慮しない場合) + max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections) (クエリのキャンセルを考慮する場合) + + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + reserved_connections (integer) + + + reserved_connections設定パラメータ + + + + + + このパラメータが1以上に設定されていると、( - reserved_connections)以上のクライアントからの接続はブロックされるのではなく受け付けられず、"Sorry, too many clients already"というエラーになります。 + たとえば、reserved_connections = 1で、 = 32なら、32番目のクライアントからの接続は拒否されます。 + これは、PostgreSQLと似た挙動で、クライアントからの接続数が多く、各セッションが長時間に渡るようなシステムで有効です。 + この場合、listenキューが非常に長くなる可能性があり、システムを不安定にさせます。 + こうした状況では、このパラメータを0以外にして、listenキューが長くなるのを防ぐのは良い考えです。 + + + + このパラメータを0にすると、クライアントからの接続要求は拒否されなくなります。 + デフォルト値は0です。 + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + + + + + 認証設定 + + + + enable_pool_hba (boolean) + + + enable_pool_hba 設定パラメータ + + + + + + trueの場合、Pgpool-IIはクライアント認証にpool_hba.confを使用します。 + クライアント認証のためpool_hba.confを設定する方法について、詳細はを参照してください。 + デフォルトはfalseです。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + pool_passwd (string) + + + pool_passwd 設定パラメータ + + + + + + 認証用のパスワードファイルへのパス(絶対パスまたは相対パス)を指定します。 + デフォルト値は"pool_passwd"です。 + 相対パスは、設定ファイルが置かれているディレクトリを基準としています。 + ''(空文字列)を指定すると パスワードファイルの使用は無効になります。 + + + + パスワードは、3つの形式でpool_passwdファイルに保存できます。 + AES256暗号化形式、平文形式、md5形式です。 + Pgpool-IIは接頭辞によってパスワードの形式を確認するため、pool_passwd内の各パスワードのエントリはパスワードの形式を接頭辞として付ける必要があります。 + + + + 平文形式のパスワードを保存するためには、TEXT接頭辞を使用します。 + 例として、pool_passwd内にクリアテキストパスワード文字列"mypassword"を保存する場合、パスワード文字列の先頭にTEXT接頭辞を追加します。 + 例えば、TEXTmypasswordとなります。 + + + + 同様に、md5ハッシュパスワードはmd5接頭辞、AES256暗号化パスワード形式はAES接頭辞を使って保存することができます。 + AES256暗号化パスワードの詳細は、を参照してください。 + + + + + 有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + allow_clear_text_frontend_auth (boolean) + + allow_clear_text_frontend_auth configuration parameter + + + + + + PostgreSQLバックエンドサーバはあるユーザの認証に対してmd5またはSCRAM認証を必要としており、そのユーザのパスワードが"pool_passwd"ファイルに存在しない場合、allow_clear_text_frontend_authPgpool-IIがフロントエンドクライアントとクリアテキストパスワード認証を行い、クライアントから平文形式のパスワードを取得しバックエンド認証のために使用することを許可します。 + + + + + デフォルトはfalseです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + allow_clear_text_frontend_authが有効でない場合のみ機能します。 + + + + + + + authentication_timeout (integer) + + + authentication_timeout 設定パラメータ + + + + + + Pgpool-IIの認証処理のタイムアウト時間を秒単位で指定します。 + 0 を指定するとタイムアウトを無効にします。 + デフォルト値は60です。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + + + + + + + プロセス管理 + + + + + + process_management_mode (enum) + + process_management_mode configuration parameter + + + + + + Pgpool-IIアイドル状態の子プロセスの管理方法を指定します。 + 有効なオプション: + + + 指定可能なプロセス管理モード + + + + + static + + + すべての子プロセスは起動時に事前にフォークされます。 + 子プロセスの数は固定です()。 + + + + + dynamic + + + 子プロセスはオンデマンドで生成され、最大です。 + アイドル状態の子プロセスの数はmin_spare_childrenとmax_spare_childrenの設定値に基づいて増減していきます。 + + + + + +
+
+ + + デフォルトはstaticで、V4.4より以前のバージョンとの互換性があります。 + + + + + process_management_modeは、Pgpool-II V4.4より以前のバージョンでは使用できません。 + + + + 詳細はを参照してください。 + + +
+
+ + + process_management_strategy (enum) + + process_management_strategy configuration parameter + + + + + + アイドル状態のプロセスの数を満たすためのプロセス管理戦略を指定します。 + 有効なオプション: + + + 指定可能なプロセス管理戦略 + + + + + lazy + + + この戦略では、スケールダウンが徐々に実行され、余分なアイドル状態のプロセスが5分以上残っている場合にのみトリガーされます。 + + + + + gentle + + + この戦略では、スケールダウンが徐々に実行され、余分なアイドル状態のプロセスが2分以上残っている場合にのみトリガーされます。 + + + + + aggressive + + + この戦略では、スケールダウンが積極的に実行され、アイドル状態のプロセスが多い場合により頻繁にトリガーされます。 + このモードでは、を満たすために、サービスを提供するための子プロセスの識別基準は、より高速でややスマートでないプロセス選択基準を使用します。 + + + + + +
+
+ + + デフォルトはgentleです。 + + + + process_management_strategyは、Pgpool-IIV4.4より以前のバージョンでは使用できません。 + + +
+
+ + + min_spare_children (integer) + + min_spare_children configuration parameter + + + + + + 保持する予備(アイドル状態)の子プロセスの最小個数を指定します。 + 予備(アイドル状態)の子プロセス数がmin_spare_childrenを下回った場合、Pgpool-IIは許容される子プロセスの合計上限()に達しない限り、新しい子プロセスを生成します。 + デフォルト値は5です。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + このパラメーターは、動的プロセス管理モードが有効になっている場合にのみ適用されます。 + + + + + + max_spare_children (integer) + + max_spare_children configuration parameter + + + + + + 保持する予備(アイドル状態)の子プロセスの最大個数を指定します。 + 予備(アイドル状態)の子プロセス数がmax_spare_childrenを超えた場合、Pgpool-IIは余分な子プロセスを強制終了します。 + プールされた接続数が少ないものから順に強制終了の対象として選ばれます。 + デフォルト値は10です。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + このパラメーターは、動的プロセス管理モードが有効になっている場合にのみ適用されます。 + + + + +
+ +
+
+ + + クラスタリングモード + + + + backend_clustering_mode (enum) + + backend_clustering_mode設定パラメータ + + + + + クラスタリングモードはPostgreSQLの同期を取る方法を指定します。 + クラスタリングモードの設定にはbackend_clustering_modeを使用します。 + この節ではクラスタリングモードの設定方法を説明します。 + 詳細はをご覧ください。 + + + + + + + ストリーミングレプリケーションモード + + + このモードはもっともよく使われており、推薦できるクラスタリングモードです。 + このモードではPostgreSQLが個々のサーバをレプリケーションします。 + このモードを有効にするにはbackend_clustering_modeにstreaming_replicationを設定してください。 + +backend_clustering_mode = streaming_replication + + このモードでは127台までのストリーミングレプリケーションスタンバイサーバを使用できます。 + また、スタンバイサーバをまったく使用しないことも可能です。 + + + このモードの難点は、検索問い合わせを負荷分散させた時に、スタンバイサーバのレプリケーション遅延を意識しなければならない点です。 + ノードをまたがる可視性の一貫性も保証されません。 + この問題を改善するために多くの追加パラメータが用意されていますが、そのことが管理を難しくする場合もあります。 + また、プライマリサーバがダウンしてスタンバイが昇格する場合にフェイルオーバの時間がかかることがあります。 + こうした問題を避けたい場合は、スナップショットアイソレーションモードをご検討ください。 + + + ストリーミングレプリケーションモードで使用する追加のパラメータについてはをご覧ください。 + + + + + ネイティブレプリケーションモード + + + + このモードではPostgreSQL間のデータレプリケーションをPgpool-IIに行わせます。 + このモードを有効にするにはbackend_clustering_modeにnative_replicationを設定してください。 + +backend_clustering_mode = native_replication + + このモードでは127台までのレプリカサーバを使用できます。 + また、レプリカサーバをまったく使用しないことも可能です。 + + + + + 参照負荷をバックエンドノードに振り分ける負荷分散(を参照)もレプリケーションモードと共に使用可能です。 + + + + このモードの難点は、ノードをまたがる可視性の一貫性が保証されないことです。 + このことでノードの間のデータの一貫性が崩れたり、一貫性のないデータを一時的に読み込んでしまうことがあります。 + こうした問題を避けたい場合は、スナップショットアイソレーションモードをご検討ください。 + + + + + 以下のオプションがレプリケーションモードにおけるPgpool-IIの動作に影響します。 + + + + + + replication_stop_on_mismatch (boolean) + + + replication_stop_on_mismatch 設定パラメータ + + + + + + + これがonで、全てのPostgreSQLバックエンドノードに送られたクエリに対して、全てのノードが同じパケット種類で応答しなかった場合、多数派とは異なる応答したバックエンドノードはPgpool-IIにより切り離されます。 + replication_stop_on_mismatchがoffの場合に同様の状況が発生したときには、Pgpool-IIは現在のユーザセッションを強制終了するだけにとどめ、バックエンドの切り離しは行いません。 + + + + - -パスワードは、3つの形式でpool_passwdファイルに保存できます。 -AES256暗号化形式、平文形式、md5形式です。 -Pgpool-IIは接頭辞によってパスワードの形式を確認するため、pool_passwd内の各パスワードのエントリはパスワードの形式を接頭語として付ける必要があります。 + + Pgpool-IIはバックエンドから返されたデータは調べずに、結果パケットの種類の比較のみにより決断します。 + + + + + replication_stop_on_mismatchを有効にする典型的なユースケースは、バックエンドノード間のデータ不整合の防止です。 + 例えば、UPDATE文が他のノードでは成功しているのにあるバックエンドノードでは失敗した場合、そのバックエンドノードを切り離したいかもしれません。 + + + + デフォルトはoffです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + failover_if_affected_tuples_mismatch (boolean) + + + failover_if_affected_tuples_mismatch 設定パラメータ + + + + + + これがonで、全てのノードの応答でINSERT/UPDATE/DELETEクエリの影響を受けたタプルの数が同じでなかった場合、多数派とは異なる応答したバックエンドノードはPgpool-IIによる切り離されます。 + failover_if_affected_tuples_mismatchがoffの場合に同様の状況が発生したときには、Pgpool-IIは現在のユーザセッションを強制終了するだけにとどめ、バックエンドの切り離しは行いません。 + + + - -平文形式のパスワードを保存するためには、TEXT接頭辞を使用します。 -例として、pool_passwd内にクリアテキストパスワード文字列"mypassword"を保存する場合、パスワード文字列の先頭にTEXT接頭辞を追加します。 -例えば、TEXTmypasswordとなります。 + + もし同票で、2つ以上のグループで同じノード数だった場合は、メインノード(最も若いDBノード番号のバックエンドノード)を含むグループが優先されます。 + + + + + デフォルトはoffです。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + replicate_select (boolean) + + + replicate_select 設定パラメータ + + + + + + onを設定すると、Pgpool-IIはSELECTクエリのレプリケーションモードを有効にします。 + すなわち、SELECTクエリが全てのバックエンドノードに送信されます。 + + + + + replicate_selectと<xref linkend="guc-load-balance-mode">がSELECTのルーティングに与える影響 + + + + + + + + + + + + replicate_selectがtrue + Y + N + + + + + load_balance_modeがtrue + ANY + Y + N + + + + + SELECTがトランザクションブロックの内部にある + ANY + Y + N + ANY + + + + + + トランザクション分離レベルがSERIALIZABLEで、トランザクションが更新クエリを発行済 + + ANY + Y + N + ANY + ANY + + + + + + 結果(R:レプリケーション、M:メインのみに送信、L:負荷分散) + + R + M + L + L + M + + + + +
+ + + + デフォルトはoffです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + +
+
+ + + insert_lock (boolean) + + + insert_lock 設定パラメータ + + + + + + onに設定すると、Pgpool-IIはINSERT文が発行される前にPostgreSQL上のテーブルを自動的にロックします。 + + + + + SERIAL型を使っているテーブルをレプリケーションすると、SERIAL型の列の値がDBノードの間で一致しなくなることがあります。 + この問題の回避策は、INSERT実行前に該当テーブルを明示的にロックすることです。 + + + + テーブルの自動ロックのため、Pgpool-IIは以下の変換を行います。 + + INSERT INTO ... + + + これを次のように変換します。 + + + BEGIN; + LOCK TABLE ... + INSERT INTO ... + COMMIT; + + + - -同様に、md5ハッシュパスワードはmd5接頭辞、AES256暗号化パスワード形式はAES接頭辞を使って保存することができます。 -AES256暗号化パスワードの詳細は、を参照してください。 + + この方法はトランザクションの並列実行性を大きく劣化させます。 - + + + + + Pgpool-II V2.2以降では、テーブルがSERIAL列を持つかどうか自動判別するため、SERIAL列がなければ決してテーブルをロックしません。 + + + + + Pgpool-II V3.0.4までのPgpool-II V3.0では、テーブルロックではなくシーケンステーブルに対して行ロックをかけます。 + これはVACUUM(autovacuumを含む)とのロック競合を最小化することを意図しています。 + しかし、これは他の問題を引き起こします。 + トランザクション周回が起きた後、シーケンステーブルに対する行ロックはPostgreSQLの内部エラー (詳細には、トランザクション状態を保持するpg_clogへのアクセスエラー)を起こします。 + これを防ぐため、PostgreSQLのコア開発者はシーケンステーブルに対する行ロックを許可しないことを決定しました。 + これはもちろんPgpool-IIを動作不能にします(修正されたPostgreSQLはバージョン 9.0.5, 8.4.9, 8.3.16そして8.2.22としてリリースされました)。 + + + + + + Pgpool-II V3.0.5以降では、新しいPostgreSQLがシーケンステーブルに対するロックを許可しなくなったため、pgpool_catalog.insert_lockテーブルに対して行ロックをかけます。 + したがって、Pgpool-II経由でアクセスするすべてのデータベースにinsert_lockテーブルをあらかじめ作成しておく必要があります。 + 詳細はをご覧ください。 + もし、insert_lockテーブルが存在しない場合は、挿入対象のテーブルに対してロックを行います。 + これは、Pgpool-II V2.2V2.3シリーズと同じ動作です。 + + + + 過去のバージョンと互換性のあるinsert_lockを使用したい場合は、configureスクリプトでロック方法を指定できます。 + 詳細はをご覧下さい。 + + + + + (文ごとの)細かい制御: + + + + + + + insert_lockをtrueにして、テーブルロックを獲得してほしくないINSERT文には、先頭に/*NO INSERT LOCK*/コメントを追加します。 + + + + + + insert_lockをfalseにして、テーブルロックを獲得してほしいINSERT文には、先頭に/*INSERT LOCK*/コメントを追加します。 + + + + + - -有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 + + insert_lockを有効にしてregression testを実行すると、PostgreSQL 8.0では transactions, privileges, rules, alter_tableがfailします。 - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - allow_clear_text_frontend_auth (boolean) - - allow_clear_text_frontend_auth configuration parameter - - - - - -PostgreSQLバックエンドサーバはあるユーザの認証に対してmd5またはSCRAM認証を必要としており、そのユーザのパスワードが"pool_passwd"ファイルに存在しない場合、allow_clear_text_frontend_authPgpool-IIがフロントエンドクライアントとクリアテキストパスワード認証を行い、クライアントから平文形式のパスワードを取得しバックエンド認証のために使用することを許可します。 - - - - -デフォルトはfalseです。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - -allow_clear_text_frontend_authが有効でない場合のみ機能します。 - - - - - - - authentication_timeout (integer) - - - authentication_timeout 設定パラメータ - - - - - -Pgpool-IIの認証処理のタイムアウト時間を秒単位で指定します。 -0 を指定するとタイムアウトを無効にします。 -デフォルト値は60です。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - -
- -
-
- - - - 動作モード - - - - マスタースレーブモード - - - -このモードはPgpool-IIと(Slony-Iやストリームレプリケーションのような)他のマスター/スレーブ型のレプリケーションソフトウェアと組み合わせるのに使用されます。 -実際にデータレプリケーションを行うのはこれらのソフトウェアに任されます。 - - - - - -スレーブノードの数は1つに限定されず、Pgpool-IIは127個までのスレーブノードを持つことができます。 -マスタースレーブモードは、スレーブノードが1つも存在しない場合マスターノードのみを動作させることができます。 - - - - - -参照負荷をスタンバイバックエンドノードに振り分ける負荷分散(を参照)もマスタースレーブモードと共に使用可能です。 - - - -マスタースレーブモードでは以下のオプションを設定する必要があります。 - - - - - - master_slave_mode (boolean) - - - master_slave_mode 設定パラメータ - - - - - -マスタースレーブモードを有効にします。 -デフォルトはoffです。 - - - - -は相互に排他的で、一度に一方しか有効にすることができません。 - - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - master_slave_sub_mode (enum) - - - master_slave_sub_mode 設定パラメータ - - - - - -PostgreSQLノード間のデータレプリケーションに用いる外部のレプリケーションシステムを指定します。 -以下の表にこのパラメータで有効な値のリストを示します。 - - - - - - master_slave_sub_modeオプション - - - - - - 説明 - - - - - - 'slony' - - Slony-Iに適合 - - - - 'stream' - - PostgreSQLの組み込みレプリケーションシステム(ストリーミングレプリケーション)に適合 - - - - 'logical' - - PostgreSQLの組み込みレプリケーションシステム(ロジカルレプリケーション)に適合 - - - - -
- - - -デフォルトは'slony'です。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - -
-
- -
-
- - - - レプリケーションモード - - - -このモードではPostgreSQL間のデータレプリケーションをPgpool-IIに行わせます。 - - - - -参照負荷をスタンバイバックエンドノードに振り分ける負荷分散(を参照)もレプリケーションモードと共に使用可能です。 - - - -以下のオプションがレプリケーションモードにおけるPgpool-IIの動作に影響します。 - - - - - - replication_mode (boolean) - - - replication_mode 設定パラメータ - - - - - -レプリケーションモードを有効にします。 -デフォルトはoffです。 - - - - -は相互に排他的で、一度に一方しか有効にすることができません。 - - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - replication_stop_on_mismatch (boolean) - - - replication_stop_on_mismatch 設定パラメータ - - - - - - -これがonで、全てのPostgreSQLバックエンドノードに送られたクエリに対して、全てのノードが同じパケット種類で応答しなかった場合、多数派とは異なる応答したバックエンドノードはPgpool-IIにより切り離されます。 -replication_stop_on_mismatchがoffの場合に同様の状況が発生したときには、Pgpool-IIは現在のユーザセッションを強制終了するだけにとどめ、バックエンドの切り離しは行いません。 - - - - - - -Pgpool-IIはバックエンドから返されたデータは調べずに、結果パケットの種類の比較のみにより決断します。 - - - - - -replication_stop_on_mismatchを有効にする典型的なユースケースは、バックエンドノード間のデータ不整合の防止です。 -例えば、UPDATE文が他のノードでは成功しているのにあるバックエンドノードでは失敗した場合、そのバックエンドノードを切り離したいかもしれません。 - - - -デフォルトはoffです。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - failover_if_affected_tuples_mismatch (boolean) - - - failover_if_affected_tuples_mismatch 設定パラメータ - - - - - -これがonで、全てのノードの応答でINSERT/UPDATE/DELETEクエリの影響を受けたタプルの数が同じでなかった場合、多数派とは異なる応答したバックエンドノードはPgpool-IIによる切り離されます。 -failover_if_affected_tuples_mismatchがoffの場合に同様の状況が発生したときには、Pgpool-IIは現在のユーザセッションを強制終了するだけにとどめ、バックエンドの切り離しは行いません。 - - - - - -もし同票で、2つ以上のグループで同じノード数だった場合は、マスターノード(最も若いDBノード番号のバックエンドノード)を含むグループが優先されます。 - - - - - -デフォルトはoffです。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - replicate_select (boolean) - - - replicate_select 設定パラメータ - - - - - -onを設定すると、Pgpool-IIはSELECTクエリのレプリケーションモードを有効にします。 -すなわち、SELECTクエリが全てのバックエンドノードに送信されます。 - - - - - replicate_selectと<xref linkend="guc-load-balance-mode">がSELECTのルーティングに与える影響 - - - - - - - - - - - - replicate_selectがtrue - Y - N - - - - - load_balance_modeがtrue - ANY - Y - N - - - - - SELECTがトランザクションブロックの内部にある - ANY - Y - N - ANY - - - - - - トランザクション分離レベルがSERIALIZABLEで、トランザクションが更新クエリを発行済 - - ANY - Y - N - ANY - ANY - - - - - - 結果(R:レプリケーション、M:マスターのみに送信、L:負荷分散) - - R - M - L - L - M - - - - -
- - - -デフォルトはoffです。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - -
-
- - - insert_lock (boolean) - - - insert_lock 設定パラメータ - - - - - -onに設定すると、Pgpool-IIはINSERT文が発行される前にPostgreSQL上のテーブルを自動的にロックします。 - - - - -SERIAL型を使っているテーブルをレプリケーションすると、SERIAL型の列の値がDBノードの間で一致しなくなることがあります。 -この問題の回避策は、INSERT実行前に該当テーブルを明示的にロックすることです。 - - - -テーブルの自動ロックのため、Pgpool-IIは以下の変換を行います。 - -INSERT INTO ... - - -これを次のように変換します。 - - -BEGIN; -LOCK TABLE ... -INSERT INTO ... -COMMIT; - - - - - -この方法はトランザクションの並列実行性を大きく劣化させます。 - - - - - -Pgpool-II V2.2以降では、テーブルがSERIAL列を持つかどうか自動判別するため、SERIAL列がなければ決してテーブルをロックしません。 - - - - -Pgpool-II V3.0.4までのPgpool-II V3.0では、テーブルロックではなくシーケンステーブルに対して行ロックをかけます。 -これはVACUUM(autovacuumを含む)とのロック競合を最小化することを意図しています。 -しかし、これは他の問題を引き起こします。 -トランザクション周回が起きた後、シーケンステーブルに対する行ロックはPostgreSQLの内部エラー (詳細には、トランザクション状態を保持するpg_clogへのアクセスエラー)を起こします。 -これを防ぐため、PostgreSQLのコア開発者はシーケンステーブルに対する行ロックを許可しないことを決定しました。 -これはもちろんPgpool-IIを動作不能にします(修正されたPostgreSQLはバージョン 9.0.5, 8.4.9, 8.3.16そして8.2.22としてリリースされました)。 - - - - - -Pgpool-II V3.0.5以降では、新しいPostgreSQLがシーケンステーブルに対するロックを許可しなくなったため、pgpool_catalog.insert_lockテーブルに対して行ロックをかけます。 -したがって、Pgpool-II経由でアクセスするすべてのデータベースにinsert_lockテーブルをあらかじめ作成しておく必要があります。 -詳細はをご覧ください。 -もし、insert_lockテーブルが存在しない場合は、挿入対象のテーブルに対してロックを行います。 -これは、Pgpool-II V2.2V2.3シリーズと同じ動作です。 - - - -過去のバージョンと互換性のあるinsert_lockを使用したい場合は、configureスクリプトでロック方法を指定できます。 -詳細はをご覧下さい。 - - - - -(文ごとの)細かい制御: - - - - - - -insert_lockをtrueにして、テーブルロックを獲得してほしくないINSERT文には、先頭に/*NO INSERT LOCK*/コメントを追加します。 - - - - - -insert_lockをfalseにして、テーブルロックを獲得してほしいINSERT文には、先頭に/*INSERT LOCK*/コメントを追加します。 - - - - - - - -insert_lockを有効にしてregression testを実行すると、PostgreSQL 8.0では transactions, privileges, rules, alter_tableがfailします。 - - - -その理由は、ruleテストでPgpool-IIがビューにLOCKを実行しようとするため、そして以下のエラーメッセージが出てしまうためです。 - -! ERROR: current transaction is aborted, commands ignored until -end of transaction block - - -たとえば、transactionsテストでは、存在しないテーブルに対してINSERTを試みており、Pgpool-IIPostgerSQLにそのテーブルのロックを獲得させることになります。 -これはもちろんエラーとなります。 -トランザクションがアボート状態になり、続くINSERTでは上記エラーが出てしまいます。 - - - - -デフォルトはoffです。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - lobj_lock_table (string) - - - lobj_lock_table 設定パラメータ - - - - - -ラージオブジェクトのレプリケーションを行いたいときにロック管理に使うためのテーブル名を指定します。 -このテーブルが指定されている場合、Pgpool-IIは、lobj_lock_tableで指定されているテーブルをロックした後、pg_largeobjectシステムカタログを参照してラージオブジェクトIDを生成し、lo_create()を呼び出してラージオブジェクトの作成を行います。 -この方法により、レプリケーションモードにおいてPgpool-IIが全てのDBノードで同じラージオブジェクトIDを得られることが保証されます。 - - - - - -PostgreSQL 8.0以前はlo_createを持たないため、PostgreSQL 8.0以前のバージョンではこの処理は行われません。 - - - - -libpqの関数lo_creat()の呼び出しがこの機能の契機となります。 -Java API(JDBCドライバ)、PHP API(pg_lo_create、またはPDOといったPHPライブラリの同様のAPI)、様々なプログラミング言語の同様のAPIを経由したラージオブジェクトの生成においても同じプロトコルが使われることがわかっているので、この機能は動作するはずです。 - - - - -この機能はラージオブジェクトに対する以下の操作では動作しません。 - - - - - - - lo_createlo_import_with_oidを使う全てのAPI。 - - - - - - バックエンドのlo_import関数をSELECTで呼び出す場合 - - - - - - バックエンドのlo_create関数をSELECTで呼び出す場合 - - - - - - - -全てのPostgreSQLユーザはlobj_lock_tableへ書き込み可能である必要が有ります。 -また、これはどのスキーマに作成されてもかまいません。 - - - - - -ラージオブジェクトロックテーブルを作る例を示します。 - -CREATE TABLE public.my_lock_table (); -GRANT ALL ON public.my_lock_table TO PUBLIC; - - - - -デフォルトは''(空文字列)で、この機能は無効です。 - - - - -
-
+ + + その理由は、ruleテストでPgpool-IIがビューにLOCKを実行しようとするため、そして以下のエラーメッセージが出てしまうためです。 + + ! ERROR: current transaction is aborted, commands ignored until + end of transaction block + + + たとえば、transactionsテストでは、存在しないテーブルに対してINSERTを試みており、Pgpool-IIPostgreSQLにそのテーブルのロックを獲得させることになります。 + これはもちろんエラーとなります。 + トランザクションがアボート状態になり、続くINSERTでは上記エラーが出てしまいます。 + + + + + デフォルトはonです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + lobj_lock_table (string) + + + lobj_lock_table 設定パラメータ + + + + + + ラージオブジェクトのレプリケーションを行いたいときにロック管理に使うためのテーブル名を指定します。 + このテーブルが指定されている場合、Pgpool-IIは、lobj_lock_tableで指定されているテーブルをロックした後、pg_largeobjectシステムカタログを参照してラージオブジェクトIDを生成し、lo_create()を呼び出してラージオブジェクトの作成を行います。 + この方法により、レプリケーションモードにおいてPgpool-IIが全てのDBノードで同じラージオブジェクトIDを得られることが保証されます。 + + + + + + PostgreSQL 8.0以前はlo_createを持たないため、PostgreSQL 8.0以前のバージョンではこの処理は行われません。 + + + + + libpqの関数lo_creat()の呼び出しがこの機能の契機となります。 + Java API(JDBCドライバ)、PHP API(pg_lo_create、またはPDOといったPHPライブラリの同様のAPI)、様々なプログラミング言語の同様のAPIを経由したラージオブジェクトの生成においても同じプロトコルが使われることがわかっているので、この機能は動作するはずです。 + + + + + この機能はラージオブジェクトに対する以下の操作では動作しません。 + + + + + + + lo_createlo_import_with_oidを使う全てのAPI。 + + + + + + バックエンドのlo_import関数をSELECTで呼び出す場合 + + + + + + バックエンドのlo_create関数をSELECTで呼び出す場合 + + + + + + + + 全てのPostgreSQLユーザはlobj_lock_tableへ書き込み可能である必要が有ります。 + また、これはどのスキーマに作成されてもかまいません。 + + + + + + ラージオブジェクトロックテーブルを作る例を示します。 + + CREATE TABLE public.my_lock_table (); + GRANT ALL ON public.my_lock_table TO PUBLIC; + + + + + デフォルトは''(空文字列)で、この機能は無効です。 + + + + + + + + + スナップショットアイソレーションモード + + + このモードは、ネイティブレプリケーションモードと似ていますが、更にノードをまたがる可視性の一貫性を保証します。 + 実装は研究論文に基づいています。 + このモードを有効にするにはbackend_clustering_modeにsnapshot_isolationを設定してください。 + +backend_clustering_mode = snapshot_isolation + + たとえば、以下のようなノードにまたがる可視性の一貫性がないことからくるノード間のデータ不整合を防ぐことができます。 + ここで、S1, S2はセッションを表し、N1, N2はPostgreSQLのサーバ1と2を表します。 + +S1/N1: BEGIN; +S1/N2: BEGIN; +S1/N1: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N2: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N1: COMMIT; +S2/N1: BEGIN; +S2/N2: BEGIN; +S2/N2: DELETE FROM t1 WHERE i = 1; -- delete 1 row since S1/N2 is not committed yet +S2/N1: DELETE FROM t1 WHERE i = 1; -- delete no row since S1/N1 is committed and i is not 1 anymore +S1/N2: COMMIT; +S2/N1: COMMIT; +S2/N2: COMMIT; + + スナップショットアイソレーションモードでは、以下のどちらかとなり、いずれにしてもノード間のデータの一貫性は損なわれません。 + +S1/N1: BEGIN; +S1/N2: BEGIN; +S1/N1: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N2: UPDATE t1 SET i = i + 1; -- i = 1 +S2/N1: BEGIN; +S2/N2: BEGIN; +S1/N1: COMMIT; +S1/N2: COMMIT; +S2/N1: DELETE FROM t1 WHERE i = 1; -- delete no row since S1/N1 is committed and i is not 1 anymore +S2/N2: DELETE FROM t1 WHERE i = 1; -- delete no row since S1/N2 is committed and i is not 1 anymore +S2/N1: COMMIT; +S2/N2: COMMIT; + + + +S1/N1: BEGIN; +S1/N2: BEGIN; +S1/N1: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N2: UPDATE t1 SET i = i + 1; -- i = 1 +S2/N1: BEGIN; +S2/N2: BEGIN; +S2/N1: DELETE FROM t1 WHERE i = 1; -- delete 1 row since S1/N1 is not committed yet +S2/N2: DELETE FROM t1 WHERE i = 1; -- delete 1 row since S1/N2 is not committed yet +S1/N1: COMMIT; +S1/N2: COMMIT; +S2/N1: COMMIT; +S2/N2: COMMIT; + + + + + + + PostgreSQLのトランザクション分離レベルをREPEATABLE READにする必要があります。 + 具体的には、postgresql.confに以下のように記述します。 + + default_transaction_isolation = 'repeatable read' + + + + + + + + + ロジカルレプリケーションモード + + + このモードではPostgreSQLが個々のサーバをレプリケーションします。 + このモードを有効にするにはbackend_clustering_modeにlogical_replicationを設定してください。 + +backend_clustering_mode = logical_replication + + このモードでは127台までのロジカルレプリケーションサーバを使用できます。 + また、スタンバイサーバをまったく使用しないことも可能です。 + + + このモードの難点は、検索問い合わせを負荷分散させた時に、スタンバイサーバのレプリケーション遅延を意識しなければならない点です。 + ノードをまたがる可視性の一貫性も保証されません。 + また、DDLやラージオブジェクトなど、一部のデータオブジェクトはレプリケーションされません。 + + + + + rawモード + + このモードでは、Pgpool-IIはデータベースの同期に関しては関与しません。 + システム全体に意味の有る動作をさせるのはユーザの責任となります。 + このモードでは負荷分散はできません。 + このモードを有効にするにはbackend_clustering_modeにrawを設定してください。 + +backend_clustering_mode = raw + + +
- - バックエンドの設定 - - - - バックエンド接続の設定 - - - - - backend_hostname (string) - - - backend_hostname 設定パラメータ - - - - - - -backend_hostnameには接続先のPostgreSQLバックエンドを指定します。 -Pgpool-IIがサーバと通信するのに使われます。 - - - - -TCP/IP通信では、このパラメータはホスト名またはIPアドレスをとることができます。 -スラッシュ(/)で始まる場合、TCP/IPではなくUNIXドメインでの通信が使用され、値はソケットファイルが作成されるディレクトリ名となります。 -backend_hostnameに空文字('')が指定された場合のデフォルトの動作は、/tmpに作成したUNIXドメインソケットで接続します。 - - - - -パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_hostname0)。 -この数字のことを「DBノードID」と呼び、0から開始します。 -DBノードIDが0のバックエンドは「マスターノード」と呼ばれます。 -複数のDBノードを定義している場合、条件によってはマスターノードがダウンしても運用を続けることができます(いくつかのモードを除きます)。 -この場合は、稼働中かつDBノードIDがもっとも若いものが新しいマスターノードになります。 - - - - -ストリーミングレプリケーションモードで運用している場合は、DBノードIDが0のノードには特別な意味はないことに注意して下さい。 -むしろ、そのDBノードが「プライマリノード」かどうかを気にするべきです。 -詳細はをご覧ください。 - - - - -1台しかPostgreSQLを使用しない場合は、backend_hostname0で指定してください。 - - - - -新しいノードはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 -ただし、既存の値を変更することはできないので、その場合にはPgpool-IIを再起動してください。 - - - - - - - - backend_port (integer) - - - backend_port 設定パラメータ - - - - - - -backend_portにはバックエンドのポート番号を指定します。 -パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_port0)。 -1台しかPostgreSQLを使用しない場合は、backend_port0で指定してください。 - - - -新しいノードはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 -ただし、既存の値を変更することはできないので、その場合にはPgpool-IIを再起動してください。 - - - - - - - backend_weight (floating point) - - - backend_weight 設定パラメータ - - - - - - -backend_weightにはバックエンドの負荷分散の比率を指定します。 -0以上の整数または浮動小数点を指定できます。 -パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_weight0)。 -1台しかPostgreSQLを使用しない場合は、backend_weight0で指定してください。 - - - -新しいbackend_weightはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 -Pgpool-II V2.2.6、V2.3以降では、設定ファイルの再読込みで値を変更できます。 -ただし、この効果が反映されるのは新しく確立されたクライアントセッションからです。 -マスタースレーブモードにおいて、スレーブに対して管理業務を実施する都合上、問い合わせがそのスレーブに送られるのを防ぎたい場合に有用です。 - - - - - - - - - - バックエンドデータの設定 - - - - - backend_data_directory (string) - - - backend_data_directory 設定パラメータ - - - - - - -backend_data_directoryにはバックエンドのデータベースクラスタのディレクトリを指定します。 -パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_data_directory0)。 -1台しかPostgreSQLを使用しない場合は、backend_data_directory0で指定してください。 - 使用する PostgreSQL サーバのデータベースクラスタのパスを指定します。 実際には、"backend_data_directory"の後にDBノードIDを付加して使用する複数のPostgreSQLを区別します。 このパラメータはオンラインリカバリの際に使用します。 オンラインリカバリを使用しない場合には設定する必要はありません。 - - - -新しいbackend_data_directoryはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 -ただし、既存の値を変更することはできないので、その場合にはPgpool-IIを再起動してください。 - - - - - - backend_flag (string) - - - backend_flag 設定パラメータ - - - - - - -backend_flagはバックエンド単位での様々な挙動を制御するフラグです。 -パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_flag0)。 -1台しかPostgreSQLを使用しない場合は、backend_flag0で指定してください。 - - - -新しいバックエンドフラグはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 -現在以下のものがあります。 -複数のフラグを"|"で連結して指定することができます。 - - - - - バックエンドフラグ - - - - - フラグ - 説明 - - - - - - ALLOW_TO_FAILOVER - - フェイルオーバやデタッチが可能になります。 - これがデフォルトの動作です。 - DISALLOW_TO_FAILOVERと同時には指定できません。 - - - - DISALLOW_TO_FAILOVER - - フェイルオーバやデタッチを禁止します。 - HeartbeatやPacemakerなどのHA (High Availability)ソフトでバックエンドを保護しているなどの場合に有用です。 - ALLOW_TO_FAILOVERと同時には指定できません。 - - - - - - ALWAYS_MASTER - ストリーミングレプリケーションでのみ有効です。 - ストリーミングレプリケーションモードについてはをご覧ください。 - このフラグがバックエンドのどれかにセットされていると、Pgpool-IIはバックエンドにアクセスしてプライマリノードを探すのではなく、このフラグがセットされているノードをプライマリノードと見なします。 - これは、Amazon Aurora for PostgreSQL Compatibilityのような、マスターサーバに固定のホスト名が割り当てられるシステムで有用です。 - 設定例についてはをご覧ください。 - - - - - -
- - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - -
-
- -
- -
+ + バックエンドの設定 + + + + バックエンド接続の設定 + + + + + backend_hostname (string) + + + backend_hostname 設定パラメータ + + + + + + + backend_hostnameには接続先のPostgreSQLバックエンドを指定します。 + Pgpool-IIがサーバと通信するのに使われます。 + + + + + TCP/IP通信では、このパラメータはホスト名またはIPアドレスをとることができます。 + スラッシュ(/)で始まる場合、TCP/IPではなくUNIXドメインでの通信が使用され、値はソケットファイルが作成されるディレクトリ名となります。 + backend_hostnameに空文字('')が指定された場合のデフォルトの動作は、/tmpに作成したUNIXドメインソケットで接続します。 + + + + + パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_hostname0)。 + この数字のことを「DBノードID」と呼び、0から開始します。 + DBノードIDが0のバックエンドは「メインノード」と呼ばれます。 + 複数のDBノードを定義している場合、条件によってはメインノードがダウンしても運用を続けることができます(いくつかのモードを除きます)。 + この場合は、稼働中かつDBノードIDがもっとも若いものが新しいメインノードになります。 + + + + レプリケーション構成において、スタンバイ側が参照するprimary_conninfohostと、Pgpool-IIがプライマリノードを識別するbackend_hostnameは同じ値を指定する必要があります。 + たとえば、プライマリノードがbackend0(ホスト名host0)、スタンバイノードがbackend1でbackend_application_nameserver1の場合、backend1のpostgresql.confは次のように設定します。 + +primary_conninfo = 'host=host0 port=5432 user=postgres application_name=''server1''' + + この場合、backend0に対応するbackend_hostnamehost0に設定してください。 + 一致していない場合Pgpool-IIがプライマリノードを識別できずストリーミングレプリケーションチェックなどがうまく動作しないことがあります。 + + + + + ストリーミングレプリケーションモードで運用している場合は、DBノードIDが0のノードには特別な意味はないことに注意して下さい。 + むしろ、そのDBノードが「プライマリノード」かどうかを気にするべきです。 + 詳細はをご覧ください。 + + + + + 1台しかPostgreSQLを使用しない場合は、backend_hostname0で指定してください。 + + + + + 新しいノードはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 + ただし、既存の値を変更することはできないので、その場合にはPgpool-IIを再起動してください。 + + + + + + + + backend_port (integer) + + + backend_port 設定パラメータ + + + + + + + backend_portにはバックエンドのポート番号を指定します。 + パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_port0)。 + 1台しかPostgreSQLを使用しない場合は、backend_port0で指定してください。 + + + + 新しいノードはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 + ただし、既存の値を変更することはできないので、その場合にはPgpool-IIを再起動してください。 + + + + + + + backend_weight (floating point) + + + backend_weight 設定パラメータ + + + + + + + backend_weightにはバックエンドの負荷分散の比率を指定します。 + 0以上の整数または浮動小数点を指定できます。 + パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_weight0)。 + 1台しかPostgreSQLを使用しない場合は、backend_weight0で指定してください。 + + + + 新しいbackend_weightはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 + Pgpool-II V2.2.6、V2.3以降では、設定ファイルの再読込みで値を変更できます。 + ただし、この効果が反映されるのは新しく確立されたクライアントセッションからです。 + ストリーミングレプリケーションモード、ロジカルレプリケーションモード、slonyモードにおいて、スタンバイに対して管理業務を実施する都合上、問い合わせがそのスタンバイに送られるのを防ぎたい場合に有用です。 + + + + + + + + + + バックエンドデータの設定 + + + + + backend_data_directory (string) + + + backend_data_directory 設定パラメータ + + + + + + + backend_data_directoryにはバックエンドのデータベースクラスタのディレクトリを指定します。 + パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_data_directory0)。 + 1台しかPostgreSQLを使用しない場合は、backend_data_directory0で指定してください。 + このパラメータはオンラインリカバリの際に使用します。 オンラインリカバリを使用しない場合には設定する必要はありません。 + + + + 新しいbackend_data_directoryはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 + ただし、既存の値を変更することはできないので、その場合にはPgpool-IIを再起動してください。 + + + + + + backend_flag (string) + + + backend_flag 設定パラメータ + + + + + + + backend_flagはバックエンド単位での様々な挙動を制御するフラグです。 + パラメータ名の末尾に数字を付加することで複数のバックエンドを指定することができます(たとえばbackend_flag0)。 + 1台しかPostgreSQLを使用しない場合は、backend_flag0で指定してください。 + + + + 新しいバックエンドフラグはパラメータ行を追加して、設定ファイル再読み込みすることで追加できます。 + 現在以下のものがあります。 + 複数のフラグを"|"で連結して指定することができます。 + + + + + バックエンドフラグ + + + + + フラグ + 説明 + + + + + + ALLOW_TO_FAILOVER + + フェイルオーバやデタッチが可能になります。 + これがデフォルトの動作です。 + DISALLOW_TO_FAILOVERと同時には指定できません。 + + + + DISALLOW_TO_FAILOVER + + フェイルオーバやデタッチを禁止します。 + HeartbeatやPacemakerなどのHA (High Availability)ソフトでバックエンドを保護しているなどの場合に有用です。 + ALLOW_TO_FAILOVERと同時には指定できません。 + + + + + + ALWAYS_PRIMARY + ストリーミングレプリケーションでのみ有効です。 + ストリーミングレプリケーションモードについてはをご覧ください。 + このフラグがバックエンドのどれかにセットされていると、Pgpool-IIはバックエンドにアクセスしてプライマリノードを探すのではなく、このフラグがセットされているノードをプライマリノードと見なします。 + これは、Amazon Aurora for PostgreSQL Compatibilityのような、プライマリサーバに固定のホスト名が割り当てられるシステムで有用です。 + 設定例についてはをご覧ください。 + + + + + +
+ + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + +
+
+ + backend_application_name (string) + + backend_application_name configuration parameter + + + + + + backend_application_nameはWAL logをプライマリサーバから読み込むwalreceiverのために使用するapplication_nameを設定します。 + ですから、ストリーミングレプリケーションモード以外では設定する必要がありません。 + また、このパラメータはコマンド中に表示される"replication_state"と"replication_sync_state"のために使用されます。 + 更に、もこのパラメータを必要とします。 + + + たとえば、プライマリノードがbackend0(そのホスト名は"host0"とします)、スタンバイノードはbackend1で、backend1のbackend_application_nameは"server1"であるとします。 + すると、postgresql.confprimary_conninfoパラメータは次のようになるはずです。 + +primary_conninfo = 'host=host0 port=5432 user=postgres application_name=''server1''' + + がそのパラメータを生成します。 + コマンドの完全な例に関しては、をご覧ください。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + +
+ +
diff --git a/doc.ja/src/sgml/errcodes-table.sgml b/doc.ja/src/sgml/errcodes-table.sgml index 1c518cf64..5d6a6860c 100644 --- a/doc.ja/src/sgml/errcodes-table.sgml +++ b/doc.ja/src/sgml/errcodes-table.sgml @@ -2,1370 +2,1370 @@ -Class 00 — Successful Completion + Class 00 — Successful Completion -00000 -successful_completion + 00000 + successful_completion -Class 01 — Warning + Class 01 — Warning -01000 -warning + 01000 + warning -0100C -dynamic_result_sets_returned + 0100C + dynamic_result_sets_returned -01008 -implicit_zero_bit_padding + 01008 + implicit_zero_bit_padding -01003 -null_value_eliminated_in_set_function + 01003 + null_value_eliminated_in_set_function -01007 -privilege_not_granted + 01007 + privilege_not_granted -01006 -privilege_not_revoked + 01006 + privilege_not_revoked -01004 -string_data_right_truncation + 01004 + string_data_right_truncation -01P01 -deprecated_feature + 01P01 + deprecated_feature -Class 02 — No Data (this is also a warning class per the SQL standard) + Class 02 — No Data (this is also a warning class per the SQL standard) -02000 -no_data + 02000 + no_data -02001 -no_additional_dynamic_result_sets_returned + 02001 + no_additional_dynamic_result_sets_returned -Class 03 — SQL Statement Not Yet Complete + Class 03 — SQL Statement Not Yet Complete -03000 -sql_statement_not_yet_complete + 03000 + sql_statement_not_yet_complete -Class 08 — Connection Exception + Class 08 — Connection Exception -08000 -connection_exception + 08000 + connection_exception -08003 -connection_does_not_exist + 08003 + connection_does_not_exist -08006 -connection_failure + 08006 + connection_failure -08001 -sqlclient_unable_to_establish_sqlconnection + 08001 + sqlclient_unable_to_establish_sqlconnection -08004 -sqlserver_rejected_establishment_of_sqlconnection + 08004 + sqlserver_rejected_establishment_of_sqlconnection -08007 -transaction_resolution_unknown + 08007 + transaction_resolution_unknown -08P01 -protocol_violation + 08P01 + protocol_violation -Class 09 — Triggered Action Exception + Class 09 — Triggered Action Exception -09000 -triggered_action_exception + 09000 + triggered_action_exception -Class 0A — Feature Not Supported + Class 0A — Feature Not Supported -0A000 -feature_not_supported + 0A000 + feature_not_supported -Class 0B — Invalid Transaction Initiation + Class 0B — Invalid Transaction Initiation -0B000 -invalid_transaction_initiation + 0B000 + invalid_transaction_initiation -Class 0F — Locator Exception + Class 0F — Locator Exception -0F000 -locator_exception + 0F000 + locator_exception -0F001 -invalid_locator_specification + 0F001 + invalid_locator_specification -Class 0L — Invalid Grantor + Class 0L — Invalid Grantor -0L000 -invalid_grantor + 0L000 + invalid_grantor -0LP01 -invalid_grant_operation + 0LP01 + invalid_grant_operation -Class 0P — Invalid Role Specification + Class 0P — Invalid Role Specification -0P000 -invalid_role_specification + 0P000 + invalid_role_specification -Class 0Z — Diagnostics Exception + Class 0Z — Diagnostics Exception -0Z000 -diagnostics_exception + 0Z000 + diagnostics_exception -0Z002 -stacked_diagnostics_accessed_without_active_handler + 0Z002 + stacked_diagnostics_accessed_without_active_handler -Class 20 — Case Not Found + Class 20 — Case Not Found -20000 -case_not_found + 20000 + case_not_found -Class 21 — Cardinality Violation + Class 21 — Cardinality Violation -21000 -cardinality_violation + 21000 + cardinality_violation -Class 22 — Data Exception + Class 22 — Data Exception -22000 -data_exception + 22000 + data_exception -2202E -array_subscript_error + 2202E + array_subscript_error -22021 -character_not_in_repertoire + 22021 + character_not_in_repertoire -22008 -datetime_field_overflow + 22008 + datetime_field_overflow -22012 -division_by_zero + 22012 + division_by_zero -22005 -error_in_assignment + 22005 + error_in_assignment -2200B -escape_character_conflict + 2200B + escape_character_conflict -22022 -indicator_overflow + 22022 + indicator_overflow -22015 -interval_field_overflow + 22015 + interval_field_overflow -2201E -invalid_argument_for_logarithm + 2201E + invalid_argument_for_logarithm -22014 -invalid_argument_for_ntile_function + 22014 + invalid_argument_for_ntile_function -22016 -invalid_argument_for_nth_value_function + 22016 + invalid_argument_for_nth_value_function -2201F -invalid_argument_for_power_function + 2201F + invalid_argument_for_power_function -2201G -invalid_argument_for_width_bucket_function + 2201G + invalid_argument_for_width_bucket_function -22018 -invalid_character_value_for_cast + 22018 + invalid_character_value_for_cast -22007 -invalid_datetime_format + 22007 + invalid_datetime_format -22019 -invalid_escape_character + 22019 + invalid_escape_character -2200D -invalid_escape_octet + 2200D + invalid_escape_octet -22025 -invalid_escape_sequence + 22025 + invalid_escape_sequence -22P06 -nonstandard_use_of_escape_character + 22P06 + nonstandard_use_of_escape_character -22010 -invalid_indicator_parameter_value + 22010 + invalid_indicator_parameter_value -22023 -invalid_parameter_value + 22023 + invalid_parameter_value -2201B -invalid_regular_expression + 2201B + invalid_regular_expression -2201W -invalid_row_count_in_limit_clause + 2201W + invalid_row_count_in_limit_clause -2201X -invalid_row_count_in_result_offset_clause + 2201X + invalid_row_count_in_result_offset_clause -22009 -invalid_time_zone_displacement_value + 22009 + invalid_time_zone_displacement_value -2200C -invalid_use_of_escape_character + 2200C + invalid_use_of_escape_character -2200G -most_specific_type_mismatch + 2200G + most_specific_type_mismatch -22004 -null_value_not_allowed + 22004 + null_value_not_allowed -22002 -null_value_no_indicator_parameter + 22002 + null_value_no_indicator_parameter -22003 -numeric_value_out_of_range + 22003 + numeric_value_out_of_range -22026 -string_data_length_mismatch + 22026 + string_data_length_mismatch -22001 -string_data_right_truncation + 22001 + string_data_right_truncation -22011 -substring_error + 22011 + substring_error -22027 -trim_error + 22027 + trim_error -22024 -unterminated_c_string + 22024 + unterminated_c_string -2200F -zero_length_character_string + 2200F + zero_length_character_string -22P01 -floating_point_exception + 22P01 + floating_point_exception -22P02 -invalid_text_representation + 22P02 + invalid_text_representation -22P03 -invalid_binary_representation + 22P03 + invalid_binary_representation -22P04 -bad_copy_file_format + 22P04 + bad_copy_file_format -22P05 -untranslatable_character + 22P05 + untranslatable_character -2200L -not_an_xml_document + 2200L + not_an_xml_document -2200M -invalid_xml_document + 2200M + invalid_xml_document -2200N -invalid_xml_content + 2200N + invalid_xml_content -2200S -invalid_xml_comment + 2200S + invalid_xml_comment -2200T -invalid_xml_processing_instruction + 2200T + invalid_xml_processing_instruction -Class 23 — Integrity Constraint Violation + Class 23 — Integrity Constraint Violation -23000 -integrity_constraint_violation + 23000 + integrity_constraint_violation -23001 -restrict_violation + 23001 + restrict_violation -23502 -not_null_violation + 23502 + not_null_violation -23503 -foreign_key_violation + 23503 + foreign_key_violation -23505 -unique_violation + 23505 + unique_violation -23514 -check_violation + 23514 + check_violation -23P01 -exclusion_violation + 23P01 + exclusion_violation -Class 24 — Invalid Cursor State + Class 24 — Invalid Cursor State -24000 -invalid_cursor_state + 24000 + invalid_cursor_state -Class 25 — Invalid Transaction State + Class 25 — Invalid Transaction State -25000 -invalid_transaction_state + 25000 + invalid_transaction_state -25001 -active_sql_transaction + 25001 + active_sql_transaction -25002 -branch_transaction_already_active + 25002 + branch_transaction_already_active -25008 -held_cursor_requires_same_isolation_level + 25008 + held_cursor_requires_same_isolation_level -25003 -inappropriate_access_mode_for_branch_transaction + 25003 + inappropriate_access_mode_for_branch_transaction -25004 -inappropriate_isolation_level_for_branch_transaction + 25004 + inappropriate_isolation_level_for_branch_transaction -25005 -no_active_sql_transaction_for_branch_transaction + 25005 + no_active_sql_transaction_for_branch_transaction -25006 -read_only_sql_transaction + 25006 + read_only_sql_transaction -25007 -schema_and_data_statement_mixing_not_supported + 25007 + schema_and_data_statement_mixing_not_supported -25P01 -no_active_sql_transaction + 25P01 + no_active_sql_transaction -25P02 -in_failed_sql_transaction + 25P02 + in_failed_sql_transaction -Class 26 — Invalid SQL Statement Name + Class 26 — Invalid SQL Statement Name -26000 -invalid_sql_statement_name + 26000 + invalid_sql_statement_name -Class 27 — Triggered Data Change Violation + Class 27 — Triggered Data Change Violation -27000 -triggered_data_change_violation + 27000 + triggered_data_change_violation -Class 28 — Invalid Authorization Specification + Class 28 — Invalid Authorization Specification -28000 -invalid_authorization_specification + 28000 + invalid_authorization_specification -28P01 -invalid_password + 28P01 + invalid_password -Class 2B — Dependent Privilege Descriptors Still Exist + Class 2B — Dependent Privilege Descriptors Still Exist -2B000 -dependent_privilege_descriptors_still_exist + 2B000 + dependent_privilege_descriptors_still_exist -2BP01 -dependent_objects_still_exist + 2BP01 + dependent_objects_still_exist -Class 2D — Invalid Transaction Termination + Class 2D — Invalid Transaction Termination -2D000 -invalid_transaction_termination + 2D000 + invalid_transaction_termination -Class 2F — SQL Routine Exception + Class 2F — SQL Routine Exception -2F000 -sql_routine_exception + 2F000 + sql_routine_exception -2F005 -function_executed_no_return_statement + 2F005 + function_executed_no_return_statement -2F002 -modifying_sql_data_not_permitted + 2F002 + modifying_sql_data_not_permitted -2F003 -prohibited_sql_statement_attempted + 2F003 + prohibited_sql_statement_attempted -2F004 -reading_sql_data_not_permitted + 2F004 + reading_sql_data_not_permitted -Class 34 — Invalid Cursor Name + Class 34 — Invalid Cursor Name -34000 -invalid_cursor_name + 34000 + invalid_cursor_name -Class 38 — External Routine Exception + Class 38 — External Routine Exception -38000 -external_routine_exception + 38000 + external_routine_exception -38001 -containing_sql_not_permitted + 38001 + containing_sql_not_permitted -38002 -modifying_sql_data_not_permitted + 38002 + modifying_sql_data_not_permitted -38003 -prohibited_sql_statement_attempted + 38003 + prohibited_sql_statement_attempted -38004 -reading_sql_data_not_permitted + 38004 + reading_sql_data_not_permitted -Class 39 — External Routine Invocation Exception + Class 39 — External Routine Invocation Exception -39000 -external_routine_invocation_exception + 39000 + external_routine_invocation_exception -39001 -invalid_sqlstate_returned + 39001 + invalid_sqlstate_returned -39004 -null_value_not_allowed + 39004 + null_value_not_allowed -39P01 -trigger_protocol_violated + 39P01 + trigger_protocol_violated -39P02 -srf_protocol_violated + 39P02 + srf_protocol_violated -Class 3B — Savepoint Exception + Class 3B — Savepoint Exception -3B000 -savepoint_exception + 3B000 + savepoint_exception -3B001 -invalid_savepoint_specification + 3B001 + invalid_savepoint_specification -Class 3D — Invalid Catalog Name + Class 3D — Invalid Catalog Name -3D000 -invalid_catalog_name + 3D000 + invalid_catalog_name -Class 3F — Invalid Schema Name + Class 3F — Invalid Schema Name -3F000 -invalid_schema_name + 3F000 + invalid_schema_name -Class 40 — Transaction Rollback + Class 40 — Transaction Rollback -40000 -transaction_rollback + 40000 + transaction_rollback -40002 -transaction_integrity_constraint_violation + 40002 + transaction_integrity_constraint_violation -40001 -serialization_failure + 40001 + serialization_failure -40003 -statement_completion_unknown + 40003 + statement_completion_unknown -40P01 -deadlock_detected + 40P01 + deadlock_detected -Class 42 — Syntax Error or Access Rule Violation + Class 42 — Syntax Error or Access Rule Violation -42000 -syntax_error_or_access_rule_violation + 42000 + syntax_error_or_access_rule_violation -42601 -syntax_error + 42601 + syntax_error -42501 -insufficient_privilege + 42501 + insufficient_privilege -42846 -cannot_coerce + 42846 + cannot_coerce -42803 -grouping_error + 42803 + grouping_error -42P20 -windowing_error + 42P20 + windowing_error -42P19 -invalid_recursion + 42P19 + invalid_recursion -42830 -invalid_foreign_key + 42830 + invalid_foreign_key -42602 -invalid_name + 42602 + invalid_name -42622 -name_too_long + 42622 + name_too_long -42939 -reserved_name + 42939 + reserved_name -42804 -datatype_mismatch + 42804 + datatype_mismatch -42P18 -indeterminate_datatype + 42P18 + indeterminate_datatype -42P21 -collation_mismatch + 42P21 + collation_mismatch -42P22 -indeterminate_collation + 42P22 + indeterminate_collation -42809 -wrong_object_type + 42809 + wrong_object_type -42703 -undefined_column + 42703 + undefined_column -42883 -undefined_function + 42883 + undefined_function -42P01 -undefined_table + 42P01 + undefined_table -42P02 -undefined_parameter + 42P02 + undefined_parameter -42704 -undefined_object + 42704 + undefined_object -42701 -duplicate_column + 42701 + duplicate_column -42P03 -duplicate_cursor + 42P03 + duplicate_cursor -42P04 -duplicate_database + 42P04 + duplicate_database -42723 -duplicate_function + 42723 + duplicate_function -42P05 -duplicate_prepared_statement + 42P05 + duplicate_prepared_statement -42P06 -duplicate_schema + 42P06 + duplicate_schema -42P07 -duplicate_table + 42P07 + duplicate_table -42712 -duplicate_alias + 42712 + duplicate_alias -42710 -duplicate_object + 42710 + duplicate_object -42702 -ambiguous_column + 42702 + ambiguous_column -42725 -ambiguous_function + 42725 + ambiguous_function -42P08 -ambiguous_parameter + 42P08 + ambiguous_parameter -42P09 -ambiguous_alias + 42P09 + ambiguous_alias -42P10 -invalid_column_reference + 42P10 + invalid_column_reference -42611 -invalid_column_definition + 42611 + invalid_column_definition -42P11 -invalid_cursor_definition + 42P11 + invalid_cursor_definition -42P12 -invalid_database_definition + 42P12 + invalid_database_definition -42P13 -invalid_function_definition + 42P13 + invalid_function_definition -42P14 -invalid_prepared_statement_definition + 42P14 + invalid_prepared_statement_definition -42P15 -invalid_schema_definition + 42P15 + invalid_schema_definition -42P16 -invalid_table_definition + 42P16 + invalid_table_definition -42P17 -invalid_object_definition + 42P17 + invalid_object_definition -Class 44 — WITH CHECK OPTION Violation + Class 44 — WITH CHECK OPTION Violation -44000 -with_check_option_violation + 44000 + with_check_option_violation -Class 53 — Insufficient Resources + Class 53 — Insufficient Resources -53000 -insufficient_resources + 53000 + insufficient_resources -53100 -disk_full + 53100 + disk_full -53200 -out_of_memory + 53200 + out_of_memory -53300 -too_many_connections + 53300 + too_many_connections -53400 -configuration_limit_exceeded + 53400 + configuration_limit_exceeded -Class 54 — Program Limit Exceeded + Class 54 — Program Limit Exceeded -54000 -program_limit_exceeded + 54000 + program_limit_exceeded -54001 -statement_too_complex + 54001 + statement_too_complex -54011 -too_many_columns + 54011 + too_many_columns -54023 -too_many_arguments + 54023 + too_many_arguments -Class 55 — Object Not In Prerequisite State + Class 55 — Object Not In Prerequisite State -55000 -object_not_in_prerequisite_state + 55000 + object_not_in_prerequisite_state -55006 -object_in_use + 55006 + object_in_use -55P02 -cant_change_runtime_param + 55P02 + cant_change_runtime_param -55P03 -lock_not_available + 55P03 + lock_not_available -Class 57 — Operator Intervention + Class 57 — Operator Intervention -57000 -operator_intervention + 57000 + operator_intervention -57014 -query_canceled + 57014 + query_canceled -57P01 -admin_shutdown + 57P01 + admin_shutdown -57P02 -crash_shutdown + 57P02 + crash_shutdown -57P03 -cannot_connect_now + 57P03 + cannot_connect_now -57P04 -database_dropped + 57P04 + database_dropped -Class 58 — System Error (errors external to PostgreSQL itself) + Class 58 — System Error (errors external to PostgreSQL itself) -58000 -system_error + 58000 + system_error -58030 -io_error + 58030 + io_error -58P01 -undefined_file + 58P01 + undefined_file -58P02 -duplicate_file + 58P02 + duplicate_file -Class F0 — Configuration File Error + Class F0 — Configuration File Error -F0000 -config_file_error + F0000 + config_file_error -F0001 -lock_file_exists + F0001 + lock_file_exists -Class HV — Foreign Data Wrapper Error (SQL/MED) + Class HV — Foreign Data Wrapper Error (SQL/MED) -HV000 -fdw_error + HV000 + fdw_error -HV005 -fdw_column_name_not_found + HV005 + fdw_column_name_not_found -HV002 -fdw_dynamic_parameter_value_needed + HV002 + fdw_dynamic_parameter_value_needed -HV010 -fdw_function_sequence_error + HV010 + fdw_function_sequence_error -HV021 -fdw_inconsistent_descriptor_information + HV021 + fdw_inconsistent_descriptor_information -HV024 -fdw_invalid_attribute_value + HV024 + fdw_invalid_attribute_value -HV007 -fdw_invalid_column_name + HV007 + fdw_invalid_column_name -HV008 -fdw_invalid_column_number + HV008 + fdw_invalid_column_number -HV004 -fdw_invalid_data_type + HV004 + fdw_invalid_data_type -HV006 -fdw_invalid_data_type_descriptors + HV006 + fdw_invalid_data_type_descriptors -HV091 -fdw_invalid_descriptor_field_identifier + HV091 + fdw_invalid_descriptor_field_identifier -HV00B -fdw_invalid_handle + HV00B + fdw_invalid_handle -HV00C -fdw_invalid_option_index + HV00C + fdw_invalid_option_index -HV00D -fdw_invalid_option_name + HV00D + fdw_invalid_option_name -HV090 -fdw_invalid_string_length_or_buffer_length + HV090 + fdw_invalid_string_length_or_buffer_length -HV00A -fdw_invalid_string_format + HV00A + fdw_invalid_string_format -HV009 -fdw_invalid_use_of_null_pointer + HV009 + fdw_invalid_use_of_null_pointer -HV014 -fdw_too_many_handles + HV014 + fdw_too_many_handles -HV001 -fdw_out_of_memory + HV001 + fdw_out_of_memory -HV00P -fdw_no_schemas + HV00P + fdw_no_schemas -HV00J -fdw_option_name_not_found + HV00J + fdw_option_name_not_found -HV00K -fdw_reply_handle + HV00K + fdw_reply_handle -HV00Q -fdw_schema_not_found + HV00Q + fdw_schema_not_found -HV00R -fdw_table_not_found + HV00R + fdw_table_not_found -HV00L -fdw_unable_to_create_execution + HV00L + fdw_unable_to_create_execution -HV00M -fdw_unable_to_create_reply + HV00M + fdw_unable_to_create_reply -HV00N -fdw_unable_to_establish_connection + HV00N + fdw_unable_to_establish_connection -Class P0 — PL/pgSQL Error + Class P0 — PL/pgSQL Error -P0000 -plpgsql_error + P0000 + plpgsql_error -P0001 -raise_exception + P0001 + raise_exception -P0002 -no_data_found + P0002 + no_data_found -P0003 -too_many_rows + P0003 + too_many_rows -Class XX — Internal Error + Class XX — Internal Error -XX000 -internal_error + XX000 + internal_error -XX001 -data_corrupted + XX001 + data_corrupted -XX002 -index_corrupted + XX002 + index_corrupted diff --git a/doc.ja/src/sgml/example-AWS.sgml b/doc.ja/src/sgml/example-AWS.sgml new file mode 100644 index 000000000..9321cc910 --- /dev/null +++ b/doc.ja/src/sgml/example-AWS.sgml @@ -0,0 +1,476 @@ + + + + AWS設定の例 + + + このチュートリアルでは、AWS上でwatchdogを使う際の仮想IPの設定例を示します。 + + + AWSで仮想IPを設定するにはいくつかの方法があります。この設定例では、以下の2つの方法について説明します。 + + + + + Elastic IPアドレスの付け替え + + + + + + ルートテーブルの書き換え + + + + + + Elastic IPアドレスの付け替え + + この節では、Elastic IPアドレスを仮想IPとして使い、複数のEC2インスタンス間で付け替える方法を説明します。 + + + + AWSのセットアップ + + この方法を利用する場合は、Pgpool-II EC2インスタンスをパブリックサブネットに配置し、クライアントはインターネット経由でPgpool-IIに接続することを想定しています。 + この方法はMulti-AZ構成に対応しています。 + + + この設定例では、3ノードのPgpool-II(watchdog)クラスタを使います。 + そこで、3つのEC2インスタンスと、1つのElastic IPアドレスを作成します。 + + + 以下のステップを実施してください。 + + + + + + EC2インスタンスを3つ起動します。 + + + + + + これらのインスタンスのセキュリティグループを設定します。 + Pgpool-IIを動かすために必要な最低限の設定は、以下のように設定してください。 + + + + + + Pgpool-IIとwatchdogが使用するポートへのインバウンドトラフィックを許可します。 + + + + + Pgpool-II(watchdog)が仮想IPに対してpingを実行し疎通確認を行うため、Elastic IP(送信元)からのICMPトラフィックを許可します。 + + + + + + + + Pgpool-IIをすべてのインスタンスにインストールします。 + + + + + + AWSのEC2インスタンス上でAWSサービスを操作・管理するために、AWS CLIを使用します。 + すべてのPgpool-IIのインスタンスにAWS CLIをインストールします。 + + + また、Pgpool-IIの起動ユーザでAWS CLIを実行できるように、Pgpool-IIの起動ユーザでaws configureを実行し認証情報設定を行います。 + RPMからインストールした場合、デフォルトでPgpool-IIpostgresユーザで起動します。 + + + + + + Elastic IPアドレスを確保します。 + この設定例では、Elastic IPアドレスは"35.163.178.3"となります。 + + + + + + + <productname>Pgpool-II</productname>の設定 + + Pgpool-IIの設定を説明します。 + この設定例はとほとんど同じになりますが、を使ってElastic IPアドレスを付与・解除するのが異なります。 + + + に仮想IPとして使用するElastic IPアドレスを指定します。 + + + +use_watchdog = on +delegate_ip = '35.163.178.3' + + + + にElastic IPアドレスを付与・解除するスクリプトを以下のように指定します。 + は、watchdogがリーダーノードになったときに、Elastic IPアドレスを付与するためにwatchdogが実行します。 + は、watchdogがリーダーノードを退任するときに、Elastic IPアドレスを解除するためにwatchdogが実行します。 + + + +if_up_cmd = '<path to script> up $_IP_$ <path to awscli>' +if_down_cmd = '<path to script> down $_IP_$ <path to awscli>' + + + + + + <path to script>: 仮想IPの付与・解除を行うスクリプトのパスを指定します。 + + + + + + <path to awscli>: AWS CLIのパスを指定します。 + + + + + + この設定例では、以下のように指定します。環境に合わせて、設定してください。 + + + +if_up_cmd = '/etc/pgpool-II/aws_eip_if_cmd.sh up $_IP_$ /usr/local/bin/aws' +if_down_cmd = '/etc/pgpool-II/aws_eip_if_cmd.sh down $_IP_$ /usr/local/bin/aws' + + + + arpingコマンドは実行不要なので、常に成功させるようにtrueに設定します。 + + +arping_cmd = 'true' + + + + + + Elastic IPアドレス付与・解除用のスクリプト + + if_up_cmd/if_down_cmdで実行するスクリプトをすべてのPgpool-IIインスタンス上に作成します。 + + + この設定例では、サンプルスクリプトaws_eip_if_cmd.shを使用します。必要に応じて、編集してください。 + + +(すべてのPgpool-IIインスタンスで実行) +# cp -p /etc/pgpool-II/sample_scripts/aws_eip_if_cmd.sh.sample /etc/pgpool-II/aws_eip_if_cmd.sh + + + + 以上で、設定は完了です。 + + + + + 実行してみる + + Pgpool-IIを起動し、ローカル環境からElastic IPアドレスを使ってPgpool-IIに接続してみます。 + + +[user@someserver]$ psql -h 35.163.178.3 -p 9999 -U postgres -c "show pool_nodes" + + + リーダーPgpool-IIを停止し、Elastic IPアドレスが新しいリーダーに付与され、Elastic IPアドレスを使ってPgpool-IIに接続できることを確認します。 + + +[user@someserver]$ psql -h 35.163.178.3 -p 9999 -U postgres -c "show pool_nodes" + + + + + + ルートテーブルの書き換え + + この節では、ルートテーブルの書き換えにより、リーダーPgpool-II(watchdog)へのルーティングを制御する方法を説明します。 + + + この方法では、プライベートIPアドレスを仮想IPとして使い、リーダーPgpool-IIインスタンスに付与します。 + フェイルオーバー時に、仮想IPの付け替えを行い、ルートテーブルを書き換えることで、仮想IPへのトラフィックを新しいリーダーPgpool-IIインスタンスへルーティングすることが可能です。 + + + + AWSのセットアップ + + この方法を利用する場合は、Pgpool-II EC2インスタンスがプライベートサブネットに配置されており、クライアントアプリケーションも同一VPC内に存在することを想定しています。 + この方法はMulti-AZ構成に対応しています。 + + + この例では、複数のアベイラビリティゾーンを跨いだ3ノードのPgpool-II (watchdog)クラスタを使います。 + + + 以下のステップを実施してください。 + + + + + + + 1つのパブリックサブネットと3つのプライベートサブネットを持つVPCを作成し、各プライベートサブネットは異なるアベイラビリティーゾーンに属しています。 + 詳細については、こちらのドキュメントを参照してください。 + + + + + + パブリックサブネットに関連付けるルートテーブルとプライベートサブネットに関連付けるルートテーブルをそれぞれ作成します。 + エントリの設定については、こちらのドキュメントを参照してください。 + + + + + + 1つのアプリケーションEC2インスタンスと3つのPgpool-II EC2インスタンスを起動します。 + アプリケーションインスタンスをパブリックサブネットに配置し、それぞれのPgpool-IIインスタンスを異なるプライベートサブネットに配置します。 + + + + + + Pgpool-II EC2インスタンスのセキュリティグループを設定し、VPCのCIDR範囲内にあるIPアドレスからPgpool-IIとwatchdogが使用するポートへのトラフィックを許可します。 + + + + + + すべてのPgpool-IIインスタンスにPgpool-IIをインストールします。 + + + + + + AWSインスタンス上でAWSサービスを操作・管理するために、AWS CLIを使用します。 + すべてのインスタンスにAWS CLIをインストールします。 + + + また、Pgpool-IIの起動ユーザでAWS CLIを実行できるように、Pgpool-IIの起動ユーザでaws configureを実行し認証情報設定を行います。 + RPMからインストールした場合、デフォルトでPgpool-IIpostgresユーザで起動します。 + + + + + + 仮想IPの付与や解除にはroot権限が必要です。 + 一般ユーザでPgpool-IIを起動する場合、起動ユーザがパスワードなしでsudoできるようにsudoersファイルを設定する必要があります。 + RPMからインストールした場合、postgresユーザの権限が自動的に設定されます。 + + + + + + あらかじめ仮想IPとして使うプライベートIPアドレスを決めておきます。 + セカンダリIPアドレスはアベイラビリティーゾーンを跨ぐことができないため、VPCのCIDR範囲外のプライベートIPアドレスを仮想IPとして使用します。この設定例では、"20.0.0.50"を使用します。 + + + + + + + <productname>Pgpool-II</productname>の設定 + + この節では、Pgpool-IIの設定を説明します。 + + + この設定例はとほとんど同じになりますが、を使ってリーダーPgpool-IIインスタンスへのルーティングを切り替えるのが異なります。 + + + に仮想IPとして使用するプライベートIPを指定します。 + + + +use_watchdog = on +delegate_ip = '20.0.0.50' + + + + にルートテーブルの書き換えを行うスクリプトを以下のように指定します。 + は、watchdogがリーダーノードになったときに、ルートテーブルの書き換えおよび仮想IPの割り当てを行うためにwatchdogが実行します。 + は、watchdogがリーダーノードを退任するときに、ルートテーブルの書き換えおよび仮想IPの解除を行うためにwatchdogが実行します。 + + +if_up_cmd = '<path to script> up $_IP_$ <interface> <route table ID> <path to awscli>' +if_down_cmd = '<path to script> down $_IP_$ <interface> <route table ID> <path to awscli>' + + + + + + + <path to script>: ルートテーブルの書き換えを行うスクリプトのパスを指定します。 + + + + + + <interface>: 仮想IPを割り当てるネットワークインターフェイスを指定します。 + + + + + + <route table ID>: 書き換え対象(接続元のアプリケーションやPgpool-IIインスタンス)となるルートテーブルIDを指定します。カンマ区切りで複数のルートテーブルIDを指定できます。 + + + + + + <path to awscli>: AWS CLIのパスを指定します。 + + + + + + + この設定例では、以下のように指定します。環境に合わせて、設定してください。ルートテーブルIDにパブリックサブネットおよびプライベートサブネットのルートテーブルIDを指定します。 + + + +if_up_cmd = '/etc/pgpool-II/aws_rtb_if_cmd.sh up $_IP_$ eth0 rtb-012345abcd,rtb-67890abcd /usr/local/bin/aws' +if_down_cmd = '/etc/pgpool-II/aws_rtb_if_cmd.sh down $_IP_$ eth0 rtb-012345abcd,rtb-67890abcd /usr/local/bin/aws' + + + + arpingコマンドは実行不要なので、常に成功させるようにtrueに設定します。 + + +arping_cmd = 'true' + + + + + ルートテーブル書き換え用のスクリプト + + if_up_cmd/if_down_cmdで実行するスクリプトをすべてのPgpool-IIインスタンス上に作成します。 + + + この設定例では、サンプルスクリプトaws_rtb_if_cmd.shを使用します。必要に応じて、編集してください。 + + +(すべてのPgpool-IIインスタンスで実行) +# cp -p /etc/pgpool-II/sample_scripts/aws_rtb_if_cmd.sh.sample /etc/pgpool-II/aws_rtb_if_cmd.sh + + + + + 「送信元/送信先チェック」の無効化 + + AWSのネットワークインターフェイスのデフォルト設定では、トラフィックの送信元または送信先をチェックします。 + ルーティングの設定を行うインスタンスでは、この設定を無効にする必要があります。 + + + すべてのPgpool-IIインスタンスのネットワークインターフェイスの設定で「送信元/送信先チェック」を無効にします。 + AWSコンソールまたは AWS CLIを使用して設定可能です。 + AWS CLIを使って設定を行う場合、以下のコマンドを実行します。 + LOCAL_INTERFACEに仮想IPを割り当てるネットワークインターフェイスを指定します。 + この設定例では、eth0を指定します。 + + + +$ sudo su - postgres +$ TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") +$ LOCAL_INTERFACE=eth0 +$ MAC_ADDR=$(ip -br link show dev ${LOCAL_INTERFACE} | tr -s ' ' | cut -d ' ' -f3) +$ EC2_NETWORK_INTERFACE_ID=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC_ADDR}/interface-id) +$ aws ec2 modify-network-interface-attribute --network-interface-id ${EC2_NETWORK_INTERFACE_ID} --no-source-dest-check + + + + 以上で、設定は完了です。 + + + + + 実行してみる + + Pgpool-IIを起動し、アプリケーションインスタンスから仮想IPアドレスを使ってPgpool-IIに接続してみます。 + + +[user@someserver]$ psql -h 20.0.0.50 -p 9999 -U postgres -c "show pool_nodes" + + + リーダーPgpool-IIを停止し、仮想IPが新しいリーダーに付与され、仮想IPを使ってPgpool-IIに接続できることを確認します。 + + +[user@someserver]$ psql -h 20.0.0.50 -p 9999 -U postgres -c "show pool_nodes" + + + + + + AWSコマンドリファレンス + + + + <ulink url="http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html">Configure AWS CLI</ulink> + + + AWS Documentation: Configuring the AWS Command Line Interface + + + + + + <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/associate-address.html">associate-address</ulink> + + + AWS Documentation: associate-address reference + + + + + + <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/disassociate-address.html">disassociate-address</ulink> + + + AWS Documentation: disassociate-address reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/create-route.html">create-route</ulink> + + + AWS Documentation: create-route reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/replace-route.html">replace-route</ulink> + + + AWS Documentation: replace-route reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-route.html">delete-route</ulink> + + + AWS Documentation: delete-route reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/modify-network-interface-attribute.html">modify-network-interface-attribute</ulink> + + + AWS Documentation: modify-network-interface-attribute + + + + + diff --git a/doc.ja/src/sgml/example-Aurora.sgml b/doc.ja/src/sgml/example-Aurora.sgml new file mode 100644 index 000000000..569d6f1dc --- /dev/null +++ b/doc.ja/src/sgml/example-Aurora.sgml @@ -0,0 +1,162 @@ + + + + + Auroraの設定例 + + + + Amazon Aurora for PostgreSQL + Compatibility (Aurora) は、PostgreSQL用のマネージドサービスです。 + ユーザから見ると、Auroraは、いくつか例外があるものの、ストリーミングレプリケーションのクラスタのように見えます。フェイルオーバやオンラインリカバリはAuroraによって管理されます。 + ですから、、 + それにオンラインリカバリ関連のパラメータは設定の必要がありません。 + この章では、Aurora用のPgpool-II設定を説明します。 + + + + + Auroraのためにpgpool.confを設定する + + + + + + pgpool.conf.sampleをコピーしてpgpool.confを作ります。 + 以下の行がpgpool.confに含まれていることを確認してください。 + +backend_clustering_mode = streaming_replication + + + + + + + を0にして、ストリーミングレプリケーション遅延チェックを無効にします。 + Auroraでは、ストリーミングレプリケーションの遅延をチェックするための関数が提供されないためです。 + + +sr_check_period = 0 + + + + + + をオンにし、md5認証を有効にします。 + (Auroraでは常にmd5認証が有効になっています) + + +enable_pool_hba = on + + + + + + pool_passwordを作成します。 + 詳細はをご覧ください。 + + + + + + 0をAuroraのクラスタエンドポイントに設定します。 + 1をAuroraの読み取りエンドポイントに設定します。 + 通常どおり、適切なを設定します。 + は設定の必要がありません。 + + +backend_hostname0 = 'クラスタエンドポイント' +backend_hostname1 = '読み取りエンドポイント' + + + + + + 0のALWAYS_PRIMARYをオンにします。 + + + + + + フェイルオーバはAuroraによって管理されますので、0と1のDISALLOW_TO_FAILOVERをオンにします。 + + +backend_flag0 = 'ALWAYS_MASTER|DISALLOW_TO_FAILOVER' +backend_flag1 = 'DISALLOW_TO_FAILOVER' + + + + + + を0にして、ヘルスチェックを無効にします。 + + +health_check_period = 0 + + + + + + 同様の理由により、接続時あるいは問い合わせ実行中のエラーによるフェイルオーバを避けるために、をオフにしてください。 + + + + + + diff --git a/doc.ja/src/sgml/example-basic.sgml b/doc.ja/src/sgml/example-basic.sgml new file mode 100644 index 000000000..c92b82f07 --- /dev/null +++ b/doc.ja/src/sgml/example-basic.sgml @@ -0,0 +1,536 @@ + + + + + 基本設定の例 + + + + さあ始めましょう + + + ここでは、レプリケーションを行うための準備として、Pgpool-II のインストールや設定、データベースノードの準備について説明します。 + + + + + <productname>Pgpool-II</productname>のインストール + + + Pgpool-IIのインストールはとても簡単です。 + ソースのtar ballを展開したディレクトリで以下のようにコマンドを実行します。 + + $ ./configure + $ make + $ make install + + + configureスクリプトはシステム情報を収集しコンパイル処理に利用します。 + configureスクリプトにコマンドライン引数を指定することにより、インストール先ディレクトリなど、デフォルトの動作を変更することができます。 + デフォルトではPgpool-II は/usr/localディレクトリ以下にインストールされます。 + + + + makeコマンドはソースコードをコンパイルし、make installコマンドで実行可能ファイルがインストールされます。 + インストール先ディレクトリに書き込み権限を持っている必要があります。 + ここでは、Pgpool-II/usr/localにインストールすることにします。 + + + + + Pgpool-IIはPostgreSQL 7.4 以降のlibpqライブラリ(3.0 プロトコル)を必要とします。 + + + + + configureスクリプトが以下のエラーメッセージを表示した場合、libpqライブラリがインストールされていないか、バージョンが3.0でない可能性があります。 + + configure: error: libpq is not installed or libpq is old + + + プロトコルのバージョンが3.0のlibpqライブラリがインストールされているにも係わらず上記のエラーメッセージが表示される場合、configureスクリプトにlibpqライブラリが認識されていない可能性があります。 + configureスクリプトは標準では/usr/local/pgsqlディレクトリ以下からlibpqライブラリを検索します。 + PostgreSQLのインストール先が/usr/local/pgsqlディレクトリ以下でなければ、configureスクリプトを実行する際にコマンドライン引数として--with-pgsql--with-pgsql-includedir--with-pgsql-libdirオプションを指定してください。 + + + + + + 設定ファイルの作成 + + + Pgpool-IIの設定パラメータはpgpool.confファイルに保存されています。 + ファイルは、1 行ごとにパラメータ名 = 値という書式です。 + Pgpool-II をインストールすると、pgpool.conf.sampleファイルが作成されます。 + それをpgpool.confというファイル名にコピーしてから編集するといいでしょう。 + + $ cp /usr/local/etc/pgpool.conf.sample /usr/local/etc/pgpool.conf + + + Pgpool-II はデフォルトではローカルホストからのポート番号9999への接続のみを受け付けます。 + Pgpool-II と異なるホストからの接続を受け付けたい場合は、'*'に設定します。 + + listen_addresses = 'localhost' + port = 9999 + + + ここではデフォルトのパラメータを使うことにします。 + + + + + + <acronym>PCP</acronym>コマンドの設定 + + + + Pgpool-IIには、データベースノードの情報取得やPgpool-II停止などをネットワーク越しに行える管理目的のインターフェイスがあります。 + PCPコマンドを使用するにはユーザ認証が必要になります。 + この認証はPostgreSQLユーザの認証とは異なります。 + ユーザ名とパスワードがpcp.confファイルに定義されている必要があります。 + このファイルでは、1行ごとにユーザ名とパスワードがペアとしてリストされており、これらがコロン(:)で区切られています。 + パスワードはMD5ハッシュ形式で暗号化されている必要があります。 + + + postgres:e8a48653851e28c69d0506508fb27fc5 + + + + Pgpool-II をインストールするとサンプルとしてpcp.conf.sampleが自動的に生成されます。 + それをpcp.confというファイル名にコピーしてから編集するといいでしょう。 + + $ cp /usr/local/etc/pcp.conf.sample /usr/local/etc/pcp.conf + + + パスワードをMD5ハッシュ形式に変換する際には、Pgpool-IIとともにインストールされるpg_md5コマンドを使用します。 + pg_md5コマンドは、コマンドライン引数として文字列を指定すると、それをMD5ハッシュ化したものを表示します。 + 例えば、以下のようにコマンドライン引数として"postgres"を指定して実行すると、それをMD5ハッシュ化したテキストが標準出力に表示されます。 + + $ /usr/local/bin/pg_md5 postgres + e8a48653851e28c69d0506508fb27fc5 + + + PCPコマンドはネットワークを通して実行されるので、ポート番号をpgpool.confファイルのパラメータに設定します。 + ここでは、のデフォルトである9898を使用することにします。 + + pcp_port = 9898 + + + + + + + + データベースノードの準備 + + + 次に、Pgpool-IIのためのPostgreSQLサーバを設定する必要があります。 + これらのサーバは、Pgpool-II と同じホストで起動しても、異なるホストであっても構いません。 + 同じホストにサーバを配置するのならば、各サーバにそれぞれ異なるポート番号を割り合てなければなりません。 + 異なるマシンで起動する場合は Pgpool-IIからのネットワーク接続を受け入れられるよう適切に設定されている必要があります。 + この設定例では、事前に3つのPostgreSQLサーバを作成しておき、それぞれのPostgreSQLサーバの情報を次のパラメータに指定します。 + + + backend_hostname0 = 'localhost' + backend_port0 = 5432 + backend_weight0 = 1 + backend_hostname1 = 'localhost' + backend_port1 = 5433 + backend_weight1 = 1 + backend_hostname2 = 'localhost' + backend_port2 = 5434 + backend_weight2 = 1 + + + + には、ノードのホスト名、ポート番号、負荷分散の割合を設定します。 + 各パラメータ名の後ろには、ノードIDが0から始まる整数(すなわち、0, 1, 2, ...)で指定されていなければなりません。 + + + + + すべてのノードでパラメータが1に設定されているのは、SELECTクエリが3台のサーバで等しく分散されることを意味しています。 + + + + + + + <productname>Pgpool-II</productname>の起動と停止 + + + Pgpool-II を起動するにはターミナルで以下のコマンドを実行します。 + + + $ pgpool + + + + しかしこれでは、Pgpool-IIが制御端末を切り離すため、ログが出力されません。 + Pgpool-IIにログメッセージを表示させたい場合、pgpoolコマンドに-nオプションを指定すると、Pgpool-IIは非デーモンプロセスとして起動し、制御端末は切り離されません。 + + $ pgpool -n & + + + + コマンドを実行した端末にログメッセージが表示されるので、以下のようなオプションを使うことをお勧めします。 + + $ pgpool -n -d > /tmp/pgpool.log 2>&1 & + + + + -d オプションはデバッグメッセージの出力を有効にします。 + 上記の例はファイルにリダイレクトさせているため、ログメッセージが/tmp/pgpool.logに追加され続けます。 + ログをローテートさせたい場合は、ローテート機能を持った外部コマンドにログを渡してください。 + たとえば、Apache2のrotatelogsが使用できます。 + + + $ pgpool -n 2>&1 | /usr/local/apache2/bin/rotatelogs \ + -l -f /var/log/pgpool/pgpool.log.%A 86400 & + + + + これにより毎日夜中の0時にログがローテートされ、pgpool.log.Thursdayのような名前のログファイルが毎日作成されます。 + ただし、すでに同じ名前のファイルがある場合にはrotatelogsはログをそのファイルに追加してしまいます。 + cronを使うことで、古いログファイルをローテーションの前に削除することができます。 + + + 55 23 * * * /usr/bin/find /var/log/pgpool -type f -mtime +5 -exec /bin/rm -f '{}' \; + + + + 注意:Linuxディストリビューションによっては、rotatelogsは/usr/sbin/rotatelogs2として存在しているかもしれません。 + -fオプションはrotatelogsが起動された直後に直ちにログファイルを作るオプションで、apache2 2.2.9以降でのみ有効です。 + cronologを使うこともできます。 + + $ pgpool -n 2>&1 | /usr/sbin/cronolog \ + --hardlink=/var/log/pgsql/pgpool.log \ + '/var/log/pgsql/%Y-%m-%d-pgpool.log' & + + + + Pgpool-II を停止するには以下のコマンドを実行します。 + + $ pgpool stop + + + + Pgpool-II を停止する際にクライアントが接続している場合、Pgpool-IIはその接続が切断されるまで待ってから停止します。 + Pgpool-IIを強制的にシャットダウンしたい場合は、以下のコマンドを実行します。 + + $ pgpool -m fast stop + + + + + + + + + 初めてのレプリケーション + + + ネィティブレプリケーションモード(を参照)では複数のデータベースノードに同じデータを複製して格納します。 + ここでは、で準備した 3 台のデータベースノードを使用し、一歩一歩データベースクラスタシステムを作っていきましょう。 + 複製させるサンプルのデータはpgbenchベンチマークプログラムで生成することにします。 + + + + + レプリケーションの設定 + + + データベースノードのレプリケーションを有効にするには、pgpool.confファイルのをonに設定します。 + + replication_mode = true + + + をonに設定することにより、Pgpool-IIは受信したクエリを全てのデータベースノードに送信します。 + 対して実行され、同じデータが複製されて格納されるようになります。 + さらに、をonに設定することにより、Pgpool-IIはSELECTクエリをデータベースノード間に振り分けます。 + + load_balance_mode = true + + + ここでは、の両方を有効にします。 + + + + + + レプリケーションの確認 + + + 上記のpgpool.confの変更をPgpool-IIに反映させるにはPgpool-IIを再起動する必要があります。 + 「Pgpool-II の起動と停止」を参照してください。 + pgpool.confの設定と再起動がすんだら、実際にレプリケーションを試してうまく行くことを確認しましょう。 + まず、複製するデータベースを作成する必要があります。 + これを"bench_replication"と名づけましょう。 + このデータベースが全てのノードで作成される必要があります。 + createdbコマンドをPgpool-II経由で実行すると、すべてのノードでデータベースが作成されます。 + + $ createdb -p 9999 bench_replication + + + そしてpgbench-iオプションを指定して実行します。 + -iオプションにより、データベースは事前に定義されたテーブルとデータで初期化されます。 + + $ pgbench -i -p 9999 bench_replication + + + pgbench -iによって作成されるテーブルとデータを以下の表にまとめます。 + すべてのノードにおいてこれらのテーブルおよびデータが作成されていれば、正常にレプリケーションが動作していることになります。 + + + + data summary + + + + + テーブル名 + 行数 + + + + + + pgbench_branches + 1 + + + + pgbench_tellers + 10 + + + + pgbench_accounts + 100000 + + + + pgbench_history + 0 + + + + +
+ + + + これをチェックするため、簡単なシェルスクリプトを実行してみましょう。 + 以下のスクリプトはすべてのノード (ポート番号 5432、5433、5434) のデータベースにおけるpgbench_branches、pgbench_tellers、pgbench_accounts、pgbench_historyの行数が表示されます。 + + $ for port in 5432 5433 5434; do + > echo $port + > for table_name in pgbench_branches pgbench_tellers pgbench_accounts pgbench_history; do + > echo $table_name + > psql -c "SELECT count(*) FROM $table_name" -p $port bench_replication + > done + > done + + + +
+
+ +
diff --git a/doc.ja/src/sgml/example-cluster.sgml b/doc.ja/src/sgml/example-cluster.sgml new file mode 100644 index 000000000..bd0f1d0f1 --- /dev/null +++ b/doc.ja/src/sgml/example-cluster.sgml @@ -0,0 +1,1393 @@ + + + + <productname>Pgpool-II</productname> + Watchdogの構築の例 + + ここでは、ストリーミングレプリケーション構成のPostgreSQLPgpool-IIで管理するシステムの構成例を示します。 + この設定例では、3台のPgpool-IIを使ってPostgreSQL(プライマリ1台、スタンバイ2台)を管理し、単一障害点やスプリットブレインの起きない堅牢なクラスタを運用することが可能です。 + + + この設定例ではPostgreSQL 18を使っています。 + + + 前提条件 + + Pgpool-IIサーバとPostgreSQLサーバが + 同じサブネットにあることを前提とします。 + + + + + 全体構成 + + 今回は、Linuxサーバを3台用意し、それぞれのホスト名はserver1server2server3とします。 + 使用するOSはすべてRocky Linux 10とします。 + それぞれのサーバにPostgreSQLPgpool-IIをインストールします。 + 3台のPostgreSQLがストリーミングレプリケーション構成になります。全体構成図は以下の通りです。 + + +
+ 全体構成図 + + + + + +
+
+ + + 「Leader」「Standby」「Primary」「Standby」といった役割は固定されているものではなく、運用と共に変化することがあります。 + + + + + ホスト名とIPアドレス + + + + ホスト名 + IPアドレス + 仮想IP + + + + + server1 + 192.168.100.51 + 192.168.100.50 + + + server2 + 192.168.100.52 + + + server3 + 192.168.100.53 + + + +
+ + + PostgreSQLのバージョンと設定情報 + + + + 項目 + + 説明 + + + + + PostgreSQLバージョン + 18.0 + - + + + ポート番号 + 5432 + - + + + $PGDATA + /var/lib/pgsql/18/data + - + + + アーカイブモード + 無効 + - + + + レプリケーションスロット + 有効 + 本設定例では、フェイルオーバやオンラインリカバリの時に実行されるスクリプトで、自動的にレプリケーションスロットを削除/作成しています。 +これらのスクリプトでは、backend_hostnameXに指定したホスト名をレプリケーションスロット名として使用しています。 +スクリプトの詳細についてはを参照してください。 + + + 同期/非同期レプリケーション + 非同期 + - + + + +
+ + + + Pgpool-IIのバージョンと設定情報 + + + + 項目 + + 説明 + + + + + Pgpool-IIバージョン + 4.6.1 + - + + + ポート番号 + 9999 + Pgpool-IIが接続を受け付けるポート番号 + + + 9898 + PCPプロセスが接続を受け付けるポート番号 + + + 9000 + Watchdogが接続を受け付けるポート番号 + + + 9694 + Watchdogのハートビート信号を受信するUDPポート番号 + + + 設定ファイル + /etc/pgpool-II/pgpool.conf + Pgpool-IIの設定ファイル + + + Pgpool-II起動ユーザ + postgres (Pgpool-II 4.1以降) + Pgpool-II 4.0以前のバージョンでは、デフォルトではrootでPgpool-IIを起動する + + + Pgpool-II動作モード + ストリーミングレプリケーションモード + - + + + Watchdog機能 + 有効 + ハートビート方式 + + + +
+ + + RPMに含まれるサンプルスクリプト + + + + 機能 + スクリプト + 説明 + + + + + 自動フェイルオーバ + /etc/pgpool-II/sample_scripts/failover.sh.sample + フェイルオーバを実行するスクリプト。で使用します。 + + + /etc/pgpool-II/sample_scripts/follow_primary.sh.sample + 上記フェイルオーバスクリプトが実行された後に、新しいプライマリサーバとスタンバイサーバを同期させるスクリプト。で使用します。 PostgreSQLサーバが2台の場合はこのスクリプトの設定は不要です。 + + + オンラインリカバリ + /etc/pgpool-II/sample_scripts/recovery_1st_stage.sample + スタンバイサーバをリカバリするスクリプト。で使用します。 + + + /etc/pgpool-II/sample_scripts/pgpool_remote_start.sample + 上記が実行された後に、スタンバイノードを起動させるスクリプト。 + + + Watchdog + /etc/pgpool-II/sample_scripts/escalation.sh.sample + + 任意の設定。Pgpool-IIのリーダー/スタンバイ切り替え時に、旧Watchdogリーダープロセスの異常終了によって旧Watchdogリーダーで仮想IPが起動したまま、新しいリーダーノードで仮想IPが起動されることを防ぐために、新しいリーダー以外で起動している仮想IPを停止するスクリプト。で使用します。 + + + + +
+ + 上記各種スクリプトはRPMパッケージに同梱されており、必要に応じてカスタマイズできます。 + +
+ + + インストール + + この設定例ではYUMを使用してPostgreSQLおよびPgpool-IIをインストールします。 + + + PostgreSQLのインストールはPostgreSQLコミュニティのリポジトリを使います。 + + +[全サーバ]# dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm +[全サーバ]# dnf -qy module disable postgresql +[全サーバ]# dnf install -y postgresql18-server + + + + Pgpool-IIのインストールはPgpool-II開発コミュニティが提供するYumリポジトリを用いてインストールします。 + + + Pgpool-II関連のパッケージはPostgreSQLコミュニティのリポジトリにもあるため、 + PostgreSQLコミュニティのリポジトリからPgpool-IIをインストールしないように/etc/yum.repos.d/pgdg-redhat-all.repoにexclude設定を追加します。 + + +[全サーバ]# vi /etc/yum.repos.d/pgdg-redhat-all.repo + + + 以下は、/etc/yum.repos.d/pgdg-redhat-all.repoの設定例です。 + + +[pgdg-common] +... +exclude=pgpool* + + +[pgdg18] +... +exclude=pgpool* + +[pgdg17] +... +exclude=pgpool* + +[pgdg16] +... +exclude=pgpool* + +[pgdg15] +... +exclude=pgpool* + +[pgdg14] +... +exclude=pgpool* + +[pgdg13] +... +exclude=pgpool* + + + + Pgpool-IIをインストールします。 + Pgpool-IIのインストールに必要なlibmemcachedライブラリをインストールするために、crbリポジトリを有効にする必要があります。 + Rocky Linux 8を使用する場合、crbリポジトリではなく、powertoolsリポジトリを使用してください。 + + + +[全サーバ]# dnf install -y https://www.pgpool.net/yum/rpms/4.6/redhat/rhel-10-x86_64/pgpool-II-release-4.6-1.noarch.rpm +[全サーバ]# dnf install -y --enablerepo=crb pgpool-II-pg18-* + + + + + 事前設定 + + Pgpool-IIの設定の前に、以下の設定を行ってください。 + + + + SSH公開鍵認証の設定 + + 自動フェイルオーバ、オンラインリカバリ機能を利用するには、すべてのPgpool-IIノード間でpostgresユーザ(Pgpool-IIのデフォルトの起動ユーザ。Pgpool-II 4.0以前、デフォルトの起動ユーザはroot)として双方向にSSH公開鍵認証(パスワードなし)で接続できるように設定する必要があります。 + + + + + まず、全サーバで以下のコマンドを実行し、SSH鍵ファイルを作成します。 + この設定例では生成される鍵ファイル名はid_rsa_pgpoolとします。 + + +[全サーバ]# su - postgres +[全サーバ]$ mkdir ~/.ssh && chmod 700 ~/.ssh +[全サーバ]$ ssh-keygen -t rsa -f ~/.ssh/id_rsa_pgpool + + + 次に、公開鍵id_rsa_pgpool.pubを各サーバの/var/lib/pgsql/.ssh/authorized_keysファイルに追加します。 + + + 設定後、postgresユーザでssh postgres@serverX -i ~/.ssh/id_rsa_pgpoolコマンドを実行し、パスワードなしでログインできることを確認してください。 + + + + + 公開鍵認証によるログインに失敗した場合には、以下を確認してください。 + + + + /etc/ssh/sshd_configで公開鍵認証が許可されていることを確認します。 + + + + +PubkeyAuthentication yes + + + + + SELinuxを有効化している場合は、SSH公開鍵認証(パスワードなし)が失敗する可能性があるので、すべてのサーバで以下のコマンドを実行する必要があります。 + + + + +[全サーバ]# su - postgres +[全サーバ]$ restorecon -Rv ~/.ssh + + + + + + + firewallの設定 + + Pgpool-IIPostgreSQLに接続する際には、ファイアーウォールによって目的のポートが開けられていなければなりません。 + Rocky Linux 10/RHEL 10の場合、以下のように設定します。 + + +[全サーバ]# firewall-cmd --permanent --zone=public --add-service=postgresql +[全サーバ]# firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp --add-port=9000/tcp --add-port=9694/udp +[全サーバ]# firewall-cmd --reload + + + + + プライマリのセットアップ + + server1PostgreSQLプライマリサーバのセットアップを行います。 + + + まず、データベースクラスタの初期化を行います。 + PostgreSQL 18ではデータベースクラスタのデフォルトの作成先は/var/lib/pgsql/18/dataで、postgresユーザの設定ファイル~/.bash_profileで環境変数PGDATAに指定されています。 + 必要に応じて変更してください。 + + + initdbコマンドを実行して、データベースクラスタの初期化を行います。 + 必要に応じて、--encoding--localeオプションを指定して、データベースのエンコーディングやロケールを設定してください。 + + +[root@server1 ~]# su - postgres +[postgres@server1 ~]$ /usr/pgsql-18/bin/initdb + + + + 次にserver1で設定ファイル$PGDATA/postgresql.confを以下のように編集します。 + pg_rewindを使うためにwal_log_hintsを有効にします。 + + +[postgres@server1 ~]$ vi $PGDATA/postgresql.conf +listen_addresses = '*' +wal_log_hints = on + + + 最後に、server1PostgreSQLを起動します。 + + +[postgres@server1 ~]$ /usr/pgsql-18/bin/pg_ctl start + + + + + スタンバイのセットアップ + + スタンバイサーバをセットアップする方法としては、次のような複数の方法があります。 + + + + Pgpool-IIのオンラインリカバリ機能()を使用して、スタンバイサーバを自動的にセットアップします。 + + + + + スタンバイでpg_basebackupを実行して、プライマリのデータディレクトリのバックアップを生成します。 + + + + + + + オンラインリカバリを使用せず手動でスタンバイをセットアップする場合は次の注意点があります。 + + + + 手動でレプリケーションスロットを作成する必要があります。 + + + + + + + pg_basebackup を実行する際には -R オプションを指定しないでください。primary_conninforecovery_target_timelineprimary_slot_namepostgresql.auto.conf ではなく、$PGDATA/myrecovery.conf に記載し、postgresql.conf に以下を追記してください。 + + + + +include_if_exists = 'myrecovery.conf' + + + + + この設定例では、Pgpool-IIの構成が完了した後に、Pgpool-IIのオンラインリカバリを使用してスタンバイサーバをセットアップします。 + + + + + PostgreSQLユーザの作成 + + Pgpool-IIPostgreSQLのユーザを使用してPostgreSQLへ接続し、ヘルスチェックやレプリケーション遅延チェックを行います。 + セキュリティ上の理由で、この設定例ではスーパーユーザを使わず、レプリケーション遅延チェックとヘルスチェック専用のユーザpgpoolを作成します。 + また、レプリケーション専用のユーザreplを作成します。 + オンラインリカバリ機能を利用するにはスーパーユーザ権限が必要なので、ここではpostgresユーザを使用します。 + + + Pgpool-II 4.0からscram-sha-256認証が利用できるようになりました。 + この設定例では、scram-sha-256認証方式を利用します。 + まず、password_encryption = 'scram-sha-256'に変更してから、ユーザを登録します。 + + + + PostgreSQLユーザ + + + + ユーザ名 + パスワード + 備考 + + + + + repl + repl + PostgreSQLのレプリケーション専用ユーザ + + + pgpool + pgpool + + Pgpool-IIのレプリケーション遅延チェック()、 + ヘルスチェック専用ユーザ() + + + + postgres + postgres + オンラインリカバリの実行ユーザ + + + +
+ + +[postgres@server1 ~]$ psql +postgres=# SET password_encryption = 'scram-sha-256'; +postgres=# CREATE ROLE pgpool WITH LOGIN; +postgres=# CREATE ROLE repl WITH REPLICATION LOGIN; +postgres=# \password pgpool +postgres=# \password repl +postgres=# \password postgres + + + + コマンドでreplication_statカラムとreplication_sync_stateカラムを表示するには、pgpoolユーザはPostgreSQLのスーパーユーザであるか、pg_monitorグループに所属する必要があります(Pgpool-II 4.1以降)。 + 以下のコマンドでpgpoolユーザをそのグループに所属させます。 + + +postgres=# GRANT pg_monitor TO pgpool; +postgres=# \q + + + + + (Pgpool-II 4.1以降)を利用する予定がある場合、"pgpool" ロールはPostgreSQLのスーパーユーザであるか、pg_monitorグループに所属する必要があります。 + + + + + この設定例では、Pgpool-IIサーバとPostgreSQLバックエンドサーバが同じサブネットワークにあることを想定し、各ユーザがscram-sha-256認証方式で接続するように、$PGDATA/pg_hba.confを編集しておきます。 + + +[postgres@server1 ~]$ vi $PGDATA/pg_hba.conf +(以下を追加) +host all pgpool samenet scram-sha-256 +host all postgres samenet scram-sha-256 +host replication repl samenet scram-sha-256 + +
+ + + .pgpassの作成 + + パスワード入力なしで、ストリーミングレプリケーションやpg_rewindを実行するために、すべてのサーバでpostgresユーザのホームディレクトリ/var/lib/pgsql.pgpassを作成し、パーミッションを600に設定しておきます。 + + +[postgres@server1 ~]$ vi ~/.pgpass +server1:5432:replication:repl:<replユーザのパスワード> +server2:5432:replication:repl:<replユーザのパスワード> +server3:5432:replication:repl:<replユーザのパスワード> +server1:5432:postgres:postgres:<postgresユーザのパスワード> +server2:5432:postgres:postgres:<postgresユーザのパスワード> +server3:5432:postgres:postgres:<postgresユーザのパスワード> + +[postgres@server1 ~]$ chmod 600 ~/.pgpass + + + server2およびserver3のpostgresユーザのホームディレクトリにコピーします。 + + +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpass postgres@server2: +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpass postgres@server3: + + +
+ + + PCP接続認証の設定 + + PCPコマンドを使用するには、username:encryptedpassword形式のPCPユーザ名とmd5暗号化パスワードをpcp.confに登録する必要があります。 + + + この設定例では、PCPユーザ名をpgpool、パスワードをpgpool_passwordに設定します。 + 必要に応じて、ユーザ名とパスワードを変更してください。 + + + 以下のように、pg_md5を使用して、pcpユーザpgpoolの暗号化されたパスワードエントリを作成します。 + + +[postgres@server1 ~]$ echo 'pgpool:'`pg_md5 pgpool_password` >> /etc/pgpool-II/pcp.conf + +[postgres@server1 ~]$ cat /etc/pgpool-II/pcp.conf +# USERID:MD5PASSWD +pgpool:4aa0cb9673e84b06d4c8a848c80eb5d0 + + + 後述のfollow_primary.shのスクリプトでパスワード入力なしでPCPコマンドを実行する必要があるので、Pgpool-IIの起動ユーザ(postgresユーザ)のホームディレクトリに.pcppassを作成します。 + + +[postgres@server1 ~]$ echo 'localhost:9898:pgpool:pgpool_password' > ~/.pcppass +[postgres@server1 ~]$ chmod 600 ~/.pcppass + + + server2およびserver3のpostgresユーザのホームディレクトリにコピーします。 + + +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pcppass postgres@server2: +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pcppass postgres@server3: +[postgres@server1 ~]$ exit + + + + + pgpool_node_idファイルの作成 + + Pgpool-II 4.2以降、すべての設定パラメータがすべてのホストで同一になりました。 + Watchdog機能が有効になっている場合、どの設定がどのホストであるかを区別するには、 + pgpool_node_idファイルの設定が必要になります。 + pgpool_node_idファイルを作成し、 + そのファイルにpgpool(watchdog)ホストを識別するためのノード番号(0、1、2など)を追加します。 + + + + + server1 + + +[root@server1 ~]# echo 0 > /etc/pgpool-II/pgpool_node_id +[root@server1 ~]# cat /etc/pgpool-II/pgpool_node_id +0 + + + + + server2 + + +[root@server2 ~]# echo 1 > /etc/pgpool-II/pgpool_node_id +[root@server2 ~]# cat /etc/pgpool-II/pgpool_node_id +1 + + + + + server3 + + +[root@server3 ~]# echo 2 > /etc/pgpool-II/pgpool_node_id +[root@server3 ~]# cat /etc/pgpool-II/pgpool_node_id +2 + + + + + + + <productname>Pgpool-II</productname>の設定 + + RPMからインストールした場合、Pgpool-IIの設定ファイル + pgpool.conf/etc/pgpool-IIにあります。 + + + Pgpool-II 4.2以降、すべての設定パラメーターがすべてのホストで同一になったので、 + どれか一つのノード上でpgpool.confを編集し、 + 編集したpgpool.confファイルを他のpgpoolノードにコピーすれば良いです。 + + + + クラスタリングモード + + Pgpool-IIにはいくつかのクラスタリングモードがあり、 + クラスタリングモードを設定するにはというパラメータを使用します。 + この設定例では、ストリーミングレプリケーションモードを使用します。 + + +[root@server1 ~]# vi /etc/pgpool-II/pgpool.conf +backend_clustering_mode = streaming_replication + + + + + listen_addresses + + Pgpool-IIおよびPCPが全てのIPアドレスから接続を受け付けるように、以下のパラメータを'*'に設定します。 + + +listen_addresses = '*' +pcp_listen_addresses = '*' + + + + + port + + Pgpool-IIが接続を受け付けるために監視するポート番号を指定します。 + + +port = 9999 + + + + + ストリーミングレプリケーションのチェック + + レプリケーションの遅延チェックユーザpgpoolユーザを設定します。 + この設定例では、pgpool.confに指定せず、 + ファイルに作成します。 + 作成方法については後述のを参照ください。 + Pgpool-II 4.0から、が空の場合、 + Pgpool-IIは空のパスワードを使用する前に + まずファイルからに + 指定したユーザのパスワードを取得できるか試みます。 + + +sr_check_user = 'pgpool' +sr_check_password = '' + + + + + ヘルスチェック + + 自動フェイルオーバのため、ヘルスチェックを有効にします。 + のデフォルト値が0で、これはヘルスチェックが無効であることを意味します。 + また、ネットワークが不安定な場合には、バックエンドが正常であるにも関わらず、 + ヘルスチェックに失敗し、フェイルオーバや縮退運転が発生してしまう可能性があります。 + そのようなヘルスチェックの誤検知を防止するため、ヘルスチェックのリトライ回数を + health_check_max_retries = 3 に設定しておきます。 + は + 前述のと同様に設定します。 + + +health_check_period = 5 +health_check_timeout = 30 +health_check_user = 'pgpool' +health_check_password = '' +health_check_max_retries = 3 + + + + + バックエンドの設定 + + また、バックエンド情報を前述のserver1server2 + 及びserver3の設定に従って設定しておきます。 + 複数バックエンドノードを定義する場合、以下のbackend_*などのパラメータ名の + 末尾にノードIDを表す数字を付加することで複数のバックエンドを指定することができます。 + + +backend_hostname0 = 'server1' +backend_port0 = 5432 +backend_weight0 = 1 +backend_data_directory0 = '/var/lib/pgsql/18/data' +backend_flag0 = 'ALLOW_TO_FAILOVER' + +backend_hostname1 = 'server2' +backend_port1 = 5432 +backend_weight1 = 1 +backend_data_directory1 = '/var/lib/pgsql/18/data' +backend_flag1 = 'ALLOW_TO_FAILOVER' + +backend_hostname2 = 'server3' +backend_port2 = 5432 +backend_weight2 = 1 +backend_data_directory2 = '/var/lib/pgsql/18/data' +backend_flag2 = 'ALLOW_TO_FAILOVER' + + + + コマンドでPgpool-II 4.1で追加された + replication_statカラムとreplication_sync_stateカラムを表示するには、 + パラメータを設定する必要があります(Pgpool-II 4.1以降)。 + ここではそれぞれのホスト名を設定します。 + backend_application_nameXに設定された値が、primary_conninfoapplication_nameに設定された値と一致していることを確認してください。 + +backend_application_name0 = 'server1' +backend_application_name1 = 'server2' +backend_application_name2 = 'server3' + + + + + + フェイルオーバの設定 + + PostgreSQLバックエンドノードがダウンした時に実行するスクリプトを + に設定します。 + また、PostgreSQLサーバが3台の場合、 + プライマリノードのフェイルオーバ後に新しいプライマリからスタンバイをリカバリするために + も設定する必要があります。 + はプライマリノードのフェイルオーバ後に実行されます。 + PostgreSQLサーバが2台の場合、の設定は不要です。 + + + + Pgpool-II 4.3で追加されたの + オプションでスイッチオーバを行う時に、 + 古いプライマリを自動でスタンバイにする場合はPostgreSQLサーバが2台であっても、 + の設定が必要になります。 + + + + それぞれの実行スクリプトの引数は、それぞれ実行時にPgpool-II + によってバックエンドの具体的な情報に置き換えられます。 + 各引数の意味はおよびをご参照ください。 + + +failover_command = '/etc/pgpool-II/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S' +follow_primary_command = '/etc/pgpool-II/follow_primary.sh %d %h %p %D %m %H %M %P %r %R' + + + + %N%SPgpool-II 4.1で追加された引数です。 + Pgpool-II 4.0または以前のバージョンを利用している場合、 + これらの引数を指定できないので、ご注意ください。 + + + + サンプルスクリプトfailover.sh及び + follow_primary.shは + /etc/pgpool-II/配下にインストールされていますので、これらのファイルをコピーして作成します。 + + +[root@server1 ~]# cp -p /etc/pgpool-II/sample_scripts/failover.sh.sample /etc/pgpool-II/failover.sh +[root@server1 ~]# cp -p /etc/pgpool-II/sample_scripts/follow_primary.sh.sample /etc/pgpool-II/follow_primary.sh +[root@server1 ~]# chown postgres:postgres /etc/pgpool-II/{failover.sh,follow_primary.sh} + + + 基本的にはPGHOMEを環境に合わせて変更すれば、動作します。 + + +[root@server1 ~]# vi /etc/pgpool-II/failover.sh +... +PGHOME=/usr/pgsql-18 +... + +[root@server1 ~]# vi /etc/pgpool-II/follow_primary.sh +... +PGHOME=/usr/pgsql-18 +... + + + follow_primary.shPCP_USERに指定されているユーザがpcp.confに登録されていることを確認してください。 + この設定例では、前述のセクションですでに登録済みです。 + + +[root@server1 ~]# vi /etc/pgpool-II/follow_primary.sh +... +PCP_USER=pgpool +... + + + + follow_primary.shスクリプトはテーブルスペースに対応していません。 + テーブルスペースを使っている場合は、スクリプトを自分で変更する必要があります。 + + + + + + オンラインリカバリの設定 + + 続いて、オンラインリカバリ()を実行するPostgreSQLユーザ及びオンラインリカバリ時に呼び出されるスクリプトを設定します。 + オンラインリカバリで実行されるpgpool_recovery関数は + PostgreSQLのスーパーユーザ権限が必要なため、recovery_userスーパーユーザを指定しなければなりません。 + ここでは、postgresユーザを指定します。 + + + この設定例ではを空のままにし、にエントリを作成します。にエントリを作成する方法については、を参照してください。 + + +recovery_user = 'postgres' +recovery_password = '' +recovery_1st_stage_command = 'recovery_1st_stage' + + + オンラインリカバリ用のサンプルスクリプトrecovery_1st_stage + 及びpgpool_remote_startは + /etc/pgpool-II/配下にインストールされていますので、 + これらのファイルをプライマリサーバ(server1)のデータベースクラスタ配下に配置します。 + + +[root@server1 ~]# su - postgres -c "cp -p /etc/pgpool-II/sample_scripts/recovery_1st_stage.sample \$PGDATA/recovery_1st_stage" +[root@server1 ~]# su - postgres -c "cp -p /etc/pgpool-II/sample_scripts/pgpool_remote_start.sample \$PGDATA/pgpool_remote_start" + + + 基本的にはPGHOMEを環境に合わせて変更すれば、動作します。 + + +[root@server1 ~]# vi /var/lib/pgsql/18/data/recovery_1st_stage +... +PGHOME=/usr/pgsql-18 +... + +[root@server1 ~]# vi /var/lib/pgsql/18/data/pgpool_remote_start +... +PGHOME=/usr/pgsql-18 +... + + + + また、オンラインリカバリ機能を使用するには、pgpool_recoverypgpool_remote_startpgpool_switch_xlogの各関数をあらかじめで指定されたデータベース(デフォルトは'postgres'です)に作成しておく必要があります。 + server1上で以下のコマンドを実行し、これらの関数をpostgresに作成します。 + にデフォルト以外の値が設定されている場合は、postgresをその設定値に置き換えてください。 + + +[root@server1 ~]# psql -U postgres postgres -c "CREATE EXTENSION pgpool_recovery" + + + + recovery_1st_stageスクリプトはテーブルスペースに対応していません。 + テーブルスペースを使っている場合は、スクリプトを自分で変更する必要があります。 + + + + + + クライアント認証の設定 + + 事前設定の章で、 + Pgpool-IIPostgreSQLの間に + 認証方式をscram-sha-256に設定しました。 + この設定例では、クライアントとPgpool-IIの間でも + scram-sha-256認証方式を利用し接続するように設定します。 + Pgpool-IIのクライアント認証の設定ファイルは + pool_hba.confと呼ばれ、RPMパッケージからインストールする場合、 + デフォルトでは/etc/pgpool-II配下にインストールされます。 + デフォルトではpool_hba.confによる認証は無効になっているので、 + pgpool.confでは以下の設定をonに変更します。 + + +enable_pool_hba = on + + + pool_hba.confのフォーマットはPostgreSQLの + pg_hba.confとほとんど同じです。 + pgpoolpostgresユーザの認証方式をscram-sha-256に設定します。 + この設定例では、Pgpool-IIに接続しているアプリケーションが同じサブネット内にあると想定しています。 + + +[root@server1 ~]# vi /etc/pgpool-II/pool_hba.conf +(以下を追加) +host all pgpool samenet scram-sha-256 +host all postgres samenet scram-sha-256 + + + + Pgpool-II 4.0の場合、pgpool.confファイル内のにはAES256暗号化形式、平文形式しか指定できないので、ご注意ください。 + + + + Pgpool-IIのクライアント認証で用いるデフォルトのパスワードファイル名はpool_passwdです。 + scram-sha-256認証を利用する場合、Pgpool-IIはそれらのパスワードを復号化するために復号鍵が必要となります。 + 復号鍵ファイルをPgpool-IIの起動ユーザpostgresPgpool-II 4.0以前のバージョンではroot)のホームディレクトリ配下に作成し、server2およびserver3にコピーします。 + + +[root@server1 ~]# su - postgres -c "echo '任意の文字列' > ~/.pgpoolkey" +[root@server1 ~]# su - postgres -c "chmod 600 ~/.pgpoolkey" +[root@server1 ~]# su - postgres -c "scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpoolkey postgres@server2:" +[root@server1 ~]# su - postgres -c "scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpoolkey postgres@server3:" + + + pg_enc -m -k /path/to/.pgpoolkey -u username -pを実行すると、ユーザ名とAES256で暗号化したパスワードのエントリがに登録されます。 + がまだ存在しなければ、pgpool.confと同じディレクトリ内に作成されます。 + + +[root@server1 ~]# pg_enc -m -k /var/lib/pgsql/.pgpoolkey -u pgpool -p +db password: (pgpoolユーザのパスワードを入力) +trying to read key from file /var/lib/pgsql/.pgpoolkey + +[root@server1 ~]# pg_enc -m -k /var/lib/pgsql/.pgpoolkey -u postgres -p +db password: (postgresユーザのパスワードを入力) +trying to read key from file /var/lib/pgsql/.pgpoolkey + +[root@server1 ~]# cat /etc/pgpool-II/pool_passwd +pgpool:AESheq2ZMZjynddMWk5sKP/Rw== +postgres:AESHs/pWL5rtXy2IwuzroHfqg== + + + + + Watchdogの設定 + + デフォルトではWatchdog機能が無効になっているため、Watchdogを有効にします。 + + +use_watchdog = on + + + Pgpool-IIリーダーノードが立ち上げる仮想IPをdelegate_ipに指定します。 + 仮想IPはまだ使われていないIPアドレスを指定してください。 + + +delegate_ip = '192.168.100.50' + + + + 仮想IPの起動/停止、ARPリクエストの送信を行う設定パラメータ + に、ネットワーク環境に合わせてネットマスクおよびネットワークインターフェース名を設定します。 + この設定例で使用しているネットワークインターフェースはenp0s8となります。 + if_up/down_cmdarping_cmdを実行するにはroot権限が必要となりますので、 + 一般ユーザで実行できるようにip/arpingコマンドにsetuidを設定するか、Pgpool-II起動ユーザ、デフォルトではpostgresユーザ (Pgpool-II 4.1以降) がパスワードなしにsudoを実行できるように設定する必要があります。 + + + + RPMからインストールした場合、postgresユーザがパスワードなしに + sudoを介してip/arpingを実行できるように設定済みです。 + +postgres ALL=NOPASSWD: /sbin/ip +postgres ALL=NOPASSWD: /usr/sbin/arping + + + + + ここでは、sudoを介して実行するように設定します。 + + +if_up_cmd = '/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev enp0s8 label enp0s8:0' +if_down_cmd = '/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev enp0s8' +arping_cmd = '/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I enp0s8' + + + + /etc/sudoersで「Defaults requiretty」を設定している場合は、 + Pgpool-IIの起動ユーザがttyなしで + if_up_cmdif_down_cmd + 及びarping_cmdコマンドを実行できるように設定する必要があります。 + + + + + ipコマンドやarpingコマンドのパスがデフォルトのパスと異なる場合、 + 環境に合わせてを設定しておいてください。 + ただし、if_up/down_cmd及びarping_cmdに指定したコマンドが"/"で始まる場合、 + フルパスとみなしif_cmd_path及びarping_pathの設定を無視します。 + + +if_cmd_path = '/sbin' +arping_path = '/usr/sbin' + + + 各Watchdogが稼働するサーバ情報を設定しておきます。 + pgpool_portXにはの + portに設定されているポート番号を指定します。 + + +hostname0 = 'server1' +wd_port0 = 9000 +pgpool_port0 = 9999 + +hostname1 = 'server2' +wd_port1 = 9000 +pgpool_port1 = 9999 + +hostname2 = 'server3' +wd_port2 = 9000 +pgpool_port2 = 9999 + + + + Watchdog死活監視の設定では、 + 死活監視の方法を指定する、 + 監視間隔(秒)を指定するを設定します。 + この設定例では、死活監視の方法はheartbeatを用います。 + + + +wd_lifecheck_method = 'heartbeat' +wd_interval = 10 + + + heartbeatに設定されている場合、 + heartbeat通信用の各Pgpool-IIサーバ情報を設定しておきます。 + + +heartbeat_hostname0 = 'server1' +heartbeat_port0 = 9694 +heartbeat_device0 = '' + +heartbeat_hostname1 = 'server2' +heartbeat_port1 = 9694 +heartbeat_device1 = '' + +heartbeat_hostname2 = 'server3' +heartbeat_port2 = 9694 +heartbeat_device2 = '' + + + heartbeatに設定されている場合、 + 障害と判断する秒数を指定する、 + ハートビート信号の送信間隔(秒)を指定するを設定します。 + + +wd_heartbeat_keepalive = 2 +wd_heartbeat_deadtime = 30 + + + Watchdogプロセスが異常終了した場合に、 + 旧リーダーノードで仮想IPが残ったまま、新しいリーダーノードで同じ仮想IPが起動されてしまう可能性があります。 + それを防ぐためにに、新しいリーダー以外のPgpool-IIノードで仮想IPを停止するスクリプトを設定します。 + この設定は任意の設定です。 + + +wd_escalation_command = '/etc/pgpool-II/escalation.sh' +   + + サンプルスクリプトescalation.shは + /etc/pgpool-II/配下にインストールされています。 + + +[root@server1 ~]# cp -p /etc/pgpool-II/sample_scripts/escalation.sh.sample /etc/pgpool-II/escalation.sh +[root@server1 ~]# chown postgres:postgres /etc/pgpool-II/escalation.sh + + + + サーバのホスト名、仮想IP、仮想IPを設定するネットワークインターフェース名を環境に合わせて変更してください。 + + +[root@server1 ~]# vi /etc/pgpool-II/escalation.sh +... +PGPOOLS=(server1 server2 server3) +VIP=192.168.100.50 +DEVICE=enp0s8 +CIDR_NETMASK=24 +... + + + + + Watchdogノードの数が偶数の場合は、 + パラメータをonにする必要があります。 + + + + + use_watchdog = onの場合は、Pgpool-IIノード番号をpgpool_node_idに設定する必要があります。 + 詳細はを参照ください。 + + + + + + ログの設定 + + Pgpool-II 4.2以降、ログ収集プロセスが追加されました。 + RPM パッケージを使用してインストールした場合、ログ収集プロセス(logging_collector)はデフォルトで有効になっています。 + ログファイルはデフォルトで/var/log/pgpool_logに出力されます。 + 要件に合わせて、ログ関連の設定パラメータを適切に調整してください。 + + +log_destination = 'stderr' +logging_collector = on +log_directory = '/var/log/pgpool' +log_filename = 'pgpool-%a.log' +log_truncate_on_rotation = on +log_rotation_age = 1d + + + これで、server1におけるPgpool-IIの設定は完了です。 + 最後に、設定ファイルを他のサーバserver2およびserver3にコピーします。 + + +[root@server1 ~]# scp -p /etc/pgpool-II/{*.conf,*.sh,pool_passwd} server2:/etc/pgpool-II/ +[root@server1 ~]# ssh server2 "chown postgres:postgres /etc/pgpool-II/{*.conf,*.sh,pool_passwd}" +[root@server1 ~]# scp -p /etc/pgpool-II/{*.conf,*.sh,pool_passwd} server3:/etc/pgpool-II/ +[root@server1 ~]# ssh server3 "chown postgres:postgres /etc/pgpool-II/{*.conf,*.sh,pool_passwd}" + + + + + + 動作確認 + + これから、動作確認を行います。 + + + Pgpool-IIの起動と停止 + + + + Pgpool-IIの起動 + + + Pgpool-IIを起動します。 + + + Pgpool-IIを起動する前に、PostgreSQLをあらかじめ起動する必要があります。 + PostgreSQLプライマリサーバがまだ起動していない場合は、まず次のコマンドを実行してPostgreSQL起動します。 + + +[root@server1 ~]# su - postgres -c "/usr/pgsql-18/bin/pg_ctl start" + + + server1server2およびserver3で以下のコマンドを実行し、Pgpool-IIを起動します。 + + +[全サーバ]# systemctl start pgpool.service + + + + + Pgpool-IIの停止 + + + Pgpool-IIを停止するときに、以下のコマンドを実行してPgpool-IIを停止します。 + + + また、PostgreSQLを停止する場合は、Pgpool-IIを先に停止する必要があります。 + Pgpool-IIが起動している状態でPostgreSQLを停止する、想定外のフェイルオーバが起きてしまうので、ご注意ください。 + + +[全サーバ]# systemctl stop pgpool.service + + + + + + + PostgreSQLスタンバイサーバの作成 + + まず、Pgpool-IIのオンラインリカバリ機能を利用し、server2server3をスタンバイサーバとして構築し、Pgpool-II管理下に追加します。 + + + 仮想IP経由でPgpool-IIに接続し、バックエンドノードのステータスを確認します。 + 下記の結果のように、プライマリサーバがserver1で起動しており、server2server3は「down」状態になっています。 + + +[いずれかのサーバ]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | primary | primary | 0 | true | 0 | | | 2023-11-10 15:30:14 + 1 | server2 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false | 0 | | | 2023-11-10 15:30:14 + 2 | server3 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false | 0 | | | 2023-11-10 15:30:14 +(3 rows) + + + オンラインリカバリ機能を使用するには、pcp_recovery_nodeコマンドを実行します。 + pcp_recovery_nodeコマンドでrecovery_1st_stagepgpool_remote_startスクリプトが実行されるので(recovery_1st_stagerecovery_1st_stage_commandパラメータに設定したスクリプト)、この2つのスクリプトが現在稼働中のプライマリサーバserver1のデータベースクラスタに存在することを確認してください。 + + +[いずれかのサーバ]# pcp_recovery_node -h 192.168.100.50 -p 9898 -U pgpool -n 1 -W +Password: +pcp_recovery_node -- Command Successful + +[いずれかのサーバ]# pcp_recovery_node -h 192.168.100.50 -p 9898 -U pgpool -n 2 -W +Password: +pcp_recovery_node -- Command Successful + + + server2server3PostgreSQLがスタンバイとして起動していることを確認します。 + + +[いずれかのサーバ]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 15:30:14 + 1 | server2 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 16:32:33 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | false | 0 | streaming | async | 2023-11-10 16:33:08 +(3 rows) + + + + + Watchdogリーダー/スタンバイの切り替え + + pcp_watchdog_infoPgpool-II + のWatchdogの情報を確認します。 + 最初に起動したPgpool-IIがリーダーになります。 + + +[いずれかのサーバ]# pcp_watchdog_info -h 192.168.100.50 -p 9898 -U pgpool -W +Password: +3 3 YES server1:9999 Linux server1 server1 + +server1:9999 Linux server1 server1 9999 9000 4 LEADER 0 MEMBER # 最初に起動したPgpool-IIがリーダーになる +server2:9999 Linux server2 server2 9999 9000 7 STANDBY 0 MEMBER # スタンバイとして稼働している +server3:9999 Linux server3 server3 9999 9000 7 STANDBY 0 MEMBER # スタンバイとして稼働している + + + リーダーであるserver1Pgpool-IIを停止し、server2またはserver3のどちらかがリーダーになることを確認します。 + server1Pgpool-IIを停止するにはPgpool-IIを停止するか、マシンをシャットダウンします。ここでは、Pgpool-IIを停止します。 + + +[root@server1 ~]# systemctl stop pgpool.service + +[root@server1 ~]# pcp_watchdog_info -p 9898 -h 192.168.100.50 -U pgpool -W +Password: +3 3 YES server2:9999 Linux server2 server2 + +server2:9999 Linux server2 server2 9999 9000 4 LEADER 0 MEMBER # server2がリーダーに昇格 +server1:9999 Linux server1 server1 9999 9000 10 SHUTDOWN 0 MEMBER # server1が停止している +server3:9999 Linux server3 server3 9999 9000 7 STANDBY 0 MEMBER # server3がタンバイとして稼働している + + + 先ほど停止したPgpool-IIを再起動し、スタンバイとして起動していることを確認します。 + + +[root@server1 ~]# systemctl start pgpool.service + +[root@server1 ~]# pcp_watchdog_info -p 9898 -h 192.168.100.50 -U pgpool -W +Password: +3 3 YES server2:9999 Linux server2 server2 + +server2:9999 Linux server2 server2 9999 9000 4 LEADER 0 MEMBER +server1:9999 Linux server1 server1 9999 9000 7 STANDBY 0 MEMBER +server3:9999 Linux server3 server3 9999 9000 7 STANDBY 0 MEMBER + + + + + 自動フェイルオーバ + + psqlで仮想IP経由でPgpool-IIに接続し、バックエンドの情報を確認します。 + + +[いずれかのサーバ]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 15:30:14 + 1 | server2 | 5432 | up | up | 0.333333 | standby | standby | 0 | false | 0 | streaming | async | 2023-11-10 16:32:33 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 16:33:08 +(3 rows) + + + 次にプライマリであるserver1PostgreSQLを停止し、 + フェイルオーバするかどうか確認してみます。 + + +[root@server1 ~]# su - postgres -c "/usr/pgsql-18/bin/pg_ctl -m immediate stop" + + + ノード1を停止した後に、フェイルオーバが発生し、server2が + プライマリに昇格したことを確認します。 + + +[いずれかのサーバ]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false | 0 | | | 2023-11-10 17:05:40 + 1 | server2 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 17:05:40 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 17:05:51 +(3 rows) + + + + server3が新しいプライマリserver2のスタンバイとして起動していることを確認します。 + + + +[server3]# psql -h server3 -p 5432 -U pgpool postgres -c "select pg_is_in_recovery()" +pg_is_in_recovery +------------------- +t + +[server2]# psql -h server2 -p 5432 -U pgpool postgres -c "select pg_is_in_recovery()" +pg_is_in_recovery +------------------- +f + +[server2]# psql -h server2 -p 5432 -U pgpool postgres -c "select * from pg_stat_replication" -x +-[ RECORD 1 ]----+------------------------------ +pid | 7198 +usesysid | 16385 +usename | repl +application_name | server3 +client_addr | 192.168.100.53 +client_hostname | +client_port | 40916 +backend_start | 2023-11-10 17:10:03.067241+00 +backend_xmin | +state | streaming +sent_lsn | 0/12000260 +write_lsn | 0/12000260 +flush_lsn | 0/12000260 +replay_lsn | 0/12000260 +write_lag | +flush_lag | +replay_lag | +sync_priority | 0 +sync_state | async +reply_time | 2023-11-10 17:17:23.886477+00 + + + + + オンラインリカバリ + + 次に、Pgpool-IIのオンラインリカバリ機能を利用し、 + 先ほど停止した旧プライマリサーバをスタンバイとして復旧させます。 + pcp_recovery_nodeコマンドでrecovery_1st_stagepgpool_remote_startスクリプトが実行されるので(recovery_1st_stagerecovery_1st_stage_commandパラメータに設定したスクリプト)、この2つのスクリプトが現在稼働中のプライマリサーバserver2のデータベースクラスタに存在することを確認してください。 + + +[いずれかのサーバ]# pcp_recovery_node -h 192.168.100.50 -p 9898 -U pgpool -n 0 -W +Password: +pcp_recovery_node -- Command Successful + + + server1がスタンバイとして起動していることを確認します。 + + +[any server]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: +node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 17:22:03 + 1 | server2 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 17:05:40 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | false | 0 | streaming | async | 2023-11-10 17:05:51 +(3 rows) + + + 以上で、動作確認が完了です。 + + + +
diff --git a/doc.ja/src/sgml/example-replication-si-mode.sgml b/doc.ja/src/sgml/example-replication-si-mode.sgml new file mode 100644 index 000000000..7c27df3e6 --- /dev/null +++ b/doc.ja/src/sgml/example-replication-si-mode.sgml @@ -0,0 +1,912 @@ + + + + ネイティブレプリケーション/スナップショットアイソレーションモードの構築の例 + + ここでは、Pgpool-IIのネイティブレプリケーションモードおよびスナップショットアイソレーションモードの設定例を示します。 + + + で紹介した「ストリーミングレプリケーションモード」では、 + PostgreSQLのストリーミングレプリケーション機能でレプリケーションを行いますが、 + ネイティブレプリケーションモードでは、Pgpool-IIが書き込みクエリをすべてのPostgreSQLで実行することで、レプリケーションを行います。 + + + また、スナップショットアイソレーションモードはネイティブレプリケーションモードにスナップショットの管理機能を追加しており、ノードを跨る読み取りの一貫性を保証できます。 + Pgpool-IIが書き込みクエリをすべてのPostgreSQLで実行し、 + レプリケーションを行う点はネイティブレプリケーションモードと同じです。 + + + この設定例ではPostgreSQL 18を使っています。 + + + + 全体構成 + + この設定例では、Pgpool-II 1台、PostgreSQL 3台を用いて、Pgpool-IIのレプリケーション機能を説明します。 + + + 物理サーバを3台用意し、それぞれのホスト名は 「server1」、「server2」、「server3」 とします。使用するOSはすべてRocky Linux 10とします。 + それぞれのサーバにPostgreSQLをインストールし、その中の1台にPgpool-IIをインストールします。 + + + また、この設定例では、レプリケーション機能を利用するための必要最低限の設定を紹介しています。 + 本番環境で利用する場合、Pgpool-IIの冗長化機能Watchdogを有効にすることをお勧めします。 + Watchdogの設定例はをご参照ください。 + + + + ホスト名とIPアドレス + + + + ホスト名 + IPアドバイス + 説明 + + + + + server1 + 192.168.137.101 + PostgreSQLノード0、Pgpool-II + + + server2 + 192.168.137.102 + PostgreSQLノード1 + + + server3 + 192.168.137.103 + PostgreSQLノード2 + + + +
+ + + PostgreSQLのバージョンと設定情報 + + + + 項目 + + 説明 + + + + + PostgreSQLバージョン + 18.0 + - + + + ポート番号 + 5432 + - + + + $PGDATA + /var/lib/pgsql/18/data + - + + + アーカイブモード + 有効 + /var/lib/pgsql/archivedir + + + +
+ + + Pgpool-IIのバージョンと設定情報 + + + + 項目 + + 説明 + + + + + Pgpool-IIバージョン + 4.6.1 + - + + + ポート番号 + 9999 + Pgpool-IIが接続を受け付けるポート番号 + + + 9898 + PCPプロセスが接続を受け付けるポート番号 + + + 設定ファイル + /etc/pgpool-II/pgpool.conf + Pgpool-IIの設定ファイル + + + Pgpool-II起動ユーザ + postgres (Pgpool-II 4.1以降) + Pgpool-II 4.0以前のバージョンでは、デフォルトではrootでPgpool-IIを起動する + + + Pgpool-II動作モード + ネイティブレプリケーションモード + - + + + スナップショットアイソレーションモード + ネイティブレプリケーションモードの拡張 + + + +
+
+ + + インストール + + この設定例ではYUMを使用してPostgreSQLおよびPgpool-IIをインストールします。 + + + PostgreSQLのインストールはPostgreSQLコミュニティのリポジトリを使います。 + + +[全サーバ]# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm +[全サーバ]# yum install -y postgresql18-server + + + + Pgpool-IIのインストールはPgpool-II開発コミュニティが提供するYumリポジトリを用いてインストールします。 + + + Pgpool-II関連のパッケージはPostgreSQLコミュニティのリポジトリにもあるため、 + PostgreSQLコミュニティのリポジトリからPgpool-IIをインストールしないように/etc/yum.repos.d/pgdg-redhat-all.repoにexclude設定を追加します。 + + +[全サーバ]# vi /etc/yum.repos.d/pgdg-redhat-all.repo + + + 以下は、/etc/yum.repos.d/pgdg-redhat-all.repoの設定例です。 + + +[pgdg-common] +... +exclude=pgpool* + + +[pgdg18] +... +exclude=pgpool* + +[pgdg17] +... +exclude=pgpool* + +[pgdg16] +... +exclude=pgpool* + +[pgdg15] +... +exclude=pgpool* + +[pgdg14] +... +exclude=pgpool* + +[pgdg13] +... +exclude=pgpool* + + + + Pgpool-IIをインストールします。 + + +[全サーバ]# yum install -y https://www.pgpool.net/yum/rpms/4.6/redhat/rhel-10-x86_64/pgpool-II-release-4.6-1.noarch.rpm +[全サーバ]# yum install -y pgpool-II-pg18-* + + + + + 事前設定 + + PostgreSQL、Pgpool-IIの設定の前に、以下の設定を行います。 + + + + SSHの設定 + + オンラインリカバリ機能を利用するには、すべてのサーバにパスワードなしでSSH接続できるように設定する必要があります。 + 全サーバで以下のコマンドを実行し、SSHの設定を行います。 + 生成される鍵ファイル名はid_rsa_pgpoolとします。 + + +[全サーバ]# su - postgres +[全サーバ]$ mkdir ~/.ssh && chmod 700 ~/.ssh +[全サーバ]$ ssh-keygen -t rsa -f ~/.ssh/id_rsa_pgpool + + + 次に、公開鍵id_rsa_pgpool.pubを各サーバの/var/lib/pgsql/.ssh/authorized_keysファイルに追加します。 + + + 設定後、postgresユーザでssh postgres@serverX -i ~/.ssh/id_rsa_pgpoolコマンドを実行し、パスワードなしでログインできることを確認してください。 + + + + + 公開鍵認証によるログインに失敗した場合には、以下を確認してください。 + + + + /etc/ssh/sshd_configで公開鍵認証が許可されていることを確認します。 + + + + +PubkeyAuthentication yes + + + + + SELinuxを有効化している場合は、SSH公開鍵認証(パスワードなし)が失敗する可能性があるので、すべてのサーバで以下のコマンドを実行する必要があります。 + + + + +[全サーバ]# su - postgres +[全サーバ]$ restorecon -Rv ~/.ssh + + + + + + + .pgpassの作成 + + PostgreSQLユーザのパスワード入力を求められることなく、 + オンラインリカバリのスクリプトを実行できるように、すべてのサーバにて + postgresユーザのホームディレクトリ/var/lib/pgsqlに + .pgpassを作成し、パーミッションを 600 に設定しておきます。 + + +[全サーバ]# su - postgres +[全サーバ]$ vi ~/.pgpass +(以下を追加) +server1:5432:replication:repl:<replユーザのパスワード> +server2:5432:replication:repl:<replユーザのパスワード> +server3:5432:replication:repl:<replユーザのパスワード> +server1:5432:postgres:postgres:<postgresユーザのパスワード> +server2:5432:postgres:postgres:<postgresユーザのパスワード> +server3:5432:postgres:postgres:<postgresユーザのパスワード> +[全サーバ]$ chmod 600 ~/.pgpass + + + + + ファイアーウォールの設定 + + Pgpool-IIPostgreSQLに接続する際には、 + ファイアーウォールによって目的のポートが開けられていなければなりません。 + Rocky Linux 10/RHEL 10の場合、以下のように設定します。 + + +[全サーバ]# firewall-cmd --permanent --zone=public --add-service=postgresql +[全サーバ]# firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp +[全サーバ]# firewall-cmd --reload + + + Watchdogを利用する場合は、9000と9694ポートも開放する必要があります。 + + +[全サーバ]# firewall-cmd --permanent --zone=public --add-port=9000/tcp --add-port=9694/udp + + + + + + <productname>PostgreSQL</productname>の設定 + + ここでは、PostgreSQLサーバの作成・設定を説明します。 + + + WALアーカイブ機能を有効にします。 + すべてのサーバにてWALを格納するディレクトリ/var/lib/pgsql/archivedirを作成します。 + + +[全サーバ]# su - postgres +[全サーバ]$ mkdir /var/lib/pgsql/archivedir + + + server1上でPostgreSQLのmainノードを作成します。他の2台のreplicaノードはPgpool-IIのオンラインリカバリ機能によって作成されるため、ここでの作成・設定は不要です。 + + + server1で以下のコマンドを実行し、PostgreSQLデータベースクラスタを作成します。 + + +[server1]# su - postgres +[server1]$ /usr/pgsql-18/bin/initdb -E UTF8 --no-locale + + + 次にserver1にて、設定ファイル$PGDATA/postgresql.confを以下のように編集します。 + + +[server1]$ vi $PGDATA/postgresql.conf +(以下を追加) +listen_addresses = '*' +archive_mode = on +archive_command = 'cp "%p" "/var/lib/pgsql/archivedir/%f"' + + + + Pgpool-IIサーバとPostgreSQLバックエンドサーバが + 同じサブネットワークにあることを想定し、各ユーザがscram-sha-256認証方式で接続できるように、 + pg_hba.confを編集しておきます。 + + +[server1]$ vi $PGDATA/pg_hba.conf +(以下を追加) +host all all samenet scram-sha-256 +host replication all samenet scram-sha-256 + + + + server1で以下のコマンドを実行し、PostgreSQLを起動します。 + + +[server1]$ /usr/pgsql-18/bin/pg_ctl start + + + + Pgpool-IIのヘルスチェックでPostgreSQLのユーザを設定する必要があります。 + セキュリティ上の理由で、この設定例ではスーパーユーザを使わないようにします。 + Pgpool-IIのヘルスチェック用のユーザpgpoolを作成します。 + また、PostgreSQLレプリケーション専用ユーザreplを作成します。 + Pgpool-II 4.0からSCRAM認証を利用できるようになりました。 + この設定例では、scram-sha-256認証方式を利用します。 + + + + ユーザ + + + + ユーザ名 + パスワード + 備考 + + + + + repl + repl + PostgreSQLのレプリケーション専用ユーザ + + + pgpool + pgpool + + Pgpool-IIのヘルスチェック専用ユーザ() + + + + postgres + postgres + オンラインリカバリを実行するユーザ + + + +
+ + +[server1]$ psql -U postgres -p 5432 +postgres=# SET password_encryption = 'scram-sha-256'; +postgres=# CREATE ROLE pgpool WITH LOGIN; +postgres=# CREATE ROLE repl WITH REPLICATION LOGIN; +postgres=# \password pgpool +postgres=# \password repl +postgres=# \password postgres + + + + スナップショットアイソレーションモードを利用する場合 + + スナップショットアイソレーションモードはPostgreSQLのトランザクション隔離レベルが「repeatable read」の場合のみ使用できます。スナップショットアイソレーションモードを利用する場合、 + postgresql.confにdefault_transaction_isolation = 'repeatable read'を設定しておきます。 + + +[server1]$ vi $PGDATA/postgresql.conf +(以下を追加) +default_transaction_isolation = 'repeatable read' + + +
+ + + <productname>Pgpool-II</productname>の設定 + + YUMからインストールした場合、Pgpool-IIの設定ファイルは/etc/pgpool-II/pgpool.confにあります。このファイルを編集し、Pgpool-IIの設定を行います。 + + + + クラスタリングモード + + Pgpool-IIのクラスタリングモードを設定します。 + + + + + ネイティブレプリケーションモードの場合 + + +backend_clustering_mode = native_replication + + + + + スナップショットアイソレーションモードの場合 + + +backend_clustering_mode = snapshot_isolation + + + + + + + listen_addresses + + Pgpool-IIが全てのIPアドレスから接続を受け付けるように、 + パラメータに'*'を設定します。 + + +listen_addresses = '*' + + + + + ヘルスチェック + + 定期的にPostgreSQLに接続し、死活監視を行うために、ヘルスチェックを有効にします。 + のデフォルト値が0で、これはヘルスチェックが無効であることを意味します。 + また、ネットワークが不安定な場合には、バックエンドが正常であるにも関わらず、 + ヘルスチェックに失敗し、フェイルオーバや縮退運転が発生してしまう可能性があります。 + そのようなヘルスチェックの誤検知を防止するため、ヘルスチェックのリトライ回数を + health_check_max_retries = 3 に設定しておきます。 + この設定例では、pgpool.confに指定せず、 + ファイルに作成します。 + 作成方法については後述のを参照ください。 + Pgpool-II 4.0から、が空の場合、 + Pgpool-IIは空のパスワードを使用する前に、 + まずファイルからに + 指定したユーザのパスワードを取得できるか試みます。 + + +health_check_period = 5 +health_check_timeout = 30 +health_check_user = 'pgpool' +health_check_password = '' +health_check_max_retries = 3 + + + + + バックエンドの設定 + + また、バックエンド情報を前述のserver1server2 + 及びserver3の設定に従って設定しておきます。 + 複数バックエンドノードを定義する場合、以下のbackend_*などのパラメータ名の + 末尾にノードIDを表す数字を付加することで複数のバックエンドを指定することができます。 + + +# - Backend Connection Settings - + +backend_hostname0 = 'server1' +backend_port0 = 5432 +backend_weight0 = 1 +backend_data_directory0 = '/var/lib/pgsql/18/data' +backend_flag0 = 'ALLOW_TO_FAILOVER' + +backend_hostname1 = 'server2' +backend_port1 = 5432 +backend_weight1 = 1 +backend_data_directory1 = '/var/lib/pgsql/18/data' +backend_flag1 = 'ALLOW_TO_FAILOVER' + +backend_hostname2 = 'server3' +backend_port2 = 5432 +backend_weight2 = 1 +backend_data_directory2 = '/var/lib/pgsql/18/data' +backend_flag2 = 'ALLOW_TO_FAILOVER' + + + + + オンラインリカバリの設定 + + 続いて、オンラインリカバリを行うためのPostgreSQLのユーザ名 + 及びオンラインリカバリ時に呼び出されるコマンドrecovery_1st_stage_command + とrecovery_2nd_stage_commandを設定します。 + オンラインリカバリで実行されるpgpool_recovery関数は + PostgreSQLのスーパーユーザ権限が必要なため、 + recovery_userスーパーユーザを指定しなければなりません。 + ここでは、postgresユーザを指定します。 + + +recovery_user = 'postgres' +recovery_password = '' + +recovery_1st_stage_command = 'recovery_1st_stage.sh' +recovery_2nd_stage_command = 'recovery_2nd_stage.sh' + + + ネイティブレプリケーションモード/スナップショットアイソレーションモード専用のオンラインリカバリ用のサンプルスクリプトreplication_mode_recovery_1st_stage.sample、 + replication_mode_recovery_2nd_stage.sample + 及びpgpool_remote_start.sampleは + /etc/pgpool-II/配下にインストールされていますので、 + これらのファイルをmainノード(server1)のデータベースクラスタ配下に配置します。 + + +[server1]# cp -p /etc/pgpool-II/sample_scripts/replication_mode_recovery_1st_stage.sample /var/lib/pgsql/18/data/recovery_1st_stage.sh +[server1]# cp -p /etc/pgpool-II/sample_scripts/replication_mode_recovery_2nd_stage.sample /var/lib/pgsql/18/data/recovery_2nd_stage.sh +[server1]# cp -p /etc/pgpool-II/sample_scripts/pgpool_remote_start.sample /var/lib/pgsql/18/data/pgpool_remote_start +[server1]# chown postgres:postgres /var/lib/pgsql/18/data/{recovery_1st_stage.sh,recovery_2nd_stage.sh,pgpool_remote_start} + + + 基本的にはPGHOMEを環境に合わせて変更すれば、動作します。 + + +[server1]# vi /var/lib/pgsql/18/data/recovery_1st_stage.sh +... +PGHOME=/usr/pgsql-18 +... + +[server1]# vi /var/lib/pgsql/18/data/recovery_2nd_stage.sh +... +PGHOME=/usr/pgsql-18 +... + +[server1]# vi /var/lib/pgsql/18/data/pgpool_remote_start +... +PGHOME=/usr/pgsql-18 +... + + + + また、オンラインリカバリ機能を使用するには、pgpool_recoverypgpool_remote_startpgpool_switch_xlogの各関数をあらかじめで指定されたデータベース(デフォルトは'postgres'です)に作成しておく必要があります。 + server1上で以下のコマンドを実行し、これらの関数をpostgresに作成します。 + にデフォルト以外の値が設定されている場合は、postgresをその設定値に置き換えてください。 + + +[server1]# psql -U postgres postgres -c "CREATE EXTENSION pgpool_recovery" + + + + recovery_1st_stageスクリプトはテーブルスペースに対応していません。 + テーブルスペースを使っている場合は、スクリプトを自分で変更する必要があります。 + + + + + + クライアント認証の設定 + + PostgreSQLの設定の章で、 + Pgpool-IIPostgreSQLの間に + 認証方式をscram-sha-256に設定しました。 + この設定例では、クライアントとPgpool-IIの間でも + scram-sha-256認証方式を利用し接続するように設定します。 + Pgpool-IIのクライアント認証の設定ファイルは + pool_hba.confと呼ばれ、YUMからインストールする場合、 + デフォルトでは/etc/pgpool-II配下にインストールされます。 + デフォルトではpool_hba.confによる認証は無効になっているので、 + pgpool.confで以下の設定をonに変更します。 + + +enable_pool_hba = on + + + pool_hba.confのフォーマットはPostgreSQLの + pg_hba.confとほとんど同じです。 + pgpoolpostgresユーザの認証方式をscram-sha-256認証に設定します。 + + +[server1]# vi /etc/pgpool-II/pool_hba.conf +(以下を追加) +host all pgpool 0.0.0.0/0 scram-sha-256 +host all postgres 0.0.0.0/0 scram-sha-256 + + + + Pgpool-II 4.1からpgpool.confファイル内の + 、 + には + AES256暗号化形式、平文形式、md5ハッシュ形式が指定できます。 + Pgpool-II 4.0ではAES256暗号化形式、 + 平文形式が指定可能で、それ以前のバージョンでは平文形式のみが指定可能です。 + + + + Pgpool-IIのクライアント認証で用いるデフォルトのパスワードファイル名はpool_passwdです。 + scram-sha-256認証を利用する場合、 + Pgpool-IIはそれらのパスワードを復号化するために復号鍵が必要となります。 + 全サーバで復号鍵ファイルをPgpool-IIの起動ユーザ + postgres (Pgpool-II 4.0以前のバージョンではroot) のホームディレクトリ配下に作成します。 + + +[server1]# su - postgres +[server1]$ echo '任意の文字列' > ~/.pgpoolkey +[server1]$ chmod 600 ~/.pgpoolkey + + + 「pg_enc -m -k /path/to/.pgpoolkey -u username -p」を実行すると、 + ユーザ名とAES256で暗号化したパスワードのエントリがに登録されます。 + がまだ存在しなければ、pgpool.confと同じディレクトリ内に作成されます。 + + +[server1]$ pg_enc -m -k ~/.pgpoolkey -u pgpool -p +db password: [pgpoolユーザのパスワード] +[server1]$ pg_enc -m -k ~/.pgpoolkey -u postgres -p +db password: [postgresユーザのパスワード] + +[server1]$ cat /etc/pgpool-II/pool_passwd +pgpool:AESheq2ZMZjynddMWk5sKP/Rw== +postgres:AESHs/pWL5rtXy2IwuzroHfqg== + + + + + PCPパスワード + + PCPコマンドを使用するにはユーザ認証が必要になるので、 + ユーザ名とmd5ハッシュに変換されたパスワードを + "username:encrypted password"の形式で + pcp.confファイルに設定します。 + + + 以下のようにコマンドを利用し、 + ハッシュ化されたpgpoolユーザのパスワードエントリを/etc/pgpool-II/pcp.confに追加します。 + + +[全サーバ]# echo 'pgpool:'`pg_md5 PCPコマンドパスワード` >> /etc/pgpool-II/pcp.conf + + + + + ログの設定 + + Pgpool-II 4.2以降、ログ収集プロセスが追加されました。 + ここでは、ログ収集プロセス(logging_collector)を有効にします。 + + +log_destination = 'stderr' +logging_collector = on +log_directory = '/var/log/pgpool' +log_filename = 'pgpool-%Y-%m-%d_%H%M%S.log' +log_truncate_on_rotation = on +log_rotation_age = 1d +log_rotation_size = 10MB + + + server1にログファイルを格納するディレクトリを作成します。 + + +[server1]# mkdir /var/log/pgpool_log/ +[server1]# chown postgres:postgres /var/log/pgpool_log/ + + + + + + システムの起動と停止 + + Pgpool-IIを起動する前に、 + バックエンドのPostgreSQLをあらかじめ起動する必要があります。 + また、PostgreSQLを停止する場合、 + Pgpool-IIを先に停止する必要があります。 + 以下のコマンドでPgpool-IIの起動・停止を行います。 + + + + + Pgpool-IIの起動 + + +# systemctl start pgpool.service + + + + + Pgpool-IIの停止 + + +# systemctl stop pgpool.service + + + + + + + 動作確認 + + これから、動作確認を行います。 + まず、server1で以下のコマンドでPgpool-IIを起動します。 + + +[server1]# systemctl start pgpool.service + + + + PostgreSQLサーバの構築 + + まず、Pgpool-IIのオンラインリカバリ機能を利用し、PostgreSQLノード1、ノード2を構築します。 + + +[server1]# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 1 +Password: +pcp_recovery_node -- Command Successful + +[server1]# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 2 +Password: +pcp_recovery_node -- Command Successful + + + ノード0がmainノードとして起動しており、ノード1とノード2がreplicaとして起動していることを確認します。 + + +# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change + ---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | main | main | 0 | true | 0 | | | 2021-12-02 16:48:21 + 1 | server2 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 + 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 +(3 rows) + + + + + レプリケーション機能の検証 + + pgbenchを使って、レプリケーション機能を試してみましょう。 + + +[server1]# /usr/pgsql-18/bin/createdb test -U postgres -p 9999 +[server1]# /usr/pgsql-18/bin/pgbench -h server1 -U postgres -i -p 9999 test + + + Pgpool-IIのレプリケーション機能が正しく動いているかどうか確かめるために、 + それぞれのノードに接続して、同じ結果を返すかどうか見てみます。 + + +[server1]# /usr/pgsql-18/bin/psql -h server1 -U postgres -p 5432 test +test=# \d + List of relations + Schema | Name | Type | Owner +--------+------------------+-------+---------- + public | pgbench_accounts | table | postgres + public | pgbench_branches | table | postgres + public | pgbench_history | table | postgres + public | pgbench_tellers | table | postgres +(4 rows) + +[server1]# /usr/pgsql-18/bin/psql -h server2 -U postgres -p 5432 test +test=# \d + List of relations + Schema | Name | Type | Owner +--------+------------------+-------+---------- + public | pgbench_accounts | table | postgres + public | pgbench_branches | table | postgres + public | pgbench_history | table | postgres + public | pgbench_tellers | table | postgres +(4 rows) + +[server1]# /usr/pgsql-18/bin/psql -h server3 -U postgres -p 5432 test +test=# \d + List of relations + Schema | Name | Type | Owner +--------+------------------+-------+---------- + public | pgbench_accounts | table | postgres + public | pgbench_branches | table | postgres + public | pgbench_history | table | postgres + public | pgbench_tellers | table | postgres +(4 rows) + + + server1、server2、server3のPostgreSQLは、同一の結果を返しています。 + + + 次に、pgbenchをしばらく走らせて、結果を見てみます。 + + +[server1]# /usr/pgsql-18/bin/pgbench -h server1 -U postgres -p 9999 -T 10 test + + + すべてのPostgreSQLは、同一の結果を返しています。 + + +[server1]# /usr/pgsql-18/bin/psql -h server1 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" +Password for user postgres: + sum +-------- + -99710 +(1 row) + +[server1]# /usr/pgsql-18/bin/psql -h server2 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" +Password for user postgres: + sum +-------- + -99710 +(1 row) + +[server1]# /usr/pgsql-18/bin/psql -h server3 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" +Password for user postgres: + sum +-------- + -99710 +(1 row) + + + + + ノード障害 + + 次にmainノードであるserver1PostgreSQLを停止し、 + mainノードの切り替えを確認してみます。 + + +[server1]# su - postgres -c "/usr/pgsql-18/bin/pg_ctl -m i stop" + + + ノード0を停止した後に、ノード0が切り離されて、mainノードの切り替えが発生することを確認します。 + + +[server1]# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | down | down | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:57:45 + 1 | server2 | 5432 | up | up | 0.333333 | main | main | 1 | true | 0 | | | 2021-12-02 16:48:21 + 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 +(3 rows) + + + + + オンラインリカバリ + + 次に、Pgpool-IIのオンラインリカバリ機能を利用し、 + 先ほど停止した旧mainノードを復旧させます。 + + +# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 0 +Password: +pcp_recovery_node -- Command Successful + + + ノード1がmainノードとして起動していることを確認します。 + + +# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | main | main | 0 | true | 0 | | | 2021-12-02 16:57:45 + 1 | server2 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 + 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 +(3 rows) + + + 以上で、動作確認が完了です。 + + + + +
+ diff --git a/doc.ja/src/sgml/examples.sgml b/doc.ja/src/sgml/examples.sgml index 6c08ce0db..aa0f5b867 100644 --- a/doc.ja/src/sgml/examples.sgml +++ b/doc.ja/src/sgml/examples.sgml @@ -1,2432 +1,30 @@ - - 例集 - - - - -様々な例 - - - - - - - 設定の例 - - - - 基本設定の例 - - - - さあ始めましょう - - -ここでは、レプリケーションを行うための準備として、Pgpool-II のインストールや設定、データベースノードの準備について説明します。 - - - - - <productname>Pgpool-II</productname>のインストール - - -Pgpool-IIのインストールはとても簡単です。 -ソースのtar ballを展開したディレクトリで以下のようにコマンドを実行します。 - -$ ./configure -$ make -$ make install - - -configureスクリプトはシステム情報を収集しコンパイル処理に利用します。 -configureスクリプトにコマンドライン引数を指定することにより、インストール先ディレクトリなど、デフォルトの動作を変更することができます。 -デフォルトではPgpool-II は/usr/localディレクトリ以下にインストールされます。 - - - -makeコマンドはソースコードはコンパイルし、make installコマンドで実行可能ファイルがインストールされます。 -インストール先ディレクトリに書き込み権限を持っている必要があります。 -ここでは、Pgpool-II/usr/localにインストールすることにします。 - - - - -Pgpool-IIはPostgreSQL 7.4 以降のlibpqライブラリ(3.0 プロトコル)を必要とします。 - - - - -configureスクリプトが以下のエラーメッセージを表示した場合、libpqライブラリがインストールされていないか、バージョンが3.0でない可能性があります。 - -configure: error: libpq is not installed or libpq is old - - -プロトコルのバージョンが3.0のlibpqライブラリがインストールされているにも係わらず上記のエラーメッセージが表示される場合、configureスクリプトにlibpqライブラリが認識されていない可能性があります。 -configureスクリプトは標準では/usr/local/pgsqlディレクトリ以下からlibpqライブラリを検索します。 -PostgreSQLのインストール先が/usr/local/pgsqlディレクトリ以下でなければ、configureスクリプトを実行する際にコマンドライン引数として--with-pgsql--with-pgsql-includedir--with-pgsql-libdirオプションを指定してください。 - - - - - - 設定ファイルの作成 - - -Pgpool-IIの設定パラメータはpgpool.confファイルに保存されてします。 -ファイルは、1 行ごとにパラメータ名 = 値という書式です。 -Pgpool-II をインストールすると、pgpool.conf.sampleファイルが作成されます。 -それをpgpool.confというファイル名にコピーしてから編集するといいでしょう。 - -$ cp /usr/local/etc/pgpool.conf.sample /usr/local/etc/pgpool.conf - - -Pgpool-II はローカルホストからのポート番号9999への接続のみを受け付けます。 -Pgpool-II と異なるホストからの接続を受け付けたい場合は、'*'に設定します。 - -listen_addresses = 'localhost' -port = 9999 - - -ここではデフォルトのパラメータを使うことにします。 - - - - - - <acronym>PCP</acronym>コマンドの設定 - - - -Pgpool-IIには、データベースノードの情報取得やPgpool-II停止などをネットワーク越しに行える管理目的のインターフェイスがあります。 -PCPコマンドを使用するにはユーザ認証が必要になります。 -この認証はPostgreSQLユーザの認証とは異なります。 -ユーザ名とパスワードがpcp.confファイルに定義されている必要があります。 -このファイルでは、1行ごとにユーザ名とパスワードがペアとしてリストされており、これららコロン(:)で区切られています。 -パスワードはMD5ハッシュ形式で暗号化されています。 - - -postgres:e8a48653851e28c69d0506508fb27fc5 - - - -Pgpool-II をインストールするとサンプルとしてpcp.conf.sampleが自動的に生成されます。 -それをpcp.confというファイル名にコピーしてから編集するといいでしょう。 - -$ cp /usr/local/etc/pcp.conf.sample /usr/local/etc/pcp.conf - - -パスワードをMD5ハッシュ形式に変換する際には、Pgpool-IIとともにインストールされるpg_md5コマンドを使用します。 -pg_md5コマンドは、コマンドライン引数として文字列を指定すると、それをMD5ハッシュ化したものを表示します。 -例えば、以下のようにコマンドライン引数として"postgres"を指定して実行すると、それをMD5ハッシュ化しテキストが標準出力に表示されます。 - -$ /usr/bin/pg_md5 postgres -e8a48653851e28c69d0506508fb27fc5 - - -PCPコマンドはネットワークを通して実行されるので、ポート番号をpgpool.confファイルのパラメータに設定します。 -ここでは、のデフォルトである9898を使用することにします。 - -pcp_port = 9898 - - - - - - - - データベースノードの準備 - - -次に、Pgpool-IIのためのPostgreSQLサーバを設定する必要があります。 -これらのサーバは、Pgpool-II と同じホストで起動しても、異なるホストであっても構いません。 -同じホストにサーバを配置するのならば、各サーバにそれぞれ異なるポート番号を割り合てなければなりません。 -異なるマシンで起動する場合は Pgpool-IIからのネットワーク接続を受け入れられるよう適切に設定されている必要があります。 - Pgpool-II ではデータベースサーバごとにレプリケーションを行うので、チュートリアルのためのデータベースクラスタを作成したほうがいいでしょう。 - -backend_hostname0 = 'localhost' -backend_port0 = 5432 -backend_weight0 = 1 -backend_hostname1 = 'localhost' -backend_port1 = 5433 -backend_weight1 = 1 -backend_hostname2 = 'localhost' -backend_port2 = 5434 -backend_weight2 = 1 - - - -には、ノードのホスト名、ポート番号、負荷分散の割合を設定します。 -各パラメータ名の後ろには、ノードIDが0から始まる整数(すなわち、0, 1, 2, ...)で指定されていなければなりません。 - - - - -すべてのノードでパラメータが1に設定してるのは、SELECTクエリが3台のサーバで等しく分散されることを意味しています。 - - - - - - - <productname>Pgpool-II</productname>の起動と停止 - - -Pgpool-II を起動するにはターミナルで以下のコマンドを実行します。 - - -$ pgpool - - - -しかしこれでは、Pgpool-IIが制御端末を切り離すため、ログが出力されません。 -Pgpool-IIにログメッセージを表示させたい場合、pgpoolコマンドに-nオプションを指定すると、Pgpool-IIは非デーモンプロセスとして起動し、制御端末は切り離されません。 - -$ pgpool -n & - - - -コマンドを実行した端末にログメッセージが表示されるので、以下のようなオプションを使うことをお勧めします。 - -$ pgpool -n -d > /tmp/pgpool.log 2>&1 & - - - --d オプションはデバッグメッセージの出力を有効にします。 -上記の例はファイルにリダイレクトさせているため、ログメッセージが/tmp/pgpool.logに追加され続けます。 -ログをローテートさせたい場合は、ローテート機能を持った外部コマンドにログを渡してください。 -たとえば、Apache2のrotatelogsが使用できます。 - - -$ pgpool -n 2>&1 | /usr/local/apache2/bin/rotatelogs \ - -l -f /var/log/pgpool/pgpool.log.%A 86400 & - - - -これにより毎日夜中の0時にログがローテートされ、pgpool.log.Thursdayのような名前のログファイルが毎日作成されます。 -ただし、すでに同じ名前のファイルがある場合にはrotatelogsはログをそのファイルに追加してしまいます。 -cronを使うことで、古いログファイルをローテーションの前に削除することができます。 - - -55 23 * * * /usr/bin/find /var/log/pgpool -type f -mtime +5 -exec /bin/rm -f '{}' \; - - - -注意:Linuxディストリビューションによっては、rotatelogsは/usr/sbin/rotatelogs2として存在しているかもしれません。 --fオプションはrotatelogsが起動された直後に直ちにログファイルを作るオプションで、apache2 2.2.9以降でのみ有効です。 -cronologを使うこともできます。 - -$ pgpool -n 2>&1 | /usr/sbin/cronolog \ - --hardlink=/var/log/pgsql/pgpool.log \ - '/var/log/pgsql/%Y-%m-%d-pgpool.log' & - - - -Pgpool-II を停止するには以下のコマンドを実行します。 - -$ pgpool stop - - - -Pgpool-II を停止する際にクライアントが接続している場合、Pgpool-IIはその接続が切断されるまで待ってから停止します。 -Pgpool-IIを強制的にシャットダウンしたい場合は、以下のコマンドを実行します。 - -$ pgpool -m fast stop - - - - - - - - - 初めてのレプリケーション - - -レプリケーション(を参照)では複数のデータベースノードに同じデータを複製して格納します。 -ここでは、で準備した 3 台のデータベースノードを使用し、一歩一歩データベースクラスタシステムを作っていきまししょう。 -複製させるサンプルのデータpgbenchベンチマークプログラムで生成することにします。 - - - - - レプリケーションの設定 - - -データベースノードのレプリケーションを有効にするには、pgpool.confファイルのをonに設定します。 - -replication_mode = true - - -をonに設定することにより、Pgpool-IIは受信したクエリを全てのデータベースノードに送信します。 -対して実行され、同じデータが複製されて格納されるようになります。 -さらに、をonに設定することにより、Pgpool-IIはSELECTクエリをデータベースノード間に振り分けます。 - -load_balance_mode = true - - -ここでは、の両方を有効にします。 - - - - - - レプリケーションの確認 - - -pgpool.confの変更をPgpool-IIに反映させるにはPgpool-IIを再起動する必要があります。 -「Pgpool-II の起動と停止」を参照してください。 -pgpool.confの設定と再起動がすんだら、実際にレプリケーションを試してうまく行くことを確認しましょう。 -まず、複製するデータベースを作成する必要があります。 -これを"bench_replication"と名づけましょう。 -このデータベースが全てのノードで作成される必要があります。 -createdbコマンドをPgpool-II経由で実行すると、すべてのノードでデータベースが作成されます。 - -$ createdb -p 9999 bench_replication - - -そしてpgbench-iオプションを指定して実行します。 --iオプションにより、データベースは事前に定義されたテーブルとデータで初期化されます。 - -$ pgbench -i -p 9999 bench_replication - - -pgbench -iによいって作成されるテーブルとデータを以下の表にまとめます。 -すべてのノードにおいてこれらのテーブルおよびデータが作成されていれば、正常にレプリケーションが動作していることになります。 - - - - data summary - - - - - テーブル名 - 行数 - - - - - - pgbench_branches - 1 - - - - pgbench_tellers - 10 - - - - pgbench_accounts - 100000 - - - - pgbench_history - 0 - - - - -
- - - -これをチェックするため、簡単なシェルスクリプトを実行してみましょう。 -以下のスクリプトはすべてのノード (ポート番号 5432、5433、5434) のデータベースにおけるpgbench_branches、pgbench_tellers、pgbench_accounts、pgbench_historyの行数が表示されます。 - -$ for port in 5432 5433 5434; do -> echo $port -> for table_name in pgbench_branches pgbench_tellers pgbench_accounts pgbench_history; do -> echo $table_name -> psql -c "SELECT count(*) FROM $table_name" -p $port bench_replication -> done -> done - - - -
-
- -
- - - - Watchdogの設定例 - - - -ここではwatchdogの機能を簡単に試す方法を説明します。 -Linux マシン2台にそれぞれ Pgpool-II がインストールされているものとします。 -また、いずれかのマシンか第 3 のマシンに、PostgreSQL がインストールされて稼働しているものとします。 -バックエンドノードは1台でかまいません。 -Pgpool-II がどのモードで稼働していても(レプリケーションモードでもマスタースレーブモードでも)、watchdogを利用することができます。 - - - -この例では、「osspc16」をActiveノードとして、「osspc20」をStandbyノードとして使います。 -「someserver」は、これらのどちらかということを意味しています。 - - - - - 共通設定 - - -アクティブとスタンバイの両サーバで以下を設定します。 - - - - - Watchdogの有効化 - - -まず、をonにします。 - -use_watchdog = on - # Activates watchdog - - - - - - - 上位サーバの設定 - - -上流のサーバ(アプリケーションサーバなど)を指定します。 -空欄にしておいても構いません。 - -trusted_servers = '' - # trusted server list which are used - # to confirm network connection - # (hostA,hostB,hostC,...) - - - - - - - Watchdog通信 - - -watchdog通信を行うTCPポート番号を指定します。 - -wd_port = 9000 - # port number for watchdog service - - - - - - - 仮想IP - - -仮想IPをに設定します。 - -delegate_IP = '133.137.177.143' - # delegate IP address - - - - - -仮想IPに設定されるIPアドレスは空いており他のマシンで使用されていないことを確認してください。 - - - - - - - - 個々のサーバ設定 - - -次に、それぞれのPgpool-IIで以下のパラメータを設定します。 -を他のPgpool-IIの値で設定します。 - - - - - Activeサーバの設定(osspc16) - - -other_pgpool_hostname0 = 'osspc20' - # Host name or IP address to connect to for other pgpool 0 -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 -other_wd_port0 = 9000 - # Port number for other watchdog 0 - - - - - - - Standbyサーバの設定(osspc20) - - -other_pgpool_hostname0 = 'osspc16' - # Host name or IP address to connect to for other pgpool 0 -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 -other_wd_port0 = 9000 - # Port number for other watchdog 0 - - - - - - - - <productname>Pgpool-II</productname>の起動 - - -両方のサーバでPgpool-IIをrootユーザで、"-n"オプションを付けて起動し、ログメッセージはpgpool.logファイルにリダイレクトします。 - - - - - ActiveサーバでのPgpool-II起動(osspc16) - - -最初に、Active サーバでPgpool-IIを起動します。 - -[user@osspc16]$ su - -[root@osspc16]# {installed_dir}/bin/pgpool -n -f {installed_dir}/etc/pgpool.conf > pgpool.log 2>&1 - - -ログから、仮想IP アドレスを使用し、またwatchdogプロセス起動したことが確認できます。 - -LOG: I am announcing my self as master/coordinator watchdog node -LOG: I am the cluster leader node -DETAIL: our declare coordinator message is accepted by all nodes -LOG: I am the cluster leader node. Starting escalation process -LOG: escalation process started with PID:59449 -LOG: watchdog process is initialized -LOG: watchdog: escalation started -LOG: I am the master watchdog node -DETAIL: using the local backend node status - - - - - - - StandbyサーバでのPgpool-II起動(osspc20) - - -次に、StandbyサーバでPgpool-IIを起動します。 - -[user@osspc20]$ su - -[root@osspc20]# {installed_dir}/bin/pgpool -n -f {installed_dir}/etc/pgpool.conf > pgpool.log 2>&1 - - -ログメッセージからPgpool-IIがwatchdogクラスタにスタンバイとして参加したことがわかります。 - -LOG: watchdog cluster configured with 1 remote nodes -LOG: watchdog remote node:0 on Linux_osspc16_9000:9000 -LOG: interface monitoring is disabled in watchdog -LOG: IPC socket path: "/tmp/.s.PGPOOLWD_CMD.9000" -LOG: watchdog node state changed from [DEAD] to [LOADING] -LOG: new outbound connection to Linux_osspc16_9000:9000 -LOG: watchdog node state changed from [LOADING] to [INITIALIZING] -LOG: watchdog node state changed from [INITIALIZING] to [STANDBY] - -LOG: successfully joined the watchdog cluster as standby node -DETAIL: our join coordinator request is accepted by cluster leader node "Linux_osspc16_9000" -LOG: watchdog process is initialized - - - - - - - - - 動作確認 - - -仮想 IP アドレスに、pingが通ることを確認します。 - -[user@someserver]$ ping 133.137.177.143 -PING 133.137.177.143 (133.137.177.143) 56(84) bytes of data. -64 bytes from 133.137.177.143: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 133.137.177.143: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 133.137.177.143: icmp_seq=3 ttl=64 time=0.412 ms - - -先にPgpool-IIを起動したActiveサーバが、仮想IPアドレスを使っていることを確認します。 - -[root@osspc16]# ifconfig -eth0 ... - -eth0:0 inet addr:133.137.177.143 ... - -lo ... - - -後からPgpool-IIを立ち上げたStandbサーバは、仮想IPアドレスを使っていないことを確認します。 - -[root@osspc20]# ifconfig -eth0 ... - -lo ... - - - -仮想IPアドレスを使って、PostgreSQL に接続をできることを確認します。 - -[user@someserver]$ psql -h 133.137.177.143 -p 9999 -l - - - - - - - 仮想IPの切り替え - - -Activeサーバがサービス供給不可な状態になったときに、Standbyがそれを引き継ぐのを確認します。 -ActiveサーバのPgpool-IIを停止します。 - -[root@osspc16]# {installed_dir}/bin/pgpool stop - - - -するとStandbyサーバで、仮想IPアドレスを使用しはじめたというログメッセージが出力されます。 - - - -LOG: remote node "Linux_osspc16_9000" is shutting down -LOG: watchdog cluster has lost the coordinator node - -LOG: watchdog node state changed from [STANDBY] to [JOINING] -LOG: watchdog node state changed from [JOINING] to [INITIALIZING] -LOG: I am the only alive node in the watchdog cluster -HINT: skipping stand for coordinator state -LOG: watchdog node state changed from [INITIALIZING] to [MASTER] -LOG: I am announcing my self as master/coordinator watchdog node -LOG: I am the cluster leader node -DETAIL: our declare coordinator message is accepted by all nodes - -LOG: I am the cluster leader node. Starting escalation process -LOG: watchdog: escalation started - -LOG: watchdog escalation process with pid: 59551 exit with SUCCESS. - - - -仮想 IP アドレスに、pingが通ることを確認します。 - -[user@someserver]$ ping 133.137.177.143 -PING 133.137.177.143 (133.137.177.143) 56(84) bytes of data. -64 bytes from 133.137.177.143: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 133.137.177.143: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 133.137.177.143: icmp_seq=3 ttl=64 time=0.412 ms - - - -Activeではもう仮想IPアドレスが使われなくなったのを確認します。 - -[root@osspc16]# ifconfig -eth0 ... - -lo ... - - - -Standbyで仮想IP アドレスが使われていることを確認します。 - -[root@osspc20]# ifconfig -eth0 ... - -eth0:0 inet addr:133.137.177.143 ... - -lo ... - - - -仮想IPアドレスを使って、PostgreSQLに接続できることを確認します。 - -[user@someserver]$ psql -h 133.137.177.143 -p 9999 -l - - - - - - - - 応用 - - - - 死活監視 - - -watchdog の監視方法について設定するパラメータがあります。 -監視間隔秒を指定する、リトライ回数を指定する、 監視に使うクエリを指定する、死活監視のタイプを指定するを記述します。 - -wd_lifecheck_method = 'query' - # Method of watchdog lifecheck ('heartbeat' or 'query' or 'external') - # (change requires restart) -wd_interval = 10 - # lifecheck interval (sec) > 0 -wd_life_point = 3 - # lifecheck retry times -wd_lifecheck_query = 'SELECT 1' - # lifecheck query to pgpool from watchdog - - - - - - - - 仮想IPの切り替え - - -IP アドレスの切り替えコマンドについて設定するパラメータがあります。 -仮想 IP を切り替える際に使うコマンドとして、そのパスを指定するを記述します。 -また、仮想IP切り替え後のARPリクエスト送信コマンドを指定する、そのパスを指定するを記述します。 - -ifconfig_path = '/sbin' - # ifconfig command path -if_up_cmd = 'ifconfig eth0:0 inet $_IP_$ netmask 255.255.255.0' - # startup delegate IP command -if_down_cmd = 'ifconfig eth0:0 down' - # shutdown delegate IP command - -arping_path = '/usr/sbin' # arping command path - -arping_cmd = 'arping -U $_IP_$ -w 1' - - -およびの設定を用いて仮想IPの起動・停止を行う同時にスクリプトを使うこともできます。 - - - - - - - - - <productname>Pgpool-II</productname> + Watchdogの構築の例 - -ここでは、ストリーミングレプリケーション構成のPostgreSQLPgpool-IIで管理するシステムの構成例を示します。この例では、3台のPgpool-IIを使ってPostgreSQLを管理し、単一障害点やスプリットブレインの起きない堅牢なクラスタを運用することが可能です。 - - - 前提条件 - -Pgpool-IIサーバとPostgreSQLサーバが同じサブネットにあることを前提とします。 - - - - - 全体構成 - -今回は、Linux サーバ 5 台を用意し、それぞれのホスト名は 「osspc16」、「osspc17」、「osspc18」、「osspc19」、「osspc20」 とします。使用するOSはすべてCentOS7とします。Pgpool-II3台 +PostgresQL2台(ストリーミングレプリケーション)の全体構成図は以下の通りです。 - - -
- 全体構成図 - - - - - -
-
- - -「アクティブ」「スタンバイ」「Primary」「Standby」といった役割は固定されているものではなく、運用と共に変化することがあります。 - - -
- - - インストール - -ここでは、 PostgreSQL 9.6.1 とPgpool-II 3.6.1 をRPMからインストールします。 - - - - Pgpool-II、PostgreSQLのバージョンと設定情報 - - - - サーバ - バージョン - ホスト名 - ポート番号 - $PGDATAディレクトリ - - - - - - PostgreSQLサーバ (プライマリ) - PostgreSQL9.6.1 - osspc19 - 5432 - /var/lib/pgsql/9.6/data - - - PostgreSQLサーバ (スタンバイ) - PostgreSQL9.6.1 - osspc20 - 5432 - /var/lib/pgsql/9.6/data - - - Pgpool-IIサーバ - Pgpool-II3.6.1 - osspc16 - 9999 - - - - - - Pgpool-IIサーバ - Pgpool-II3.6.1 - osspc17 - 9999 - - - - - - Pgpool-IIサーバ - Pgpool-II3.6.1 - osspc18 - 9999 - - - - - - -
- -Pgpool-IIのインストール方法は以下の通りです。 - - -# yum install http://www.pgpool.net/yum/rpms/3.6/redhat/rhel-7-x86_64/pgpool-II-release-3.6-1.noarch.rpm -# yum install pgpool-II-pg96 -# yum install pgpool-II-pg96-debuginfo -# yum install pgpool-II-pg96-devel -# yum install pgpool-II-pg96-extensions - - - -PostgreSQLのインストールはPostgreSQLコミュニティのリポジトリを使います。 - - -# yum install https://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm - -# yum install postgresql96 postgresql96-devel postgresql96-server - -
- - - 事前設定 - - - - -PostgreSQLプライマリサーバのストリーミングレプリケーションの設定を行います。ここではアーカイブリカバリを行うように設定します。 - - -まず、WALを格納するディレクトリ/var/lib/pgsql/archivedirPostgreSQLバックエンドサーバosspc19osspc20に事前に作成します。 - - -[PostgreSQLサーバ]$ mkdir /var/lib/pgsql/archivedir - - - -次に設定ファイル$PGDATA/postgresql.confを以下のように編集します。 - - -listen_addresses = '*' -wal_level = hot_standby -max_wal_senders = 2 - -archive_mode = on -archive_command = 'cp "%p" "/var/lib/pgsql/archivedir/%f"' - - -スタンバイサーバの設定は、プライマリが起動した状態で、Pgpool-IIのオンラインリカバリ機能を使って行います。 - - - - - -セキュリティ上の理由で、PostgreSQLプライマリサーバosspc19でレプリケーション専用ユーザreplを作成します。また、Pgpool-IIのレプリケーションの遅延チェックとヘルスチェック用のユーザpgpoolも作成します。 Pgpool-IIサーバとPostgreSQLバックエンドサーバが133.137.174.0/24のネットワークにあることを想定し、各ユーザがmd5認証方式で接続できるように、pg_hba.confを編集しておきます。 - - -host all pgpool 133.137.174.0/24 md5 -host all all 0.0.0.0/0 md5 - -host replication repl 133.137.174.0/24 md5 - - - - - -自動フェイルオーバ、オンラインリカバリ機能を利用するために 5台のサーバでは、postgresユーザがパスワードなしで双方向にssh接続できる状態にする必要があります。 - - - - - - -replユーザのパスワード入力なしで、ストリーミングレプリケーションとオンラインリカバリを行うために、バックエンドのosspc19osspc20postgresユーザのホームディレクト/var/lib/pgsql.pgpassを作成・配置し、パーミッションを 600 に設定しておきます。 - - -[osspc19]$ cat /var/lib/pgsql/.pgpass -osspc20:5432:replication:repl:<replユーザのパスワード> - - - -[osspc20]$ cat /var/lib/pgsql/.pgpass -osspc19:5432:replication:repl:<replユーザのパスワード> - - - -$ chmod 600 /var/lib/pgsql/.pgpass - - - - - - -Pgpool-IIが他のPostgreSQLサーバに接続する際には、ファイアーウォールによって目的のポートが開けられていなければなりません。CentOS/RHEL7の場合、以下のように設定します。 - - -[PostgreSQLサーバ]# firewall-cmd --permanent --zone=public --add-service=postgresql -[PostgreSQLサーバ]# firewall-cmd --reload - - - - - -Pgpool-IIPostgreSQLの自動起動の設定をします。 - - -[Pgpool-IIサーバ]# systemctl enable pgpool.service - - -[PostgreSQLサーバ]# systemctl enable postgresql.service - - - - - - - <productname>Pgpool-II</productname>の設定 - - 共通設定 - -以下の操作はosspc16, osspc17, osspc18での共通の設定です。 - - -RPM からインストールする場合、すべてのPgpool-II設定ファイルは/etc/pgpool-IIにあります。今回はストリーミングレプリケーションモードのテンプレートとしてpgpool.conf.sample-streamサンプルファイルを使用します。 - - -# cp /etc/pgpool-II/pgpool.conf.sample-stream /etc/pgpool-II/pgpool.conf - - -Pgpool-IIが全てのIPアドレスから接続を受け付けるように、listen_addressesパラメータに'*'を設定します。 - - -listen_addresses = '*' - - -レプリケーションの遅延チェックユーザとパスワードを設定します。 - - -sr_check_user = 'pgpool' -sr_check_password = 'pgpool' - - -自動フェイルオーバのため、ヘルスチェックを有効にします。 また、ネットワークが不安定な場合には、バックエンドが正常であるにも関わらず、ヘルスチェックに失敗し、フェイルオーバや縮退運転が発生してしまう可能性があります。そのようなヘルスチェックの誤検知を防止するため、ヘルスチェックのリトライ回数をhealth_check_max_retries = 10 に設定しておきます。 - - -health_check_period = 5 - # Health check period - # Disabled (0) by default -health_check_timeout = 20 - # Health check timeout - # 0 means no timeout -health_check_user = 'pgpool' -health_check_password = 'pgpool' - -health_check_max_retries = 10 - - -また、バックエンド情報を前述のosspc19osspc20の設定に従って設定しておきます。 - - -# - Backend Connection Settings - - -backend_hostname0 = 'osspc19' - # Host name or IP address to connect to for backend 0 -backend_port0 = 5432 - # Port number for backend 0 -backend_weight0 = 1 - # Weight for backend 0 (only in load balancing mode) -backend_data_directory0 = '/var/lib/pgsql/9.6/data' - # Data directory for backend 0 -backend_flag0 = 'ALLOW_TO_FAILOVER' - # Controls various backend behavior - # ALLOW_TO_FAILOVER or DISALLOW_TO_FAILOVER -backend_hostname1 = 'osspc20' -backend_port1 = 5432 -backend_weight1 = 1 -backend_data_directory1 = '/var/lib/pgsql/9.6/data' -backend_flag1 = 'ALLOW_TO_FAILOVER' - - - - - フェイルオーバの設定 - -failover_commandを次のように設定します。引数の %d %P %H %R は、それぞれ実行時にPgpool-IIによって「切り離されたノード番号」、「古いプライマリノードのID 」、「新しいマスターのホスト名」、「新しいマスターノードのデータベースクラスタのパス 」に置き換えられます。 - - -failover_command = '/etc/pgpool-II/failover.sh %d %P %H %R' - - -また、/etc/pgpool-II/failover.shを作成し、実行権限を与えておきます。 - - -# vi /etc/pgpool-II/failover.sh -# chmod 755 /etc/pgpool-II/failover.sh - - - - - -/etc/pgpool-II/failover.sh - - -#! /bin/sh -x -# Execute command by failover. -# special values: %d = node id -# %h = host name -# %p = port number -# %D = database cluster path -# %m = new master node id -# %M = old master node id -# %H = new master node host name -# %P = old primary node id -# %R = new master database cluster path -# %r = new master port number -# %% = '%' character - -falling_node=$1 # %d -old_primary=$2 # %P -new_primary=$3 # %H -pgdata=$4 # %R - -pghome=/usr/pgsql-9.6 -log=/var/log/pgpool/failover.log - -date >> $log -echo "failed_node_id=$falling_node new_primary=$new_primary" >> $log - -if [ $falling_node = $old_primary ]; then - if [ $UID -eq 0 ] - then - su postgres -c "ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata" - else - ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata - fi - exit 0; -fi; -exit 0; - - - - - - - - オンラインリカバリの設定 - -続いて、オンラインリカバリを行うためのPostgreSQLのユーザ名およびオンラインリカバリ時に呼び出されるコマンドrecovery_1st_stageを設定します。オンラインリカバリ用のスクリプトrecovery_1st_stagepgpool_remote_startをプライマリサーバのデータベースクラスタ配下に配置し、実行権限を与えておきます。 - - -recovery_user = 'postgres' - # Online recovery user -recovery_password = 'postgres' - # Online recovery password - -recovery_1st_stage_command = 'recovery_1st_stage' - - -$ vi /var/lib/pgsql/9.6/data/recovery_1st_stage -$ vi /var/lib/pgsql/9.6/data/pgpool_remote_start -$ chmod 755 /var/lib/pgsql/9.6/data/recovery_1st_stage -$ chmod 755 /var/lib/pgsql/9.6/data/pgpool_remote_start - - - - - -/var/lib/pgsql/9.6/data/recovery_1st_stage - - -#!/bin/bash -x -# Recovery script for streaming replication. - -pgdata=$1 -remote_host=$2 -remote_pgdata=$3 -port=$4 - -pghome=/usr/pgsql-9.6 -archivedir=/var/lib/pgsql/archivedir -hostname=$(hostname) - -ssh -T postgres@$remote_host " -rm -rf $remote_pgdata -$pghome/bin/pg_basebackup -h $hostname -U repl -D $remote_pgdata -x -c fast -rm -rf $archivedir/* - -cd $remote_pgdata -cp postgresql.conf postgresql.conf.bak -sed -e 's/#*hot_standby = off/hot_standby = on/' postgresql.conf.bak > postgresql.conf -rm -f postgresql.conf.bak -cat > recovery.conf << EOT -standby_mode = 'on' -primary_conninfo = 'host="$hostname" port=$port user=repl' -restore_command = 'scp $hostname:$archivedir/%f %p' -EOT -" - - - - - -/var/lib/pgsql/9.6/data/pgpool_remote_start - - -#! /bin/sh -x - -pghome=/usr/pgsql-9.6 -remote_host=$1 -remote_pgdata=$2 - -# リカバリ先のPostgreSQLを起動 -ssh -T $remote_host $pghome/bin/pg_ctl -w -D $remote_pgdata start > /dev/null 2>&1 < /dev/null & - - - - - -また、オンラインリカバリ機能を使用するには、pgpool_recoverypgpool_remote_startpgpool_switch_xlogという関数が必要になるので、PostgreSQLサーバosspc19の template1 にpgpool_recoveryをインストールしておきます。 - - -# su - postgres -$ psql template1 -=# CREATE EXTENSION pgpool_recovery; - - - - - クライアント認証の設定 - -事前設定の章で、PostgreSQLのクライアント認証方式をmd5に設定しましたので、クライアントがPgpool-IIを経由でバックエンドに接続できるようにPgpool-II側でもクライアント認証の設定を行う必要があります。Pgpool-IIのクライアント認証の設定ファイルはpool_hba.confと呼ばれ、RPMパッケージからインストールする場合、デフォルトでは/etc/pgpool-II配下にインストールされます。デフォルトではpool_hba.confによる認証は無効になっているので、 pgpool.confでは以下の設定を on に変更します。 - - -enable_pool_hba = on - - -pool_hba.confのフォーマットはPostgreSQLpg_hba.confとほとんど同じです。pgpoolpostgresユーザをmd5認証に設定します。 - - -host all pgpool 0.0.0.0/0 md5 -host all postgres 0.0.0.0/0 md5 - - -md5 認証で用いるデフォルトのファイル名は pool_passwd です。 「pg_md5 --md5auth --username=ユーザ名 パスワード」 コマンドを実行すると、ユーザ名と md5 によりハッシュ化 されたパスワードが pool_passwd に登録されます。 pool_passwd がまだ存在しなければ、pgpool.confと同じディレクトリ内に作成されます。 - - -# pg_md5 --md5auth --username=pgpool <pgpoolユーザのパスワード> -# pg_md5 --md5auth --username=postgres <postgresユーザのパスワード> - - - - - Watchdogの設定 - -osspc16osspc17osspc18watchdogを有効にします。 - - -use_watchdog = on - - -アクティブ機が立ち上げる仮想 IP を delegate_IP に指定します。仮想 IP はまだ使われていない IP アドレスを指定してください。osspc16、osspc17、osspc18 の共通の設定です。 - - -delegate_IP = '133.137.174.153' - - -各watchdog が稼働するサーバ情報を設定しておきます。 - - - - -osspc16の場合 - - -wd_hostname = 'osspc16' -wd_port = 9000 - - - - -osspc17の場合 - - -wd_hostname = 'osspc17' -wd_port = 9000 - - - - -osspc18の場合 - - -wd_hostname = 'osspc18' -wd_port = 9000 - - - - - -各監視対象のPgpool-IIサーバ情報を設定しておきます。 - - - - -osspc16の場合 - - -# - Other pgpool Connection Settings - - -other_pgpool_hostname0 = 'osspc17' - # Host name or IP address to connect to for other pgpool 0 - # (change requires restart) -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 - # (change requires restart) -other_wd_port0 = 9000 - # Port number for other watchdog 0 - # (change requires restart) -other_pgpool_hostname1 = 'osspc18' -other_pgpool_port1 = 9999 -other_wd_port1 = 9000 - - - - -osspc17の場合 - - -# - Other pgpool Connection Settings - - -other_pgpool_hostname0 = 'osspc16' - # Host name or IP address to connect to for other pgpool 0 - # (change requires restart) -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 - # (change requires restart) -other_wd_port0 = 9000 - # Port number for other watchdog 0 - # (change requires restart) -other_pgpool_hostname1 = 'osspc18' -other_pgpool_port1 = 9999 -other_wd_port1 = 9000 - - - - -osspc18の場合 - - -# - Other pgpool Connection Settings - - -other_pgpool_hostname0 = 'osspc16' - # Host name or IP address to connect to for other pgpool 0 - # (change requires restart) -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 - # (change requires restart) -other_wd_port0 = 9000 - # Port number for other watchdog 0 - # (change requires restart) -other_pgpool_hostname1 = 'osspc17' -other_pgpool_port1 = 9999 -other_wd_port1 = 9000 - - - - - -ハートビート信号の送信先のホスト名とポート番号を指定します。 - - - - -osspc16の場合 - - -heartbeat_destination0 = 'osspc17' - # Host name or IP address of destination 0 - # for sending heartbeat signal. - # (change requires restart) -heartbeat_destination_port0 = 9694 - # Port number of destination 0 for sending - # heartbeat signal. Usually this is the - # same as wd_heartbeat_port. - # (change requires restart) -heartbeat_device0 = '' - # Name of NIC device (such like 'eth0') - # used for sending/receiving heartbeat - # signal to/from destination 0. - # This works only when this is not empty - # and pgpool has root privilege. - # (change requires restart) - -heartbeat_destination1 = 'osspc18' -heartbeat_destination_port1 = 9694 -heartbeat_device1 = '' - - - - - -osspc17の場合 - - -heartbeat_destination0 = 'osspc16' - # Host name or IP address of destination 0 - # for sending heartbeat signal. - # (change requires restart) -heartbeat_destination_port0 = 9694 - # Port number of destination 0 for sending - # heartbeat signal. Usually this is the - # same as wd_heartbeat_port. - # (change requires restart) -heartbeat_device0 = '' - # Name of NIC device (such like 'eth0') - # used for sending/receiving heartbeat - # signal to/from destination 0. - # This works only when this is not empty - # and pgpool has root privilege. - # (change requires restart) - -heartbeat_destination1 = 'osspc18' -heartbeat_destination_port1 = 9694 -heartbeat_device1 = '' - - - - - -osspc18の場合 - - -heartbeat_destination0 = 'osspc16' - # Host name or IP address of destination 0 - # for sending heartbeat signal. - # (change requires restart) -heartbeat_destination_port0 = 9694 - # Port number of destination 0 for sending - # heartbeat signal. Usually this is the - # same as wd_heartbeat_port. - # (change requires restart) -heartbeat_device0 = '' - # Name of NIC device (such like 'eth0') - # used for sending/receiving heartbeat - # signal to/from destination 0. - # This works only when this is not empty - # and pgpool has root privilege. - # (change requires restart) - -heartbeat_destination1 = 'osspc17' -heartbeat_destination_port1 = 9694 -heartbeat_device1 = '' - - - - - - - PCPコマンドの設定 - -PCPコマンドを使用するにはユーザ認証が必要になるので、ユーザ名とmd5ハッシュに変換されたパスワードをpcp.confファイルに設定します。ここではユーザ名にpostgresを使用し、<ユーザ名:ハッシュ化されたパスワード>を/etc/pgpool-II/pcp.confに追記しておきます。 - - -# pg_md5 -p -Password: (パスワードを入力) -(ハッシュ化されたパスワードをpcp.confに貼り付ける) - -# vi /etc/pgpool-II/pcp.conf -(以下1行を追記) -ユーザ名:ハッシュ化されたパスワード - - -ここで、Pgpool-IIの設定は完了です。 - - - - - - システムの起動と停止 - -Pgpool-IIの設定が完了したら、次にPgpool-IIを起動します。Pgpool-IIを起動する前に、バックエンドのPostgreSQLをあらかじめ起動する必要があります。また、PostgreSQLを停止する場合、Pgpool-IIを先に停止する必要があります。 - - - - -Pgpool-IIの起動 - - -前述の事前設定の章でPgpool-IIの自動起動が設定済なので、ここでシステム全体を再起動するか、以下のコマンドを実行してください。 - - -# systemctl start pgpool.service - - - - -Pgpool-IIの停止 - - -# systemctl stop pgpool.service - - - - - - - ログの確認 - -Pgpool-IIのログはjournalctlコマンドを使用し確認します。 - - -# journalctl -a | grep pgpool - - - - - 動作確認 - -これから、動作確認を行います。まず、osspc16osspc17osspc18で以下のコマンドで Pgpool-II を起動します。 - - -# systemctl start pgpool.service - - - - PostgreSQL スタンバイサーバを構築 - -まず、Pgpool-IIのオンラインリカバリ機能を利用し、スタンバイサーバを構築します。pcp_recovery_nodeコマンドで実行されるrecovery_1st_stage_commandパラメータに指定したrecovery_1st_stagepgpool_remote_startスプリクトが実行されるので、この 2つのスクリプトが現在稼働中のプライマリサーバosspc19のデータベースクラスタの下に存在することを確認します。 - - -# pcp_recovery_node -h 133.137.174.153 -p 9898 -U postgres -n 1 - - -osspc20がスタンバイとして起動されたことを確認します。 - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | up | 0.500000 | primary | 0 | true | 0 - 1 | osspc20 | 5432 | up | 0.500000 | standby | 0 | false | 0 -(2 行) - - - - - watchdog アクティブ/スタンバイの切り替え - -pcp_watchdog_infoPgpool-IIwatchdogの情報を確認します。最初に起動したPgpool-IIが「MASTER」になります。 - - -# pcp_watchdog_info -h 133.137.174.153 -p 9898 -U postgres -Password: -3 YES osspc16:9999 Linux osspc16 osspc16 - -osspc16:9999 Linux osspc16 osspc16 9999 9000 4 MASTER #最初に起動されたサーバがMASTERになる -osspc17:9999 Linux osspc17 osspc17 9999 9000 7 STANDBY #スタンバイとして稼働 -osspc18:9999 Linux osspc18 osspc18 9999 9000 7 STANDBY #スタンバイとして稼働 - - -アクティブであるosspc16を停止し、osspc17またはosspc18がスタンバイからアクティブに昇格することを確認します。osspc16を停止する方法はPgpool-IIを停止する、またはマシンをシャットダウンします。ここでは、Pgpool-IIを停止します。 - - -[root@osspc16 ~]# systemctl stop pgpool.service -[root@osspc16 ~]# pcp_watchdog_info -h 133.137.174.153 -p 9898 -U postgres -Password: -3 YES osspc17:9999 Linux osspc17 osspc17 - -osspc17:9999 Linux osspc17 osspc17 9999 9000 4 MASTER #osspc17がアクティブに昇格 -osspc16:9999 Linux osspc16 osspc16 9999 9000 10 SHUTDOWN #osspc16が停止された -osspc18:9999 Linux osspc18 osspc18 9999 9000 7 STANDBY #スタンバイとして稼働 - - -先ほど停止したPgpool-IIを再起動し、スタンバイとして起動したことを確認します。 - - -[root@osspc16 ~]# systemctl start pgpool.service -[root@osspc16 ~]# pcp_watchdog_info -h 133.137.174.153 -p 9898 -U postgres -Password: -3 YES osspc17:9999 Linux osspc17 osspc17 - -osspc17:9999 Linux osspc17 osspc17 9999 9000 4 MASTER -osspc16:9999 Linux osspc16 osspc16 9999 9000 7 STANDBY -osspc18:9999 Linux osspc18 osspc18 9999 9000 7 STANDBY - - - - - 自動フェイルオーバ - -psqlで仮想IPに接続し、バックエンドの情報を確認します。 - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | up | 0.500000 | primary | 0 | true | 0 - 1 | osspc20 | 5432 | up | 0.500000 | standby | 0 | false | 0 -(2 行) - - -次にプライマリであるosspc19PostgreSQLを停止し、フェイルオーバするかどうか確認してみます。 - - -$ pg_ctl -D /var/lib/pgsql/9.6/data -m immediate stop - - -osspc19を停止後、フェイルオーバが発生し、osspc20がプライマリに昇格したことを確認します。 - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | down | 0.500000 | standby | 0 | false | 0 - 1 | osspc20 | 5432 | up | 0.500000 | primary | 0 | true | 0 -(2 行) - - - - - オンラインリカバリ - -次に、Pgpool-IIのオンラインリカバリ機能を利用し、先ほど停止した旧プライマリサーバをスタンバイとして復旧させます。pcp_recovery_nodeコマンドで実行されるrecovery_1st_stage_commandパラメータに指定したrecovery_1st_stagepgpool_remote_startスプリクトが現在稼働中のプライマリサーバosspc20のデータベースクラスタの下に存在することを確認します。 - - -# pcp_recovery_node -h 133.137.174.153 -p 9898 -U postgres -n 0 - - -osspc19がスタンバイとして起動されたことを確認します。 - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | up | 0.500000 | standby | 0 | false | 0 - 1 | osspc20 | 5432 | up | 0.500000 | primary | 0 | true | 0 -(2 行) - - -以上で、動作確認が完了です。 - - - - -
- - - - AWS設定の例 - - - -このチュートリアルでは、AWS上で"Watchdog"を使う簡単な例を示します。 -この例では、高可用性のためにElastic IP Addressを仮想IPとして使います。 - - - watchdogは、Pgpool-IIのすべてのモード、すなわちレプリケーションモード、マスタ/スレーブモード、ローモードのいずれでも使えます。 - - - - - - - AWSのセットアップ - - -この例では、2ノードのPgpool-II watchdogクラスタを使います。 -そこで、2つのAmazon Linux EC2インスタンスを設定し、ひとつのElastic IPアドレスを使用します。 -以下のステップを実施してください。 - - - - - - -Amazon Linux EC2インスタンスを2つ起動します。 -この例では、それぞれ"instance-1"と"instance-2"という名前を付けます。 - - - - - - -これらのインスタンスのセキュリティグループを設定し、Pgpool-IIとwatchdogが使用するポートへのインバウンドトラフィックを許可します。 - - - - - - -Pgpool-IIを両方のインスタンスにインストールします。 - - - - - - -Elastic IPアドレスを確保します。 -この例では、Elastic IPアドレスに"35.163.178.3"を設定します。 - - - - - - - - - - <productname>Pgpool-II</productname>の設定 - - -この例の設定はとほとんど同じになりますが、を設定せず、代わりにを使ってmaster/Active Pgpool-IIノードのElastic IPアドレスを切り替えるのが異なります。 - - - - - Instance-1における<productname>Pgpool-II</productname>の設定 - - - -use_watchdog = on -delegate_IP = '' -wd_hostname = 'instance-1-private-ip' -other_pgpool_hostname0 = 'instance-2-private-ip' -other_pgpool_port0 = 9999 -other_wd_port0 = 9000 -wd_escalation_command = '$path_to_script/aws-escalation.sh' -wd_de_escalation_command = '$path_to_script/aws-de-escalation.sh' - - - - - - - - Instance-2における<productname>Pgpool-II</productname>の設定 - - - -use_watchdog = on -delegate_IP = '' -wd_hostname = 'instance-2-private-ip' -other_pgpool_hostname0 = 'instance-1-private-ip' -other_pgpool_port0 = 9999 -other_wd_port0 = 9000 -wd_escalation_command = '$path_to_script/aws-escalation.sh' -wd_de_escalation_command = '$path_to_script/aws-de-escalation.sh' - - - - - - - - - エスカレーションおよびディエスカレーション用のスクリプト - - -aws-escalation.shとaws-de-escalation.shスクリプトを2つのインスタンス上に作成し、がそれぞれそれらを指すようにしてください。 - - - - - -AWSインスタンス上でwd-escalation.shとwd-de-escalation.shで使用するコマンドが実行できるようにするために、AWS CLIの設定が必要になるかもしれません。 -configure AWS CLIを参照してください。 - - - - - - エスカレーションスクリプト - - - -このスクリプトは、watchdogがactive/masterノードになったときに、Elastic IPをアサインするためにwatchdogが実行します。 - - - aws-escalation.sh: - -#! /bin/sh - -ELASTIC_IP=35.163.178.3 - # replace it with the Elastic IP address you - # allocated from the aws console -INSTANCE_ID=i-0a9b64e449b17ed4b - # replace it with the instance id of the Instance - # this script is installed on - -echo "Assigning Elastic IP $ELASTIC_IP to the instance $INSTANCE_ID" -# bring up the Elastic IP -aws ec2 associate-address --instance-id $INSTANCE_ID --public-ip $ELASTIC_IP - -exit 0 - - - - - - - - ディエスカレーションスクリプト - - -このスクリプトは、watchdogがactive/masterノードを退任するときに、Elastic IPのアサインを解除するためにwatchdogが実行します。 - - - aws-de-escalation.sh: - -#! /bin/sh - -ELASTIC_IP=35.163.178.3 - # replace it with the Elastic IP address you - # allocated from the aws console - -echo "disassociating the Elastic IP $ELASTIC_IP from the instance" -# bring down the Elastic IP -aws ec2 disassociate-address --public-ip $ELASTIC_IP -exit 0 - - - - - - - AWSコマンドリファレンス - - - - <ulink url="http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html">Configure AWS CLI</ulink> - - - AWS Documentation: Configuring the AWS Command Line Interface - - - - - - <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/associate-address.html">associate-address</ulink> - - - AWS Documentation: associate-address reference - - - - - - <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/disassociate-address.html">disassociate-address</ulink> - - - AWS Documentation: disassociate-address reference - - - - - - - - - 実行してみる - - -それぞれのサーバ上でPgpool-IIを"-n"スイッチ付きで起動し、pgpool.logにログメッセージをリダイレクトします。 -master/active Pgpool-IIノードは、Elastic IPのアサインメッセージを表示します。 - -LOG: I am the cluster leader node. Starting escalation process -LOG: escalation process started with PID:23543 -LOG: watchdog: escalation started - -Assigning Elastic IP 35.163.178.3 to the instance i-0a9b64e449b17ed4b -{ - "AssociationId": "eipassoc-39853c42" -} - -LOG: watchdog escalation successful -LOG: watchdog escalation process with pid: 23543 exit with SUCCESS. - - - - - -Elastic IPアドレスにpingが通ることを確かめます。 - -[user@someserver]$ ping 35.163.178.3 -PING 35.163.178.3 (35.163.178.3) 56(84) bytes of data. -64 bytes from 35.163.178.3: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 35.163.178.3: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 35.163.178.3: icmp_seq=3 ttl=64 time=0.412 ms - - - - - -"psql -h ELASTIC_IP -p port"でPostgreSQLに接続してみます。 - -[user@someserver]$ psql -h 35.163.178.3 -p 9999 -l - - - - - - - Elastic IPの切換 - - -アクティブなサーバが使用できなくなった時にスタンバイサーバがElastic IPを獲得できることを確認するために、アクティブサーバ上のPgpool-IIを停止します。 -すると、スタンバイサーバはElastic IPアドレスを使い始めるはずです。 -Pgpool-IIのログには以下のようなメッセージが表示されます。 - - -LOG: remote node "172.31.2.94:9999 [Linux ip-172-31-2-94]" is shutting down -LOG: watchdog cluster has lost the coordinator node - -LOG: watchdog node state changed from [STANDBY] to [JOINING] -LOG: watchdog node state changed from [JOINING] to [INITIALIZING] -LOG: I am the only alive node in the watchdog cluster -HINT: skipping stand for coordinator state -LOG: watchdog node state changed from [INITIALIZING] to [MASTER] -LOG: I am announcing my self as master/coordinator watchdog node -LOG: I am the cluster leader node -DETAIL: our declare coordinator message is accepted by all nodes -LOG: I am the cluster leader node. Starting escalation process -LOG: escalation process started with PID:23543 -LOG: watchdog: escalation started - -Assigning Elastic IP 35.163.178.3 to the instance i-0dd3e60734a6ebe14 -{ - "AssociationId": "eipassoc-39853c42" -} - -LOG: watchdog escalation successful -LOG: watchdog escalation process with pid: 61581 exit with SUCCESS. - - -Elastic IPアドレスにpingが通ることを再度確かめます。 - -[user@someserver]$ ping 35.163.178.3 -PING 35.163.178.3 (35.163.178.3) 56(84) bytes of data. -64 bytes from 35.163.178.3: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 35.163.178.3: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 35.163.178.3: icmp_seq=3 ttl=64 time=0.412 ms - - - - -"psql -h ELASTIC_IP -p port"でPostgreSQLに接続してみます。 - -[user@someserver]$ psql -h 35.163.178.3 -p 9999 -l - - - - - - - - Auroraの設定例 - - - - Amazon Aurora for PostgreSQL - Compatibility (Aurora) は、PostgreSQL用のマネージドサービスです。 - ユーザから見ると、Auroraは、いくつか例外があるものの、ストリーミングレプリケーションのクラスタのように見えます。フェイルオーバやオンラインリカバリはAuroraによって管理されます。 - ですから、、 - それにオンラインリカバリ関連のパラメータは設定の必要がありません。 - この章では、Aurora用のPgpool-II設定を説明します。 - - - - - Auroraのためにpgpool.confを設定する - - - - - - pgpool.conf.sample-streamをコピーしてpgpool.confを作ります。 - - - - - - を0にして、ストリーミングレプリケーション遅延チェックを無効にします。 - Auroraでは、ストリーミングレプリケーションの遅延をチェックするための関数が提供されないためです。 - - - - - - をオンにし、md5認証を有効にします。 - (Auroraでは常にmd5認証が有効になっています) - - - - - - pool_passwordを作成します。 - 詳細はをご覧ください。 - - - - - - 0をAuroraのwriterノードに設定します。 - 他のはAuroraのreaderノードに設定します。 - は設定の必要がありません。 - - - - - - 0のALWAYS_MASTERをオンにします。 - - - - - - ヘルスチェックを有効にします。 - に5を設定します. - 、 - - に適切な値を設定します。 - リトライを設定します。 - Auroraは、スィッチングオーバやフェイルオーバの際に、一時的に全DBノードを停止します。 - リトライを行わないと、Pgpool-IIから見ると全DBノードがダウン状態になり、Pgpool-IIの再起動が必要になります。 - を20に、を1にして、そのような問題を回避してください。 - - - - - -同様の理由により、接続時あるいは問い合わせ実行中のエラーによるフェイルオーバを避けるために、をオフにしてください。 - - - - - - - -
+ + 例集 + + + + + 様々な例 + + + + + + + 設定の例 + &example-basic; + &example-cluster; + &example-replication-si-mode; + &example-AWS; + &example-Aurora; +
diff --git a/doc.ja/src/sgml/failover.sgml b/doc.ja/src/sgml/failover.sgml index 6d13053a8..00e0384f0 100644 --- a/doc.ja/src/sgml/failover.sgml +++ b/doc.ja/src/sgml/failover.sgml @@ -1,710 +1,1082 @@ - + --> フェイルオーバとフェイルバック - + + フェイルオーバは、Pgpool-IIから見て使用できなくなったPostgreSQLバックエンドノードをPgpool-IIが自動的に切り離す処理を指します。 + これはPgpool-IIの設定に関わらず、自動的に行われるいわゆる自動フェイルオーバ処理です。 + Pgpool-IIPostgreSQLバックエンドノードが使用できなくなったことを、以下の方法で確認します。 - + --> フェイルオーバとフェイルバックの設定 - - failover_command (string) - - failover_command 設定パラメータ - - - - - -PostgreSQLバックエンドノードが切り離される時に実行するユーザコマンドを指定します。 -Pgpool-IIはコマンド実行の前に、以下の特殊文字をバックエンドの具体的な情報に置き換えます。 - + + failover_command (string) + + failover_command 設定パラメータ + + + + + + PostgreSQLバックエンドノードが切り離される時に実行するユーザコマンドを指定します。 + Pgpool-IIはコマンド実行の前に、以下の特殊文字をバックエンドの具体的な情報に置き換えます。 + - - - フェイルオーバコマンドオプション - - - - - 特殊文字 - 説明 - - - - - - %d - - 切り離されたノードのDBノードID - - - %h - - 切り離されたノードのホスト名 - - - %p - - 切り離されたノードのポート番号 - - - %D - - 切り離されたノードのデータベースクラスタパス - - - %M - - 古いマスターノードのID - - - %m - - 新しいマスターノードのID - - - %H - - 新しいマスターノードのホスト名 - - - %P - - 古いプライマリノードのID - - - %r - - 新しいマスターノードのポート番号 - - - %R - - 新しいマスターノードのデータベースクラスタパス - - - %% - - '%'文字 - +
+ + フェイルオーバコマンドオプション + + + + + 特殊文字 + 説明 + + - - -
+ + + %d + + 切り離されたノードのDBノードID + + + %h + + 切り離されたノードのホスト名 + + + %p + + 切り離されたノードのポート番号 + + + %D + + 切り離されたノードのデータベースクラスタパス + + + %m + + 新しいメインノードのID + + + %H + + 新しいメインノードのホスト名 + + + %M + + 古いメインノードのID + + + %P + + 古いプライマリノードのID + + + %r + + 新しいメインノードのポート番号 + + + %R + + 新しいメインノードのデータベースクラスタパス + + + %N + + 古いプライマリノードのホスト名(Pgpool-II 4.1以降) + + + %S + + 古いプライマリノードのポート番号(Pgpool-II 4.1以降) + + + %% + + '%'文字 + - - - -フェイルオーバーが実行されると、基本的にPgpool-IIは子プロセスを切断します。 -これにより、Pgpool-IIへの全てのアクティブセッションが終了されます。 -その後、Pgpool-IIfailover_commandを実行し、コマンドが完了した後にPgpool-IIはクライアントからの接続を再び受け付ける準備のため新しい子プロセスを起動します。 - - - -しかし、Pgpool-II 3.6以降では、そのセッションがダウンしたスタンバイを使用していない場合には、フェイルオーバが起こってもセッションが切断されません。 -プライマリサーバがダウンしたときには、依然としてすべてのセッションが切断されます。 -ヘルスチェックがタイムアウトした場合にも、すべてのセッションが切断されます。 -それ以外のケース、たとえばヘルスチェックの再試行回数がオーバーした場合には、全セッションの切断は起きません。 - - - - - - -スクリプトの中でpsqlやその他のコマンドを使ってバックエンドにアクセスし、情報を取り出すことはできますが、psqlPgpool-II自体に対して実行することはできません。 -スクリプトはPgpool-IIから呼ばれ、Pgpool-IIがフェイルオーバーを実行している間に動作するからです。 - - + + + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - -
-
- - - failback_command (string) - - failback_command 設定パラメータ - - - - - -PostgreSQLバックエンドノードがPgpool-IIに復帰された時に実行するユーザコマンドを指定します。 -Pgpool-IIはコマンド実行の前に、以下の特殊文字をバックエンドの具体的な情報に置き換えます。 - + + + + メインノードは、生きているデータベースノードの中から一番若い(小さい)ノードIDを持つノードを参照します。 + ストリーミングレプリケーションモードでは、このノードはプライマリノードとは異なる場合があります。 + 内では、 %mはPgpool-IIによって選出された新しいメインノードとなります。 + 新しいメインノードには生きているノードで一番若い(小さい)ノードが割り当てられます。 + 例えば、ノード0、1、2という3つのノードを持ち、ノード1がプライマリノード、全てのノードは正常である(ダウンしているノードがない)と仮定します。 + ノード1がダウンした場合、failover_command は %m = 0 で呼び出されます。 + また、全てのスタンバイノードがダウンした状態でプライマリノードのフェイルオーバが起きた場合、failover_commandは %m = -1、および%H,%R,%r = "" で呼び出されます。 + + - - - フェイルバックコマンドオプション - - - - - 特殊文字 - 説明 - - - - - - %d - - 復帰したノードのDBノードID - - - %h - - 復帰したノードのホスト名 - - - %p - - 復帰したノードのポート番号 - - - %D - - 復帰したノードのデータベースクラスタパス - - - %M - - 古いマスターノードのID - - - %m - - 新しいマスターノードのID - - - %H - - 新しいマスターノードのホスト名 - - - %P - - 古いプライマリノードのID - - - %r - - 新しいマスターノードのポート番号 - - - %R - - 新しいマスターノードのデータベースクラスタパス - - - %% - - '%'文字 - + + + + フェイルオーバーが実行されると、基本的にPgpool-IIは子プロセスを切断します。 + これにより、Pgpool-IIへの全てのアクティブセッションが終了されます。 + その後、Pgpool-IIfailover_commandを実行し、コマンドが完了した後にPgpool-IIはクライアントからの接続を再び受け付ける準備のため新しい子プロセスを起動します。 + + + しかし、Pgpool-II 3.6以降では、そのセッションがダウンしたスタンバイを使用していない場合には、フェイルオーバが起こってもセッションが切断されません。 + (ただし、フェイルオーバ処理中にそのセッションを使って問い合わせを発行すると、そのセッションは切断されるので注意してください。) + プライマリサーバがダウンしたときには、依然としてすべてのセッションが切断されます。 + ヘルスチェックがタイムアウトした場合にも、すべてのセッションが切断されます。 + それ以外のケース、たとえばヘルスチェックの再試行回数がオーバーした場合には、全セッションの切断は起きません。 + + - - -
+ + + + スクリプトの中でpsqlやその他のコマンドを使ってバックエンドにアクセスし、情報を取り出すことはできますが、psqlPgpool-II自体に対して実行することはできません。 + スクリプトはPgpool-IIから呼ばれ、Pgpool-IIがフェイルオーバーを実行している間に動作するからです。 + + - - - -スクリプトの中でpsqlやその他のコマンドを使ってバックエンドにアクセスし、情報を取り出すことはできますが、psqlPgpool-II自体に対して実行することはできません。 -スクリプトはPgpool-IIから呼ばれ、Pgpool-IIがフェイルオーバーを実行している間に動作するからです。 - - + + + failover_commandの完全な例がにあります。 + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - -
-
- - - follow_master_command (string) - - follow_master_command 設定パラメータ - - - - - - -プライマリノードのフェイルオーバー後に実行するユーザコマンドを指定します。 -この機能は、マスタースレーブモードでストリーミングレプリケーション構成の場合のみ有効です。 -Pgpool-IIはコマンド実行の前に、以下の特殊文字をバックエンドの具体的な情報に置き換えます。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + -
+ + failback_command (string) + + failback_command 設定パラメータ + + + + + + PostgreSQLバックエンドノードがPgpool-IIに復帰された時に実行するユーザコマンドを指定します。 + Pgpool-IIはコマンド実行の前に、以下の特殊文字をバックエンドの具体的な情報に置き換えます。 + - - - フォローマスターコマンドオプション - - - - - 特殊文字 - 説明 - - - - - - %d - - 切り離されたノードのDBノードID - - - %h - - 切り離されたノードのホスト名 - - - %p - - 切り離されたノードのポート番号 - - - %D - - 切り離されたノードのデータベースクラスタパス - - - %M - - 古いマスターノードのID - - - %m - - 新しいプライマリノードのID - - - %H - - 新しいプライマリノードのホスト名 - - - %P - - 古いプライマリノードのID - - - %r - - 新しいプライマリノードのポート番号 - - - %R - - 新しいプライマリノードのデータベースクラスタパス - - - %% - - '%'文字 - +
+ + フェイルバックコマンドオプション + + + + + 特殊文字 + 説明 + + - - -
+ + + %d + + 復帰したノードのDBノードID + + + %h + + 復帰したノードのホスト名 + + + %p + + 復帰したノードのポート番号 + + + %D + + 復帰したノードのデータベースクラスタパス + + + %m + + 新しいメインノードのID + + + %H + + 新しいメインノードのホスト名 + + + %M + + 古いメインノードのID + + + %P + + 古いプライマリノードのID + + + %r + + 新しいメインノードのポート番号 + + + %R + + 新しいメインノードのデータベースクラスタパス + + + %N + + 古いプライマリノードのホスト名(Pgpool-II 4.1以降) + + + %S + + 古いプライマリノードのポート番号(Pgpool-II 4.1以降) + + + %% + + '%'文字 + - - - -follow_master_commandが空文字列でない場合、ストリーミングレプリケーションによるマスタースレーブでプライマリノードのフェイルオーバーが完了した後に、Pgpool-IIは新しいプライマリ以外のすべてのノードを切り離し、クライアントから再び接続を受け付ける準備のため再度新しい子プロセスを起動します。 -その後、Pgpool-IIは切り離されたそれぞれのノードに対してfollow_master_commandに設定したコマンドを実行します。 - - - - -通常は、follow_master_commandコマンドはコマンドを呼んで新しいプライマリからスレーブをリカバリするために使用します。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - -
-
- - - failover_on_backend_error (boolean) - - failover_on_backend_error 設定パラメータ - - - - - -onに設定した場合、Pgpool-IIPostgreSQLバックエンド接続からの読み出し、書き込みのエラーをバックエンドノードの故障と見なし、現在のセッションを切断した後にそのノードをフェイルオーバします。 -offに設定した場合、そのようなエラーの場合でもPgpool-IIは単にエラーをレポートしセッションが切断するのみです。 - - - - -failover_on_backend_errorをoffにする場合は、バックエンドのヘルスチェックを有効にすることをお勧めします(をご覧ください)。 - なお、PostgreSQLバックエンドサーバが管理コマンドでシャットダウンされたことをPgpool-IIが検知した場合には、依然としてフェイルオーバが起こることに注意してください。 -この場合にもフェイルオーバを避けたい場合には、でDISALLOW_TO_FAILOVERを指定してください。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - -Pgpool-II V4.0より前では、この設定パラメータの名前はfail_over_on_backend_errorでした。 - - - - - - - search_primary_node_timeout (integer) - - search_primary_node_timeout 設定パラメータ - - - - - -フェイルオーバが起きた時にプライマリノードを検索するための最大時間を秒単位で指定します。 -Pgpool-IIは、ここで設定した時間の間にプライマリノードを見つけられなかった場合、探すのを諦めます。 -デフォルト値は300です。 -0を指定すると、永久に検索し続けます。 - - - -このパラメータはストリーミングレプリケーションによるマスタースレーブモードの場合のみ有効です。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - detach_false_primary (boolean) - - - detach_false_primary設定パラメータ - - - - - -onにすると、不正なプライマリを切り離します。 -デフォルトはoffです。 -このパラメータは、ストリーミングレプリケーションモードでかつ、PostgreSQL 9.6以降を使っている場合にのみ有効です。 -というのも、pg_stat_wal_receiverを使っているからです。 -PostgreSQL 9.5以前を使っている場合は、エラーは報告されず、単にこの設定は無視されます。 - - - -プライマリノードが存在しない場合は、検査を実施しません。 - - - -スタンバイノードが存在せず、プライマリノードがひとつだけ存在する場合は検査を実施しません。 - - - -スタンバイノードが存在せず、プライマリノードが複数存在する場合は、もっとも若いノード番号を持つプライマリノードだけを残し、それ以外は切り離します。 - - - -もし複数のプライマリと一つ以上のスタンバイがある場合は、PostgreSQL 9.6以降であれば、プライマリとスタンバイノードの間の接続性をpg_stat_wal_receiverで検証します。 -もしあるプライマリがすべてのスタンバイに接続している場合は、そのプライマリは「正しい」と見なされ、それ以外のプライマリは「不正」と見なされ、detach_false_primaryがonなら不正なプライマリは切り離されます。 -もし、正しいプライマリが見つからない場合は、何も起きません。 - - - -Pgpool-IIが起動した時、不正なプライマリのチェックはPgpool-IIのメインプロセスの中で一度だけ行われます。 -もしが0より大きければ、不正なプライマリのチェックは、ストリーミングレプリケーションの遅延チェックと同じタイミングで行われます。 - - - -このパラメータは、ストリーミングレプリケーションモードの時だけに適用されます。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - + + + + + + + + スクリプトの中でpsqlやその他のコマンドを使ってバックエンドにアクセスし、情報を取り出すことはできますが、psqlPgpool-II自体に対して実行することはできません。 + スクリプトはPgpool-IIから呼ばれ、Pgpool-IIがフェイルバックを実行している間に動作するからです。 + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + follow_primary_command (string) + + follow_primary_command 設定パラメータ + + + + + + + プライマリノードのフェイルオーバー後に実行するユーザコマンドを指定します。 + スタンバイがフェイルオーバーした際にはこのコマンドは実行されません。 + このコマンドは、コマンドによってノードを昇格する要求があった場合にも起動されます。 + この機能は、ストリーミングレプリケーションモードでのみ有効です。 + + + + + このコマンドは、フェイルオーバが完了した後に Pgpool-II によりフォークされた子プロセス内で実行されるので、 + follow_primary_command の実行はPgpool-IIのサービスを妨げることはありません。 + 以下で、このコマンドがどのように実行されるのかを疑似コードで説明します。 + +for each backend node +{ + if (the node is not the new primary) + set down node status to shared memory status + memorize that follow primary command is needed to execute +} +if (we need to executed follow primary command) +{ + fork a child process + (within the child process) + + for each backend node + { + if (the node status in shared memory is down) + execute follow primary command + } +} + + + + + + Pgpool-IIはコマンド実行の前に、以下の特殊文字をバックエンドの具体的な情報に置き換えます。 + + - -
+ + + フォロープライマリコマンドオプション + + + + + 特殊文字 + 説明 + + + + + + %d + + 切り離されたノードのDBノードID + + + %h + + 切り離されたノードのホスト名 + + + %p + + 切り離されたノードのポート番号 + + + %D + + 切り離されたノードのデータベースクラスタパス + + + %m + + 新しいプライマリノードのID + + + %H + + 新しいプライマリノードのホスト名 + + + %M + + 古いメインノードのID + + + %P + + 古いプライマリノードのID + + + %r + + 新しいプライマリノードのポート番号 + + + %R + + 新しいプライマリノードのデータベースクラスタパス + + + %N + + 古いプライマリノードのホスト名(Pgpool-II 4.1以降) + + + %S + + 古いプライマリノードのポート番号(Pgpool-II 4.1以降) + + + %% + + '%'文字 + + + + +
+ + + + + follow_primary_commandが空文字列でない場合、ストリーミングレプリケーションモードでプライマリノードのフェイルオーバーが完了した後に、Pgpool-IIは新しいプライマリ以外のすべてのノードを切り離し、クライアントから再び接続を受け付ける準備のため再度新しい子プロセスを起動します。 + その後、Pgpool-IIは切り離されたそれぞれのノードに対してfollow_primary_commandに設定したコマンドを実行します。 + + + + + 通常は、follow_primary_commandコマンドはコマンドを呼んで新しいプライマリからスタンバイをリカバリするために使用します。 + follow_primary_command中では、pg_ctlを使ってターゲットのPostgreSQLノードが動いているかどうかを確認することをお勧めします。 + たとえば、そのノードはハードウェア障害で停止しているかも知れませんし、管理者が保守のために停止しているのかも知れません。 + ノードが停止している場合は、そのノードをスキップしてください。 + ノードが動いている場合は、まずそのノードを停止してからリカバリしてください。 + コマンドを呼ばずに、直接pg_basebackupなどを呼び出してリカバリすることも可能ですが、その場合は、リカバリ後にを呼び出して、スタンバイサーバが利用可能になったことをPgpool-IIに通知してください。 + そうでないとそのスタンバイサーバはダウン状態のままになってしまいます。 + (コマンドは内部でを呼び出しているので、リカバリ後にスクリプトの中でを呼び出す必要はありません。) + follow_primary_commandの完全な例は、にあります。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + failover_on_backend_shutdown (boolean) + + + failover_on_backend_shutdown設定パラメータ + + + + + + onに設定した場合、Pgpool-IIは確立したクライアントとバックエンドのセッション上で特定のエラーコード:57P0157P02をチェックすることにより、バックエンドのシャットダウンイベントを検出します。 + それらのエラーコードを検出すると、そのノードでフェイルオーバが起動されます。 + offに設定した場合、そのようなエラーの場合でもPgpool-IIは単にエラーをレポートしセッションが切断するのみです。 + + + なお、ストリーミングレプリケーションモードでは、シャットダウン処理が行われたPostgreSQLがスタンバイノードで、かつロードバランスノードでない場合は、このパラメータがonでもフェイルオーバしません。 + 現在のセッションでどのノードがロードバランスなのかは、またはで確認できます。 + + + デフォルトはoffです。 + + + + クライアントが接続されていなければ、このパラメータがonでもPgpool-IIはシャットダウンを検出しません。 + + + + 57P01はシャットダウンだけでなく、現在接続中のバックエンドがpg_terminate_backendあるいはSIGTERMシグナルによって終了させられた場合にも送られてくることに注意してください。 + これは望まないフェイルオーバを引き起こすので困りものです。 + これを防ぐには、このパラメータをoffにしてください。 + + + + - 不正なプライマリの検出 - - - - - -
-
- -
-
+ failover_on_backend_shutdownをoffにする場合は、バックエンドのヘルスチェックを有効にすることをお勧めします(をご覧ください)。 + + + + + + このパラメータはPgpool-II 4.3以降で利用可能です。 + 4.2以前では、このパラメータが常にonであるのと同じ動作をします。 + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + failover_on_backend_error (boolean) + + failover_on_backend_error 設定パラメータ + + + + + + onに設定した場合、Pgpool-IIPostgreSQLバックエンド接続からの読み出し、書き込みのエラーをバックエンドノードの故障と見なし、現在のセッションを切断した後にそのノードをフェイルオーバします。 + offに設定した場合、そのようなエラーの場合でもPgpool-IIは単にエラーをレポートしセッションが切断するのみです。 + + + + + failover_on_backend_errorをoffにする場合は、バックエンドのヘルスチェックを有効にすることをお勧めします(をご覧ください)。 + なお、がonなら、PostgreSQLバックエンドサーバが管理コマンドでシャットダウンされたことをPgpool-IIが検知した場合には、依然としてフェイルオーバが起こることに注意してください。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + Pgpool-II V4.0より前では、この設定パラメータの名前はfail_over_on_backend_errorでした。 + + + + + + + search_primary_node_timeout (integer) + + search_primary_node_timeout 設定パラメータ + + + + + + フェイルオーバが起きた時にプライマリノードを検索するための最大時間を秒単位で指定します。 + Pgpool-IIは、ここで設定した時間の間にプライマリノードを見つけられなかった場合、探すのを諦めます。 + デフォルト値は300です。 + 0を指定すると、永久に検索し続けます。 + + + + このパラメータはストリーミングレプリケーションモードの場合のみ有効です。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + detach_false_primary (boolean) + + + detach_false_primary設定パラメータ + + + + + + onにすると、不正なプライマリを切り離します。 + デフォルトはoffです。 + このパラメータは、ストリーミングレプリケーションモードでかつ、PostgreSQL 9.6以降を使っている場合にのみ有効です。 + というのも、pg_stat_wal_receiverを使っているからです。 + PostgreSQL 9.5以前を使っている場合は、エラーは報告されず、単にこの設定は無視されます。 + + + + プライマリノードが存在しない場合は、検査を実施しません。 + + + + スタンバイノードが存在せず、プライマリノードがひとつだけ存在する場合は検査を実施しません。 + + + + スタンバイノードが存在せず、プライマリノードが複数存在する場合は、もっとも若いノード番号を持つプライマリノードだけを残し、それ以外は切り離します。 + + + + もし複数のプライマリと一つ以上のスタンバイがある場合は、PostgreSQL 9.6以降であれば、プライマリとスタンバイノードの間の接続性をpg_stat_wal_receiverで検証します。 + もしあるプライマリがすべてのスタンバイに接続している場合は、そのプライマリは「正しい」と見なされ、それ以外のプライマリは「不正」と見なされ、detach_false_primaryがonなら不正なプライマリは切り離されます。 + もし、正しいプライマリが見つからない場合は、何も起きません。 + + + + Pgpool-IIが起動した時、不正なプライマリのチェックはPgpool-IIのメインプロセスの中で一度だけ行われます。 + もしが0より大きければ、不正なプライマリのチェックは、ストリーミングレプリケーションの遅延チェックと同じタイミングで行われます。 + + + + + + この機能を使うためには、PostgreSQLのスーパーユーザーであるか、"pg_monitor"グループに所属していなければなりません。 + をpg_monitorグループに所属させるには、以下のSQLコマンドをPostgreSQLスーパーユーザーで実行してください("sr_check_user"をの設定値で置き換えてください) + + GRANT pg_monitor TO sr_check_user; + + + PostgreSQL 9.6にはpg_monitorグループがないので、PostgreSQLのスーパーユーザーでなければなりません。 + + + + + + watchdogが有効な場合、不正なプライマリの切り離しは、リーダーwatchdogでのみ実施されます。 + たとえがオンでも、この機能によるプライマリの切り離しは、リーダーwatchdogの判断だけで行われ、多数派の承認は必要とされません。 + + + + + このパラメータは、ストリーミングレプリケーションモードの時だけに適用されます。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + +
+ + 不正なプライマリの検出 + + + + + +
+
+ +
+
+ + + auto_failback (boolean) + + auto_failback 設定パラメータ + + + + + + onに設定した場合、ストリーミングレプリケーションが正常に動作しており、かつバックエンドノードのステータスがダウンのとき、スタンバイノードを自動で復帰させることができます。 + これは、一時的なネットワーク障害などによりスタンバイノードが認識できず縮退が行われた場合などに役立ちます。 + + + + この機能を使用するためには、streaming replication check (参照)が有効であり、バックエンドノードとしてPostgreSQLが9.1以降である必要があります。 + この機能は、プライマリノードでpg_stat_replicationを実行します。自動フェイルバックはスタンバイノードに対してのみ実行されます。 + failback_commandが空でなければ、failback_commandも実行されることに注意してください。 + メンテナンスなどで、一時的にスタンバイノードを切り離す場合は、このパラメータをOFFにしてから実施してください。 + 意図せずスタンバイノードが復帰してしまう可能性があります。 + + + + デフォルトはoffです。 + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + レプリケーションスロットを使用している場合、が動作しない可能性があることに注意してください。 + スタンバイノードがダウンした際にによりスタンバイのレプリケーションスロットが削除され、レプリケーションが停止している可能性があるためです。 + + + + + + + auto_failback_interval (integer) + + auto_failback_interval 設定パラメータ + + + + + + 自動フェイルバックの実行間隔の最小時間を秒単位で指定します。 + 次の自動フェイルバックは前回の自動フェイルバックから指定した時間経過するまで実行されません。 + ネットワークのエラーなどによりPgpool-IIが頻繁にバックエンドのDOWNを検出するような場合、大きい値を設定することでフェイルバックとフェイルオーバが繰り返される事を防ぐことができます。 + デフォルトは60です。 + 0を指定すると自動フェイルバックは待ちません。 + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + +
- + --> rawモードにおけるフェイルオーバ - -rawモードにおいて、複数のバックエンドサーバが定義されている場合、フェイルオーバが可能です。 -通常の動作ではPgpool-IIはbackend_hostname0で指定したバックエンドにアクセスします。 -何らかの理由でbackend_hostname0のサーバに障害が発生すると、Pgpool-IIはbackend_hostname1へのアクセスを試みます。 -これが失敗した場合にはPgpool-IIはbackend_hostname2, 3と以下同様に試みます。 + + rawモードにおいて、複数のバックエンドサーバが定義されている場合、フェイルオーバが可能です。 + 通常の動作ではPgpool-IIはbackend_hostname0で指定したバックエンドにアクセスします。 + 何らかの理由でbackend_hostname0のサーバに障害が発生すると、Pgpool-IIはbackend_hostname1へのアクセスを試みます。 + これが失敗した場合にはPgpool-IIはbackend_hostname2, 3と以下同様に試みます。 diff --git a/doc.ja/src/sgml/features-supported.sgml b/doc.ja/src/sgml/features-supported.sgml deleted file mode 100644 index c879328a9..000000000 --- a/doc.ja/src/sgml/features-supported.sgml +++ /dev/null @@ -1,2174 +0,0 @@ - - - B012 - - Embedded C - - - - B021 - - Direct SQL - - - - E011 - Core - Numeric data types - - - - E011-01 - Core - INTEGER and SMALLINT data types - - - - E011-02 - Core - REAL, DOUBLE PRECISION, and FLOAT data types - - - - E011-03 - Core - DECIMAL and NUMERIC data types - - - - E011-04 - Core - Arithmetic operators - - - - E011-05 - Core - Numeric comparison - - - - E011-06 - Core - Implicit casting among the numeric data types - - - - E021 - Core - Character data types - - - - E021-01 - Core - CHARACTER data type - - - - E021-02 - Core - CHARACTER VARYING data type - - - - E021-03 - Core - Character literals - - - - E021-04 - Core - CHARACTER_LENGTH function - trims trailing spaces from CHARACTER values before counting - - - E021-05 - Core - OCTET_LENGTH function - - - - E021-06 - Core - SUBSTRING function - - - - E021-07 - Core - Character concatenation - - - - E021-08 - Core - UPPER and LOWER functions - - - - E021-09 - Core - TRIM function - - - - E021-10 - Core - Implicit casting among the character string types - - - - E021-11 - Core - POSITION function - - - - E021-12 - Core - Character comparison - - - - E031 - Core - Identifiers - - - - E031-01 - Core - Delimited identifiers - - - - E031-02 - Core - Lower case identifiers - - - - E031-03 - Core - Trailing underscore - - - - E051 - Core - Basic query specification - - - - E051-01 - Core - SELECT DISTINCT - - - - E051-02 - Core - GROUP BY clause - - - - E051-04 - Core - GROUP BY can contain columns not in <select list> - - - - E051-05 - Core - Select list items can be renamed - - - - E051-06 - Core - HAVING clause - - - - E051-07 - Core - Qualified * in select list - - - - E051-08 - Core - Correlation names in the FROM clause - - - - E051-09 - Core - Rename columns in the FROM clause - - - - E061 - Core - Basic predicates and search conditions - - - - E061-01 - Core - Comparison predicate - - - - E061-02 - Core - BETWEEN predicate - - - - E061-03 - Core - IN predicate with list of values - - - - E061-04 - Core - LIKE predicate - - - - E061-05 - Core - LIKE predicate ESCAPE clause - - - - E061-06 - Core - NULL predicate - - - - E061-07 - Core - Quantified comparison predicate - - - - E061-08 - Core - EXISTS predicate - - - - E061-09 - Core - Subqueries in comparison predicate - - - - E061-11 - Core - Subqueries in IN predicate - - - - E061-12 - Core - Subqueries in quantified comparison predicate - - - - E061-13 - Core - Correlated subqueries - - - - E061-14 - Core - Search condition - - - - E071 - Core - Basic query expressions - - - - E071-01 - Core - UNION DISTINCT table operator - - - - E071-02 - Core - UNION ALL table operator - - - - E071-03 - Core - EXCEPT DISTINCT table operator - - - - E071-05 - Core - Columns combined via table operators need not have exactly the same data type - - - - E071-06 - Core - Table operators in subqueries - - - - E081 - Core - Basic Privileges - - - - E081-01 - Core - SELECT privilege - - - - E081-02 - Core - DELETE privilege - - - - E081-03 - Core - INSERT privilege at the table level - - - - E081-04 - Core - UPDATE privilege at the table level - - - - E081-05 - Core - UPDATE privilege at the column level - - - - E081-06 - Core - REFERENCES privilege at the table level - - - - E081-07 - Core - REFERENCES privilege at the column level - - - - E081-08 - Core - WITH GRANT OPTION - - - - E081-09 - Core - USAGE privilege - - - - E081-10 - Core - EXECUTE privilege - - - - E091 - Core - Set functions - - - - E091-01 - Core - AVG - - - - E091-02 - Core - COUNT - - - - E091-03 - Core - MAX - - - - E091-04 - Core - MIN - - - - E091-05 - Core - SUM - - - - E091-06 - Core - ALL quantifier - - - - E091-07 - Core - DISTINCT quantifier - - - - E101 - Core - Basic data manipulation - - - - E101-01 - Core - INSERT statement - - - - E101-03 - Core - Searched UPDATE statement - - - - E101-04 - Core - Searched DELETE statement - - - - E111 - Core - Single row SELECT statement - - - - E121 - Core - Basic cursor support - - - - E121-01 - Core - DECLARE CURSOR - - - - E121-02 - Core - ORDER BY columns need not be in select list - - - - E121-03 - Core - Value expressions in ORDER BY clause - - - - E121-04 - Core - OPEN statement - - - - E121-06 - Core - Positioned UPDATE statement - - - - E121-07 - Core - Positioned DELETE statement - - - - E121-08 - Core - CLOSE statement - - - - E121-10 - Core - FETCH statement implicit NEXT - - - - E121-17 - Core - WITH HOLD cursors - - - - E131 - Core - Null value support (nulls in lieu of values) - - - - E141 - Core - Basic integrity constraints - - - - E141-01 - Core - NOT NULL constraints - - - - E141-02 - Core - UNIQUE constraints of NOT NULL columns - - - - E141-03 - Core - PRIMARY KEY constraints - - - - E141-04 - Core - Basic FOREIGN KEY constraint with the NO ACTION default for both referential delete action and referential update action - - - - E141-06 - Core - CHECK constraints - - - - E141-07 - Core - Column defaults - - - - E141-08 - Core - NOT NULL inferred on PRIMARY KEY - - - - E141-10 - Core - Names in a foreign key can be specified in any order - - - - E151 - Core - Transaction support - - - - E151-01 - Core - COMMIT statement - - - - E151-02 - Core - ROLLBACK statement - - - - E152 - Core - Basic SET TRANSACTION statement - - - - E152-01 - Core - SET TRANSACTION statement: ISOLATION LEVEL SERIALIZABLE clause - - - - E152-02 - Core - SET TRANSACTION statement: READ ONLY and READ WRITE clauses - - - - E153 - Core - Updatable queries with subqueries - - - - E161 - Core - SQL comments using leading double minus - - - - E171 - Core - SQLSTATE support - - - - F021 - Core - Basic information schema - - - - F021-01 - Core - COLUMNS view - - - - F021-02 - Core - TABLES view - - - - F021-03 - Core - VIEWS view - - - - F021-04 - Core - TABLE_CONSTRAINTS view - - - - F021-05 - Core - REFERENTIAL_CONSTRAINTS view - - - - F021-06 - Core - CHECK_CONSTRAINTS view - - - - F031 - Core - Basic schema manipulation - - - - F031-01 - Core - CREATE TABLE statement to create persistent base tables - - - - F031-02 - Core - CREATE VIEW statement - - - - F031-03 - Core - GRANT statement - - - - F031-04 - Core - ALTER TABLE statement: ADD COLUMN clause - - - - F031-13 - Core - DROP TABLE statement: RESTRICT clause - - - - F031-16 - Core - DROP VIEW statement: RESTRICT clause - - - - F031-19 - Core - REVOKE statement: RESTRICT clause - - - - F032 - - CASCADE drop behavior - - - - F033 - - ALTER TABLE statement: DROP COLUMN clause - - - - F034 - - Extended REVOKE statement - - - - F034-01 - - REVOKE statement performed by other than the owner of a schema object - - - - F034-02 - - REVOKE statement: GRANT OPTION FOR clause - - - - F034-03 - - REVOKE statement to revoke a privilege that the grantee has WITH GRANT OPTION - - - - F041 - Core - Basic joined table - - - - F041-01 - Core - Inner join (but not necessarily the INNER keyword) - - - - F041-02 - Core - INNER keyword - - - - F041-03 - Core - LEFT OUTER JOIN - - - - F041-04 - Core - RIGHT OUTER JOIN - - - - F041-05 - Core - Outer joins can be nested - - - - F041-07 - Core - The inner table in a left or right outer join can also be used in an inner join - - - - F041-08 - Core - All comparison operators are supported (rather than just =) - - - - F051 - Core - Basic date and time - - - - F051-01 - Core - DATE data type (including support of DATE literal) - - - - F051-02 - Core - TIME data type (including support of TIME literal) with fractional seconds precision of at least 0 - - - - F051-03 - Core - TIMESTAMP data type (including support of TIMESTAMP literal) with fractional seconds precision of at least 0 and 6 - - - - F051-04 - Core - Comparison predicate on DATE, TIME, and TIMESTAMP data types - - - - F051-05 - Core - Explicit CAST between datetime types and character string types - - - - F051-06 - Core - CURRENT_DATE - - - - F051-07 - Core - LOCALTIME - - - - F051-08 - Core - LOCALTIMESTAMP - - - - F052 - Enhanced datetime facilities - Intervals and datetime arithmetic - - - - F053 - - OVERLAPS predicate - - - - F081 - Core - UNION and EXCEPT in views - - - - F111 - - Isolation levels other than SERIALIZABLE - - - - F111-01 - - READ UNCOMMITTED isolation level - - - - F111-02 - - READ COMMITTED isolation level - - - - F111-03 - - REPEATABLE READ isolation level - - - - F131 - Core - Grouped operations - - - - F131-01 - Core - WHERE, GROUP BY, and HAVING clauses supported in queries with grouped views - - - - F131-02 - Core - Multiple tables supported in queries with grouped views - - - - F131-03 - Core - Set functions supported in queries with grouped views - - - - F131-04 - Core - Subqueries with GROUP BY and HAVING clauses and grouped views - - - - F131-05 - Core - Single row SELECT with GROUP BY and HAVING clauses and grouped views - - - - F171 - - Multiple schemas per user - - - - F191 - Enhanced integrity management - Referential delete actions - - - - F200 - - TRUNCATE TABLE statement - - - - F201 - Core - CAST function - - - - F221 - Core - Explicit defaults - - - - F222 - - INSERT statement: DEFAULT VALUES clause - - - - F231 - - Privilege tables - - - - F231-01 - - TABLE_PRIVILEGES view - - - - F231-02 - - COLUMN_PRIVILEGES view - - - - F231-03 - - USAGE_PRIVILEGES view - - - - F251 - - Domain support - - - - F261 - Core - CASE expression - - - - F261-01 - Core - Simple CASE - - - - F261-02 - Core - Searched CASE - - - - F261-03 - Core - NULLIF - - - - F261-04 - Core - COALESCE - - - - F262 - - Extended CASE expression - - - - F271 - - Compound character literals - - - - F281 - - LIKE enhancements - - - - F302 - - INTERSECT table operator - - - - F302-01 - - INTERSECT DISTINCT table operator - - - - F302-02 - - INTERSECT ALL table operator - - - - F304 - - EXCEPT ALL table operator - - - - F311-01 - Core - CREATE SCHEMA - - - - F311-02 - Core - CREATE TABLE for persistent base tables - - - - F311-03 - Core - CREATE VIEW - - - - F311-04 - Core - CREATE VIEW: WITH CHECK OPTION - - - - F311-05 - Core - GRANT statement - - - - F321 - - User authorization - - - - F361 - - Subprogram support - - - - F381 - - Extended schema manipulation - - - - F381-01 - - ALTER TABLE statement: ALTER COLUMN clause - - - - F381-02 - - ALTER TABLE statement: ADD CONSTRAINT clause - - - - F381-03 - - ALTER TABLE statement: DROP CONSTRAINT clause - - - - F382 - - Alter column data type - - - - F383 - - Set column not null clause - - - - F391 - - Long identifiers - - - - F392 - - Unicode escapes in identifiers - - - - F393 - - Unicode escapes in literals - - - - F401 - - Extended joined table - - - - F401-01 - - NATURAL JOIN - - - - F401-02 - - FULL OUTER JOIN - - - - F401-04 - - CROSS JOIN - - - - F402 - - Named column joins for LOBs, arrays, and multisets - - - - F411 - Enhanced datetime facilities - Time zone specification - differences regarding literal interpretation - - - F421 - - National character - - - - F431 - - Read-only scrollable cursors - - - - F431-01 - - FETCH with explicit NEXT - - - - F431-02 - - FETCH FIRST - - - - F431-03 - - FETCH LAST - - - - F431-04 - - FETCH PRIOR - - - - F431-05 - - FETCH ABSOLUTE - - - - F431-06 - - FETCH RELATIVE - - - - F441 - - Extended set function support - - - - F442 - - Mixed column references in set functions - - - - F471 - Core - Scalar subquery values - - - - F481 - Core - Expanded NULL predicate - - - - F491 - Enhanced integrity management - Constraint management - - - - F501 - Core - Features and conformance views - - - - F501-01 - Core - SQL_FEATURES view - - - - F501-02 - Core - SQL_SIZING view - - - - F501-03 - Core - SQL_LANGUAGES view - - - - F502 - - Enhanced documentation tables - - - - F502-01 - - SQL_SIZING_PROFILES view - - - - F502-02 - - SQL_IMPLEMENTATION_INFO view - - - - F502-03 - - SQL_PACKAGES view - - - - F531 - - Temporary tables - - - - F555 - Enhanced datetime facilities - Enhanced seconds precision - - - - F561 - - Full value expressions - - - - F571 - - Truth value tests - - - - F591 - - Derived tables - - - - F611 - - Indicator data types - - - - F641 - - Row and table constructors - - - - F651 - - Catalog name qualifiers - - - - F661 - - Simple tables - - - - F672 - - Retrospective check constraints - - - - F690 - - Collation support - but no character set support - - - F692 - - Extended collation support - - - - F701 - Enhanced integrity management - Referential update actions - - - - F711 - - ALTER domain - - - - F731 - - INSERT column privileges - - - - F751 - - View CHECK enhancements - - - - F761 - - Session management - - - - F762 - - CURRENT_CATALOG - - - - F763 - - CURRENT_SCHEMA - - - - F771 - - Connection management - - - - F781 - - Self-referencing operations - - - - F791 - - Insensitive cursors - - - - F801 - - Full set function - - - - F850 - - Top-level <order by clause> in <query expression> - - - - F851 - - <order by clause> in subqueries - - - - F852 - - Top-level <order by clause> in views - - - - F855 - - Nested <order by clause> in <query expression> - - - - F856 - - Nested <fetch first clause> in <query expression> - - - - F857 - - Top-level <fetch first clause> in <query expression> - - - - F858 - - <fetch first clause> in subqueries - - - - F859 - - Top-level <fetch first clause> in views - - - - F860 - - <fetch first row count> in <fetch first clause> - - - - F861 - - Top-level <result offset clause> in <query expression> - - - - F862 - - <result offset clause> in subqueries - - - - F863 - - Nested <result offset clause> in <query expression> - - - - F864 - - Top-level <result offset clause> in views - - - - F865 - - <offset row count> in <result offset clause> - - - - S071 - Enhanced object support - SQL paths in function and type name resolution - - - - S092 - - Arrays of user-defined types - - - - S095 - - Array constructors by query - - - - S096 - - Optional array bounds - - - - S098 - - ARRAY_AGG - - - - S111 - Enhanced object support - ONLY in query expressions - - - - S201 - - SQL-invoked routines on arrays - - - - S201-01 - - Array parameters - - - - S201-02 - - Array as result type of functions - - - - S211 - Enhanced object support - User-defined cast functions - - - - T031 - - BOOLEAN data type - - - - T071 - - BIGINT data type - - - - T121 - - WITH (excluding RECURSIVE) in query expression - - - - T122 - - WITH (excluding RECURSIVE) in subquery - - - - T131 - - Recursive query - - - - T132 - - Recursive query in subquery - - - - T141 - - SIMILAR predicate - - - - T151 - - DISTINCT predicate - - - - T152 - - DISTINCT predicate with negation - - - - T171 - - LIKE clause in table definition - - - - T172 - - AS subquery clause in table definition - - - - T173 - - Extended LIKE clause in table definition - - - - T191 - Enhanced integrity management - Referential action RESTRICT - - - - T201 - Enhanced integrity management - Comparable data types for referential constraints - - - - T211-01 - Active database, Enhanced integrity management - Triggers activated on UPDATE, INSERT, or DELETE of one base table - - - - T211-02 - Active database, Enhanced integrity management - BEFORE triggers - - - - T211-03 - Active database, Enhanced integrity management - AFTER triggers - - - - T211-04 - Active database, Enhanced integrity management - FOR EACH ROW triggers - - - - T211-05 - Active database, Enhanced integrity management - Ability to specify a search condition that must be true before the trigger is invoked - - - - T211-07 - Active database, Enhanced integrity management - TRIGGER privilege - - - - T212 - Enhanced integrity management - Enhanced trigger capability - - - - T213 - - INSTEAD OF triggers - - - - T231 - - Sensitive cursors - - - - T241 - - START TRANSACTION statement - - - - T271 - - Savepoints - - - - T281 - - SELECT privilege with column granularity - - - - T312 - - OVERLAY function - - - - T321-01 - Core - User-defined functions with no overloading - - - - T321-03 - Core - Function invocation - - - - T321-06 - Core - ROUTINES view - - - - T321-07 - Core - PARAMETERS view - - - - T323 - - Explicit security for external routines - - - - T325 - - Qualified SQL parameter references - - - - T331 - - Basic roles - - - - T341 - - Overloading of SQL-invoked functions and procedures - - - - T351 - - Bracketed SQL comments (/*...*/ comments) - - - - T441 - - ABS and MOD functions - - - - T461 - - Symmetric BETWEEN predicate - - - - T491 - - LATERAL derived table - - - - T501 - - Enhanced EXISTS predicate - - - - T551 - - Optional key words for default syntax - - - - T581 - - Regular expression substring function - - - - T591 - - UNIQUE constraints of possibly null columns - - - - T614 - - NTILE function - - - - T615 - - LEAD and LAG functions - - - - T617 - - FIRST_VALUE and LAST_VALUE function - - - - T621 - - Enhanced numeric functions - - - - T631 - Core - IN predicate with one list element - - - - T651 - - SQL-schema statements in SQL routines - - - - T655 - - Cyclically dependent routines - - - - X010 - - XML type - - - - X011 - - Arrays of XML type - - - - X016 - - Persistent XML values - - - - X020 - - XMLConcat - - - - X031 - - XMLElement - - - - X032 - - XMLForest - - - - X034 - - XMLAgg - - - - X035 - - XMLAgg: ORDER BY option - - - - X036 - - XMLComment - - - - X037 - - XMLPI - - - - X040 - - Basic table mapping - - - - X041 - - Basic table mapping: nulls absent - - - - X042 - - Basic table mapping: null as nil - - - - X043 - - Basic table mapping: table as forest - - - - X044 - - Basic table mapping: table as element - - - - X045 - - Basic table mapping: with target namespace - - - - X046 - - Basic table mapping: data mapping - - - - X047 - - Basic table mapping: metadata mapping - - - - X048 - - Basic table mapping: base64 encoding of binary strings - - - - X049 - - Basic table mapping: hex encoding of binary strings - - - - X050 - - Advanced table mapping - - - - X051 - - Advanced table mapping: nulls absent - - - - X052 - - Advanced table mapping: null as nil - - - - X053 - - Advanced table mapping: table as forest - - - - X054 - - Advanced table mapping: table as element - - - - X055 - - Advanced table mapping: target namespace - - - - X056 - - Advanced table mapping: data mapping - - - - X057 - - Advanced table mapping: metadata mapping - - - - X058 - - Advanced table mapping: base64 encoding of binary strings - - - - X059 - - Advanced table mapping: hex encoding of binary strings - - - - X060 - - XMLParse: Character string input and CONTENT option - - - - X061 - - XMLParse: Character string input and DOCUMENT option - - - - X070 - - XMLSerialize: Character string serialization and CONTENT option - - - - X071 - - XMLSerialize: Character string serialization and DOCUMENT option - - - - X072 - - XMLSerialize: Character string serialization - - - - X090 - - XML document predicate - - - - X120 - - XML parameters in SQL routines - - - - X121 - - XML parameters in external routines - - - - X400 - - Name and identifier mapping - - - - X410 - - Alter column data type: XML type - - - diff --git a/doc.ja/src/sgml/features-unsupported.sgml b/doc.ja/src/sgml/features-unsupported.sgml deleted file mode 100644 index 4d42fbbff..000000000 --- a/doc.ja/src/sgml/features-unsupported.sgml +++ /dev/null @@ -1,1862 +0,0 @@ - - - B011 - - Embedded Ada - - - - B013 - - Embedded COBOL - - - - B014 - - Embedded Fortran - - - - B015 - - Embedded MUMPS - - - - B016 - - Embedded Pascal - - - - B017 - - Embedded PL/I - - - - B031 - - Basic dynamic SQL - - - - B032 - - Extended dynamic SQL - - - - B032-01 - - <describe input statement> - - - - B033 - - Untyped SQL-invoked function arguments - - - - B034 - - Dynamic specification of cursor attributes - - - - B035 - - Non-extended descriptor names - - - - B041 - - Extensions to embedded SQL exception declarations - - - - B051 - - Enhanced execution rights - - - - B111 - - Module language Ada - - - - B112 - - Module language C - - - - B113 - - Module language COBOL - - - - B114 - - Module language Fortran - - - - B115 - - Module language MUMPS - - - - B116 - - Module language Pascal - - - - B117 - - Module language PL/I - - - - B121 - - Routine language Ada - - - - B122 - - Routine language C - - - - B123 - - Routine language COBOL - - - - B124 - - Routine language Fortran - - - - B125 - - Routine language MUMPS - - - - B126 - - Routine language Pascal - - - - B127 - - Routine language PL/I - - - - B128 - - Routine language SQL - - - - B211 - - Module language Ada: VARCHAR and NUMERIC support - - - - B221 - - Routine language Ada: VARCHAR and NUMERIC support - - - - E182 - Core - Module language - - - - F054 - - TIMESTAMP in DATE type precedence list - - - - F121 - - Basic diagnostics management - - - - F121-01 - - GET DIAGNOSTICS statement - - - - F121-02 - - SET TRANSACTION statement: DIAGNOSTICS SIZE clause - - - - F122 - - Enhanced diagnostics management - - - - F123 - - All diagnostics - - - - F181 - Core - Multiple module support - - - - F202 - - TRUNCATE TABLE: identity column restart option - - - - F263 - - Comma-separated predicates in simple CASE expression - - - - F291 - - UNIQUE predicate - - - - F301 - - CORRESPONDING in query expressions - - - - F311 - Core - Schema definition statement - - - - F312 - - MERGE statement - - - - F313 - - Enhanced MERGE statement - - - - F314 - - MERGE statement with DELETE branch - - - - F341 - - Usage tables - no ROUTINE_*_USAGE tables - - - F384 - - Drop identity property clause - - - - F385 - - Drop column generation expression clause - - - - F386 - - Set identity column generation clause - - - - F394 - - Optional normal form specification - - - - F403 - - Partitioned joined tables - - - - F451 - - Character set definition - - - - F461 - - Named character sets - - - - F492 - - Optional table constraint enforcement - - - - F521 - Enhanced integrity management - Assertions - - - - F671 - Enhanced integrity management - Subqueries in CHECK - intentionally omitted - - - F693 - - SQL-session and client module collations - - - - F695 - - Translation support - - - - F696 - - Additional translation documentation - - - - F721 - - Deferrable constraints - foreign and unique keys only - - - F741 - - Referential MATCH types - no partial match yet - - - F812 - Core - Basic flagging - - - - F813 - - Extended flagging - - - - F821 - - Local table references - - - - F831 - - Full cursor update - - - - F831-01 - - Updatable scrollable cursors - - - - F831-02 - - Updatable ordered cursors - - - - F841 - - LIKE_REGEX predicate - - - - F842 - - OCCURENCES_REGEX function - - - - F843 - - POSITION_REGEX function - - - - F844 - - SUBSTRING_REGEX function - - - - F845 - - TRANSLATE_REGEX function - - - - F846 - - Octet support in regular expression operators - - - - F847 - - Nonconstant regular expressions - - - - F866 - - FETCH FIRST clause: PERCENT option - - - - F867 - - FETCH FIRST clause: WITH TIES option - - - - S011 - Core - Distinct data types - - - - S011-01 - Core - USER_DEFINED_TYPES view - - - - S023 - Basic object support - Basic structured types - - - - S024 - Enhanced object support - Enhanced structured types - - - - S025 - - Final structured types - - - - S026 - - Self-referencing structured types - - - - S027 - - Create method by specific method name - - - - S028 - - Permutable UDT options list - - - - S041 - Basic object support - Basic reference types - - - - S043 - Enhanced object support - Enhanced reference types - - - - S051 - Basic object support - Create table of type - partially supported - - - S081 - Enhanced object support - Subtables - - - - S091 - - Basic array support - partially supported - - - S091-01 - - Arrays of built-in data types - - - - S091-02 - - Arrays of distinct types - - - - S091-03 - - Array expressions - - - - S094 - - Arrays of reference types - - - - S097 - - Array element assignment - - - - S151 - Basic object support - Type predicate - - - - S161 - Enhanced object support - Subtype treatment - - - - S162 - - Subtype treatment for references - - - - S202 - - SQL-invoked routines on multisets - - - - S231 - Enhanced object support - Structured type locators - - - - S232 - - Array locators - - - - S233 - - Multiset locators - - - - S241 - - Transform functions - - - - S242 - - Alter transform statement - - - - S251 - - User-defined orderings - - - - S261 - - Specific type method - - - - S271 - - Basic multiset support - - - - S272 - - Multisets of user-defined types - - - - S274 - - Multisets of reference types - - - - S275 - - Advanced multiset support - - - - S281 - - Nested collection types - - - - S291 - - Unique constraint on entire row - - - - S301 - - Enhanced UNNEST - - - - S401 - - Distinct types based on array types - - - - S402 - - Distinct types based on distinct types - - - - S403 - - ARRAY_MAX_CARDINALITY - - - - S404 - - TRIM_ARRAY - - - - T011 - - Timestamp in Information Schema - - - - T021 - - BINARY and VARBINARY data types - - - - T022 - - Advanced support for BINARY and VARBINARY data types - - - - T023 - - Compound binary literal - - - - T024 - - Spaces in binary literals - - - - T041 - Basic object support - Basic LOB data type support - - - - T041-01 - Basic object support - BLOB data type - - - - T041-02 - Basic object support - CLOB data type - - - - T041-03 - Basic object support - POSITION, LENGTH, LOWER, TRIM, UPPER, and SUBSTRING functions for LOB data types - - - - T041-04 - Basic object support - Concatenation of LOB data types - - - - T041-05 - Basic object support - LOB locator: non-holdable - - - - T042 - - Extended LOB data type support - - - - T043 - - Multiplier T - - - - T044 - - Multiplier P - - - - T051 - - Row types - - - - T052 - - MAX and MIN for row types - - - - T053 - - Explicit aliases for all-fields reference - - - - T061 - - UCS support - - - - T101 - - Enhanced nullability determination - - - - T111 - - Updatable joins, unions, and columns - - - - T174 - - Identity columns - - - - T175 - - Generated columns - - - - T176 - - Sequence generator support - - - - T177 - - Sequence generator support: simple restart option - - - - T178 - - Identity columns: simple restart option - - - - T180 - - System-versioned tables - - - - T181 - - Application-time period tables - - - - T211 - Active database, Enhanced integrity management - Basic trigger capability - - - - T211-06 - Active database, Enhanced integrity management - Support for run-time rules for the interaction of triggers and constraints - - - - T211-08 - Active database, Enhanced integrity management - Multiple triggers for the same event are executed in the order in which they were created in the catalog - intentionally omitted - - - T251 - - SET TRANSACTION statement: LOCAL option - - - - T261 - - Chained transactions - - - - T272 - - Enhanced savepoint management - - - - T285 - - Enhanced derived column names - - - - T301 - - Functional dependencies - partially supported - - - T321 - Core - Basic SQL-invoked routines - - - - T321-02 - Core - User-defined stored procedures with no overloading - - - - T321-04 - Core - CALL statement - - - - T321-05 - Core - RETURN statement - - - - T322 - PSM - Declared data type attributes - - - - T324 - - Explicit security for SQL routines - - - - T326 - - Table functions - - - - T332 - - Extended roles - mostly supported - - - T431 - OLAP - Extended grouping capabilities - - - - T432 - - Nested and concatenated GROUPING SETS - - - - T433 - - Multiargument GROUPING function - - - - T434 - - GROUP BY DISTINCT - - - - T471 - - Result sets return value - - - - T472 - - DESCRIBE CURSOR - - - - T495 - - Combined data change and retrieval - different syntax - - - T502 - - Period predicates - - - - T511 - - Transaction counts - - - - T521 - - Named arguments in CALL statement - - - - T522 - - Default values for IN parameters of SQL-invoked procedures - - - - T541 - - Updatable table references - - - - T561 - - Holdable locators - - - - T571 - - Array-returning external SQL-invoked functions - - - - T572 - - Multiset-returning external SQL-invoked functions - - - - T601 - - Local cursor references - - - - T611 - OLAP - Elementary OLAP operations - most forms supported - - - T612 - - Advanced OLAP operations - some forms supported - - - T613 - - Sampling - - - - T616 - - Null treatment option for LEAD and LAG functions - - - - T618 - - NTH_VALUE function - function exists, but some options missing - - - T619 - - Nested window functions - - - - T620 - - WINDOW clause: GROUPS option - - - - T641 - - Multiple column assignment - only some syntax variants supported - - - T652 - - SQL-dynamic statements in SQL routines - - - - T653 - - SQL-schema statements in external routines - - - - T654 - - SQL-dynamic statements in external routines - - - - M001 - - Datalinks - - - - M002 - - Datalinks via SQL/CLI - - - - M003 - - Datalinks via Embedded SQL - - - - M004 - - Foreign data support - partially supported - - - M005 - - Foreign schema support - - - - M006 - - GetSQLString routine - - - - M007 - - TransmitRequest - - - - M009 - - GetOpts and GetStatistics routines - - - - M010 - - Foreign data wrapper support - different API - - - M011 - - Datalinks via Ada - - - - M012 - - Datalinks via C - - - - M013 - - Datalinks via COBOL - - - - M014 - - Datalinks via Fortran - - - - M015 - - Datalinks via M - - - - M016 - - Datalinks via Pascal - - - - M017 - - Datalinks via PL/I - - - - M018 - - Foreign data wrapper interface routines in Ada - - - - M019 - - Foreign data wrapper interface routines in C - different API - - - M020 - - Foreign data wrapper interface routines in COBOL - - - - M021 - - Foreign data wrapper interface routines in Fortran - - - - M022 - - Foreign data wrapper interface routines in MUMPS - - - - M023 - - Foreign data wrapper interface routines in Pascal - - - - M024 - - Foreign data wrapper interface routines in PL/I - - - - M030 - - SQL-server foreign data support - - - - M031 - - Foreign data wrapper general routines - - - - X012 - - Multisets of XML type - - - - X013 - - Distinct types of XML type - - - - X014 - - Attributes of XML type - - - - X015 - - Fields of XML type - - - - X025 - - XMLCast - - - - X030 - - XMLDocument - - - - X038 - - XMLText - - - - X065 - - XMLParse: BLOB input and CONTENT option - - - - X066 - - XMLParse: BLOB input and DOCUMENT option - - - - X068 - - XMLSerialize: BOM - - - - X069 - - XMLSerialize: INDENT - - - - X073 - - XMLSerialize: BLOB serialization and CONTENT option - - - - X074 - - XMLSerialize: BLOB serialization and DOCUMENT option - - - - X075 - - XMLSerialize: BLOB serialization - - - - X076 - - XMLSerialize: VERSION - - - - X077 - - XMLSerialize: explicit ENCODING option - - - - X078 - - XMLSerialize: explicit XML declaration - - - - X080 - - Namespaces in XML publishing - - - - X081 - - Query-level XML namespace declarations - - - - X082 - - XML namespace declarations in DML - - - - X083 - - XML namespace declarations in DDL - - - - X084 - - XML namespace declarations in compound statements - - - - X085 - - Predefined namespace prefixes - - - - X086 - - XML namespace declarations in XMLTable - - - - X091 - - XML content predicate - - - - X096 - - XMLExists - - - - X100 - - Host language support for XML: CONTENT option - - - - X101 - - Host language support for XML: DOCUMENT option - - - - X110 - - Host language support for XML: VARCHAR mapping - - - - X111 - - Host language support for XML: CLOB mapping - - - - X112 - - Host language support for XML: BLOB mapping - - - - X113 - - Host language support for XML: STRIP WHITESPACE option - - - - X114 - - Host language support for XML: PRESERVE WHITESPACE option - - - - X131 - - Query-level XMLBINARY clause - - - - X132 - - XMLBINARY clause in DML - - - - X133 - - XMLBINARY clause in DDL - - - - X134 - - XMLBINARY clause in compound statements - - - - X135 - - XMLBINARY clause in subqueries - - - - X141 - - IS VALID predicate: data-driven case - - - - X142 - - IS VALID predicate: ACCORDING TO clause - - - - X143 - - IS VALID predicate: ELEMENT clause - - - - X144 - - IS VALID predicate: schema location - - - - X145 - - IS VALID predicate outside check constraints - - - - X151 - - IS VALID predicate with DOCUMENT option - - - - X152 - - IS VALID predicate with CONTENT option - - - - X153 - - IS VALID predicate with SEQUENCE option - - - - X155 - - IS VALID predicate: NAMESPACE without ELEMENT clause - - - - X157 - - IS VALID predicate: NO NAMESPACE with ELEMENT clause - - - - X160 - - Basic Information Schema for registered XML Schemas - - - - X161 - - Advanced Information Schema for registered XML Schemas - - - - X170 - - XML null handling options - - - - X171 - - NIL ON NO CONTENT option - - - - X181 - - XML(DOCUMENT(UNTYPED)) type - - - - X182 - - XML(DOCUMENT(ANY)) type - - - - X190 - - XML(SEQUENCE) type - - - - X191 - - XML(DOCUMENT(XMLSCHEMA)) type - - - - X192 - - XML(CONTENT(XMLSCHEMA)) type - - - - X200 - - XMLQuery - - - - X201 - - XMLQuery: RETURNING CONTENT - - - - X202 - - XMLQuery: RETURNING SEQUENCE - - - - X203 - - XMLQuery: passing a context item - - - - X204 - - XMLQuery: initializing an XQuery variable - - - - X205 - - XMLQuery: EMPTY ON EMPTY option - - - - X206 - - XMLQuery: NULL ON EMPTY option - - - - X211 - - XML 1.1 support - - - - X221 - - XML passing mechanism BY VALUE - - - - X222 - - XML passing mechanism BY REF - - - - X231 - - XML(CONTENT(UNTYPED)) type - - - - X232 - - XML(CONTENT(ANY)) type - - - - X241 - - RETURNING CONTENT in XML publishing - - - - X242 - - RETURNING SEQUENCE in XML publishing - - - - X251 - - Persistent XML values of XML(DOCUMENT(UNTYPED)) type - - - - X252 - - Persistent XML values of XML(DOCUMENT(ANY)) type - - - - X253 - - Persistent XML values of XML(CONTENT(UNTYPED)) type - - - - X254 - - Persistent XML values of XML(CONTENT(ANY)) type - - - - X255 - - Persistent XML values of XML(SEQUENCE) type - - - - X256 - - Persistent XML values of XML(DOCUMENT(XMLSCHEMA)) type - - - - X257 - - Persistent XML values of XML(CONTENT(XMLSCHEMA)) type - - - - X260 - - XML type: ELEMENT clause - - - - X261 - - XML type: NAMESPACE without ELEMENT clause - - - - X263 - - XML type: NO NAMESPACE with ELEMENT clause - - - - X264 - - XML type: schema location - - - - X271 - - XMLValidate: data-driven case - - - - X272 - - XMLValidate: ACCORDING TO clause - - - - X273 - - XMLValidate: ELEMENT clause - - - - X274 - - XMLValidate: schema location - - - - X281 - - XMLValidate: with DOCUMENT option - - - - X282 - - XMLValidate with CONTENT option - - - - X283 - - XMLValidate with SEQUENCE option - - - - X284 - - XMLValidate NAMESPACE without ELEMENT clause - - - - X286 - - XMLValidate: NO NAMESPACE with ELEMENT clause - - - - X300 - - XMLTable - - - - X301 - - XMLTable: derived column list option - - - - X302 - - XMLTable: ordinality column option - - - - X303 - - XMLTable: column default option - - - - X304 - - XMLTable: passing a context item - - - - X305 - - XMLTable: initializing an XQuery variable - - - diff --git a/doc.ja/src/sgml/filelist.sgml b/doc.ja/src/sgml/filelist.sgml index a7efd6a7a..ea205e2fb 100644 --- a/doc.ja/src/sgml/filelist.sgml +++ b/doc.ja/src/sgml/filelist.sgml @@ -13,36 +13,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -60,127 +35,31 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + %allfiles; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + @@ -191,14 +70,8 @@ - - - - - - - + - - ヘルスチェック + + ヘルスチェック - - -Pgpool-IIはサーバネットワークの障害を検知するために、設定されたバックエンドに定期的に接続を試みます。 -この障害チェックの手続きを「ヘルスチェック」と言います。 -障害が検知されると、Pgpool-IIは設定に基づいてフェイルオーバや縮退運転を試みます。 - - - -ヘルスチェックは各バックエンドノードへの余分の接続を1つ必要としますので、postgresql.confmax_connectionsもそれに応じて調整する必要があります。 - - - + + + Pgpool-IIはサーバやネットワークの障害を検知するために、設定されたバックエンドに定期的に接続を試みます。 + この障害チェックの手続きを「ヘルスチェック」と言います。 + + + + SSLが有効なら、ヘルスチェックプロセスはSSL接続を使うかもしれません。 + + + 障害が検知されると、Pgpool-IIは設定に基づいてフェイルオーバや縮退運転を試みます。 + + + + ヘルスチェックは各バックエンドノードへの余分の接続を1つ必要としますので、postgresql.confmax_connectionsもそれに応じて調整する必要があります。 + + + + + + ヘルスチェックプロセスは、ヘルスチェックの合計実行回数のような様々な統計情報データを収集します。 + 統計情報を調べるには、コマンドを使用してください。 + なお、このデータは共有メモリ領域に格納されるので、Pgpool-IIの起動時に初期化されることに注意してください。 + - - + + -以下のパラメータは、名前の最後に数字の接尾辞を持つことができます。その -接尾辞は、のようなバックエンド情報で定義されるバックエンドのIDに対応します。 -たとえばhealth_check_timeout0は、バックエンド0のhealth_check_timeoutに適用されます。 - - - -接尾辞付きのパラメータがない場合は、そのバックエンドの設定値は接尾辞なしのパラメータの値が使用されます。 -つまり、接尾辞なしのパラメータは、「広域変数」のように扱われます。 - + 以下のパラメータは、名前の最後に数字の接尾辞を持つことができます。その + 接尾辞は、のようなバックエンド情報で定義されるバックエンドのIDに対応します。 + たとえばhealth_check_timeout0は、バックエンド0のhealth_check_timeoutに適用されます。 + + + + 接尾辞付きのパラメータがない場合は、そのバックエンドの設定値は接尾辞なしのパラメータの値が使用されます。 + つまり、接尾辞なしのパラメータは、「広域変数」のように扱われます。 + - + - - health_check_timeout (integer) - - - health_check_timeout 設定パラメータ - - - + + health_check_timeout (integer) + + + health_check_timeout 設定パラメータ + + + - -TCP接続が時間内に成功せずにバックエンドのPostgreSQLへの接続を諦めるまでのタイムアウト値を秒単位で指定します。 + + TCP接続が時間内に成功せずにバックエンドのPostgreSQLへの接続を諦めるまでのタイムアウト値を秒単位で指定します。 - -このパラメータは、ネットワークケーブルが抜けた際などにヘルスチェックが長時間待たされるのを防止します。 -デフォルトは20秒です。0を指定するとタイムアウト処理をしません (TCP/IP のタイムアウトまで待ちます)。 + + このパラメータは、ネットワークケーブルが抜けた際などにヘルスチェックが長時間待たされるのを防止します。 + デフォルトは20秒です。0を指定するとタイムアウト処理をしません (TCP/IP のタイムアウトまで待ちます)。 - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - + + - - health_check_period (integer) - - - health_check_period 設定パラメータ - - - + + health_check_period (integer) + + + health_check_period 設定パラメータ + + + - -ヘルスチェックの間隔を秒単位で指定します。 -デフォルトは0で、これはヘルスチェックが無効であることを意味します。 + + ヘルスチェックの間隔を秒単位で指定します。 + デフォルトは0で、これはヘルスチェックが無効であることを意味します。 - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + --> + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - + + - - health_check_user (string) - - - health_check_user 設定パラメータ - - - - - -ヘルスチェックを行うPostgreSQLユーザ名を指定します。 -同じユーザ名が全てのPostgreSQLバックエンドに存在していなければなりません。 -さもないと、ヘルスチェックがエラーとなります。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + health_check_user (string) + + + health_check_user 設定パラメータ + + + + + + ヘルスチェックを行うPostgreSQLユーザ名を指定します。 + デフォルトは''(空文字)です。 + 同じユーザ名が全てのPostgreSQLバックエンドに存在していなければなりません。 + さもないと、ヘルスチェックがエラーとなります。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - - health_check_password (string) - - - health_check_password 設定パラメータ - - - - - -で設定したヘルスチェックを行うPostgreSQLユーザ名のパスワードを指定します。 -ユーザとパスワードは全てのPostgreSQLバックエンドで同じである必要があります。 -さもないと、ヘルスチェックがエラーとなります。 - - - -health_check_passwordが空白のままの場合、 Pgpool-IIは空のパスワードを使用する前にまずファイルからのパスワードを取得できるか試みます。 - - - -health_check_passwordにAES256-CBCで暗号化されたパスワードも指定することができます。 -AESで暗号化されたパスワードを指定するためには、パスワード文字列は暗号化(aes-256-cbcアルゴリズムを使用)およびbase64でエンコードした後、AESを接頭辞として付けなければいけません。 - - - -暗号化されていないクリアテキストパスワードを指定するためには、TEXTをパスワード文字列の前に付けます。 -例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定すべきです。 -有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 - - - -正しくフォーマットされたAES暗号化パスワード文字をコマンドを使用して作成することもできます。 - - - -Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 -Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 - + + health_check_password (string) + + + health_check_password 設定パラメータ + + + + + + で設定したヘルスチェックを行うPostgreSQLユーザのパスワードを指定します。 + ユーザとパスワードは全てのPostgreSQLバックエンドで同じである必要があります。 + さもないと、ヘルスチェックがエラーとなります。 + + + + health_check_passwordが空のままの場合、 Pgpool-IIは空のパスワードを使用する前にまずファイルからのパスワードを取得できるか試みます。 + + + health_check_passwordは以下の書式で指定します。 + + + AES256-CBC暗号化パスワード + + + パスワードを格納する最もセキュアで推奨できる方法です。 + パスワード文字列はAESで始まっていなければなりません。 + ユーティリティを使って正しくAESで暗号化された文字列を作ることができます。 + Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 + Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 + + + - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - + + MD5ハッシュパスワード + + + AESほどはセキュアではありませんが、平文パスワードよりは良いです。 + パスワード文字列はMD5で始まっていなければなりません。 + バックエンドにはMD5認証を設定しなければならないことに注意してください。 + ユーティリティを使って正しいMD5ハッシュパワード文字列を作ることができます。 + + + + + + 平文パスワード + + + 暗号化されていない平文のパスワードです。 + 可能ならば使用を避けるべきです。 + パスワード文字列はTEXTで始まっていなければなりません。 + 例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定します。 + 有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 + + + + + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + - health_check_database (string) - - - health_check_database 設定パラメータ - - - - - -ヘルスチェックを行う対象のPostgreSQLデータベース名を指定します。 -デフォルトは''で、この場合は最初にpostgresデータベースが試され、その後でtemplate1データベースが試されます。 -これはPgpool-II V3.4以前の挙動と同じです。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - + health_check_database (string) + + + health_check_database 設定パラメータ + + + + + + ヘルスチェックを行う対象のPostgreSQLデータベース名を指定します。 + デフォルトは''で、この場合は最初にpostgresデータベースが試され、その後でtemplate1データベースが試されます。 + これはPgpool-II V3.4以前の挙動と同じです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + - health_check_max_retries (integer) - - - health_check_max_retries 設定パラメータ - - - + health_check_max_retries (integer) + + + health_check_max_retries 設定パラメータ + + + + + + ヘルスチェックに失敗したときに、諦めてフェイルオーバを始める前にリトライする最大回数を指定します。 + - -ヘルスチェックに失敗したときに、諦めてフェイルオーバを始める前にリトライする最大回数を指定します。 - - - -この設定は動作にむらのあるネットワーク環境において、マスターノードが正常であるにも関わらず、たまにヘルスチェックが失敗することが予想される場合に有用です。 - - - - - -health_check_max_retreisを有効にする場合は、を無効にするのが望ましいです。 - - - -デフォルト値は0で、この場合はリトライをしません。 + + この設定は動作にむらのあるネットワーク環境において、ノードが正常であるにも関わらず、たまにヘルスチェックが失敗することが予想される場合に有用です。 + + - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + health_check_max_retriesを有効にする場合は、を無効にするのが望ましいです。 - + + + デフォルト値は0で、この場合はリトライをしません。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + - health_check_retry_delay (integer) - - - health_check_retry_delay 設定パラメータ - - - - - -ヘルスチェックのリトライ間の時間間隔を秒単位で指定します( > 0でなければ有効になりません)。 -0を指定すると、待ち時間はなくリトライは直ちに行われます。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - + health_check_retry_delay (integer) + + + health_check_retry_delay 設定パラメータ + + + + + + ヘルスチェックのリトライ間の時間間隔を秒単位で指定します( > 0でなければ有効になりません)。 + 0を指定すると、待ち時間はなくリトライは直ちに行われます。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + - - connect_timeout (integer) - - - connect_timeout 設定パラメータ - - - - - -connect()システムコールを使ったバックエンドへの接続を諦めるまでの時間をミリ秒単位で指定します。 -デフォルトは10000ミリ秒(10秒)です。 -不安定なネットワークを使う場合、この値を大きくすると良いでしょう。 -0を指定すると、タイムアウトしません。 - - - -connect_timeoutの値はヘルスチェックだけではなく通常の接続プールを生成するときにも使われます。 - - - + + connect_timeout (integer) + + + connect_timeout 設定パラメータ + + + + + + connect()システムコールを使ったバックエンドへの接続を諦めるまでの時間をミリ秒単位で指定します。 + デフォルトは10000ミリ秒(10秒)です。 + 不安定なネットワークを使う場合、この値を大きくすると良いでしょう。 + 0を指定すると、タイムアウトしません。 + - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + connect_timeoutの値はヘルスチェックだけではなく通常の接続プールを生成するときにも使われます。 - - + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - + diff --git a/doc.ja/src/sgml/history.sgml b/doc.ja/src/sgml/history.sgml index 16b00bbe3..d767b48e2 100644 --- a/doc.ja/src/sgml/history.sgml +++ b/doc.ja/src/sgml/history.sgml @@ -1,64 +1,64 @@ - + --> <productname>Pgpool-II</productname>の歴史概要 - + --> 歴史 Pgpool-IIの - -Pgpool-IIは、その人生を、石井達夫の個人プロジェクトとしてスタートしました。 -そのプロジェクトでは、Pgpool-IIは、単なるコネクションプール用のソフトウェアでした。 -そこからPgpoolという名前が由来しました。 -最初のバージョンは2003年に公開されました。 + + Pgpool-IIは、その人生を、石井達夫の個人プロジェクトとしてスタートしました。 + そのプロジェクトでは、Pgpool-IIは、単なるコネクションプール用のソフトウェアでした。 + そこからPgpoolという名前が由来しました。 + 最初のバージョンは2003年に公開されました。 - -2004年にPgpool 1.0がネィティブレプリケーション機能(SQL文ベースのレプリケーション)を搭載してリリースされました。 -同じ年に負荷分散機能を搭載し、バージョン3のフロントエンド/バックエンドプロトコルをサポートした2.0がリリースされました。 -2005年には自動フェイルオーバ機能を搭載され、マスタースレーブモードがサポートされました。 + + 2004年にPgpool 1.0がネィティブレプリケーション機能(SQL文ベースのレプリケーション)を搭載してリリースされました。 + 同じ年に負荷分散機能を搭載し、バージョン3のフロントエンド/バックエンドプロトコルをサポートした2.0がリリースされました。 + 2005年には自動フェイルオーバ機能が搭載され、マスタースレーブモードがサポートされました。 - -2006年、PgpoolPgpool-IIとなりました。 -最初の1.0リリースでは、Pgpoolの多くの制限事項が撤廃されました。 -たとえば、PostgreSQLサーバ数は2まで、といった制限です。 -また、パラレルクエリやPCPコマンド(PCPは、"Pgpool Control Protocol"の略です)といった多くの機能が追加されました。 -PgpoolからPgpool-IIへの一番重要な変更は、おそらく個人プロジェクトから、Pgpool Developement Groupが所有するグループプロジェクトになったことでした。 + + 2006年、PgpoolPgpool-IIとなりました。 + 最初の1.0リリースでは、Pgpoolの多くの制限事項が撤廃されました。 + たとえば、PostgreSQLサーバ数は2まで、といった制限です。 + また、パラレルクエリやPCPコマンド(PCPは、"Pgpool Control Protocol"の略です)といった多くの機能が追加されました。 + PgpoolからPgpool-IIへの一番重要な変更は、おそらく個人プロジェクトから、Pgpool Development Groupが所有するグループプロジェクトになったことでした。 diff --git a/doc.ja/src/sgml/info.sgml b/doc.ja/src/sgml/info.sgml index 46d8fa860..a31e249b1 100644 --- a/doc.ja/src/sgml/info.sgml +++ b/doc.ja/src/sgml/info.sgml @@ -1,64 +1,64 @@ - + --> 更なる情報 - -この文書、すなわち本書のことですが、以外にもPgpool-IIに関する情報があります。 + --> + この文書、すなわち本書のことですが、以外にもPgpool-IIに関する情報があります。 - + --> Webサイト - -Pgpool-IIwebサイトは、Pgpool-IIのダウンロード、ドキュメント、FAQ、メーリングリストアーカイブなどに関する公式情報を提供する中心的な場所です。 + --> + Pgpool-IIwebサイトは、Pgpool-IIのダウンロード、ドキュメント、FAQ、メーリングリストアーカイブなどに関する公式情報を提供する中心的な場所です。 - + --> メーリングリスト - -メーリングリストは、質問に答えてもらったり、他のユーザと経験を共有したり、開発者に連絡するための良い場所です。 -詳細はpgpool-IIWebサイトを見てください。 + --> + メーリングリストは、質問に答えてもらったり、他のユーザと経験を共有したり、開発者に連絡するための良い場所です。 + 詳細はpgpool-IIWebサイトを見てください。 - + --> あなた自身! - -Pgpool-IIはオープンソースプロジェクトです。 -そういうものなので、ユーザコミュニティの継続的なサポートに依存しています。 -Pgpool-IIを使いはじめるにあたっては、ドキュメントを通じて、あるいはメーリングリストを通じて、他の人の助けに頼ることでしょう。 -ドキュメントにないことを学んだなら、それを書いて寄稿してください。 -もしコードに機能を追加したら、それを寄稿してください。 + --> + Pgpool-IIはオープンソースプロジェクトです。 + そういうものなので、ユーザコミュニティの継続的なサポートに依存しています。 + Pgpool-IIを使いはじめるにあたっては、ドキュメントを通じて、あるいはメーリングリストを通じて、他の人の助けに頼ることでしょう。 + ドキュメントにないことを学んだなら、それを書いて寄稿してください。 + もしコードに機能を追加したら、それを寄稿してください。 diff --git a/doc.ja/src/sgml/installation-rpm.sgml b/doc.ja/src/sgml/installation-rpm.sgml index 58a5d36d2..438a35c1e 100644 --- a/doc.ja/src/sgml/installation-rpm.sgml +++ b/doc.ja/src/sgml/installation-rpm.sgml @@ -1,200 +1,283 @@ - - - RPMからのインストール - - -この章では、RPMからPgpool-IIのインストールについて説明します。 -ソースコードからインストールする場合は、を参照してください。 - + + + RPMからのインストール + + + この章では、RPMからPgpool-IIをインストールする方法について説明します。 + ソースコードからインストールする場合は、を参照してください。 + + + + Pgpool-IIコミュニティはRHEL10/9/8および互換OS向けにRPMパッケージを提供しています。 + パッケージファイルはPgpool-IIの公式リポジトリから入手できます。 + + + + 以下のパッケージがあります。 + + + Pgpool-II RPM Packages + + + + パッケージ名 + 説明 + + + + + pgpool-II-pgXX + Pgpool-IIの動作上に必要なライブラリやバイナリが含まれる + + + pgpool-II-pgXX-extensions + オンラインリカバリ機能を使用する場合、このパッケージをすべてのPostgreSQLサーバにインストールする必要がある + + + pgpool-II-pgXX-debuginfo + デバッグ情報が含まれる + + + pgpool-II-pgXX-debugsource + RHEL10/9/8の場合のみ。デバッグ情報が含まれる + + + pgpool-II-pgXX-extensions-debuginfo + RHEL10/9/8の場合のみ。デバッグ情報が含まれる + + + pgpool-II-pgXX-devel + 開発者向けのヘッダーファイルが含まれる + + + +
- - - RPMのインストール - - -Pgpool-IIの公式RPMは、http://www.pgpool.net/yumから入手できます。 - + + + Pgpool-IIPostgreSQLのライブラリと拡張のディレクトリが必要です。 + そのディレクトリへのパスはPostgreSQLのバージョンごとに異なっているので、Pgpool-IIはPostgreSQLバージョンごとにパッケージを提供しています。 + 上記パッケージの「XX」はPostgreSQLのバージョンを表す2桁の数値です。PostgreSQLバージョンに対応するPgpool-IIのRPMを選んでください。(例えば、PostgreSQL 18を利用している場合は、pgpool-II-pg18を使用してください) + - - -RHELとその派生ディストリビューションでは、以下を一度行ってください。 - -yum install http://www.pgpool.net/yum/rpms/3.6/redhat/rhel-7-x86_64/pgpool-II-release-3.6-1.noarch.rpm - - -そして以下を実施してください。 - -yum install pgpool-II-pg96 - - - -pg96は、PostgreSQL 9.6を意味しています。 -Pgpool-IIPostgreSQLのライブラリと拡張のディレクトリが必要です。 -そのディレクトリへのパスはPostgreSQLのバージョンごとに異なっているので、PostgreSQLに対応するRPMを選んでください。 -またRPMは、PostgreSQLコミュニティRPMを使用することを前提としています。 - -yum install pgpool-II-pg96-debuginfo - - -これにより、コアファイルあるいはバックトレースにおいて、デバッグ用のシンボルを得ることができます。 -インストールすることを推奨します。 -開発向けのオプションパッケージがあります。 - -yum install pgpool-II-pg96-devel - - -これにより、開発者向けのヘッダーファイルがインストールされます。 - + + + 事前準備 + + + Pgpool-II関連のパッケージはPostgreSQLコミュニティのリポジトリにもあるため、 + PostgreSQLのリポジトリパッケージがすでにインストールされている場合は、PostgreSQLコミュニティのリポジトリからPgpool-IIをインストールしないように/etc/yum.repos.d/pgdg-redhat-all.repoにexclude設定を追加します。Pgpool-IIPostgreSQLをそれぞれ別のサーバにインストールする場合は、以下の設定は不要です。 + + +vi /etc/yum.repos.d/pgdg-redhat-all.repo + + + + 以下は、/etc/yum.repos.d/pgdg-redhat-all.repoの設定例です。 + + +[pgdg-common] +... +exclude=pgpool* - - -すべてのPostgreSQLサーバに、以下をインストールしてください。 - -yum install pgpool-II-pg96-extensions - - - +[pgdg18] +... +exclude=pgpool* + +[pgdg17] +... +exclude=pgpool* + +[pgdg16] +... +exclude=pgpool* - - - RPMの設定 +[pgdg15] +... +exclude=pgpool* + +[pgdg14] +... +exclude=pgpool* + +[pgdg13] +... +exclude=pgpool* + + + + + + RPMのインストール + + + ここではPgpool-IIの公式YUMレポジトリを使用してPgpool-IIをインストールします。 + + + + 以下の手順はRHEL10にPostgreSQL 18に対応したPgpool-II 4.6.xをインストールすることが前提となります。 + 他のバージョンのPostgreSQLを利用している場合は、PostgreSQLのバージョンに応じて「pgXX」を適宜置き換えてください。 + + + + まず、Pgpool-IIバージョンとディストリビューションに対応するレポジトリをインストールします。 + REHL9/8の場合は、こちらを参照してください。 + + +dnf install https://www.pgpool.net/yum/rpms/4.6/redhat/rhel-10-x86_64/pgpool-II-release-4.6-1.noarch.rpm + + + + 次に、Pgpool-IIをインストールします。 + + +dnf install pgpool-II-pg18 + + + + Pgpool-IIのオンラインリカバリ機能を利用するには、すべてのPostgreSQLサーバにpgpool-II-pgXX-extensionsをインストールします。また、pgpool-II-pgXX-extensionspgpool-II-pgXXパッケージに依存しているため、Pgpool-IIPostgreSQLをそれぞれ別のサーバにインストールしている場合は、pgpool-II-pgXXPostgreSQLが稼働しているサーバにインストールする必要があります。 + + - -すべてのPgpool-II設定ファイルは/etc/pgpool-IIにあります。 -設定方法についてはを参照ください。 + + pgpool-II-pgXX-extensionsPostgreSQLサーバ側にインストールするパッケージとなります。Pgpool-IIPostgreSQLをそれぞれ別のサーバにインストールしている場合は、pgpool-II-pgXX-extensionsPgpool-IIが稼働しているサーバにインストールする必要はありません。 - - - - - Pgpool-IIの起動と停止 - - - - -systemctl enable pgpool.service - + + +dnf install pgpool-II-pg18-extensions pgpool-II-pg18 + + + + 必要に応じて、開発者向けのオプションパッケージdebuginfoおよびdevelパッケージをインストールします。 + + +dnf install pgpool-II-pg18-debuginfo pgpool-II-pg18-devel + + - -この後システム全体を再起動するか、以下を実行してください。 + + + Pgpool-IIの設定 + + + すべてのPgpool-II設定ファイルは/etc/pgpool-IIにあります。 + 設定方法についてはを参照ください。 + + - -systemctl start pgpool.service - - - + Pgpool-IIの起動と停止 + + + RHEL10/9/8では、Pgpool-IIの自動起動を設定する場合、以下を実行してください。 + +systemctl enable pgpool.service + - To stop Pgpool-II: ---> -PostgreSQLサーバは、これよりも前に起動済みでなければならないことに注意してください。 + + この後Pgpool-IIを起動するには、システム全体を再起動するか、以下を実行してください。 + PostgreSQLサーバは、これよりも前に起動済みでなければならないことに注意してください。 + +systemctl start pgpool.service + - + + Pgpool-IIを停止するには、以下を実行してください。PostgreSQLを停止する場合、Pgpool-IIを先に停止する必要があります。 + systemctl stop pgpool.service - - - -この後、PostgreSQLサーバを停止しても構いません。 - - - -RHEL6/CentOS 6では、以下を一度行ってください。 - - -chkconfig pgpool on - - - -この後システム全体を再起動するか、以下を実行してください。 - -service start pgpool - - - -PostgreSQLサーバは、これよりも前に起動済みでなければならないことに注意してください。 - -Pgpool-IIを停止するには、次のようにしてください。 - - -service stop pgpool - - - -この後、PostgreSQLサーバを停止しても構いません。 - - - - -
+ + + + この後、PostgreSQLサーバを停止しても構いません。 +
+ +
diff --git a/doc.ja/src/sgml/installation-tips.sgml b/doc.ja/src/sgml/installation-tips.sgml index 6ff75d933..f11f3e533 100644 --- a/doc.ja/src/sgml/installation-tips.sgml +++ b/doc.ja/src/sgml/installation-tips.sgml @@ -1,72 +1,92 @@ - - インストールのヒント - - -この章では、Pgpool-IIをインストールする際の様々なヒントを集めました。 - + + インストールのヒント + + + この章では、Pgpool-IIをインストールする際の様々なヒントを集めました。 + - - - ファイアーウォール - - -Pgpool-IIが他のPgpool-IIサーバやPostgreSQLサーバに接続する際には、ファイアーウォールの管理ソフトによって目的のポートが開けられていなければなりません。 - + + + ファイアーウォール + + + Pgpool-IIが他のPgpool-IIサーバやPostgreSQLサーバに接続する際には、ファイアーウォールの管理ソフトによって目的のポートが開けられていなければなりません。 + - - -CentOS/RHEL7において、PostgreSQLにアクセスが必要な場合の例を示します。 - -firewall-cmd --permanent --zone=public --add-service=postgresql -firewall-cmd --reload - - -"postgresql"はPostgreSQLに割り当てられたサービス名です。 -サービス名の一覧は、以下のようにして得られます。 - - firewall-cmd --get-services - - -/usr/lib/firewalld/services/にあなた好みのサービス名を定義することもできることに注意してください。 - + + + 以下の例では、Pgpool-IIの受付ポート番号を9999、PCPの受付ポート番号を9898、watchdogの受付ポート番号を9000、heartbeatの受付ポート番号を9694とします。 + まず、Pgpool-IIの使用するポートを開放します。 + heartbeatのポートのみUDPで、それ以外はすべてTCPであることに注意してください。 - - -PostgreSQLが標準の5432ポートではなく、11002をリッスンしている場合は以下のように設定できます。 - - firewall-cmd --zone=public --remove-service=popstgresql --permanent - firewall-cmd --zone=public --add-port=11002/tcp --permanent - firewall-cmd --reload - - + + firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp --add-port=9000/tcp + firewall-cmd --permanent --zone=public --add-port=9694/udp + firewall-cmd --reload + + + + + Rocky Linux/RHEL10において、PostgreSQLにアクセスが必要な場合の例を示します。 + + firewall-cmd --permanent --zone=public --add-service=postgresql + firewall-cmd --reload + + + "postgresql"はPostgreSQLに割り当てられたサービス名です。 + サービス名の一覧は、以下のようにして得られます。 + + firewall-cmd --get-services + + + /usr/lib/firewalld/services/にあなた好みのサービス名を定義することもできることに注意してください。 + - + + + PostgreSQLが標準の5432ポートではなく、11002をリッスンしている場合は以下のように設定できます。 + + firewall-cmd --zone=public --remove-service=postgresql --permanent + firewall-cmd --zone=public --add-port=11002/tcp --permanent + firewall-cmd --reload + + + + diff --git a/doc.ja/src/sgml/installation.sgml b/doc.ja/src/sgml/installation.sgml index 4c04a0c80..68cd0e222 100644 --- a/doc.ja/src/sgml/installation.sgml +++ b/doc.ja/src/sgml/installation.sgml @@ -1,56 +1,149 @@ - + --> <productname>Pgpool-II</productname>のインストール - + --> インストール + + プランニング + + Pgpool-IIPostgreSQLを管理するツールなので、まずはPostgreSQLの利用形態を決めなければなりません。 + 加えて、Pgpool-IIではそれ自体の可用性を高めるために、複数のPgpool-IIを導入することができます。 + 何本のPgpool-IIを導入するのが適切なのかを事前に計画しなければなりません。 + この節では最初にPostgreSQLの動作モードを議論し、次にPgpool-IIの導入形態を議論します。 + + + + PostgreSQLのクラスタリングモード + + PostgreSQLの導入台数は1以上が可能ですが、1台ではそのPostgreSQLがダウンした時にデータベースシステム全体が使えなくなるため、通常2台以上のPostgreSQLを導入します。 + 2台以上のPostgreSQLを用いる場合、何らかの方法でそれらのデータベース内容を同じになるようにしなければなりません。 + データベースの同期方法の違いをここでは「クラスタリングモード」と呼びます。 + もっとも広く使われているクラスタリングモードは、「ストリーミングレプリケーションモード」です。 + 特に何か特別な考慮が必要でなければ、ストリーミングレプリケーションモードを選択することをお勧めします。 + 動作モードの詳細についてはをご覧ください。 + + + 次に考えなければならないのは、何台のPostgreSQLを使うかです。 + 2台あれば最低限片方のPostgreSQLがダウンしてもデータベースの運用は継続できますが、検索処理を複数のサーバで分担させる検索負荷分散処理を行うのであれば、3台以上のPostgreSQLを使うことも珍しくありません。 + Pgpool-IIは豊富な負荷分散の調整パラメータを用意しています。 + 詳細はをご覧ください。 + + + Pgpool-IIでは柔軟にPostgreSQLサーバを後から追加できるので、とりあえずPgpool-IIを使ってみたい、という方は2台のPostgreSQLから始めるのが良いでしょう。 + + + + + Pgpool-IIの導入形態 + + Pgpool-IIは1台でも利用が可能ですが、そのPgpool-IIが停止するとデータベース全体が利用できなくなるので、複数のPgpool-IIを導入することをお勧めします。 + 複数のPgpool-IIはwatchdogと言う仕組みで連携を取りつつお互いを監視し、その中の1台が「リーダー」と呼ばれて仮想IPを持つので、クライアントはその仮想IPにアクセスすればよく、複数のPgpool-IIが導入されていることを意識する必要はありません。 + (watchdogについてはをご覧ください。) + もしあるPgpool-IIがダウンすると、別のPgpool-IIが取って代わってリーダーになります。 + + + リーダーは複数存在してはいけないので、新しいリーダーを決める際にはwatchdogは投票を行ないます。 + この時Pgpool-IIが偶数台だと多数決でリーダーを決めることができなくなってしまいます。 + ですからPgpool-IIは3台以上の奇数台で構成することをお勧めします。 + + + なお、Pgpool-IIPostgreSQLは同じサーバに同居していても構いません。 + たとえば、リソースを節約するために3台のサーバのみを用意し、それぞれにPgpool-IIPostgreSQLを動かすこともできます。 + + + Pgpool-II3台、PostgreSQL2台をストリーミングレプリケーションモードで動作させる本格的な例が + で詳しく紹介されているので、すぐにプロダクションレベルでPgpool-IIを動かしたい方はそれを参考にすると良いでしょう。 + + + + - + --> Pgpool-IIのインストール - - -この章はPgpool-IIのインストールについて書かれています。 -最初に、ソースコード配布物からのインストールについて説明します。 -その後、RPMパッケージからのインストールについて説明します。 - + + + この章はPgpool-IIのインストールについて書かれています。 + 最初に、ソースコード配布物からのインストールについて説明します。 + その後、RPMパッケージからのインストールについて説明します。 + - + --> 必要条件 + + 動作環境 + + Pgpool-IIはほとんどのUNIX互換環境で動作すると思われます。 + Windows はサポートされてません。 + 開発コミュニティが動作検証しているのは以下のものです。 + これ以外は開発コミュニティは動作検証を行っていません。 + + + + Rocky Linux 10 (x86_64) + + + + + Rocky Linux 9 (x86_64) + + + + + Rocky Linux 8 (x86_64) + + + + これらと互換性のあるLinuxディストリビューションでも動作するはずです。 + - -通常、最近のUnix互換プラットフォームならばPgpool-IIを動作させることができるはずです。 -Windows はサポートされてません。 + Debian/Ubuntuに関してはパッケージが提供されています。 + + ユーザから動作報告があったのは以下のものです。 + + + + Ubuntu 20.04 (x86_64) + + + + + OpenBSD + + + + + + + ソフトウェア要件 - -Pgpool-IIを構築するには以下のソフトウェアパッケージが必要です。 + --> + Pgpool-IIを構築するには以下のソフトウェアパッケージが必要です。 @@ -58,44 +151,56 @@ Windows はサポートされてません。 make - -GNU makeのバージョン3.80以上が必要です。 -他のmakeや古いGNU makeでは動作しません。 -(GNU makeはときどきgmakeという名前でインストールされます。) -GNU makeの試験を行うためには以下を実行してください。 - -make --version - + --> + GNU makeのバージョン3.80以上が必要です。 + 他のmakeや古いGNU makeでは動作しません。 + (GNU makeはときどきgmakeという名前でインストールされます。) + GNU makeの試験を行うためには以下を実行してください。 + + make --version + - -ISO/ANSI Cコンパイラ(最低限C89-準拠)が必要です。 -GCC の最近のバージョンをお勧めしますが、Pgpool-IIは異なるベンダの、様々なコンパイラを使用して構築できることで知られています。 + --> + ISO/ANSI Cコンパイラ(最低限C89-準拠)が必要です。 + GCC の最近のバージョンをお勧めしますが、Pgpool-IIは異なるベンダの、様々なコンパイラを使用して構築できることで知られています。 - -配布物を展開するために、tarおよびgzipが必要です。 + --> + 配布物を展開するために、tarおよびgzipが必要です。 + + + + + + + Pgpool-IIをインストールするためにはPostgreSQLのいくつかのパッケージが必要となります。 + PostgreSQLをソースコードからインストールする、もしくはpostgresql-libs,postgresql-develのパッケージをインストールしてください。 @@ -103,12 +208,12 @@ Windows はサポートされてません。 - -リリースされたソースパッケージではなくGitツリーからの構築の場合、またはサーバ開発を行いたい場合には、以下のパッケージも必要となります。 + --> + リリースされたソースパッケージではなくGitツリーからの構築の場合、またはサーバ開発を行いたい場合には、以下のパッケージも必要となります。 @@ -128,17 +233,17 @@ Windows はサポートされてません。 yacc - -FlexおよびBisonは、Gitチェックアウトから構築する場合や、実際のスキャナとパーサの定義ファイルを変更した場合に必要となります。 -それらが必要な場合は、Flex 2.5.31以降とBison 1.875以降を使うようにしてください。 -他のlexとyaccプログラムは使用できません。 + --> + FlexおよびBisonは、Gitチェックアウトから構築する場合や、実際のスキャナとパーサの定義ファイルを変更した場合に必要となります。 + それらが必要な場合は、Flex 2.5.31以降とBison 1.875以降を使うようにしてください。 + 他のlexとyaccプログラムは使用できません。 @@ -146,562 +251,546 @@ Windows はサポートされてません。 - -GNUパッケージの入手が必要な場合、近くのGNUミラーサイトから探してください(ミラーサイトの一覧はにあります)。 -または、から探してください。 + --> + GNUパッケージの入手が必要な場合、近くのGNUミラーサイトから探してください(ミラーサイトの一覧はにあります)。 + または、から探してください。 - -また、十分なディスク領域があることも確認してください。 -コンパイル中、ソースツリーのために40メガバイト、インストールディレクトリに20メガバイトほど必要となります。 -リグレッションテストを実行する場合は、一時的に最大で4ギガバイトの領域がさらに必要になります。 -ディスクの空き容量を確認するためにはdfコマンドを使います。 + --> + また、十分なディスク領域があることも確認してください。 + コンパイル中、ソースツリーのために40メガバイト、インストールディレクトリに20メガバイトほど必要となります。 + リグレッションテストを実行する場合は、一時的に最大で4ギガバイトの領域がさらに必要になります。 + ディスクの空き容量を確認するためにはdfコマンドを使います。 + - + --> ソースの入手 - -Pgpool-IIのソースは、Webサイトのダウンロードページから入手することができます。 -pgpool-II-&version;.tar.gzという名前のファイルを入手してください。 -ファイルを入手したら、展開します。 - + --> + Pgpool-IIのソースは、Webサイトのダウンロードページから入手することができます。 + pgpool-II-&version;.tar.gzという名前のファイルを入手してください。 + ファイルを入手したら、展開します。 + tar xf pgpool-II-&version;.tar.gz - - -これにより、カレントディレクトリ以下にpgpool-II-&version;というディレクトリが作成され、Pgpool-IIのソースが展開されます。 -この後のインストール手順を行うために、このディレクトリに移動してください。 + --> + これにより、カレントディレクトリ以下にpgpool-II-&version;というディレクトリが作成され、Pgpool-IIのソースが展開されます。 + この後のインストール手順を行うために、このディレクトリに移動してください。 - - - Pgpool-IIのインストール - - -ソースのtarballを展開したら、configureスクリプトを実行します。 - + + + Pgpool-IIのインストール + + + ソースのtarballを展開したら、以下の手順にしたがって、ソースコードをビルドして、Pgpool-IIをインストールします。 + + + + Pgpool-II 4.5から、autoconf/autoreconfによって生成されるconfigureなどのファイルはリポジトリから削除されたので、まずautoreconf -fiを実行し、configureを生成します。 + +dnf install libtool + +cd pgpool-II-&version; +autoreconf -fi + + + + + + 次に、configureスクリプトを実行します。 + ./configure - - - - - -configureに以下のコマンドラインオプションを1つ以上指定することで、構築処理やインストール処理を変更することができます。 - - - - - - - - - + configureに以下のコマンドラインオプションを1つ以上指定することで、構築処理やインストール処理を変更することができます。 + + + + + + + + + -Pgpool-IIバイナリやドキュメントなどの関連ファイルがインストールされるトップディレクトリを指定します。 -デフォルトは/usr/localです。 - - - - - - - - - + Pgpool-IIバイナリやドキュメントなどの関連ファイルがインストールされるトップディレクトリを指定します。 + デフォルトは/usr/localです。 + + + + + + + + + -PostgreSQLのクライアントライブラリなどがインストールされているトップディレクトリを指定します。 -デフォルト値はpg_configコマンドで取得できるパスです。 - - - - - - - - - -Pgpool-IIバイナリがOpenSSLサポート付で構築されます。 -デフォルトではOpenSSLサポートは無効です。 - - - - - - - - - -Pgpool-II 3.0シリーズ (3.0.4まで) 互換の insert_lock を使用します。 -Pgpool-IIは、シーケンステーブルの行に対してロックを行います。 -2011年06月より後にリリースされたPostgreSQL 8.2以降ではこのロック方式は使用できません。 - - - - - - - - - -Pgpool-II 2.2と2.3シリーズ互換のinsert_lockを使用します。 -Pgpool-IIは、挿入対象のテーブルに対してロックを行ないます。 -このロック方式はVACUUMとロック競合するため非推奨です。 - - - - - - - - - -Pgpool-IIバイナリはインメモリクエリキャッシュのキャッシュストレージにmemcachedを利用します。 -libMemcachedのインストールが必要です - - - - - - - - - -Pgpool-IIバイナリがPAM認証サポート付で構築されます。 -デフォルトでは、PAM認証サポートは無効です。 - - - - - - - - + --> + PostgreSQLのクライアントライブラリなどがインストールされているトップディレクトリを指定します。 + デフォルト値はpg_configコマンドで取得できるパスです。 + + + + + + + + + + Pgpool-IIバイナリがOpenSSLサポート付で構築されます。 + 必要なOpenSSLの最小バージョンは1.0.2です。 + AES256暗号化を使ってパスワードを暗号化する場合もこのオプションが必要です。 + 詳細はを参照してください。 + デフォルトではOpenSSLサポートは無効です。 + + + + + + + + + + Pgpool-II 3.0シリーズ (3.0.4まで) 互換の insert_lock を使用します。 + Pgpool-IIは、シーケンステーブルの行に対してロックを行います。 + 2011年06月より後にリリースされたPostgreSQL 8.2以降ではこのロック方式は使用できません。 + + + + + + + + + + Pgpool-II 2.2と2.3シリーズ互換のinsert_lockを使用します。 + Pgpool-IIは、挿入対象のテーブルに対してロックを行ないます。 + このロック方式はVACUUMとロック競合するため非推奨です。 + + + + + + + + + + Pgpool-IIバイナリはインメモリクエリキャッシュのキャッシュストレージにmemcachedを利用します。 + libMemcachedのインストールが必要です + + + + + + + + + + Pgpool-IIバイナリがPAM認証サポート付で構築されます。 + デフォルトでは、PAM認証サポートは無効です。 + + + + + + + + + Pgpool-IIバイナリがLDAP認証サポート付で構築されます。 + デフォルトでは、LDAP認証サポートは無効です。 + + + + + + + + ソースファイルのコンパイルを行います。 + make + + + + + Pgpool-IIをインストールします。 + make install - - -これによりPgpool-IIがインストールされます。 -(SolarisまたはFreeBSDを使用している場合はmakeをgmakeで置き換えて下さい。) - - - - - - - pgpool_recoveryのインストール - - -これは全てのPgpool-IIのインストールで必要です。 - -$ cd pgpool-II-x.x.x/src/sql/pgpool-recovery + + + これによりPgpool-IIがインストールされます。 + (SolarisまたはFreeBSDを使用している場合はmakeをgmakeで置き換えて下さい。) + + + + + + + pgpool_recoveryのインストール + + + 後述のオンラインリカバリの機能を使う場合には、 pgpool_recoverypgpool_remote_start、およびpgpool_switch_xlogという関数が必要です。 + また管理ツールである pgpoolAdmin の画面上から、バックエンドノードの PostgreSQL を停止・再起動・設定再読み込みを行なうことができますが、これには pgpool_pgctl という関数が使われます。 + + + + + これは全てのPgpool-IIのインストールで必要です。 + +$ cd pgpool-II-&version/src/sql/pgpool-recovery $ make $ make install - - -この後に以下か、 - -$ psql template1 + + + この後、以下のコマンドを実行して、で指定されたデータベースに(デフォルトは'postgres'です)pgpool_recoverypgpool_remote_startおよびpgpool_switch_xlog関数を作成します。 + にデフォルト以外の値が設定されている場合は、"postgres"をその設定値に置き換えてください。 + +$ psql postgres =# CREATE EXTENSION pgpool_recovery; - - - -または - -$ psql -f pgpool-recovery.sql template1 - -を実行します。 - - - - - -Pgpool-II 3.3 以降では、postgresql.confを変更する必要があります。 -pg_ctlへのパスが/usr/local/pgsql/bin/pg_ctlであるとします。 -その場合、postgresql.confに以下を追加してください。 - - + + + + または + +$ psql -f pgpool-recovery.sql postgres + + を実行します。 + + + + + + Pgpool-II 3.3 以降では、postgresql.confを変更する必要があります。 + pg_ctlへのパスが/usr/local/pgsql/bin/pg_ctlであるとします。 + その場合、postgresql.confに以下を追加してください。 + + pgpool.pg_ctl = '/usr/local/pgsql/bin/pg_ctl' - + - -もしかするとその後に以下を実行する必要があるかもしれません。 - + + もしかするとその後に以下を実行する必要があるかもしれません。 + $ pg_ctl reload -D /usr/local/pgsql/data - - - - - - - - pgpool-regclassのインストール - - -PostgreSQL 9.4以降を使用している場合には、本節は飛ばすことができます。 - - - - -PostgreSQL 8.0からPostgreSQL 9.3までを使用している場合は、Pgpool-II がアクセスする全てのPostgreSQLにおいてpgpool_regclass 関数をインストールすることを強く推奨します。 -Pgpool-IIから内部的に使用されるからです。 -これがないと、異なるスキーマの間で重複するテーブル名を扱う際の不具合の原因となります。 -(一時テーブルの場合は問題となりません。) -PostgreSQL 9.4以降を使用している場合は、同等の関数(to_regclass)がPostgreSQLに含まれているため、pgpool_regclassのインストールは必要ありません。 - - - - -$ cd pgpool-II-x.x.x/src/sql/pgpool-regclass + + + + + + + + pgpool-regclassのインストール + + + PostgreSQL 9.4以降を使用している場合には、本節は飛ばすことができます。 + + + + + PostgreSQL 8.0からPostgreSQL 9.3までを使用している場合は、Pgpool-II がアクセスする全てのPostgreSQLにおいてpgpool_regclass 関数をインストールすることを強く推奨します。 + Pgpool-IIから内部的に使用されるからです。 + これがないと、異なるスキーマの間で重複するテーブル名を扱う際の不具合の原因となります。 + (一時テーブルの場合は問題となりません。) + PostgreSQL 9.4以降を使用している場合は、同等の関数(to_regclass)がPostgreSQLに含まれているため、pgpool_regclassのインストールは必要ありません。 + + + + +$ cd pgpool-II-&version/src/sql/pgpool-regclass $ make $ make install - - -この後に以下か、 + + + この後に以下か、 - + $ psql template1 =# CREATE EXTENSION pgpool_regclass; - + - -または + + または - + $ psql -f pgpool-regclass.sql template1 - - -を実行します。 - - -CREATE EXTENSIONまたはpgpool-regclass.sqlの実行は、Pgpool-II経由でアクセスされる全てのデータベースで実行しなければなりません。 -ただし、CREATE EXTENSINONまたは"psql -f pgpool-regclass.sql template1"の実行後に作成されたデータベースでは、新しいデータベース作成のためにテンプレートデータベースが複製されるため、これを実行する必要はありません。 - - - - - - - insert_lockテーブルの作成 - - - -ネイティブレプリケーションモードを使う予定のない場合は、本節は飛ばすことができます。 - - - - -ネイティブレプリケーションモードでinsert_lockを利用したい場合は、排他制御用のテーブルpgpool_catalog.insert_lockを作成することを強く推奨します。 -これがなくてもある程度はinsert_lock は動作します。 -しかしその場合は、Pgpool-IIは挿入対象のテーブルに対してロックを行います。 -これはPgpool-II 2.2と2.3 シリーズの動作と同じです。 -このテーブルに対するロックは、VACUUMと競合するため、INSERT処理が長時間待たされ続ける可能性があります。 - - - $ cd pgpool-II-x.x.x/src/sql - $ psql -f insert_lock.sql template1 - - - - - - -insert_lock.sqlは、pgpool-II経由で利用するデータベース毎に必要になります。 -ただし、"psql -f insert_lock.sql template1"の実行後に作成されたデータベースでは、新しいデータベース作成のためにテンプレートデータベースが複製されるため、これを実行する必要はありません。 - - - - - - pgpool.confの設定 - - - -各Pgpool-IIの動作モードについて設定のサンプルがあります。 - - - - - - pgpool.confのサンプル - - - - - - 動作モード - 設定ファイル名 - - - - - - - ストリーミングレプリケーションモード - pgpool.conf.sample-stream - - - - ネイティブレプリケーションモード - pgpool.conf.sample-replication - - - - マスタースレーブモード - pgpool.conf.sample-master-slave - - - - Rawモード - pgpool.conf.sample - - - - ロジカルレプリケーションモード - pgpool.conf.sample-logical - - - -
- - - -これらの設定ファイルはデフォルトのソースコードからのインストールでは/usr/local/etcに配置されています。 -これらをpgpool.confとしてコピーして使うことが可能です。 -(もしかするとそのためにはroot権限が必要かもしれません。) - -# cd /usr/local/etc -# cp pgpool.conf.sample-stream pgpool.conf - - -
- - - - ドキュメントのコンパイルとインストール - - - - ツールセット - - - -Pgpool-IIのドキュメントはSGML(より正確には、SGMLを使って実装された言語であるDocBook)で書かれています。 -ユーザが読めるHTMLドキュメントを生成するには、docbookツールを使ってコンパイルする必要があります。 -RHEL類似のシステムでツールをインストールするには、以下を実行します。 - - yum install docbook-dtds docbook-style-dsssl docbook-style-xsl libxslt openjade - - - - - - - ドキュメントのコンパイル - - -ツールセットがインストールされたら、以下のようにコンパイルします。 - - $ cd doc - $ make - $ cd .. - $ cd doc.ja - $ make - - -HTMLドキュメントはdoc/src/sgml/htmlに、オンラインマニュアルはsgml/man[1-8]にあります。 -日本語のドキュメントはdoc.ja/src/sgml/htmlに、オンラインマニュアルはsgml/man[1-8]にあります。 - - - - -&installation-rpm; - -&installation-tips; + + + を実行します。 + + + CREATE EXTENSIONまたはpgpool-regclass.sqlの実行は、Pgpool-II経由でアクセスされる全てのデータベースで実行しなければなりません。 + ただし、CREATE EXTENSIONまたは"psql -f pgpool-regclass.sql template1"の実行後に作成されたデータベースでは、新しいデータベース作成のためにテンプレートデータベースが複製されるため、これを実行する必要はありません。 + + +
+ + + + insert_lockテーブルの作成 + + + + またはを使う予定のない場合は、本節は飛ばすことができます。 + + + + + またはでinsert_lockを利用したい場合は、排他制御用のテーブルpgpool_catalog.insert_lockを作成することを強く推奨します。 + これがなくてもある程度はinsert_lock は動作します。 + しかしその場合は、Pgpool-IIは挿入対象のテーブルに対してロックを行います。 + これはPgpool-II 2.2と2.3 シリーズの動作と同じです。 + このテーブルに対するロックは、VACUUMと競合するため、INSERT処理が長時間待たされ続ける可能性があります。 + + +$ cd pgpool-II-&version/src/sql +$ psql -f insert_lock.sql template1 + + + + + + + insert_lock.sqlは、pgpool-II経由で利用するデータベース毎に必要になります。 + ただし、"psql -f insert_lock.sql template1"の実行後に作成されたデータベースでは、新しいデータベース作成のためにテンプレートデータベースが複製されるため、これを実行する必要はありません。 + + + + + + ドキュメントのコンパイルとインストール + + + + ツールセット + + + + Pgpool-IIのドキュメントはSGML(より正確には、SGMLを使って実装された言語であるDocBook)で書かれています。 + ユーザが読めるHTMLドキュメントを生成するには、docbookツールを使ってコンパイルする必要があります。 + RHEL類似のシステムでツールをインストールするには、以下を実行します。 + +dnf install --enablerepo=powertools docbook-dtds docbook-style-dsssl docbook-style-xsl libxslt openjade + + + + + + + ドキュメントのコンパイル + + + ツールセットがインストールされたら、以下のようにコンパイルします。 + +$ cd doc +$ make +$ cd .. +$ cd doc.ja +$ make + + + HTMLドキュメントはdoc/src/sgml/htmlに、オンラインマニュアルはsgml/man[1-8]にあります。 + 日本語のドキュメントはdoc.ja/src/sgml/htmlに、オンラインマニュアルはsgml/man[1-8]にあります。 + + + + + &installation-rpm; + + &installation-tips;
diff --git a/doc.ja/src/sgml/intro.sgml b/doc.ja/src/sgml/intro.sgml index ac72eeb71..1f70bd754 100644 --- a/doc.ja/src/sgml/intro.sgml +++ b/doc.ja/src/sgml/intro.sgml @@ -1,13 +1,13 @@ - + --> はじめに - -本書は、Pgpool-IIのオフィシャルドキュメントです。 -Pgpool-IIソフトウェアの開発と並行して、Pgpool-IIの開発者とそれ以外のボランティアによって作成されてきました。 -現在のバージョンのPgpool-IIが正式にサポートするすべての機能について説明しています。 + --> + 本書は、Pgpool-IIのオフィシャルドキュメントです。 + Pgpool-IIソフトウェアの開発と並行して、Pgpool-IIの開発者とそれ以外のボランティアによって作成されてきました。 + 現在のバージョンのPgpool-IIが正式にサポートするすべての機能について説明しています。 - -Pgpool-IIに関する膨大な情報を管理しやすくするために、本書はいくつかの部分に分かれています。 -それぞれの部分のユーザの層の違い、あるいはPgpool-IIの経験の違いに合せて構成されてます。 + --> + Pgpool-IIに関する膨大な情報を管理しやすくするために、本書はいくつかの部分に分かれています。 + それぞれの部分のユーザの層の違い、あるいはPgpool-IIの経験の違いに合せて構成されてます。 - -は入門者のための導入情報です。 + --> + は入門者のための導入情報です。 - -では、サーバのインストールと管理について記述しています。 -個人目的であれ、他の人のために動かすのであれ、Pgpool-IIサーバを動かす人はこの章を読んでください。 + --> + では、サーバのインストールと管理について記述しています。 + 個人目的であれ、他の人のために動かすのであれ、Pgpool-IIサーバを動かす人はこの章を読んでください。 - -では、実際のシステムで使う際のスタートポイントとしてユーザが選択できるように。何種類かの構成例を説明しています。 + --> + では、ユーザが実際のシステムで使う際の起点として選択できるように何種類かの構成例を説明しています。 - -には、SQLコマンド、クライアント、サーバプログラムが含まれます。 -コマンドあるいはプログラムでソートされた構造的な情報となっており、本書の他の部分をサポートするように考慮されています。 + --> + には、SQLコマンド、クライアント、サーバプログラムが含まれます。 + コマンドあるいはプログラムでソートされた構造的な情報となっており、本書の他の部分をサポートするように考慮されています。 - -はリリースノートのような追加情報です。 + --> + はリリースノートのような追加情報です。 - + + contains assorted information that might be of + use to PostgreSQL developers. + + + --> - + --> <productname>Pgpool-II</productname>とは? - -Pgpool-IIは、PostgreSQLサーバとPostgreSQLデータベースクライアントの間に位置するプロキシソフトウェアです。 -以下のような機能を提供します。 + + Pgpool-IIPostgreSQLpoolを管理することによって、単一のPostgreSQL構成では得られない以下のような機能を提供します。 - + - + - コネクションプーリング - + 高可用性 + -Pgpool-IIは、PostgreSQLサーバへの確立された接続を維持し、プロパティ(つまりユーザ名、データベース、プロトコルバージョン)が同じ新規のコネクションが到着する度に再利用します。 -コネクションオーバヘッドを軽減することによって、システム全体のスループットを改善します。 + Pgpool-IIは複数のPostgreSQLサーバを使い、故障したサーバを自動的に取り除くことによってデータベースの仕事を継続して高可用性 (HA)機能を提供します。 + これは自動フェイルオーバと呼ばれます。 + また、Pgpool-IIPgpool-II自身のHA機能を提供しており、これをWatchdogと呼びます (詳細はをご覧ください。) + 更にPgpool-IIは洗練されたクォーラム(quorum)アルゴリズムを採用しており、偽陽性エラーとスプリットブレイン問題を回避することが可能で、HAシステム全体が非常に信頼性の高いものになっています。 + 詳細はをご覧ください。 - - + + - + - 負荷分散 - + 負荷分散 + -(レプリケーションモードあるいはマスタースレーブモードで動作しているので)データベースがレプリケーションされている場合は、どのサーバにSELECTを発行しても同じ結果が得られます。 -Pgpool-IIは、個々のPostgreSQLサーバの負荷を軽減するために、レプリケーションを利用します。 -SELECTクエリをサーバに分散させ、システム全体のスループットを改善します。 -理想的には、PostgreSQLサーバの数に比例して検索性能が向上します。 -多数のユーザが検索のみのクエリを同時に発行するようなシナリオで、負荷分散は最大の効果を発揮します。 + Pgpool-IIは読み込みクエリを複数のPostgreSQLサーバに分散させて性能向上させることがで +きます。 + これは負荷分散と呼ばれます。書き込みクエリはプライマリサーバ(ストリーミングレプリケーションモード時)かすべてのサーバ(ネィティブレプリケーションモードあるいはスナップショットアイソレーションモード)に送られます。 + これらのモードの詳細はをご覧ください。 + どの場合でも、Pgpool-IIは自動的に読み込みクエリと書き込みクエリの違いを判断します。 - - - - - 自動フェイルオーバ - - + + + + + -データベースサーバのどれかがダウンしたり、到達できなくなったときは、Pgpool-IIはそのサーバを切り離し、残ったサーバで運用を継続します。 -自動フェイルオーバの助けになるような、タイムアウト、リトライといった洗練された機能もあります。 + これらの基本的な機能以外に、Pgpool-IIは以下の機能を提供します。 + + + + + + + + コネクションプーリング + + + + Pgpool-IIは、PostgreSQLサーバへの確立された接続を維持し、プロパティ(つまりユーザ名、データベース、プロトコルバージョン、他に指定されていれば接続パラメータも)が同じ新規のコネクションが到着する度に再利用します。 + コネクションオーバヘッドを軽減することによって、システム全体のスループットを改善します。 - - + + - - レプリケーション - + + + オンラインリカバリ + - -Pgpool-IIは複数のPostgreSQLサーバを管理することができます。 -レプリケーション機能を有効にすることにより、2つあるいはそれ以上のPostgreSQLクラスタのリアルタイムバックアップを作成できます。 -これによって、クラスタの一つがダウンしても、中断なしにサービスを継続できます。 -Pgpool-IIには、組み込みレプリケーション(ネィティブレプリケーション)機能があります。 -しかし、PostgreSQLのストリーミングレプリケーションのような、外部のレプリケーション機能を使うこともできます。 + + Pgpool-IIはコマンド一つでデータベースノードのオンラインリカバリができます。 + 自動フェイルオーバと組み合わせることで、フェイルオーバにより切り離されたノードをスタンバイとして自動で復帰させることも可能です。 + 新しいPostgreSQLサーバを同期しノードとして追加することもできます。 - - + + - - 限度を超えた接続の制限 - + + 限度を超えた接続の制限 + - -PostgreSQLへの最大同時接続数には制限があり、その制限に達すると新しいコネクションは拒否されます。 -最大接続数を大きくすると、リソースの消費が増え、システム全体の性能に悪影響があります。 -Pgpool-IIにも最大接続数の制限があります。 -しかし、制限を超えた接続要求はすぐにエラーが返るのではなく、待ち行列に入ります。 - - - + + PostgreSQLへの最大同時接続数には制限があり、その制限に達すると新しいコネクションは拒否されます。 + 最大接続数を大きくすると、リソースの消費が増え、システム全体の性能に悪影響があります。 + Pgpool-IIにも最大接続数の制限があります。 + しかし、制限を超えた接続要求はすぐにエラーが返るのではなく、待ち行列に入ります。 + ただし、制限を超えた接続要求に対してエラーを返すように設定することも可能です(4.1 以降)。 + + + + + + Watchdog + + + Watchdogは、複数のPgpool-IIを協調させて動作させることにより、単一障害点やスプリットブレインの起きない堅牢なクラスタを運用することが可能です。 + スプリットブレインを防ぐためには、少なくとも3台のPgpool-IIノードが必要です。 + 他のPgpool-IIの死活監視を行い、障害を検出することができます。 + 稼働系のPgpool-IIがダウンしても、待機系のPgpool-IIが稼動系に昇格し、仮想IPを引き継ぐことができます。 + + + + + + インメモリキャッシュ + + + + SELECT文とその検索結果をキャッシュに保存できます。同じSELECT文が発行された場合、Pgpool-IIはキャッシュから結果を返します。 + SQLの解析もPostgreSQLへのアクセスも行われないため、インメモリキャッシュの利用は非常に高速です。 + 反面、キャッシュを保存するオーバヘッドが生じるので、通常の方法より遅くなる場合もあります。 + + + - + - -Pgpool-IIは、PostgreSQLのバックエンドフロントエンドプロトコルを理解し、バックエンドとフロントエンドの間でメッセージを転送します。 -つまり、データベースアプリケーション(フロントエンド)にはPgpool-IIが実際のPostgreSQLサーバであるように見えます。 -サーバ(バックエンド)には、Pgpool-IIがフロントエンドであるように見えます。 -Pgpool-IIは、サーバとクライアントに対して透過なので、既存のデータベースアプリケーションは、ソースコードに変更を加えることなくPgpool-IIを利用できます。 + + Pgpool-IIは、PostgreSQLのバックエンドフロントエンドプロトコルを理解し、バックエンドとフロントエンドの間でメッセージを転送します。 + つまり、データベースアプリケーション(フロントエンド)にはPgpool-IIが実際のPostgreSQLサーバであるように見えます。 + サーバ(バックエンド)には、Pgpool-IIがフロントエンドであるように見えます。 + Pgpool-IIは、サーバとクライアントに対して透過なので、既存のデータベースアプリケーションは、ソースコードに変更を加えることなくPgpool-IIを利用できます。 - -Pgpool-II は、Linuxをはじめ、SolarisやFreeBSDなどのほとんどのUNIX環境で動作します。 -Windows では動きません。 -対応するPostgreSQLのバージョンは、6.4 以降です。 -また、PostgreSQL 7.4 より前のバージョンでは、使用できる機能に制限事項があります。 -もっとも、そのような古いバージョンのPostgreSQL はそもそも使うべきではありません。 -Pgpool-II配下で利用するPostgreSQLサーバのメジャーバージョン、 -OS やハードウェアアーキテクチャを同じものにしなければなりません。 -また、バージョンが同じであっても、PostgreSQL のビルド方法が違うものを混ぜている場合の動作は保証できません。 -たとえば、SSL サポートの有無、日付型の実装方法 (--disable-integer-datetimes)、ブロックサイズの違いなどは、Pgpool-IIの一部の機能に影響を与えるでしょう。 -PostgreSQL のマイナーバージョンが違う場合は大抵の場合問題になりませんが、 -すべてのPostgreSQLのマイナーバージョンを検証したわけではないので、 -できればマイナーバージョンを合わせておくことをお勧めします。 + + Pgpool-II は、Linuxをはじめ、SolarisやFreeBSDなどのほとんどのUNIX環境で動作します。 + Windows では動きません。 + 対応するPostgreSQLのバージョンは、7.4 以降です。 + Pgpool-II配下で利用するPostgreSQLサーバのメジャーバージョン、 + OS やハードウェアアーキテクチャを同じものにしなければなりません。 + また、バージョンが同じであっても、PostgreSQL のビルド方法が違うものを混ぜている場合の動作は保証できません。 + たとえば、SSL サポートの有無、日付型の実装方法 (--disable-integer-datetimes)、ブロックサイズの違いなどは、Pgpool-IIの一部の機能に影響を与えるでしょう。 + PostgreSQL のマイナーバージョンが違う場合は大抵の場合問題になりませんが、 + すべてのPostgreSQLのマイナーバージョンを検証したわけではないので、 + できればマイナーバージョンを合わせておくことをお勧めします。 - -Pgpool-IIでSQLを使うにあたっては、制限事項があります。 -詳細は制限事項をご覧ください。 + + Pgpool-IIでSQLを使うにあたっては、制限事項があります。 + 詳細は制限事項をご覧ください。 diff --git a/doc.ja/src/sgml/legal.sgml b/doc.ja/src/sgml/legal.sgml index bab7400c5..4e5f8cb65 100644 --- a/doc.ja/src/sgml/legal.sgml +++ b/doc.ja/src/sgml/legal.sgml @@ -1,9 +1,9 @@ -2018 +2023 - 2003-2018 + 2003-2026 The Pgpool Global Development Group @@ -11,12 +11,12 @@ Legal Notice - Pgpool and Pgpool-II are Copyright © 2003-2018 + Pgpool and Pgpool-II are Copyright © 2003-2026 by the Pgpool Global Development Group. - PostgreSQL are Copyright © 1996-2018 + PostgreSQL are Copyright © 1996-2023 by the PostgreSQL Global Development Group. diff --git a/doc.ja/src/sgml/loadbalance.sgml b/doc.ja/src/sgml/loadbalance.sgml index 8f455ccc4..3a0703632 100644 --- a/doc.ja/src/sgml/loadbalance.sgml +++ b/doc.ja/src/sgml/loadbalance.sgml @@ -1,1355 +1,1933 @@ - - 負荷分散 - + + 負荷分散 + + + Pgpool-IIのSELECTクエリの負荷分散はrawモードを除くすべてのクラスタリングモードで動作します。 + 有効時、Pgpool-IIは更新を伴うクエリを、ストリーミングレプリケーションモード、ロジカルレプリケーションモードではプライマリノードに、レプリケーションモードでは全てのバックエンドノードに対し送信します。 + そして、その他のクエリは全てのバックエンドの間で負荷分散されます。 + が指定されている場合を除き、負荷分散メカニズムが参照クエリをどのノードに送信するかはセッション開始時に決められ、セッションの終了まで変更されません。 + ただし、いくつかの例外があります。 + 詳細については以下をご覧ください。 + + - -Pgpool-IIのSELECTクエリの負荷分散はマスタースレーブモード()とレプリケーションモード()で動作します。 -有効時、Pgpool-IIは更新を伴うクエリを、マスタースレーブモードではプライマリノードに、レプリケーションモードでは全てのバックエンドノードに対し送信します。 -そして、その他のクエリは全てのバックエンドの間で負荷分散されます。 -負荷分散メカニズムが参照クエリをどのノードに送信するかはセッション開始時に決められ、セッションの終了まで変更されません。 -ただし、いくつかの例外があります。 -詳細については以下をご覧ください。 + + 負荷分散ができないためにプライマリノードまたは全バックエンドノードに送られるクエリもまた、 負荷分散アルゴリズムの考慮に入れられます。 - - - -負荷分散ができないためにプライマリノードまたは全バックエンドノードに送られるクエリもまた、 -負荷分散アルゴリズムの考慮に入れられます。 - - - - - -もし負荷分散対象のクエリをPgpool-IIに負荷分散してほしくない場合には、SELECT文の前の/*NO LOAD BALANCE*/コメントを付与することができます。 -これにより、そのクエリの負荷分散は無効となり、Pgpool-IIはこれをマスターノード(マスタースレーブモードではプライマリノード)に送信します。 - - + - - - -どのDBノードが負荷分散ノードになっているかは、を利用して確認できます。 - - + + + + どのDBノードが負荷分散ノードになっているかは、を利用して確認できます。 + + - + --> 負荷分散の条件について - -クエリが負荷分散されるためには、以下の全ての条件を満たす必要があります: - + + クエリが負荷分散されるためには、以下の全ての条件を満たす必要があります: + - - -PostgreSQLのバージョンが7.4以降である - + --> + PostgreSQLのバージョンが7.4以降である + - - -レプリケーションモードまたはマスタースレーブモードである - + + + ロジカルレプリケーションモードのどれかである。 + - - -問い合わせが明示的なトランクザションブロックの内側にない(つまり、BEGINを発行していない) - - - - - -ただし、以下の条件が満たされればトランザクションブロックの内側であっても負荷分散の対象となります。 - - - - -トランザクション分離レベルがSERIALIZABLEでない - - - - - -トランザクション内で更新を伴うクエリが実行されていない -(更新を伴うクエリが実行されるまでは負荷分散されます。 -ここで「更新を伴うクエリ」とは、SELECT以外のDDLやDMLを指します。 -black/white function listで指定される更新関数を含むSELECTは更新を伴うクエリとは見なされません。 -この仕様は将来変更される可能性があります) - - - - - -もしblack/white function listが空の場合は、関数を持つSELECTは、更新を伴うクエリとは見なされません。 - - - - - - + --> + 問い合わせが明示的なトランクザションブロックの内側にない(つまり、BEGINを発行していない) + + + + + + ただし、以下の条件が満たされればトランザクションブロックの内側であっても負荷分散の対象となります。 + + + + + トランザクション分離レベルがSERIALIZABLEでない + + + + + + トランザクション内で更新を伴うクエリが実行されていない + (更新を伴うクエリが実行されるまでは負荷分散されます。 + ここで「更新を伴うクエリ」とは、SELECT以外のDDLやDMLを指します。 + Pgpool-II4.1以前のバージョンでは、write/read_only function list + で指定される更新関数を含むSELECTは更新を伴うクエリとは見なされません。) + + + + + もしwrite/read_only function listが空の場合は、揮発性ではない関数を持つSELECTは、更新を伴うクエリとは見なされません。 + + + + + + - - -SELECT INTO 文ではない - + --> + SELECT INTO 文ではない + - - -SELECT FOR UPDATE/SELECT FOR SHARE文ではない - + --> + SELECT FOR UPDATE/SELECT FOR SHARE文ではない + - - -SELECT または COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... から始まる。 -(またはで指定された書き込み関数を含むSELECTを除く) - = trueの場合は最初の空白文字は無視されます。 + --> + SELECT または COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... から始まる。 + (またはで指定された書き込み関数を含むSELECTを除く) + = trueの場合は最初の空白文字は無視されます。 - - -マスタースレーブモードの場合、更に以下の条件が満たされなければなりません。 - - - - - -一時テーブルを使っていない - - - - - -unloggedテーブルを使っていない - - - - - -システムカタログを使っていない - - - + + + の場合、更に以下の条件が満たされなければなりません。 + + + + + + 一時テーブルを使っていない (一時テーブルはレプリケーションされません) + + + + + + unloggedテーブルを使っていない (一時テーブルはレプリケーションされません) + + + + + + システムカタログを使っていない(システムカタログは重要なので、レプリケーション遅延を避けることが望まれます) + + + - + - - -SELECTクエリの前に任意のコメントを挿入することにより負荷分散を抑制することができます。 - - + --> + SELECTクエリの前に任意のコメントを挿入することにより負荷分散を抑制することができます。 + + /*REPLICATION*/ SELECT ... - - - -SQLコメントの記述が負荷分散に影響を与えないようにするには、をonにします。 -も参照してください。 - + --> + SQLコメントの記述が負荷分散に影響を与えないようにするには、をonにします。 + も参照してください。 + - - -JDBC ドライバにはautocommitオプションがあります。 -autocommit を無効にすると、ドライバが内部でBEGINおよびCOMMITコマンドを実行し、明示的なトランザクションが開始されます。 -この場合、トランザクション内における上記の負荷分散の制限事項が適用されます。 - + --> + JDBC ドライバにはautocommitオプションがあります。 + autocommit を無効にすると、ドライバが内部でBEGINおよびCOMMITコマンドを実行し、明示的なトランザクションが開始されます。 + この場合、トランザクション内における上記の負荷分散の制限事項が適用されます。 + - - 更新を伴うクエリは負荷分散に影響する可能性がある - - -一般的には、特定の条件を満している場合、参照クエリは負荷分散します。 -ただし、更新を伴うクエリは負荷分散に影響する可能性があります。 -ここで、”更新を伴うクエリ”とは以下の例を除く全てのクエリを指します。 - + + 更新を伴うクエリは負荷分散に影響する可能性がある + + + 一般的には、特定の条件を満たしている場合、参照クエリは負荷分散します。 + ただし、更新を伴うクエリは負荷分散に影響する可能性があります。 + ここで、”更新を伴うクエリ”とは以下の例を除く全てのクエリを指します。 + - + - - - -FOR UPDATE/SHARE がないSELECT/WITH - - + + + + FOR UPDATE/SHARE がないSELECT/WITH + + - - - COPY TO STDOUT - - + + + COPY TO STDOUT + + - - - EXPLAIN - - + + + EXPLAIN + + - - - -EXPLAIN ANALYZEおよびクエリが書き込み関数を含まないSELECT - - + + + + EXPLAIN ANALYZEおよびクエリが書き込み関数を含まないSELECT + + - - - SHOW - - + + + SHOW + + - + - - -更新を伴うクエリが存在する場合、続いて実行される参照クエリは負荷分散しません。 -すなわち、の設定に応じて(ストリーミングレプリケーションの)プライマリノードまたは(その他のモードの)マスターノードに送ります。 - + + + 更新を伴うクエリが存在する場合、続いて実行される参照クエリは負荷分散しません。 + すなわち、の設定に応じて(ストリーミングレプリケーションの)プライマリノードまたは(その他のモードの)メインノードに送ります。 + - + - - ストリーミングレプリケーションにおける負荷分散 + + ストリーミングレプリケーションにおける負荷分散 - - -ストリーミングレプリケーションとHot Standbyを利用している環境では、プライマリノードに送ってよい問い合わせ、スタンバイに送ってもよい問い合わせ、両方に送らなければならない問い合わせを厳密に管理する必要があります。 -Pgpool-IIのストリーミングレプリケーションモードは、こうした振り分けを自動的に行ないます。 - + --> + ストリーミングレプリケーションとHot Standbyを利用している環境では、プライマリノードに送ってよい問い合わせ、スタンバイに送ってもよい問い合わせ、両方に送らなければならない問い合わせを厳密に管理する必要があります。 + Pgpool-IIのストリーミングレプリケーションモードは、こうした振り分けを自動的に行ないます。 + - - - クエリそのものから、どのクエリがどのノードに送られるべきかを区別します。 - + --> + クエリそのものから、どのクエリがどのノードに送られるべきかを区別します。 + + + + + プライマリノードにしか送られない問い合わせ + - - -プライマリノードにしか送られない問い合わせ - - - - INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT - - - - - SELECT ... FOR SHARE | UPDATE - - - - - -トランザクションの分離レベルがSERIALIZABLEの場合のSELECT - - - - - -ROW EXCLUSIVE MODEよりも強いLOCK - - - - - DECLARE, FETCH, CLOSE - - - - - SHOW - - - - - -トランザクションコマンドの一部 - - - - BEGIN READ WRITE, START TRANSACTION READ WRITE - - - - - SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE - - - - - SET transaction_read_only = off - - - - - - - - -二相コミット関連のコマンド。PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED - - - - - LISTEN, UNLISTEN, NOTIFY - - - - - VACUUM - - - - - -シーケンス関連の関数(nextvalやsetvalなど)の呼び出し。 - - - - - -ラージオブジェクトの生成 - - - - - - - - -プライマリノードとスタンバイノードのどちらにも送ることのできる問い合わせ。 -負荷分散設定が有効ならば、スタンバイノードにも送信されます。 -レプリケーションの遅延がを上回っている場合は問い合わせはプライマリノードに送られます。 - - - - - SELECT (上記以外) - - - - - COPY TO - - - - - - - - -プライマリノードとスタンバイノードのどちらにも送られる問い合わせ - - - - SET - - - - - DISCARD - - - - - DEALLOCATE ALL - - - - + + INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT + - - - - - -明示的なトランザクションでは、以下のようになります。 - - - - -BEGINなどのトランザクション開始コマンドは、プライマリノードとスタンバイノードの両方に送られます。 - + + SELECT ... FOR SHARE | UPDATE + - - -続くSELECTなど、プライマリ/スタンバイのどちらにも送ることのできる問い合わせは、プライマリのトランザクション内でそのまま実行されるか、スタンバイノードで実行されます。 - + + + トランザクションの分離レベルがSERIALIZABLEの場合のSELECT + - - -INSERTなど、スタンバイに送ることのできない問い合わせが現われた場合はプライマリに送られます。 -そういったコマンドの後は、SELECTであってもプライマリノードに送られます。 -これは、INSERTなどの問い合わせの結果を SELECTが直ちに参照できるようにするためです。 -この状態は、トランザクションが閉じるか、アボートするまで続きます。 - + + + ROW EXCLUSIVE MODEよりも強いLOCK + - - - - - -問い合わせが、拡張問い合わせモードで実行される場合は、問い合わせのparse段階で、問い合わせがスタンバイに送信可能かが決まります。 -その際の判断ルールは通常のSQLと同じです。 -たとえば問い合わせがINSERTならば、プライマリノードに送られます。 -それに後に続くbind, describe, executeも同じくプライマリに送られます。 - - - - - -負荷分散によりSELECT文のparseがスタンバイノードに送信され、その後INSERTなどのDML文がPgpool-IIに送られた場合、parse済のSELECTはプライマリノードで実行されなければなりません。 -そのため、同じSELECTがプライマリノードで再度パースされることになります。 - - - - - -最後に、pgpool-IIのパーサが構文エラーと判断した問い合わせはプライマリノードだけに送られます。 - - + + + DECLARE, FETCH, CLOSE + + + + + SHOW + + + + + + トランザクションコマンドの一部 + + + + BEGIN READ WRITE, START TRANSACTION READ WRITE + + + + + SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE + + + + + SET transaction_read_only = off + + + + + + + + + 二相コミット関連のコマンド。PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED + + + + + LISTEN, UNLISTEN, NOTIFY + + + + + VACUUM + + + + + + シーケンス関連の関数(nextvalやsetvalなど)の呼び出し + + + + + + ラージオブジェクトの生成 + + + + + マルチステートメントSQL(1行の中に複数のSQLが含まれている) + + + + + + + + + プライマリノードとスタンバイノードのどちらにも送ることのできる問い合わせ。 + 負荷分散設定が有効ならば、スタンバイノードにも送信されます。 + レプリケーションの遅延がを上回っている場合は問い合わせはプライマリノードに送られます。 + + + + + SELECT (上記以外) + + + + + COPY TO + + + + + + + + + プライマリノードとスタンバイノードのどちらにも送られる問い合わせ + + + + SET + + + + + DISCARD + + + + + DEALLOCATE ALL + + + + + SAVEPOINT (そしてRELEASE SAVEPOINTのような関連コマンド) + + + + + + + + + + + 明示的なトランザクションでは、以下のようになります。 + + + + + + BEGINなどのトランザクション開始コマンドは、プライマリノードとスタンバイノードの両方に送られます。 + + + + + + 続くSELECTなど、プライマリ/スタンバイのどちらにも送ることのできる問い合わせは、プライマリのトランザクション内でそのまま実行されるか、スタンバイノードで実行されます。 + + + + + + INSERTなど、スタンバイに送ることのできない問い合わせが現われた場合はプライマリに送られます。 + そういったコマンドの後は、SELECTであってもプライマリノードに送られます。 + これは、INSERTなどの問い合わせの結果を SELECTが直ちに参照できるようにするためです。 + この状態は、トランザクションが閉じるか、アボートするまで続きます。 + + + + + + + + 問い合わせが、拡張問い合わせモードで実行される場合は、問い合わせのparse段階で、問い合わせがスタンバイに送信可能かが決まります。 + その際の判断ルールは通常のSQLと同じです。 + たとえば問い合わせがINSERTならば、プライマリノードに送られます。 + それに後に続くbind, describe, executeも同じくプライマリに送られます。 + + + + + + 負荷分散によりSELECT文のparseがスタンバイノードに送信され、その後INSERTなどのDML文がPgpool-IIに送られた場合、parse済のSELECTはプライマリノードで実行されなければなりません。 + そのため、同じSELECTがプライマリノードで再度パースされることになります。 + + + + + + 最後に、pgpool-IIのパーサが構文エラーと判断した問い合わせはプライマリノードだけに送られます。 + + - + --> 負荷分散の設定 - - load_balance_mode (boolean) - - - load_balance_mode 設定パラメータ - - - - - -onに設定すると、Pgpool-IIは入ってきたSELECTクエリに対する負荷分散を有効にします。 -すなわち、クライアントからのSELECTクエリは設定されたPostgreSQLバックエンドに振り分けます。 -デフォルトはoffです。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - + + load_balance_mode (boolean) + + + load_balance_mode 設定パラメータ + + + + + + onに設定すると、Pgpool-IIは入ってきたSELECTクエリに対する負荷分散を有効にします。 + すなわち、クライアントからのSELECTクエリは設定されたPostgreSQLバックエンドに振り分けます。 + デフォルトはonです。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + - ignore_leading_white_space (boolean) - - - ignore_leading_white_space 設定パラメータ - - - - - -onに設定すると、負荷分散の際にSQL文行頭の空白を無視します(全角スペースは無視されません)。 -これは、DBI/DBD:Pgのように、ユーザの意図に反してに空白を追加するようなAPIを使っているときに有用です。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + ignore_leading_white_space (boolean) + + + ignore_leading_white_space 設定パラメータ + + + + + + onに設定すると、負荷分散の際にSQL文行頭の空白を無視します(全角スペースは無視されません)。 + これは、DBI/DBD:Pgのように、ユーザの意図に反して空白を追加するようなAPIを使っているときに有用です。 + デフォルトはonです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + read_only_function_list (string) + + + read_only_function_list 設定パラメータ + + + + + + データベースに対して更新を行なわない関数名をコンマ区切りで指定します。 + このリストに指定されていない関数呼び出しを含むSELECTは負荷分散されません。 + これらのクエリはレプリケーションモードにおいてはすべてのDBノードで複製され、それ以外のモードにおいてはプライマリノードにのみ送信されます。 + + + + 関数名のマッチングに正規表現を使うことができます。 + 正規表現には自動的に^$が付与されます。 + - - white_function_list (string) - - - white_function_list 設定パラメータ - - - - - -データベースに対して更新を行なわない関数名をコンマ区切りで指定します。 -このリストに指定されていない関数呼び出しを含むSELECTは負荷分散されません。 -これらのクエリはレプリケーションモードにおいてはすべてのDBノードで複製され、マスタースレーブモードにおいてはプライマリノードにのみ送信されます。 - - - -関数名のマッチングに正規表現を使うことができます。 -正規表現には自動的に^$が付与されます。 - + + + 正規表現の使用 + + + もし読み出しのみを行う関数が"get_"あるいは"select_"で始まるようにしてあるのであれば、を以下のように設定可能です。 + +read_only_function_list = 'get_.*,select_.*' + + + - - - 正規表現の使用 - - -もし読み出しのみを行う関数が"get_"あるいは"select_"で始まるようにしてあるのであれば、を以下のように設定可能です。 - -white_function_list = 'get_.*,select_.*' - - - + + + 問い合わせがスキーマ修飾なしあるいはスキーマ修飾ありの両方の関数を参照するなら、その両者をリストに登録しなければなりません。 + +#たとえば、ある問い合わせが"f1()"を、他の問い合わせが"public.f1()"を関数f1を参照するなら、 +#read_only_function_listは以下のように設定されるでしょう。 - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - +read_only_function_list = "f1,public.f1" - - black_function_list (string) - - - black_function_list 設定パラメータ - - - - - -データベースに対して更新を行う関数名をコンマ区切りで指定します。 -このリストに指定された関数呼び出しを含むSELECTは負荷分散されません。 -これらのクエリはレプリケーションモードにおいてはすべてのDBノードで複製され、マスタースレーブモードにおいてはプライマリノードにのみ送信されます。 - - - -関数名のマッチングに正規表現を使うことができます。 -正規表現には自動的に^$が付与されます。 - + - - - 正規表現の使用 - - -もし更新を行う関数が"set_"、"update_"、"delete_"、あるいは"insert_"で始まるようにしてあるのであれば、を以下のように設定可能です。 - -black_function_list = 'nextval,setval,set_.*,update_.*,delete_.*,insert_.*' - - - - - - - -は互いに排他的で、2つのリストの内、どちらか一方のみ設定することができます。 - - + + - - - <literal>nextval()</literal>と<literal>setval()</literal>を適切なバックエンドに送る設定 - - -Pgpool-II V3.0より前のバージョンでは、固定でnextval()setval()がデータベースに書き込みを行なう関数であると認識されていました。 -以下のようにを設定することで、それと同じように動作させることができます。 - -white_function_list = '' -black_function_list = 'nextval,setval,lastval,currval' - - - - - - - -PostgreSQLにはnextval()setval()に加え、lastval()currval()があります。 -lastval()currval()は書き込みを行う関数ではありませんが、これらの関数が負荷分散されることで発生するエラーを防ぐため、lastval()currval()を書き込みを行う関数として扱うのが望ましいです。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + + このパラメータとが空文字なら、関数の揮発性属性が検査されます。 + これが揮発性(volatile)なら、この関数は書き込みを行うと見なされます。 + これは便利ですし、推奨できる設定です。 + しかしこれにより初回システムカタログへのアクセスが発生します(次回以降はキャッシュされた結果が使用されるので余計な問い合わせは送信されません。) + そのようなクエリの送信を望まないのであれば、このパラメータを使い続けることができます。 + + - - black_query_pattern_list (string) - - - black_query_pattern_list 設定パラメータ - - - - - -特定の SQL をプライマリノードに送信するように を設定します。 -SQL パターンをセミコロン区切りで指定します。 -マスタースレーブモードのみで動作します。 - + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + write_function_list (string) + + + write_function_list 設定パラメータ + + + + + + データベースに対して更新を行う関数名をコンマ区切りで指定します。 + このリストに指定された関数呼び出しを含むSELECTは負荷分散されません。 + これらのクエリはレプリケーションモードにおいてはすべてのDBノードで複製され、それ以外のモードにおいてはプライマリノードにのみ送信されます。 + + + + 関数名のマッチングに正規表現を使うことができます。 + 正規表現には自動的に^$が付与されます。 + + + + + 正規表現の使用 + + + もし更新を行う関数が"set_"、"update_"、"delete_"、あるいは"insert_"で始まるようにしてあるのであれば、を以下のように設定可能です。 + + write_function_list = 'nextval,setval,set_.*,update_.*,delete_.*,insert_.*' + + + + + + + 問い合わせがスキーマ修飾なしあるいはスキーマ修飾ありの両方の関数を参照するなら、その両者をリストに登録しなければなりません。 + +#たとえば、ある問い合わせが"f1()"を、他の問い合わせが"public.f1()"を関数f1を参照するなら、 +#write_function_listは以下のように設定されるでしょう。 + +write_function_list = "f1,public.f1" + + + + + + + + + は互いに排他的で、2つのリストの内、どちらか一方のみ設定することができます。 + + + + + + <literal>nextval()</literal>と<literal>setval()</literal>を適切なバックエンドに送る設定 + + + Pgpool-II V3.0より前のバージョンでは、固定でnextval()setval()がデータベースに書き込みを行なう関数であると認識されていました。 + 以下のようにを設定することで、それと同じように動作させることができます。 + +read_only_function_list = '' +write_function_list = 'nextval,setval,lastval,currval' + + + + + + + + PostgreSQLにはnextval()setval()に加え、lastval()currval()があります。 + lastval()currval()は書き込みを行う関数ではありませんが、これらの関数が負荷分散されることで発生するエラーを防ぐため、lastval()currval()を書き込みを行う関数として扱うのが望ましいです。 + + + + + + このパラメータとが空文字なら、関数の揮発性属性が検査されます。 + これが揮発性(volatile)なら、この関数は書き込みを行うと見なされます。 + これは便利ですし、推奨できる設定です。 + しかしこれにより初回システムカタログへのアクセスが発生します(次回以降はキャッシュされた結果が使用されるので余計な問い合わせは送信されません。) + そのようなクエリの送信を望まないのであれば、このパラメータを使い続けることができます。 + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + primary_routing_query_pattern_list (string) + + + primary_routing_query_pattern_list 設定パラメータ + + + + + + 特定の SQL をプライマリノードに送信するように を設定します。 + SQL パターンをセミコロン区切りで指定します。 + ネイティブレプリケーションモード以外でのみで動作します。 + + + + SQL のマッチングに正規表現を使うことができます。 + 正規表現には自動的に^$が付与されます。 + "'"、";" あるいは "*" などの文字を SQL パターンの中で利用する場合、"\" でエスケープする必要があります。 + SQL パターンの中で正規表現の特殊文字を使用する場合、"\" でエスケープする必要があります。 + 例えば、"'"、";"、"*"、"("、")"、"|"、"+"、"."、"\"、"?"、"^"、"$"、"{"、"}"、"{"、"}" などの特殊文字の場合、"\" でエスケープする必要があります。 + また、指定される SQL パターンでは大文字と小文字を区別しません。 + + + + + 正規表現の使用 + + + もし以下の SQL をプライマリノードに送信したい場合、を以下のように設定可能です。 + + + + + SELECT * FROM table_name1; + + + + + SELECT col1, col2 FROM table_name2 WHERE col1 LIKE '%a%'; + + + + + + table_name3 という文字列を含む SQL + + + + + + + +primary_routing_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM table_name2 WHERE col1 LIKE \'%a%\'\;;.*table_name3.*' + + + + + + + + の両方にマッチした場合、 + の設定が無視され、プライマリノードのみに送信されます。 + + + + + SQL のパターンにもよりますが、この機能を使用する場合、パフォーマンスが 1-2% 低下する可能性があります。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + user_redirect_preference_list (string) + + + user_redirect_preference_list 設定パラメータ + + + + + + 特定のユーザの接続でSELECTクエリが指定したロードバランス比率で特定のバックエンドノードに送信されるように、"ユーザ名:ノードID(比率)"ペアのリストを指定します。ロードバランス比率は0-1の間の値を指定します。 + 比率の指定を省略した場合は、デフォルトの1.0となります。 + + + + たとえば"user1:1(0.5)"とした場合、user1ユーザからの接続においては、Pgpool-IIは50%のSELECTクエリをIDが1のバックエンドノードに送信します。 + + + + 複数の"ユーザ名:ノードID(比率)"のペアをカンマ(,)で区切って指定することができます。 + + + + ユーザ名には正規表現を指定することができます。 + ノードIDには特別なキーワードを使うことができます。 + "primary"が指定された場合にはクエリはプライマリノードに送られます。 + また、"standby"が指定された場合はスタンバイノードのうちどれかをロードバランス比率に応じてランダムに選択します。 + + + + + user_redirect_preference_listの利用 + + + SELECTクエリのルーティングルールを以下のように設定したい場合: + + + + - -SQL のマッチングに正規表現を使うことができます。 -正規表現には自動的に^$が付与されます。 -"'"、";" あるいは "*" などの文字を SQL パターンの中で利用する場合、"\" でエスケープする必要があります。 -SQL パターンの中で正規表現の特殊文字を使用する場合、"\" でエスケープする必要があります。 -例えば、"'"、";"、"*"、"("、")"、"|"、"+"、"."、"\"、"?"、"^"、"$"、"{","}"、"{"、"}" などの特殊文字の場合、"\" でエスケープする必要があります。 -また、指定される SQL パターンでは大文字と小文字を区別しません。 + + 全てのpostgresユーザからのSELECTクエリはプライマリバックエンドノードに送る。 - - - - 正規表現の使用 - - -もし以下の SQL をプライマリノードに送信したい場合、を以下のように設定可能です。 - - - - - SELECT * FROM table_name1; - - - - - SELECT col1, col2 FROM table_name2 WHERE col1 LIKE '%a%'; - - - - - - table_name3 という文字列を含む SQL - - - - - - - -black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM table_name2 WHERE col1 LIKE \'%a%\'\;;.*table_name3.*' - - - - - - - -の両方にマッチした場合、 -の設定が無視され、プライマリノードのみに送信されます。 - - + + - -SQL のパターンにもよりますが、この機能を使用する場合、パフォーマンスが 1-2% 低下する可能性があります。 + + user0またはuser1ユーザからの30%のSELECTクエリはIDが1のバックエンドノードに送る。 + 残りの70%のSELECTクエリは他のバックエンドノードに送る。 + + - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + 全てのuser2ユーザからのSELECTクエリはスタンバイバックエンドノードに送る。 - - + + + + + + は以下のように設定します。 + +user_redirect_preference_list = 'postgres:primary,user[01]:1(0.3),user2:standby' + + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - database_redirect_preference_list (string) - - - database_redirect_preference_list 設定パラメータ - - - + database_redirect_preference_list (string) + + + database_redirect_preference_list 設定パラメータ + + + + + + 特定のデータベース接続でSELECTクエリが指定したロードバランス比率で特定のバックエンドノードに送信されるように、"データベース名:ノードID(比率)"ペアのリストを指定します。ロードバランス比率は0-1の間の値を指定します。 + 比率の指定を省略した場合は、デフォルトの1.0となります。 + + + + たとえば"test:1(0.5)"とした場合、testデータベースへの接続においては、Pgpool-IIは50%のSELECTクエリをIDが1のバックエンドノードに送信します。 + + + + 複数の"データベース名:ノードID(比率)"のペアをカンマ(,)で区切って指定することができます。 + + + + データベース名には正規表現を指定することができます。 + ノードIDには特別なキーワードを使うことができます。 + "primary"が指定された場合にはクエリはプライマリノードに送られます。 + また、"standby"が指定された場合はスタンバイノードのうちどれかをロードバランス比率に応じてランダムに選択します。 + + + + + database_redirect_preference_listの利用 + + + SELECTクエリのルーティングルールを以下のように設定したい場合: + + + + - -特定のデータベース接続でSELECTクエリが指定したロードバランス比率で特定のバックエンドノードに送信されるように、"データベース名:ノードID(比率)"ペアのリストを指定します。ロードバランス比率は0-1の間の値を指定します。 -比率の指定を省略した場合は、デフォルトの1.0となります。 + + 全てのpostgresデータベースにおけるSELECTクエリはプライマリバックエンドノードに送る。 + + - -たとえば"test:1(0.5)"とした場合、"test"データベースへの接続においては、Pgpool-IIは50%のSELECTクエリをIDが1のバックエンドノードに送信します。 -複数の"データベース名:ノードID"のペアを カンマ(,)で区切って指定することができます。 + + mydb0またはmydb1データベースにおける30%のSELECTクエリはIDが1のバックエンドノードに送る。 + 残りの70%のSELECTクエリは他のバックエンドノードに送る。 + + - -データベース名には正規表現を指定することができます。 -ノードIDには特別なキーワードを使うことができます。 -"primary"が指定された場合にはクエリはプライマリノードに送られます。 -また、"standby"が指定された場合はスタンバイノードのうちどれかをウェイト()に応じてランダムに選択します。 + + 全てのmydb2データベースにおけるSELECTクエリはスタンバイバックエンドノードに送る。 + - - - database_redirect_preference_listの利用 - - -SELECTクエリのルーティングルールを以下のように設定したい場合: - + + + + は以下のように設定します。 + +database_redirect_preference_list = 'postgres:primary,mydb[01]:1(0.3),mydb2:standby' + + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + app_name_redirect_preference_list (string) + + + app_name_redirect_preference_list 設定パラメータ + + + + + + + 特定のクライアントアプリケーションの接続でSELECTクエリが指定したロードバランス比率で特定のバックエンドノードに送信されるように、"アプリケーション名:ノードID(比率)"ペアのリストを指定します。 + ロードバランス比率は0-1の間の値を指定します。 + 比率の指定を省略した場合は、デフォルトの1.0となります。 + 複数の"アプリケーション名:ノードID(比率)"のペアを カンマ(,)で区切って指定することができます。 + + + + + + 「アプリケーション名」とはクライアントがデータベースに接続する時に指定する名称で、PostgreSQL V9.0以降で利用可能です。 + + + + + + たとえば、psqlコマンドのアプリケーション名は"psql"です。 + + + + + + Pgpool-IIは、クライアントから送信されたスタートアップパケットに含まれるアプリケーション名だけを認識します。 + クライアントは事後にセッションの中でアプリケーション名を指定できますが、それはPgpool-IIのクエリルーティングでは考慮されません。 + + + + + + アプリケーション名には正規表現を指定することができます。 + ノードIDには特別なキーワードを使うことができます。 + "primary"が指定された場合にはクエリはプライマリノードに送られます。 + また、"standby"が指定された場合はスタンバイノードのうちどれかをロードバランス比率に応じてランダムに選択します。 + + + + + app_name_redirect_preference_listの利用 + + + SELECTクエリのルーティングルールを以下のように設定したい場合: + + + + + + + 全てのpsqlクライアントからのSELECTクエリはプライマリバックエンドノードに送る。 + + + + + + myapp1クライアントからの30%のSELECTクエリはIDが1のバックエンドノードに送る。 + 残りの70%のSELECTクエリは他のバックエンドノードに送る。 + + + + + + 全てのmyapp2クライアントからのSELECTクエリはスタンバイバックエンドノードに送る。 + + + + + + + は以下のように設定します。 + +app_name_redirect_preference_list = 'psql:primary,myapp1:1(0.3),myapp2:standby' + + + - - - - -全てのpostgresデータベースにおけるSELECTクエリはプライマリバックエンドノードに送る。 - - - - - -全てのmydb0またはmydb1データベースにおける30%のSELECTクエリはIDが1のバックエンドノードに送る。 - - - - - -全てのmydb2データベースにおけるSELECTクエリはスタンバイバックエンドノードに送る。 - - + + + + およびの優先順位は以下の通りです。 + +app_name_redirect_preference_list > database_redirect_preference_list > user_redirect_preference_list + + + + + たとえば、 + database_redirect_preference_list = 'postgres:standby(1.0)'、 + app_name_redirect_preference_list = 'myapp1:primary(1.0)' + と設定した場合、アプリケーションmyapp1postgresデータベースでのSELECTはプライマリバックエンドノードに送られます。 + + - - - -は以下のように設定します。 - -database_redirect_preference_list = 'postgres:primary,mydb[01]:1(0.3),mydb2:standby' - - - + + + + およびの設定では、複数のユーザ名やデータベース名、アプリケーション名にマッチした場合、最初の設定が反映されます。 + + + + たとえば、 + database_redirect_preference_list = 'postgres:primary,postgres:standby' + と設定した場合、postgres:primaryの設定が反映されます。 + + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + + + JDBCドライバのpostgresql-9.3以前のバージョンでは、JDBCドライバの"ApplicationName" と "assumeMinServerVersion=9.0"オプションを指定してもスタートアップパケットの中にアプリケーション名を含みません。 + JDBCから機能を使用したければ、postgresql-9.4 以降のドライバをお使いください + + - - app_name_redirect_preference_list (string) - - - app_name_redirect_preference_list 設定パラメータ - - - + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - - -特定のクライアントアプリケーションの接続でSELECTクエリが指定したロードバランス比率で特定のバックエンドノードに送信されるように、"アプリケーション名:ノードID(比率)"ペアのリストを指定します。 - + + allow_sql_comments (boolean) + + + allow_sql_comments 設定パラメータ + + + + + + onに設定すると、Pgpool-IIは負荷分散やクエリキャッシュができるかどうかの判定の際にSQLコメントを無視します。 + このパラメータがoffに設定されている場合、クエリのSQLコメントにより、クエリの負荷分散やキャッシュを防止することができます。 + (Pgpool-II V3.4より前のバージョンの動作です)。 + + + + デフォルトはoffです。 + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + - - - -「アプリケーション名」とはクライアントがデータベースに接続する時に指定する名称で、PostgreSQL V9.0以降で利用可能です。 - - + + disable_load_balance_on_write (enum) + + + disable_load_balance_on_write設定パラメータ + + + + + + writeクエリが発行された時の負荷分散の振る舞いを指定します。 + このパラメータは、特にストリーミングレプリケーションモードで有効です。 + writeクエリがプライマリサーバに送られた時、この変更はスタンバイサーバにも適用されますが、そこには時間差があります。 + ですからクライアントが行を更新して同じ行をスタンバイから読むと、その行の最新データを読めないかもしれません。 + もしこれが問題になるようなら、クライアントは常にプライマリサーバからデータを読むべきです。 + しかし、これは実質的に負荷分散を無効にして、性能低下をもたらします。 + このパラメータは、クラスタリングについて考慮しないアプリケーションにおける互換性と、性能の間におけるトレードオフの細かな調整を可能にします。 + + + + このパラメータがoffなら、writeクエリが来ても負荷分散が行われます。 + この設定では最大の性能を期待できますが、クライアントは古いデータを読むことになるかもしれません。 + この設定は、PostgreSQLのパラメータsynchronous_commit = 'remote_apply'が設定されているか、ネィティブレプリケーションモードのときに有用です。 + そのような環境ではレプリケーションの遅延が発生しないからです。 + + + + このパラメータがtransactionで、明示的なトランザクション中にwriteクエリが来ると、トランザクションが終了するまで負荷分散が行われません。 + なお、明示的なトランザクション中ではないreadクエリは、このパラメータの影響を受けないことに注意してください。 + この設定は、たいていの場合に最良のバランスを提供するので、この設定から試すことをお勧めします。 + これはデフォルトで、Pgpool-II 3.7以前のバージョンと同じ振る舞いです。 + + + + このパラメータがtrans_transactionで、明示的なトランザクション中にwriteクエリが来ると、トランザクションが終了するまで負荷分散が行われません。 + また、セッションが終了するまで後続の明示的なトランザクション中でも負荷分散が行われません。 + この設定は古いアプリケーションにとって安全ですが、transactionよりは性能が低下します。 + なお、明示的なトランザクション内にないreadクエリは、このパラメータの影響を受けないことに注意してください。 + - - -たとえば、psqlコマンドのアプリケーション名は"psql"です。 - + + + このパラメータがalwaysで、writeクエリが来ると、明示的なトランザクション中であるかどうかを問わず、セッションが終了するまで負荷分散が行われません。 + この設定により、クラスタリングについて考慮しないアプリケーションを使った場合最大の互換性が得られますが、性能は最低になります。 + - - + -Pgpool-IIは、クライアントから送信されたスタートアップパケットに含まれるアプリケーション名だけを認識します。 -クライアントは事後にセッションの中でアプリケーション名を指定できますが、それはPgpool-IIのクエリルーティングでは考慮されません。 - - + このパラメータがdml_adaptiveに設定されると、Pgpool-IIは明示的なトランザクション内のWRITE文に含まれる個々のテーブルを追跡し、テーブルが同じトランザクション内で事前に変更されている場合には後続のREADクエリを負荷分散しません。 + テーブルが依存する関数、トリガ、ビューはで設定できます。 + - - -の記法はと同じですので、アプリケーション名には正規表現も使用できます。 -同様に特別なキーワード"primary"はプライマリノードを、"standby"はスタンバイサーバのいずれかを意味します。 -ロードバランス比率は0-1の間の値を指定します。ロードバランス比率の指定を省略した場合は、デフォルトの1.0となります。 - + + このパラメータがdml_adaptive_globalに設定されると、Pgpool-IIdml_adaptiveのように振る舞いますが(トランザクション単位の書き込み追跡)、更に共有メモリを使って、最近書き込みがあったテーブルの追跡をデータベースクラスタ中の全セッションについて行います。 + テーブルがあるセッションで書き込まれると、すべてのセッションでのそのテーブルからの後続の読み込は、TTL(計測されたレプリケーションの遅延に基づきます)が期限切れになるまでプライマリに転送されます。 + これにより、書き込み後、古いデータの読み取りが、セッションが異なる場合でも防止されます。 + 共有メモリを使った追跡の挙動を制御する配下のパラメータについてはをご覧ください。 + + + - + + dml_adaptive_object_relationship_list (string) + - app_name_redirect_preference_listの利用 - - -SELECTクエリのルーティングルールを以下のように設定したい場合: - + dml_adaptive_object_relationship_list設定パラメータ + + + - - - - -全てのpsqlクライアントからのSELECTクエリはプライマリバックエンドノードに送る。 - - - - - -全てのmyapp1クライアントからの30%のSELECTクエリはIDが1のバックエンドノードに送る。 - - - - + -全てのmyapp2クライアントからのSELECTクエリはスタンバイバックエンドノードに送る。 - - + To prevent load balancing of READ dependent objects, you may specify the object name + followed by a colon(:) and then a comma(,) separated list of dependent object names. + "[object]:[dependent-object]" + In an explicit transaction block after a WRITE statement has been issues, this will prevent + load balancing of any READ statements containing references of dependent object(s). + + Configuring dml adaptive object relationship +--> + オブジェクトに依存しているREAD問い合わせが負荷分散しないようにするために、オブジェクト名の後にコロン(:)、続いてカンマ(,)で区切られた依存オブジェクトの名前のリストを指定できます。 + "[object]:[dependent-object]" + 明示的なトランザクションブロックの中でWRITE文が発行された後、依存オブジェクトへの参照を含むREAD文は負荷分散されないようになります。 + + dmlが関与するオブジェクト関係の設定 + + + table_1へのINSERTのたびにtable_2にINSERTを行うトリガがtable_1に設定されており、table_1へのINSERTの後でtable_2からの読み出しが同じトランザクション内で負荷分散されないようにしたいとします。 + このための設定は以下のようになります。 + +dml_adaptive_object_relationship_list = 'table_1:table_2' + + + + + + このパラメータは='dml_adaptive'のときにのみ有効です。 + + + +関数の依存性を設定するには、関数はで設定済みでなければなりません。 + + - - - -は以下のように設定します。 - -app_name_redirect_preference_list = 'psql:primary,myapp1:1(0.3),myapp2:standby' - - - + - - - -は、よりも優先されます。 - - - -たとえば、 -database_redirect_preference_list = 'postgres:standby(1.0)'、 -app_name_redirect_preference_list = 'myapp1:primary(1.0)' -と設定した場合、アプリケーションmyapp1postgresデータベースでのSELECTはプライマリバックエンドノードに送られます。 - - - - - - -及びの設定では、複数のデータベース名やアプリケーション名にマッチした場合、最初の設定が反映されます。 - - - -たとえば、 -database_redirect_preference_list = 'postgres:primary,postgres:standby' -と設定した場合、postgres:primaryの設定が反映されます。 - - - - - + + + + + statement_level_load_balance (boolean) + + + statement_level_load_balance 設定パラメータ + + + + + + onに設定し、がonに設定されていると、参照クエリごとに負荷分散先を決めます。 + offに設定すると、セッションが始まるときに決められた負荷分散先がセッションが終了するまで変更されません。 + 例えば、コネクションプールを利用し、バックエンドサーバに接続したままのようなアプリケーションの場合、 + セッションが長い間保持される可能性があるので、セッションが終了するまで負荷分散先のノードが変わりません。 + このようなアプリケーションでは、statement_level_load_balanceを有効にすると、 + セッションごとではなく、クエリごとに負荷分散先を決めることが可能です。デフォルトはoffです。 + + + -JDBCドライバのpostgresql-9.3以前のバージョンでは、JDBCドライバの"ApplicationName" と "assumeMinServerVersion=9.0"オプションを指定してもスタートアップパケットの中にアプリケーション名を含みません。 -JDBCから機能を使用したければ、postgresql-9.4 以降のドライバをお使いください - - + In streaming replication mode, certain kind of queries such as + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE + SAVEPOINT/DEALLOCATE ALL/DISCARD are sent to primary node and + load balance node. If + is on, such + queries are sent to all standby nodes as well. This is not + usually a problem. But when one of standbys are in remote + network, the network latency may cause significant slow down in + case of such queries. +--> + streaming replication modeでは、BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE ALL/DISCARDのようなクエリはプライマリノードとロードバランスノードに送られます。 + がonなら、そうしたクエリはすべてのスタンバイノードにも送られます + これは通常問題になりません。 + しかしスタンバイノードの一つが遠隔ネットワークにあると、ネットワーク遅延のためにこうしたクエリで大きな速度低下を起こすことがあります。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + テーブル変更追跡設定 + + これらのパラメータは、テーブル変更追跡機能を設定します。 + テーブル変更追跡機能は、dml_adaptive_globalにすることで有効になります。 + この機能は直近のテーブルへの書き込みを追跡し、レプリケーションの遅延がある状況下で、古いデータをレプリカノードから読んでしまうことを防止します。 + + + テーブルが変更されると(INSERT/UPDATE/DELETE)、そのテーブルにはTTL期間(replication_delay * track_table_mutation_ttl_factor)「古い」印が付きます。 + 古いテーブルへのすべてのSELECTクエリは、レプリカではなくプライマリノードに転送されます。 + これにより、read-after-write一貫性が保証されます。 + + + この機能には、時刻ベースのレプリケーション遅延監視が必要です。 + これは、(外部コマンドモード)、あるいは(PostgreSQL 10以降のpg_stat_replication.replay_lagを使用します)を設定することで利用可能になります。 + どちらも設定されていなければ、TTLはデフォルトである最小値(100ミリ秒)のままとなり、実際のレプリケーション遅延に基づいて更新されることがありません。 + これにより、最適ではないルーティングが採用されるかもしれません。 + - - allow_sql_comments (boolean) - - - allow_sql_comments 設定パラメータ - - - - - -onに設定すると、Pgpool-IIは負荷分散やクエリキャッシュができるかどうかの判定の際にSQLコメントを無視します。 -このパラメータがoffに設定されている場合、クエリのSQLコメントにより、クエリの負荷分散やキャッシュを防止することができます。 -(Pgpool-II V3.4より前のバージョンの動作です)。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - + + + dml_adaptive_globalを有効にすると、共有メモリがより多く使用されます。 + デフォルトの設定では、この機能によっておおよそ80 KBの共有メモリが使用されます。 + track_table_mutation_table_size * 40 bytes + (default: 2048 * 40 = ~80 KB). + + - - disable_load_balance_on_write (string) - - - disable_load_balance_on_write設定パラメータ - - - - - -writeクエリが発行された時の負荷分散の振る舞いを指定します。 -このパラメータは、特にストリーミングレプリケーションモードで有効です。 -writeクエリがプライマリサーバに送られた時、この変更はスタンバイサーバにも適用されますが、そこには時間差があります。 -ですからクライアントが行を更新して同じ行をスタンバイから読むと、その行の最新データを読めないかもしれません。 -もしこれが問題になるようなら、クライアントは常にプライマリサーバからデータを読むべきです。 -しかし、これは実質的に負荷分散を無効にして、性能低下をもたらします。 -このパラメータは、クラスタリングについて考慮しないアプリケーションにおける互換性と、性能の間におけるトレードオフの細かな調整を可能にします。 - - - -このパラメータがoffなら、writeクエリが来ても負荷分散が行われます。 -この設定では最大の性能を期待できますが、クライアントは古いデータを読むことになるかもしれません。 -この設定は、PostgreSQLのパラメータsynchronous_commit = 'remote_apply'が設定されているか、ネィティブレプリケーションモードのときに有用です。 -そのような環境ではレプリケーションの遅延が発生しないからです。 - - - -このパラメータがtransactionで、明示的なトランザクション中にwriteクエリが来ると、トランザクションが終了するまで負荷分散が行われません。 -なお、明示的なトランザクション中ではないreadクエリは、このパラメータの影響を受けないことに注意してください。 -この設定は、たいていの場合に最良のバランスを提供するので、この設定から試すことをお勧めします。 -これはデフォルトで、Pgpool-II 3.7以前のバージョンと同じ振る舞いです。 - - - -このパラメータがtrans_transactionで、明示的なトランザクション中にwriteクエリが来ると、トランザクションが終了するまで負荷分散が行われません。 -また、セッションが終了するまで後続の明示的なトランザクション中でも負荷分散が行われません。 -この設定は古いアプリケーションにとって安全ですが、transactionよりは性能が低下します。 -なお、明示的なトランザクション内にないreadクエリは、このパラメータの影響を受けないことに注意してください。 - + - - -このパラメータがalwaysで、writeクエリが来ると、明示的なトランザクション中であるかどうかを問わず、セッションが終了するまで負荷分散が行われません。 -この設定により、クラスタリングについて考慮しないアプリケーションを使った場合最大の互換性が得られますが、性能は最低になります。 - - - + + track_table_mutation_ttl_factor (floating point) + + track_table_mutation_ttl_factor設定パラメータ + + + + + TTLを計算する際の乗数です。 + TTLは以下となります。 + TTL = replication_delay * track_table_mutation_ttl_factor。 + 高い値を設定すると安全マージンが増えますが、レプリケーションの使用が制限されます。 + + + 有効な範囲は1.0-100.0です。 + デフォルトは5.0です。 + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + track_table_mutation_max_staleness (integer) + + track_table_mutation_max_staleness設定パラメータ + + + + + 単一のテーブルエントリが継続的にプライマリにクエリを送信されるミリ秒単位の最長の期間です。 + この期間は、最初にテーブルが古いとマークされたときから計測されます。 + この制限値に到達すると、そのエントリは直近で書き込みがあったかどうかに関わらず期限切れとなります。 + 期限切れになった後に再度テーブルへの書き込みがあると、新しい追跡エントリが作られます。 + + + このパラメータは、セッションをまたがるテーブル更新の追跡のインパクトを制限します。 + テーブルが頻繁にループの中で書き込まれるとしても、他のセッションの負荷分散に対する影響は、この期間に限定されます。 + もともと書き込みが頻繁なテーブルでは、強いられた期限切れと次のテーブルへの再マーク付の間の期限はごくわずかです(典型的にはミリ秒)。 + + + 0にするとこの制限が無効になります(実システムではおすすめしない設定です)。 + 有効な設定範囲は0-3600000ミリ秒です。 + デフォルトは60000(60秒)です。 + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + track_table_mutation_cold_start_duration (integer) + + track_table_mutation_cold_start_duration設定パラメータ + + + + + 子プロセスが起動した後に、すべてのクエリをプライマリに転送する期間をミリ秒単位で設定します。 + テーブル更新追跡が直近の書き込み履歴によって設定されるまでの間に新しい接続が古いデータを読むのを防止します。 + + + watchdogが有効な場合、ローカルノードがリーダーになると、Pgpool-IIは、リーダーの変更後古いデータの読み込みを避けるために、グローバルなコールドスタートを開始します。 + + + 有効な値は64-65536です。 + デフォルトは1024です。 + このパラメータはサーバの起動時にのみ設定可能です。 + + + + + + track_table_mutation_table_buckets (integer) + + track_table_mutation_table_buckets設定パラメータ + + + + + テーブル更新追跡ハッシュテーブルのためのハッシュバケットの数です。 + 大きな値を設定するとハッシュの衝突を減らすことができるので、ルックアップ性能を改善できます。 + + + 有効な範囲は64-65536です。デフォルトは1024です。 + このパラメータはサーバの起動時にのみ設定可能です。 + + + + + + track_table_mutation_table_size (integer) + + track_table_mutation_table_size設定パラメータ + + + + + テーブル変更追跡機能で同時に追跡できるテーブル数の最大値です。 + いっぱいになると、単純な立ち退き戦略により、最も古いエントリが立ち退きます。 + + + 有効な範囲は128-131072です。 + デフォルトは2048です。 + エントリごとに約40バイトを消費します。 + このパラメータはサーバの起動時にのみ設定可能です。 + + + + + + テーブル変更追跡の設定例 + + レプリケーション遅延の監視を使ってテーブル変更追跡を有効にします。 + +# Enable dml_adaptive_global mode (includes track table mutation) +disable_load_balance_on_write = 'dml_adaptive_global' +track_table_mutation_ttl_factor = 5.0 +track_table_mutation_max_staleness = 60000 +track_table_mutation_cold_start_duration = 2000 + +# Option A: Use external command for replication delay +replication_delay_source_cmd = '/path/to/get-replication-delay.sh' +replication_delay_source_timeout = 10 + +# Option B: Use pg_stat_replication replay_lag (PG 10+) +# delay_threshold_by_time = 1000 + +# Adjust table map size based on workload +track_table_mutation_table_size = 4096 + + + + 上記の設定で必要とする共有メモリはテーブルマップのために約160 KBです。 + デフォルトの設定(テーブル数2048)では約80 KBとなります。 + + + + + 制限事項 + + テーブル変更追跡機能には以下の制限事項があります。 + + + + + PREPARE文は追跡されません。 + prepare文の実行にデータ変更が含まれていても、テーブル変更は記録されません。 + + + + + データが古いことのチェックでは、SELECTクエリあたり、最大128のテーブルが追跡されます。 + この制限は、クエリキャッシュサブシステムと共通です(POOL_MAX_SELECT_OIDS)。 + + + + + 使用するアプリケーションがprepared文を使っており、read-after-write一貫性を要求する場合は、明示的なトランザクションによるルーティングか、/*NO LOAD BALANCE*/コメント指令を影響のあるクエリに使用することを考慮してください。 + + + 次の文追跡され、テーブルが古いとマークされます。 + + + + + INSERT, UPDATE, DELETE文(RETURNING句を伴う文も含む)。 + + + + + TRUNCATE文(複数のテーブルも含む)。 + + + + + MERGE文(PostgreSQL 15以降)。 + + + + + データ変更を伴うWITH句 (INSERT, UPDATE, DELETEを伴う共通テーブル式)。 + 例:WITH deleted AS (DELETE FROM t1 RETURNING *) SELECT * FROM deletedは、正しくt1が古いとマークします。 + + + + + トランザクションのロールバック時の振る舞い: + 明示的なトランザクション内では、トランザクションがコミットされたときにのみテーブルは古いとマークされます。 + トランザクションがロールバックされると、テーブルはマークされません。 + レプリカにデータ変更が起きないからです。 + これにより、ロールバックされたトランザクションが不必要に負荷分散を阻止することを防ぎます。 + 自動コミットの文(明示的なトランザクションの外側)は、テーブルはコマンドの実行完了時に直ちにマークされます。 + + + セッションをまたがる影響と安全性の限界: + dml_adaptive(書き込みを発行したセッションにのみ影響を与えます)とは異なり、dml_adaptive_globalは同じデータベースの同じテーブルを読んでいるすべてのセッションに影響を与えます。 + 次に述べる安全機構がセッションをまたがる影響を制限します。 + + + + + + 古さの上限: + パラメータ(デフォルト60秒)は単一のテーブルエントリが継続的にプライマリへのルーティングを強いられるかの制限を設けます。 + 継続した書き込み下においても、そのエントリはこの期間がすぎると期限切れになり、そのエントリは後続のコミットされた書き込みのみによって更新されます。 + + + + + データベース隔離: + テーブルの古さ追跡はデータベースOIDの範囲内です。 + あるデータベースへの書き込みは他のデータベースに接続したセッションの負荷分散の判定に決して影響を与えません。 + テナントが別々のデータベースを使用するマルチテナントの設定では、あるテナントの書き込みは他のテナントのクエリのルーティングに影響を与えることができません。 + + + + + コミットされた書き込みのみ: + コミットされたトランザクションだけがテーブルに古いとマークを付けます。 + ロールバックされたトランザクションは共有の追跡状態に影響を与えません。 + + + + + テーブルマップサイズの制約: + 共有メモリのテーブルマップには固定の最大サイズがあります()。 + 最大でもこの数のテーブルが同時に古いマークをつけます。 + これにより、自然にこの機能の上限が設けられます。 + + + + + + diff --git a/doc.ja/src/sgml/memcache.sgml b/doc.ja/src/sgml/memcache.sgml index ee9c4316a..0a6665138 100644 --- a/doc.ja/src/sgml/memcache.sgml +++ b/doc.ja/src/sgml/memcache.sgml @@ -1,75 +1,170 @@ + + インメモリキャッシュ + + - インメモリキャッシュ + In memory query cache can be used with all modes of + Pgpool-II. + Pgpool-II does not + need a restart when the cache gets outdated because of + the underlying table updates. + --> + Pgpool-IIの全てのモードでインメモリクエリキャッシュを利用することができます。 + クエリキャッシュはSELECTの結果を保管しておいて再利用するものです。 + テーブルの更新によりキャッシュが古くなると、自動的にそのテーブルに関連したキャッシュが削除される(がonの場合。デフォルトでこの項目はonになっています)のでPgpool-IIの再起動の必要はありません。 + + + + + まず、クエリが以下のSQLコメントで始まるかどうかがチェックされます(大文字小文字は区別されません)。 + + /*FORCE QUERY CACHE*/ + + もしこのコメントで始まっているなら、そのクエリがSELECTあるいはWITH + SELECTである限り無条件にキャッシュされます。 + しかし、この機能は注意深く使う必要があります。 + たとえば、 + + /*FORCE QUERY CACHE*/SELECT now(); + + このクエリがキャッシュされると、pgpoolが再起動するまで同じタイムスタンプを返し続けます。 + このクエリキャッシュは、以下のクエリによってさえも削除されません。 + + /*NO QUERY CACHE*/SELECT now(); + + なぜなら、これはこのクエリのキャッシュエントリが作成されないようにするだけで、FORCE QUERY CACHEコメントを使ったクエリには影響を与えないからです。 + このようなクエリキャッシュは、コマンドか、コマンドで削除できます。 + - - Pgpool-IIの全てのモードでインメモリクエリキャッシュを利用することができます。 - テーブルが更新によりキャッシュが古くなっても、Pgpool-IIの再起動の必要はありません。 - - - - - - 基本的に以下のSELECTはキャッシュされません。 - - immutableな関数を含むSELECT - 一時テーブル、unloggedテーブルを使ったSELECT - 検索結果が memqcache_maxcache を越えるようなSELECT - SELECT FOR SHARE/UPDATE - /*NO QUERY CACHE*/コメントで始まるSELECT - システムカタログを使用しているSELECT - TABLESAMPLEを使っているSELECT - - ただし、VIEWと unloggedテーブルは、white_memqcache_table_list に記載することでキャッシュされます。 - - - - インメモリクエリキャッシュは、SELECT文(拡張問い合わせの場合は更にバインドパラメータ)と 検索結果をペアで記録します。 - 同じSELECT文が発行された場合に、Pgpool-IIはキャッシュから結果を返します。 + Note that for following query: + + /*FORCE QUERY CACHE*/SELECT * FROM t1; + + usual cache validation due to an update to the table (in this case + t1) works. + --> + 次のクエリ + + /*FORCE QUERY CACHE*/SELECT * FROM t1; + + に対しては、テーブル(この場合はt1)の更新によるキャッシュの削除は機能することに注意してください。 + + + + クエリがFORCE QUERY CACHEコメントで始まっていなければ、以下のチェックが行われます。 + 以下の一つでも該当すれば、SELECTはキャッシュされません。 + + immutableでない関数を含むSELECT + 一時テーブル、unloggedテーブルを使ったSELECT + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を使っているSELECT + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEへのキャストを含むSELECT + SQLValueFunction (CURRENT_TIME, CURRENT_USERなど)を含むSELECT + 検索結果が memqcache_maxcache を越えるようなSELECT + SELECT FOR SHARE/UPDATE + /*NO QUERY CACHE*/コメント(大文字小文字は区別されません)で始まるSELECT + システムカタログを使用しているSELECT + TABLESAMPLEを使っているSELECT + 行セキュリティが設定されているテーブルを使っているSELECT + + ただし、VIEWと unloggedテーブルは、cache_safe_memqcache_table_list に記載することでキャッシュされます。 + + + + + + 以下のコマンドはクエリキャッシュとデータベース内容の整合性を失わせる可能性があるので、実行されるとクエリキャッシュをすべて削除します。 + + ALTER DATABASE + ALTER ROLE or USER (WITH CONNECTION LIMITとWITH [ENCRYPTED] PASSWORDを除く) + ALTER TABLE + REVOKE + + また、SET ROLE、SET SESSION AUTHORIZATIONが実行されると、そのセッション内ではクエリキャッシュは使用されず、また新たにクエリキャッシュが作成されることもありません。 + Pgpool-IIはセッションユーザが異なるとクエリキャッシュを違うものと見なしますが、一方でPostgreSQLのアクセス権管理はカレントユーザ(current user)を基準に行っており、これらのコマンドはクエリキャッシュとPostgreSQLのアクセス権管理の間の整合性を損なう可能性があるからです。 + ただし、更新クエリによるクエリキャッシュの削除はこれらのコマンドが使われていない場合と同様に行われます。 + + + + + + 関数が同じ名前で複数登録されていて、その中にTIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数が含まれている場合、実際にSQL文の中で使われている関数がTIMESTAMP WITH TIMEZONEを返さないものであっても、Pgpool-IIは、キャッシュできないと判断します。 + その場合は、その関数のラッパー関数を作成し、TIMESTAMP WITHOUT TIMEZONEあるいはTIME WITHOUT TIMEZONEを返すようにするか、/*FORCE QUERY CACHE*/コメントを使用することによってクエリキャッシュが使えます。 + + + + + + インメモリクエリキャッシュは、ユーザ名、データベース名、SELECT文(拡張問い合わせの場合は更にバインドパラメータ)と 検索結果をペアで記録します。 + ユーザ名、データベース名、バインドパラメータが同じSELECT文が発行された場合に、Pgpool-IIはキャッシュから結果を返します。 SQLの解析もPostgreSQLへのアクセスも行われないため、インメモリキャッシュからの結果の提供は非常に高速です。 - - + + + Enabling in memory query cache + --> インメモリクエリキャッシュを有効にする - - memory_cache_enabled (boolean) - - - memory_cache_enabled 設定パラメータ - - - - - - onにするとメモリキャッシュが有効になります。 - デフォルトはoffです。 - - - - このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - - - + memory_cache_enabled 設定パラメータ + + + + + + onにするとメモリキャッシュが有効になります。 + デフォルトはoffです。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + が有効の場合、クエリキャッシュはリレーションキャッシュでも使用されます。 + その上、たとえパラメータがオフに設定されていたとしても、クエリキャッシュは使用されます。 + リレーションキャッシュの詳細はを参照してください。 + + + + + + + + + + キャッシュストレージの選択 - - memqcache_method (string) - - - memqcache_method 設定パラメータ - - - - - - キャッシュに用いるストレージのタイプを指定します。 - このパラメータで有効な全ての値のリストを以下の表に示します。 - - - - Memcache method options - - - - - - 説明 - - - - - - 'shmem' - - 共有メモリを使用 - - - - 'memcached' - - memcachedを使用 - - - - -
- - - - デフォルトは'shmem'です。 - - - - - このパラメータはサーバ起動時にのみ設定可能です。 - -
-
+ + memqcache_method (enum) + + + memqcache_method 設定パラメータ + + + + + + キャッシュに用いるストレージのタイプを指定します。 + このパラメータで有効な全ての値のリストを以下の表に示します。 + + + + Memqcache method options + + + + + + 説明 + + + + + + shmem + + 共有メモリを使用 + + + + memcached + + memcachedを使用 + + + + +
+ + + + 一般的にshmemはネットワークアクセスが不要なため、memcachedより高速です。 + しかし、shmemでは、memqcache_total_sizeはシステムで決まっている共有メモリサイズの合計に制限されます。 + 最近のLinuxシステムでは、そのサイズは十分大きいのですが、他のシステムでは制限値が小さいかもしれません。 + この場合は共有メモリサイズの最大値のシステム設定を変更する必要があるでしょう。 + PostgreSQLのドキュメントに共有メモリに関する良い記述があります。 + + + + どちらのmemqcache_methodを使ったらよいかわからない場合は、まずshmemを試してください。 + + + + + デフォルトはshmemです。 + + + + + このパラメータはサーバ起動時にのみ設定可能です。 + +
+
-
+ - + + Common configurations + --> 共通設定 - - 以下はshmemmemcachedの両タイプのクエリキャッシュで有効なパラメータです。 + + 以下はshmemmemcachedの両タイプのクエリキャッシュで有効なパラメータです。 - - memqcache_expire (integer) - - - memqcache_expire 設定パラメータ - - - - - - クエリキャッシュの寿命を秒単位で設定します。 - デフォルト0で、キャッシュの期限はなくなり、関連テーブルが更新されるまではキャッシュが有効になります。 - - - - このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - memqcache_expireは互いに独立です。 - - + + memqcache_expire (integer) + + + memqcache_expire 設定パラメータ + + + + + + クエリキャッシュの寿命を秒単位で設定します。 + デフォルト0で、キャッシュの期限はなくなり、関連テーブルが更新されるまではキャッシュが有効になります。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + - - + + + + memqcache_expireは互いに独立です。 + + - - memqcache_auto_cache_invalidation (boolean) - + + + + + memqcache_auto_cache_invalidation (boolean) + + memqcache_auto_cache_invalidation configuration parameter + --> memqcache_auto_cache_invalidation 設定パラメータ - - - - - + + + + + onに設定した場合、更新されたテーブルに関連するキャッシュを自動で削除します。 offならばキャッシュは削除されません。 - - + + + Default is on. + --> デフォルト値はonです。 - - + + - - memqcache_auto_cache_invalidationは互いに独立です。 + + memqcache_auto_cache_invalidationは互いに独立です。 - - + + + This parameter can be changed by reloading the Pgpool-II configurations. + --> このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - +
+ + - - memqcache_maxcache (integer) - + + memqcache_maxcache (integer) + + memqcache_maxcache configuration parameter + --> memqcache_maxcache 設定パラメータ - - - - - + + + + + キャッシュされるSELECTクエリ結果の最大サイズをバイト数で指定します。 この値より大きいサイズのデータの結果はPgpool-IIにキャッシュされません。 サイズの制約によりデータのキャッシュができなかった場合、以下のメッセージが表示されます。 - LOG: pid 13756: pool_add_temp_query_cache: data size exceeds memqcache_maxcache. current:4095 requested:111 memq_maxcache:4096 + LOG: pid 13756: pool_add_temp_query_cache: data size exceeds memqcache_maxcache. current:4095 requested:111 memq_maxcache:4096 - - + + - - 共有メモリによるクエリキャッシュ('shmem')の場合は、memqcache_maxcacheを超えないように、'memcached'を使用する場合は、slabのサイズ(デフォルトで1MB)を超えないようにしてください。 + + 共有メモリによるクエリキャッシュ('shmem')の場合は、memqcache_maxcacheを超えないように、'memcached'を使用する場合は、slabのサイズ(デフォルトで1MB)を超えないようにしてください。 - - + + - このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - white_memqcache_table_list (string) - - - white_memqcache_table_list 設定パラメータ - - - - - - + This parameter can only be set at server start. + --> + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + cache_safe_memqcache_table_list (string) + + + cache_safe_memqcache_table_list 設定パラメータ + + + + + + SELECT結果がPgpool-IIにキャッシュされるべきテーブル名のリストをカンマ区切りで指定します。 このパラメータは、VIEWとunloggedテーブルにのみ適用されます。 - 通常のテーブルは、に記載されていない限りキャッシュされます。 - + 通常のテーブルは、に記載されていない限りキャッシュされます。 + - + + You can use regular expression into the list to match table name + (to which ^ and $ are automatically added). + --> テーブル名のマッチングには正規表現も利用できます (指定した各表現に ^ と $ をつけた形で使われます)。 - + - + - - スキーマ名を付けないテーブル名とスキーマ名を付けた形の両方をクエリの中で使う場合は、両方共リストに登録してください。 - - #For example: - #If the queries sometime use "table1" and other times "public.table1" - #to refer the table1 then the white_memqcache_table_list - #would be configured as follows. - - white_memqcache_table_list = "table1,public.table1" - - + + スキーマ名を付けないテーブル名とスキーマ名を付けた形の両方をクエリの中で使う場合は、両方共リストに登録してください。 + + #For example: + #If the queries sometime use "table1" and other times "public.table1" + #to refer the table1 then the cache_safe_memqcache_table_list + #would be configured as follows. + + cache_safe_memqcache_table_list = "table1,public.table1" + + - - + + - - black_memqcache_table_listより優先されます。 + + cache_unsafe_memqcache_table_listより優先されます。 - - + + + This parameter can be changed by reloading the Pgpool-II configurations. + --> このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - black_memqcache_table_list (string) - - - black_memqcache_table_list 設定パラメータ - - - - - + + + + + + cache_unsafe_memqcache_table_list (string) + + + cache_unsafe_memqcache_table_list 設定パラメータ + + + + + SELECT結果がPgpool-IIにキャッシュされるべきでないテーブル名のリストをカンマ区切りで指定します。 - + - + + You can use regular expression into the list to match table name + (to which ^ and $ are automatically added), + --> テーブル名のマッチングには正規表現も利用できます (指定した各表現に ^ と $ をつけた形で使われます)。 - + - + - - スキーマ名を付けないテーブル名とスキーマ名を付けた形の両方をクエリの中で使う場合は、両方共リストに登録してください。 - - #For example: - #If the queries sometime use "table1" and other times "public.table1" - #to refer the table1 then the black_memqcache_table_list - #would be configured as follows. - - black_function_list = "table1,public.table1" - - + + スキーマ名を付けないテーブル名とスキーマ名を付けた形の両方をクエリの中で使う場合は、両方共リストに登録してください。 + + #For example: + #If the queries sometime use "table1" and other times "public.table1" + #to refer the table1 then the cache_unsafe_memqcache_table_list + #would be configured as follows. + + cache_unsafe_memqcache_table_list = "table1,public.table1" + + - - + + + This parameter can be changed by reloading the Pgpool-II configurations. + --> このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + + - - memqcache_oiddir (string) - + + memqcache_oiddir (string) + + memqcache_oiddir configuration parameter + --> memqcache_oiddir 設定パラメータ - - - - - + + + + + SELECTクエリが使用するテーブルにOIDを格納するディレクトリへのフルパスで指定します。 - - + + + memqcache_oiddir directory contains the sub directories + for the databases. The directory name is the OID of the database. In addition, each + database directory contains the files for each table used by SELECT statement. + Again the name of the file is the OID of the table. + These files contains the pointers to query cache which are used as key for + deleting the caches. + --> memqcache_oiddirには、各データベースのためのディレクトリが格納されます。 そのディレクトリ名はデータベースのOIDです。 更に、各データベースディレクトリの下には各テーブルのためのファイルが格納されます。 そのファイル名は同じくテーブルのOIDです。 これらのファイルの中にはクエリキャッシュへのポインタが格納されており、 キャッシュを削除する際のキーとして使われます。 - - + + - - Pgpool-IIの通常の再起動ではmemqcache_oiddirの中身はクリアされません。 + + Pgpool-IIの通常の再起動ではmemqcache_oiddirの中身はクリアされません。 - - + + - このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + This parameter can be changed by reloading the Pgpool-II configurations. + --> + このパラメータはサーバ起動時にのみ設定可能です。 + + + - - + + - + + Configurations to use shared memory + --> 共有メモリ使用時の設定 - - これらはキャッシュストレージとして共有メモリを使用した場合に使われるパラメーターです。 + + これらはキャッシュストレージとして共有メモリを使用した場合に使われるパラメーターです。 - - memqcache_total_size (integer) - - - memqcache_total_size 設定パラメータ - - - - - - 共有メモリのキャッシュサイズをバイト単位で指定します。 - - - - このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - memqcache_max_num_cache (integer) - - - memqcache_max_num_cache 設定パラメータ - - - - - - キャッシュエントリの数を指定します。 - この設定項目は、キャッシュの管理領域の大きさを決めるために使用します。 - - - - - 管理領域の大きさは、memqcache_max_num_cache * 48バイトで計算できます。 - 少なすぎるとキャッシュを登録することができずにエラーになります。 - 逆に多すぎると単に空間の無駄になります。 - - - - - このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - memqcache_cache_block_size (integer) - - - memqcache_cache_block_size 設定パラメータ - - - - - - キャッシュのブロックサイズを指定します。 - Pgpool-IImemqcache_cache_block_sizeのブロックで管理されたキャッシュメモリを利用します。 - SELECT結果はこのブロックに詰め込まれ、1つのブロックに収まらなければなりません。 - 従って、memqcache_cache_block_sizeを検索結果が超えると、キャッシュされません。 - - - - - memqcache_cache_block_sizeは、512以上の値でなければなりません。 - - - - - このパラメータはサーバ起動時にのみ設定可能です。 - - - + + memqcache_total_size (integer) + + + memqcache_total_size 設定パラメータ + + + + + + 共有メモリのキャッシュサイズを指定します。 + デフォルトは64MBです。 + + + キャッシュはで指定される固定長のブロックに格納されます。 + このブロックの数は、 / で計算できます。 + ブロック数が整数になるように小数点以下が切り捨てられます。 + ブロック数が0になると、エラーとなります。 + つまり、memqcache_total_sizeは、よりも大きくなければなりません。 + + + 各キャッシュデータは64バイトの管理データと、クエリ結果のデータに分けて一つのブロックに格納されます。 + クエリ結果とその管理データは複数のブロックにまたがって格納されることはないので、クエリ結果のデータ長+64バイトがより大きいと、ブロックに格納できず、キャッシュされません。 + + + あるブロックがキャッシュで一杯になると、次のブロックが利用されます。 + すべてのブロックが一杯になると、最も古いブロックのキャッシュが消去されて再利用されます + (新しいキャッシュデータは空きがある最初のブロックに格納されるので、最も古いブロックが最も古いキャッシュデータを保持しているとは限らないことに注意してください)。 + したがって、memqcache_total_sizeが小さくてもエラーになりませんが、キャッシュヒット率が下がり、性能を低下させます。 + キャッシュヒット率はcache_hit_ratioで確認できます。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + memqcache_max_num_cache (integer) + + + memqcache_max_num_cache 設定パラメータ + + + + + キャッシュエントリの数を指定します。 + デフォルトは1,000,000です。 + + + この設定項目は、登録できるキャッシュの数の上限を決めます。 + memqcache_max_num_cacheを超えてキャッシュを登録しようと、キャッシュ登録済みのブロックのキャッシュが消去されて再利用されます。 + したがって、memqcache_max_num_cacheが小さくてもエラーになりませんが、キャッシュヒット率が下がり、性能を低下させます。 + キャッシュヒット率はcache_hit_ratioで確認できます。 + + + + キャッシュはアクセスを高速にするために共有メモリ上のハッシュテーブルで管理されており、その大きさは、memqcache_max_num_cache * 64バイトで計算できます。 + ハッシュテーブルのエントリ数はnum_hash_entriesで確認できます。 + num_hash_entriesは通常memqcache_max_num_cacheと一致しますが、memqcache_max_num_cacheが2のべき乗になっていない場合は、memqcache_max_num_cacheより大きい2のべき乗に丸められるので、一致しないこともあります。 + 使用済みのエントリ数はused_hash_entriesで確認できます。 + + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + memqcache_cache_block_size (integer) + + + memqcache_cache_block_size 設定パラメータ + + + + + + キャッシュのブロックサイズを指定します。 + デフォルトは1MBです。 + + + + Pgpool-IImemqcache_cache_block_sizeのブロックで管理されたキャッシュメモリを利用します。 + 各キャッシュデータは64バイトの管理データと、クエリ結果のデータに分けて一つのブロックに格納されます。 + クエリ結果とその管理データは複数のブロックにまたがって格納されることはないので、クエリ結果のデータ長+64バイトがより大きいと、ブロックに格納できず、キャッシュされません。 + + + + + memqcache_cache_block_sizeは、512バイト以上の値でなければなりません。 + + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + - + - + + Configurations to use memcached + --> memcached使用時の設定 - - これらはキャッシュストレージとしてmemcachedを使用した場合に使われるパラメーターです。 + + これらはキャッシュストレージとしてmemcachedを使用した場合に使われるパラメーターです。 - - memqcache_memcached_host (string) - - - memqcache_memcached_host 設定パラメータ - - - - - - memcachedが動いているホスト名またはIPアドレスを指定します。 - Pgpool-IIと同じマシンでmemcachedを動かす場合は、'localhost'が使えます。 - - - - このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - memqcache_memcached_port (integer) - - - memqcache_memcached_port 設定パラメータ - - - - - - memcachedのポート番号を指定します。 - デフォルトは 11211 です。 - - - - - このパラメータはサーバ起動時にのみ設定可能です。 - - - + + memqcache_memcached_host (string) + + + memqcache_memcached_host 設定パラメータ + + + + + + memcachedが動いているホスト名またはIPアドレスを指定します。 + Pgpool-IIと同じマシンでmemcachedを動かす場合は、'localhost'が使えます。 + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + memqcache_memcached_port (integer) + + + memqcache_memcached_port 設定パラメータ + + + + + + memcachedのポート番号を指定します。 + デフォルトは 11211 です。 + + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + - +
diff --git a/doc.ja/src/sgml/misc-config.sgml b/doc.ja/src/sgml/misc-config.sgml index a101de2b2..3a0e2d37c 100644 --- a/doc.ja/src/sgml/misc-config.sgml +++ b/doc.ja/src/sgml/misc-config.sgml @@ -1,241 +1,391 @@ - - その他の設定パラメータ + + その他の設定パラメータ - + - - relcache_expire (integer) - - - relcache_expire 設定パラメータ - - - + + relcache_expire (integer) + + + relcache_expire 設定パラメータ + + + - - -リレーションキャッシュの寿命を秒単位で指定します。 -リレーションキャッシュは、Pgpool-IIがテーブルの構造を含む様々な情報を取得したり、テーブルのタイプ(たとえば、参照されているテーブルが一時テーブルかどうかなど)をチェックするために使うPostgreSQLのシステムカタログの問い合わせ結果を保存しておくものです。 -キャッシュはpgpoolの子プロセスのローカルメモリ空間に保管されています。 -もしALTER TABLEでテーブルが変更された場合などは、リレーションキャッシュと一致しなくなります。 -そのため、relcache_expireがキャッシュの寿命をコントロールしています。 -デフォルトは0で、キャッシュの期限が切れることはありません。 - - - - -このパラメータは、サーバ起動時にのみ設定できます。 - + + + リレーションキャッシュの寿命を秒単位で指定します。 + リレーションキャッシュは、Pgpool-IIがテーブルの構造を含む様々な情報を取得したり、テーブルのタイプ(たとえば、参照されているテーブルが一時テーブルかどうかなど)をチェックするために使うPostgreSQLのシステムカタログの問い合わせ結果を保存しておくものです。 + キャッシュはpgpoolの子プロセスのローカルメモリ空間に保管されています。 + が有効な場合、子プロセス間で共有するために共有メモリにも保管されます。 + もしALTER TABLEでテーブルが変更された場合などは、リレーションキャッシュと一致しなくなります。 + そのため、relcache_expireがキャッシュの寿命をコントロールしています。 + デフォルトは0で、キャッシュの期限が切れることはありません。 + - - + + + このパラメータは、サーバ起動時にのみ設定できます。 + - - relcache_size (integer) - - - relcache_size 設定パラメータ - - - + + - - -リレーションキャッシュのエントリ数を指定します。 -デフォルトは256です。 - - - - -もし以下のようなメッセージがPgpool-IIログに頻繁に出る場合は、パフォーマンス向上のためrelcache_sizeを大きくしてください。 - -"pool_search_relcache: cache replacement happened" - - - - - -このパラメータは、サーバ起動時にのみ設定できます。 - + + relcache_size (integer) + + + relcache_size 設定パラメータ + + + - - + + + リレーションキャッシュのエントリ数を指定します。 + デフォルトは256です。 + リレーションキャッシュは、一つのテーブルあたり最大10個程度のエントリが作成されます。 + そのため、必要なリレーションキャッシュのサイズは、使用するテーブル数 * 10 で見積れます。 + + + + + もし以下のようなメッセージがPgpool-IIログに頻繁に出る場合は、パフォーマンス向上のためrelcache_sizeを大きくしてください。 + + "pool_search_relcache: cache replacement occurred" + + + + + + このパラメータは、サーバ起動時にのみ設定できます。 + - - check_temp_table (boolean) - - - check_temp_table 設定パラメータ - - - + + - - -onに設定されたとき、SELECTに含まれるテーブルが一時テーブルかどうかのチェックを行います。 -一時テーブルをチェックするためPgpool-IIはプライマリ/マスターPostgreSQLバックエンドのシステムカタログに問い合わせ、プライマリ/マスタサーバの負荷を上げます。 -もしシステムが決して一時テーブルを使用しないことが確かならば、安全にcheck_tmp_tableをoffにすることができます。 -デフォルトはonです。 - + + enable_shared_relcache (boolean) + + + enable_shared_relcache 設定パラメータ + + + + + onにするとインメモリクエリキャッシュ(参照)を利用して子プロセス間でリレーションキャッシュを共有します。 + デフォルトはonです。 + それぞれの子プロセスはPostgreSQLのシステムカタログを参照するためにクエリを実行します。 + この機能を有効にすると、他のプロセスはクエリキャッシュからカタログを参照した結果を得ることができるので、クエリの実行頻度が減ることが期待できます。 + システムカタログが変更されてもキャッシュは削除されません。 + ですから時間によるキャッシュの削除をを使って行うことを強くお勧めします。 + + + 本パラメータは、がoffの場合も有効です。 + この場合、一部のクエリキャッシュのパラメータ(、および各キャッシュストレージ用のパラメータ)も有効になります。 + + + このパラメータがonなら、Pgpool-IIはローカルのリレーションキャッシュをまず検索します。 + 該当するキャッシュエントリが見つからない場合は、次に共有クエリキャッシュを検索します。 + もしクエリキャッシュに該当エントリが見つかったら、ローカルキャッシュにコピーします。 + 見つからなかった場合には、PostgreSQLにクエリを発行して問い合わせを実行し、結果をクエリキャッシュに登録するとともに、ローカルキャッシュにも登録します。 + + + + このパラメータはサーバ起動時にのみ設定可能です + + + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - + + relcache_query_target (enum) + + relcache_query_target設定パラメータ + + + + + リレーションキャッシュを作成するためのクエリを送る先のノードを指定します。 + primaryにすると、クエリはメイン(プライマリ)に送られます。 + これがデフォルトで、最新のデータを入手できるため、ほとんどのユーザに推奨する設定です。 + もしメイン(プライマリ)の負荷を下げたい場合は、このパラメータをload_balance_nodeに設定できます。 + これにより、クエリは負荷分散ノードに送られます。 + これは特に、大陸AにPgpool-IIとプライマリサーバがあり、一方大陸BにPgpool-IIとスタンバイサーバがあるような構成で有効です。 + Bのユーザは地理的にスタンバイサーバが近いため、スタンバイからデータを読みたいと思うでしょう。 + その場合は、backend_weight0 (これはプライマリの設定です)を0に、backend_weight1(これはスタンバイの設定です)を1にし、relcache_query_targetをload_balance_nodeにします。 + + + しかし、スタンバイにクエリを送る場合、レプリケーションの遅延により、最近作られたテーブルや行はスタンバイサーバにはまだないかもしれないことに注意してください。 + ですから、更新頻度の高いシステムではこの設定はおすすめできません。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - - + + check_temp_table (enum) + + + check_temp_table 設定パラメータ + + + - - check_unlogged_table (boolean) - - - check_unlogged_table 設定パラメータ - - - + + catalogあるいはtraceに設定されたとき、SELECTに含まれるテーブルが一時テーブルかどうかのチェックを行います。 + catalogに設定すると一時テーブルをチェックするためPgpool-IIはプライマリ/メインPostgreSQLバックエンドのシステムカタログに問い合わせ、プライマリ/マスタサーバの負荷を上げます。 + + + traceに設定されていると、一時テーブルの情報を入手するためにPgpool-IIは一時テーブルの作成と削除を追跡します。 + ですからシステムカタログへアクセする必要がありません。 + しかし、一時テーブルの生成がPgpool-IIから見えない場合(たとえば関数やトリガの中で行われる場合)、Pgpool-IIは一時テーブルの生成を認識できません。 + + + もしシステムが決して一時テーブルを使用しないことが確かならば、安全にcheck_tmp_tablenoneにすることができます。 + + + + 4.0以前のバージョンとの互換性のために、catalogと同じ意味のonnoneと同じ意味のoffも受け付けますが、将来のバージョンではこれらは削除されるかもしれません。 + + + + デフォルトはcatalogです。 + - - -onに設定されたとき、SELECTに含まれるテーブルがunloggedテーブルかどうかのチェックを行います。 -unloggedテーブルをチェックするためPgpool-IIはプライマリ/マスターPostgreSQLバックエンドのシステムカタログに問い合わせ、プライマリ/マスタサーバの負荷を上げます。 -もしシステムが決してunloggedテーブルを使用しないことが確かならば(たとえば、9.0 以前のバージョンのPostgreSQLを使っている)、安全にcheck_unlogged_tableをoffにすることができます。 -デフォルトはonです。 - + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - + + - - + + check_unlogged_table (boolean) + + + check_unlogged_table 設定パラメータ + + + - - pid_file_name (string) - - - pid_file_name 設定パラメータ - - - + + + onに設定されたとき、SELECTに含まれるテーブルがunloggedテーブルかどうかのチェックを行います。 + unloggedテーブルをチェックするためPgpool-IIはプライマリ/メインPostgreSQLバックエンドのシステムカタログに問い合わせ、プライマリ/マスタサーバの負荷を上げます。 + もしシステムが決してunloggedテーブルを使用しないことが確かならば(たとえば、9.0 以前のバージョンのPostgreSQLを使っている)、安全にcheck_unlogged_tableをoffにすることができます。 + デフォルトはonです。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + + + + + pid_file_name (string) + + + pid_file_name 設定パラメータ + + + + + + + Pgpool-IIのプロセスIDを格納するファイルのフルパスを指定します。 + デフォルトは'/var/run/pgpool/pgpool.pid'です。 + + + + + このパラメータは、サーバ起動時にのみ設定できます。 + - + + + + + work_dir (string) + + + work_dir 設定パラメータ + + + + + + + pgpool_statusファイルを格納するディレクトリのフルパスを指定します。 + デフォルトは'/tmp'です。 + + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + + health_check_test (boolean) + -Pgpool-IIのプロセスIDを格納するファイルのフルパスを指定します。 -デフォルトは'/var/run/pgpool/pgpool.pid'です。 - - - + health_check_test設定パラメータr + + + + + -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - - logdir (string) - + 実運用のシステムでこのパラメータをonにしないでください。 + この機能はテスト目的専用です。 + + + - logdir 設定パラメータ - - - - - + onにすると、ヘルスチェックのテスト機能が有効になります。 + この場合、ヘルスチェックプロセスはの下にあるbackend_down_requestを参照します。 + このファイルは、複数の行から構成され、各行は各々のバックエンドに対応します。 + 各行はバックエンドID(ゼロから始まる十進数でなければなりません)で始まり、続いてタブ、最後に"down"で終わります。 + そのバックエンドはダウン状態と見なされ、Pgpool-IIはフェイルオーバを開始します。 + フェイルオーバが完了すると、"down"はヘルスチェックプロセスによって"already_down"に書き換えられ、何度もフェイルオーバが起きることを防ぎます。 + + -pool_statusファイルを格納するディレクトリのフルパスを指定します。 -デフォルトは"/tmp"です。 - - - + この機能は特にのテストに有用です。 + 今3つのwatchdogノードがあるとします。 + 各々のwatchdogはバックエンド0の健全性を検証します。 + "0 down"とwatchdog 0の配下のファイルのみに書き込むと、他のバックエンドはバックエンド0が健全ではないことに同意しないので、フェイルオーバは起きません。 + このような、部分的なネットワーク障害がこの機能でシミュレーションできます。 + + -このパラメータは、サーバ起動時にのみ設定できます。 - + デフォルトはoffです。 + + + + + このパラメータは、サーバ起動時にのみ設定できます。 + - - + + - + diff --git a/doc.ja/src/sgml/notation.sgml b/doc.ja/src/sgml/notation.sgml index 6ee01e16e..68d28e1b5 100644 --- a/doc.ja/src/sgml/notation.sgml +++ b/doc.ja/src/sgml/notation.sgml @@ -1,13 +1,13 @@ - + --> 規約 - -以下の規約はコマンドの概要に対して適用されます。 -大括弧([および])はオプションである部分を示します。 -(Tcl コマンドの概要では疑問符(?)をTclのしきたりとして代わりに使います。) -中括弧({および})そして縦線(|)はいずれか1つを選択しなければならないことを意味します。 -点々(...)は前にある要素が繰り返されるという意味です。 + --> + 以下の規約はコマンドの概要に対して適用されます。 + 大括弧([および])はオプションである部分を示します。 + (Tcl コマンドの概要では疑問符(?)をTclのしきたりとして代わりに使います。) + 中括弧({および})そして縦線(|)はいずれか1つを選択しなければならないことを意味します。 + 点々(...)は前にある要素が繰り返されるという意味です。 - -明確性を強調する場面では、SQLコマンドの前には=>を付け、シェルコマンドの前には$を付けます。 -とは言っても通常プロンプトは示しません。 + --> + 明確性を強調する場面では、SQLコマンドの前には=>を付け、シェルコマンドの前には$を付けます。 + とは言っても通常プロンプトは示しません。 - -一般的に管理者とは、サーバのインストールと運営の責にあたる人のことです。 -ユーザとは、Pgpool-IIシステムの一部でも活用したり、もしくはこれから使用する誰もがその対象です。 -これらの用語は厳密に解釈されるものではありません。 -本書はシステム管理の手順について特定の固定観念を想定していません。 + --> + 一般的に管理者とは、サーバのインストールと運営の責にあたる人のことです。 + ユーザとは、Pgpool-IIシステムの一部でも活用したり、もしくはこれから使用する誰もがその対象です。 + これらの用語は厳密に解釈されるものではありません。 + 本書はシステム管理の手順について特定の固定観念を想定していません。 diff --git a/doc.ja/src/sgml/online-recovery.sgml b/doc.ja/src/sgml/online-recovery.sgml index e33881ad2..8b895dad0 100644 --- a/doc.ja/src/sgml/online-recovery.sgml +++ b/doc.ja/src/sgml/online-recovery.sgml @@ -1,622 +1,760 @@ - - オンラインリカバリ - + + オンラインリカバリ + + online recovery + + + オンラインリカバリ + + + + Pgpool-II はサービスを止めることなくデータベースノードを同期させ、ノードを復帰させることができます。 + この機能は「オンラインリカバリ」と呼ばれます。 + オンラインリカバリはコマンドで実行できます。 + + + + オンラインリカバリを実施するためには、リカバリ対象のノードはPgpool-IIから切り離された状態になっていなければなりません。 + このことは、そのノードが、で手動で切り離された状態にあるか、フェイルオーバの結果、Pgpool-IIにより自動的に切り離された状態にあるかのいずれかでなければならないことを意味します。 + + + + 新しいPostgreSQLサーバを動的に追加したい場合には、および関連パラメータを追加した後にpgpool.confを再読み込みします。 + これにより新しいサーバが切り離された状態のバックエンドノードとしてPgpool-IIに登録されるので、その後コマンドを実行しサーバを追加できます。 + + + - -Pgpool-II はサービスを止めることなくデータベースノードを同期させ、ノードを復帰させることができます。 -この機能は「オンラインリカバリ」と呼ばれます。 -オンラインリカバリはコマンドで実行できます。 + + オンラインリカバリ実行のためには、対象となるPostgreSQLサーバは稼働していてはいけません。 + 対象のPostgreSQLがすでに動作中であれば、オンラインリカバリを開始する前にシャットダウンしておいてください。 + + + + + + オンラインリカバリは2段階に分けて実施されます。 + 第1段階は「ファーストステージ」、第2段階は「セカンドステージ」と呼ばれます。 + あるいはの時のみセカンドステージが必要です。 + ストリーミングレプリケーションモードを含むその他のモードでは、セカンドステージは実施されず、用のスクリプトを用意する必要はありません。 + つまり、そのエントリを空文字にしておいても問題ありません。 + + + + ファーストステージでは、PostgreSQLpg_basebackupコマンドなどを利用してメイン(プライマリ)ノードのバックアップコピーからレプリカ(スタンバイ)ノードを作ります。 + ファーストステージ中に更新されたデータはPostgreSQLのトランザクションログに記録されます。 + + + セカンドステージでは、リカバリ対象のレプリカノードを起動します。 + この時にトランザクションログが再生され、このレプリカノードは完全にメインノードと同期します。 + + それぞれのステージ用にスクリプトを用意する必要があります。 + 完全なサンプルスクリプトが/etc/pgpool-II/recovery_1st_stage.sampleおよび/etc/pgpool-II/recovery_2nd_stage.sampleに用意されています。 + これらのスクリプトを使ったインストール例はにあります。 + + + + ファーストステージではデータの更新や読み取りができますが、セカンドステージではクライアントからの接続は許されていません。 + + + + オンラインリカバリではPgpool-IIは以下の手順を実施します。 + + + + + + CHECKPOINT. + + + + + + オンラインリカバリのファーストステージ。 + + + + + + 全てのクライアント接続が切断されるまで待機(あるいはのみ)。 + + + + + CHECKPOINT. + + + + + + オンラインリカバリのセカンドステージ(あるいはのみ)。 + + + + + + postmasterの起動(pgpool_remote_startの実施) + + + + pgpool_remote_startは、リカバリ対象のPostgreSQLを起動するためのスクリプトです。 + pgpool_remote_startは次の2つの引数を受けとります。 + + + + + リカバリされるバックエンドノードのホスト名 + + + + + + リカバリされるバックエンドノードのデータベースクラスタへのパス + + + + + スクリプトの例はにあります。 + + + + スクリプトのパスおよびファイル名は固定されており、メイン(プライマリ)ノード上で$PGDATA/pgpool_remote_startが実行されます。 + + + + + + + + + ノードの復帰 + + + + + - -オンラインリカバリを実施するためには、リカバリ対象のノードはPgpool-IIから切り離された状態になっていなければなりません。 -このことは、そのノードが、で手動で切り離された状態にあるか、フェイルオーバの結果、Pgpool-IIにより自動的に切り離された状態にあるかのいずれかでなければならないことを意味します。 - - - -新しいPostgreSQLサーバを動的に追加したい場合には、および関連パラメータを追加した後にpgpool.confを再読み込みします。 -これにより新しいサーバが切り離された状態のバックエンドノードとしてPgpool-IIに登録されます。 + + あるいはでのオンラインリカバリには制限事項があります。 + Watchdogを有効にせずにPgpool-IIを複数のホストにインストールしている場合、Pgpool-IIはオンラインリカバリの2ndステージの間全てのクライアントを止める必要があるため、オンラインリカバリは正しく動作しません。 + 複数のPgpool-IIホストがある場合、そのうちの1台のみがオンラインリカバコマンドを受け取り、クライアントからの接続をブロックします。 - + recovery_user 設定パラメータ + + + - Make sure that autovacuum is stopped on the - master node (the first node which is up and running) before starting the - online recovery. Autovacuum can change the contents of the database which - can cause the inconsistency after the online recovery. -オンラインリカバリを実行する前に、マスタノード(稼働中のノードのうち、一番番号が若いノード)上でのautovacuumを停止してください。 -オンラインリカバリ中にautovacuumが動作すると、データベースの内容が変化する可能性があるため、ノード間の同期がきちんと取れなくなる可能性があります。 + + オンラインリカバリを行うためのPostgreSQLユーザ名です。 + デフォルトは''(空文字)です。 + オンラインリカバリで実行されるpgpool_recovery関数はPostgreSQLのスーパーユーザ権限が必要なため、recovery_userにスーパーユーザを指定しなければなりません。 - This applies only if you're recovering with a simple copy mechanism, - such as the rsync and doesn't apply when using - the PostgreSQL's PITR mechanism. -この制限は、rsyncなどの単純なコピー方法を使っている場合にのみ適用されます。 -PostgreSQLのPITRを使っている場合は適用されません。 + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + recovery_password (string) + + + recovery_password 設定パラメータ + + + + + + オンラインリカバリを行うための PostgreSQL ユーザパスワードです。 + + + + recovery_passwordが空のままの場合、 Pgpool-IIは空のパスワードを使用する前にまずファイルからのパスワードを取得できるか試みます。 + + + + recovery_passwordにAES256-CBCで暗号化されたパスワードも指定することができます。 + AESで暗号化されたパスワードを指定するためには、パスワード文字列は暗号化(aes-256-cbcアルゴリズムを使用)およびbase64でエンコードした後、AESを接頭辞として付けなければいけません。 - ---> - - -オンラインリカバリ実行のためには、対象となるPostgreSQLサーバは稼働していてはいけません。 -対象のPostgreSQLがすでに動作中であれば、オンラインリカバリを開始する前にシャットダウンしておいてください。 + + 暗号化されていないクリアテキストパスワードを指定するためには、TEXTをパスワード文字列の前に付けます。 + 例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定すべきです。 + 有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 + + + + 正しくフォーマットされたAES暗号化パスワードをコマンドを使用して作成することもできます。 + + + + Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 + Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 + + - - - + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - Online recovery is performed in two phases. Connections from cliens are - not allowd in second phase of online recovery while the data can be - updated or retrieved during the first phase. - Pgpool-II performs the follows steps in online recovery: ---> -オンラインリカバリは2段階に分けて実施されます。 -第1段階は「ファーストステージ」、第2段階は「セカンドステージ」と呼ばれます。 -それぞれのステージ用にスクリプトを用意する必要があります。 -の時のみセカンドステージが必要です。 -ストリーミングレプリケーションモードを含むその他のモードでは、セカンドステージは実施されず、用のスクリプトを用意する必要はありません。 -つまり、そのエントリを空文字にしておいても問題ありません。 - - - -ファーストステージではデータの更新や読み取りができますが、セカンドステージではクライアントからの接続は許されていません。 - - - -オンラインリカバリではPgpool-IIは以下の手順を実施します。 - - + + recovery_database (string) + + + recovery_database 設定パラメータ + + + + + + オンラインリカバリを行うためのPostgreSQLデータベースです。 + デフォルトは'postgres'です。 + 空文字('')が指定された場合、Pgpool-IIは + 「postgres」データベースの使用を試みます。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + オンラインリカバリを実行するには、パラメータで指定されたデータベースに、pgpool_recovery、pgpool_remote_start、および pgpool_switch_xlog 関数を作成しておく必要があります。 + これらの関数をデフォルトのデータベースpostgresに作成するには、以下のコマンドを実行してください。 + (デフォルト値以外が設定されている場合は、postgresに設定された値に置き換えてください) + +$ psql postgres -c "CREATE EXTENSION pgpool_recovery" + + + + + - + + recovery_1st_stage_command (string) + + + recovery_1st_stage_command 設定パラメータ + + + + + + オンラインリカバリのファーストステージでメイン(プライマリ)ノードで実行されるコマンドを指定します。 + コマンドファイルはセキュリティ上の観点からデータベースクラスタ内に配置される必要があります。 + 例えば、recovery_1st_stage_command = 'sync-command'となっている場合、Pgpool-IIはコマンドスクリプトを$PGDATAディレクトリの中で探し、$PGDATA/sync-commandを起動しようとします。 + + + + recovery_1st_stage_commandは次の7つの引数を受けとります。 + + + + - CHECKPOINT. + + メイン(プライマリ)ノードのデータベースクラスタへのパス - - + + - -オンラインリカバリのファーストステージ。 + + リカバリされるバックエンドノードのホスト名 - - + + - -全てのクライアント接続が切断されるまで待機(のみ)。 + + リカバリされるノードのデータベースクラスタへのパス - - + + - CHECKPOINT(のみ)。 + + メイン(プライマリ)ノードのポート番号(Pgpool-II 3.4以降) - - + + - -オンラインリカバリのセカンドステージ(のみ)。 + + リカバリされるノードの番号(Pgpool-II 4.0以降) - - + + - -postmasterの起動(pgpool_remote_startの実施) + + リカバリされるノードのポート番号(Pgpool-II 4.1以降) - - + + - -ノードの復帰 + + main (primary)ノードのホスト名(Pgpool-II 4.3以降) - - - - - - -でのオンラインリカバリには制限事項があります。 -Pgpool-IIが複数のホストにインストールされている場合、Pgpool-IIはオンラインリカバリの2ndステージの間全てのクライアントを止める必要があるため、オンラインリカバリは正しく動作しません。 -複数のPgpool-IIホストがある場合、そのうちの1台のみがオンラインリカバコマンドを受け取り、クライアントからの接続をブロックします。 - - - - - - recovery_user (string) - - - recovery_user 設定パラメータ - - - - -オンラインリカバリを行うためのPostgreSQLユーザ名です。 + + 以前はmain (primary)ノードのホスト名はhostnameコマンドを使って取得されていました。 + スクリプトがmain (primary)ノードで実行されるため、これはほとんどの場合問題になりません。 + しかし、ある種のシステムでは、hostnameコマンドを使って取得したホスト名とbackend_hostname設定パラメータが一致しません。 + これはで問題になります。 + なぜなら、recovery_1st_stage_commandが生成するprimary_conninfohostパラメータを使ってプライマリとスタンバイの接続性を確認するからです。 + ですから、recovery_1st_stage_commandにおいては、hostnameコマンドではなく、このパラメータを使ってプライマリノードのホスト名を得るようにすることを強くおすすめします。 - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - recovery_password (string) - - - recovery_password 設定パラメータ - - - - - -オンラインリカバリを行うための PostgreSQL ユーザパスワードです。 - - - -recovery_passwordが空白のままの場合、 Pgpool-IIは空のパスワードを使用する前にまずファイルからのパスワードを取得できるか試みます。 - - - -recovery_passwordにAES256-CBCで暗号化されたパスワードも指定することができます。 -AESで暗号化されたパスワードを指定するためには、パスワード文字列は暗号化(aes-256-cbcアルゴリズムを使用)およびbase64でエンコードした後、AESを接頭辞として付けなければいけません。 - - - -暗号化されていないクリアテキストパスワードを指定するためには、TEXTをパスワード文字列の前に付けます。 -例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定すべきです。 -有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 - - - -正しくフォーマットされたAES暗号化パスワードをコマンドを使用して作成することもできます。 - - - -Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 -Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 - - - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - recovery_1st_stage_command (string) - - - recovery_1st_stage_command 設定パラメータ - - - - - -オンラインリカバリのファーストステージでマスタ(プライマリ)ノードで実行されるコマンドを指定します。 -コマンドファイルはセキュリティ上の観点からデータベースクラスタ内に配置される必要があります。 -例えば、recovery_1st_stage_command = 'sync-command'となっている場合、Pgpool-IIはコマンドスクリプトを$PGDATAディレクトリの中で探し、$PGDATA/sync-commandを起動しようとします。 - - - -recovery_1st_stage_commandは次の5つの引数を受けとります。 - - - - - - -マスター(プライマリ)ノードのデータベースクラスタへのパス - - - - - -リカバリされるバックエンドノードのホスト名 - - - - - -リカバリされるノードのデータベースクラスタへのパス - - - - - -マスター(プライマリ)ノードのポート番号(Pgpool-II 3.4以降) - - - - - -リカバリされるノードの番号(Pgpool-II 4.0以降) - - - - - - - -recovery_1st_stage_commandの実行中はPgpool-IIは接続やクエリを受け付けており、データの参照や更新を行うことができます。 - - - - - - -recovery_1st_stage_commandは、PostgreSQLから見ると、一つのSQLとして実行されます。 -そのため、PostgreSQLのstatement_timeoutrecovery_1st_stage_commandの完了にかかる時間よりも短く設定されていると、recovery_1st_stagecommandコマンドの実行が途中でキャンセルされます。 - - - -典型的なエラーは以下のようなものです。 - -rsync used in the command is killed by signal 2 for example. - - - + + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + + + recovery_1st_stage_commandの実行中はPgpool-IIは接続やクエリを受け付けており、データの参照や更新を行うことができます。 + + - - recovery_2nd_stage_command (string) - - - recovery_2nd_stage_command 設定パラメータ - - - + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - - -オンラインリカバリのセカンドステージでマスタ(プライマリ)ノードで実行されるコマンドを指定します。 -コマンドファイルはセキュリティ上の観点からデータベースクラスタ内に配置される必要があります。 -例えば、recovery_2nd_stage_command = 'sync-command'となっている場合、Pgpool-IIはコマンドスクリプトを$PGDATAディレクトリの中で探し、$PGDATA/sync-commandを起動しようとします。 - - - -recovery_2nd_stage_commandは次の5つの引数を受けとります。 - + + recovery_2nd_stage_command (string) + + + recovery_2nd_stage_command 設定パラメータ + + + - - - - -マスター(プライマリ)ノードのデータベースクラスタへのパス - - - - - -リカバリされるバックエンドノードのホスト名 - - - - - -リカバリされるノードのデータベースクラスタへのパス - - - - - -マスター(プライマリ)ノードのポート番号(Pgpool-II 3.4以降) - - - - - -リカバリされるノードの番号(Pgpool-II 4.0以降) - - - + + + オンラインリカバリのセカンドステージでメインノードで実行されるコマンドを指定します。 + これはあるいは時のみ必要であるため、他のモードではコマンドファイルを用意する必要はありません。 + コマンドファイルはセキュリティ上の観点からデータベースクラスタ内に配置される必要があります。 + 例えば、recovery_2nd_stage_command = 'sync-command'となっている場合、Pgpool-IIはコマンドスクリプトを$PGDATAディレクトリの中で探し、$PGDATA/sync-commandを起動しようとします。 + + + + recovery_2nd_stage_commandは次の7つの引数を受けとります。 + - - - -recovery_2nd_stage_commandの実行中は、Pgpool-IIはクライアントからの接続およびクエリを受け付けません。 -また、コマンドを実行する前に既存のクライアントが接続を閉じるのを待ちます。 -そのため、長時間接続したままのクライアントがいる場合、recovery_2nd_stage_commandは実行されない可能性があります。 - - + + + + + メイン(プライマリ)ノードのデータベースクラスタへのパス + + + + + + リカバリされるバックエンドノードのホスト名 + + + + + + リカバリされるノードのデータベースクラスタへのパス + + + + + + メイン(プライマリ)ノードのポート番号(Pgpool-II 3.4以降) + + + + + + リカバリされるノードの番号(Pgpool-II 4.0以降) + + + + + + リカバリされるノードのポート番号(Pgpool-II 4.1以降) + + + + + + main (primary)ノードのホスト名(Pgpool-II 4.3以降) + + + - - - -recovery_2nd_stage_commandは、PostgreSQLから見ると、一つのSQLとして実行されます。 -そのため、PostgreSQLのstatement_timeoutrecovery_2nd_stage_commandの完了にかかる時間よりも短く設定されていると、recovery_1st_stagecommandコマンドの実行が途中でキャンセルされます。 - - + + + + recovery_2nd_stage_commandの実行中は、Pgpool-IIはクライアントからの接続およびクエリを受け付けません。 + また、コマンドを実行する前に既存のクライアントが接続を閉じるのを待ちます。 + そのため、長時間接続したままのクライアントがいる場合、recovery_2nd_stage_commandは実行されない可能性があります。 + + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - - recovery_timeout (integer) - - - recovery_timeout 設定パラメータ - - - - - -時間内にオンラインリカバリが完了しなかった場合に、これをキャンセルするためのタイムアウトを秒単位で指定します。 -Pgpool-IIは、オンラインリカバリのセカンドステージの間は接続を受け付けないので、このパラメータはオンラインリカバリの最中のサーバがダウンした時にオンラインリカバリをキャンセルするのに使えます。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - + + recovery_timeout (integer) + + + recovery_timeout 設定パラメータ + + + + + + 時間内にオンラインリカバリが完了しなかった場合に、これをキャンセルするためのタイムアウトを秒単位で指定します。 + Pgpool-IIは、オンラインリカバリのセカンドステージの間は接続を受け付けないので、このパラメータはオンラインリカバリの最中のサーバがダウンした時にオンラインリカバリをキャンセルするのに使えます。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + - - client_idle_limit_in_recovery (integer) - - - client_idle_limit_in_recovery 設定パラメータ - - - - - -オンラインリカバリの最中で、クライアントが前回のクエリからアイドル状態のままでいるときに、それを切断するまでの時間を秒単位で指定します。 -client_idle_limit_in_recoveryと似ていますが、オンラインリカバリのセカンドステージでのみ効果を持ちます。 - - - -これは、だらしないクライアントやPgpool-IIの間のTCP/IPコネクションの不調(例えばケーブルの切断など)によって、Pgpool-IIのリカバリが邪魔されるのを防止するのに役立ちます。 - + + client_idle_limit_in_recovery (integer) + + + client_idle_limit_in_recovery 設定パラメータ + + + + + + オンラインリカバリの最中で、クライアントが前回のクエリからアイドル状態のままでいるときに、それを切断するまでの時間を秒単位で指定します。 + client_idle_limit_in_recoveryと似ていますが、オンラインリカバリのセカンドステージでのみ効果を持ちます。 + + + + これは、だらしないクライアントやPgpool-IIの間のTCP/IPコネクションの不調(例えばケーブルの切断など)によって、Pgpool-IIのリカバリが邪魔されるのを防止するのに役立ちます。 + - - - -client_idle_limit_in_recoveryは、よりも小さな値でなければなりません。 -さもないと、のタイムアウトが先に起こり、オンラインリカバリを実行中に以下のエラーとなります。 - + + + + client_idle_limit_in_recoveryは、よりも小さな値でなければなりません。 + さもないと、のタイムアウトが先に起こり、オンラインリカバリを実行中に以下のエラーとなります。 + ERROR: node recovery failed, waiting connection closed in the other pgpools timeout - - - + + + - - --1に設定すると、オンラインリカバリのセカンドステージが始まると全てのクライアントは直ちに切断されます。 -デフォルト値は0で、この機能は無効です。 - + + + -1に設定すると、オンラインリカバリのセカンドステージが始まると全てのクライアントは直ちに切断されます。 + デフォルト値は0で、この機能は無効です。 + - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 -現在のセッションでのパラメータ値は、コマンドで変更することもできます。 - - - + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + 現在のセッションでのパラメータ値は、コマンドで変更することもできます。 + + + - + diff --git a/doc.ja/src/sgml/performance.sgml b/doc.ja/src/sgml/performance.sgml new file mode 100644 index 000000000..ae5fc4f83 --- /dev/null +++ b/doc.ja/src/sgml/performance.sgml @@ -0,0 +1,262 @@ + + + + 性能に関する考慮 + + + 性能 + サーバの + + + + Pgpool-IIの性能に関する数多くのパラメータがあります。 + この章ではそれらを調整する方法を説明します。 + + + + 必要リソース + + + Pgpool-IIはさほど多くのリソースを消費しません。 + しかし、最低限の必要リソースはあります。 + この節ではそれを順番に説明します。 + + + + 必要メモリ + + + Pgpool-IIでは2種類のメモリの利用方法があります。 + 共有メモリとプロセスのプライベートメモリです。 + 前者はPgpool-IIメインサーバプロセスが起動されたときに確保され、Pgpool-II全体が終了するまで解放されません。 + 後者は各々のPgpool-II子プロセス内で確保され、そのプロセスが終了した時に解放されます。 + + + + 必要共有メモリ + + + 必要共有メモリの計算式を示します。 + + 必要共有メモリ(メガバイト) = 10 + * * 0.02 + + 例えばnum_init_children = 32 (デフォルト値です)で、max_pool = 4 (デフォルト値です)ならば、必要メモリは10 + 32 * 4 * 0.02 = 12.6 MBです。 + + + + 共有メモリでインメモリクエリキャッシュ(詳細は参照)を使う予定があるなら、余分なメモリが必要です。 + 必要メモリ量に関してはを参照してください。 + + + + ただしPgpool-II 4.1以降では、インメモリクエリキャッシュが有効になっていなくても、が有効なら(デフォルトで有効です)、追加で128MBの共有メモリを使用することに注意してください。 + + + + + + 必要プロセスメモリ + + 必要プロセスメモリの計算式を示します。 + + 合計必要プロセスメモリ(メガバイト単位) = * 0.16 + + たとえばnum_init_children = 32 (デフォルト値です)なら、5.2 MBのメモリが必要です。 + なお、このメモリ量はPgpool-II子プロセス起動時の最低限の必要メモリで、プロセスが稼働するにしたがって、通信データの大きさなどに応じて更に使用するメモリが増えていきます。 + 実際にPgpool-IIを動かして、必要なメモリ量がどのくらいになるのか実運用に入る前に検証することをお勧めします。 + + + + + + 必要ディスク + + Pgpool-IIはさほど多くのディスク領域を消費しません。 + また、Pgpool-IIによるディスクI/O量は少ないため、高速ディスクの必要もありません。 + ただし、多くのログを生成する計画があるなら、そのためのディスク領域が必要です。 + + + + + + クライアント接続の管理 + + 受け付けるクライアント接続数が増えると、新しい接続を受け付けるPgpool-II子プロセスの数は減少し、ついには0になります。 + こうなると、子プロセスの一つが空くまでクライアントは待たされます。 + 高負荷状況では、待機状態の待ち行列が長くなり、ついにはシステム設定の上限を超えてしまいます("535 times the listen queue of a socket overflowed" + エラーをご覧になったことがあるかも知れません)。 + この場合、待ち行列の制限を大きくする必要があります。 + この問題に対処するための方法がいくつかあります。 + + + + num_init_childrenの調整 + + この問題に対処するための明らかな方法は、子プロセスの数を増やすことです。 + を調整することにより、これは可能です。 + しかし、子プロセスを増やすと。より多くのCPU、メモリリソースが必要になります。 + また、ひとたび子プロセスの数がmax_connectionsを超えると、PostgreSQLは接続を受け付けなくなり、フェイルオーバが起きるきっかけになるので、PostgreSQLのmax_connectionsパラメータについては非常に慎重に検討する必要があります。 + + + num_init_childrenを増やすもう一つの欠点は、「大規模な群れ問題(thundering herd problem)」です。 + 新しい接続要求が到達すると、カーネルはaccept()システムコールを発行するために休眠中のプロセスをすべて起こします。 + これはプロセス同士がソケットを奪い合うきっかけとなり、システムに高負荷を与えます。 + をonにすることにより、接続を受け付けるソケットを確保するプロセスをひとつだけにすることができます。 + ただし、この方法では、同時に接続するクライアント数が少ない時に、性能が低下する可能性があることに注意してください + + + Pgpool-II 4.4以降では、を使ってより効果的な対処が可能です。 + process-management-modedynamicにすることにより、同時に接続するクライアント数が少ない時にはPgpool-IIの子プロセスの数を削減し、システムのリソースの消費を抑えます。 + 一方、同時に接続するクライアント数が増えてくると、必要に応じて子プロセスの数を増やすので、増大する接続要求にも応えられます。 + ただし、子プロセスを増やすには新たなプロセスの起動が必要となり、接続に要する時間が増えることに留意してください。 + + + process-management-modeについては、もご覧ください。 + + + + + listen_backlog_multiplierの制御 + + 別な解決方法は、接続要求待ち行列を長くすることです。 + を大きくすることによりこれは可能です。 + + + + + どのような時にreserved_connectionsを使うべきか + + しかし、上記の方法では待ち行列が満杯にならないことを保証することはできません。 + クエリを処理する速度を上回ってクライアントからの接続要求が到達すれば、いつかは待ち行列が満杯になります。 + たとえば、処理に時間を要する重いクエリがあると、容易にこの問題の引き金になります。 + + + 解決方法は、を使って、すでにPostgreSQLが行っているように、溢れてしまうような接続要求は拒否することです。 + これはアプリケーションから見える"Sorry max_connections already"エラーを起こすので、アプリケーションは処理を再実行する必要があります。 + ですから、この方法はシステムの負荷を事前に予測できないときにだけ使用するべきです。 + + + + + + + 読み出しクエリの負荷分散 + + 複数のPostgreSQLノードがあり、Pgpool-IIがストリーミングレプリケーションモード、ロジカルレプリケーションモード、レプリケーションモードで動作していると(これらの動作モードについてはを参照のこと)、読み出しクエリをこれらのデータベースノードに分散させ、各々のノードにより少ない数のクエリを処理させることによってより高いスループットを得ることができます。 + この機能を使うためには、をonにする必要があります。 + + + + 今の所、非常に多くのシステムがストリーミングレプリケーションモードを使用しているので、以後このモードに焦点を当てて説明します。 + + + + セッションレベルのロードバランスとステートメントレベルのロードバランス + + デフォルトではロードバランスモードは「セッションレベル」で、読み出しクエリを送るノードはクライアントがPgpool-IIに接続した時に決定されます。 + たとえば、ノード0、1があると、新しいセッションが作られた時にどちらかのノードがランダムに選択されます。 + 長期的にはどちらのノードが選ばれるかの確率は、0と1の比率に近づきます。 + これらの値が等しければ、どちらかのノードが選ばれるチャンスは同じになるでしょう。 + + + + 一方、がonなら、 + ロードバランスノードは各クエリが開始する時に決まります。 + これは、アプリケーションが自分自身のコネクションプールを持っており、Pgpool-IIに接続し続けるので、ひとたびアプリケーションが起動するとロードバランスノードが変わらない場合に有効です。 + 他のユースケースはバッチアプリケーションです。たくさんのクエリを発行しますが、セッションは一つです。 + ステートメントレベルのロードバランスによって、複数のサーバを利用できます。 + + + + + 特定目的のデータベースノードを作る + + OLAP環境では、特定目的のために大きな読み出し専用のデータベースを持つことが望ましいです。 + ストリーミングレプリケーションでレプリカデータベースを作ることによって、このようなデータベースを作ることができます。 + 読み出しクエリをそのデータベースに発行する方法は2つあります。 + データベース名を指定する方法と、アプリケーション名を指定する方法です。 + 前者のためにはを、後者のためにはを使ってください。 + + + + + + + インメモリクエリキャッシュ + + Pgpool-IIは読み出しクエリの結果をキャッシュし、後で再利用することができます。 + これは、同じ読み出しクエリを何度も発行するタイプのアプリケーションでは大きなメリットがあります。 + 2つのクエリが文字列として同じで(そしてもしあればプリペアドステートメントのパラメータ)が同じなら、それは「同じ」クエリと見なされます。 + 最初にそのクエリが送信されると、Pgpool-IIはクエリの結果を保存し、PostgreSQLに一切問い合わせることなく2つ目のクエリのために使用します。 + この技術はで説明されています。 + + + + インメモリクエリキャッシュを使用すべきでない場合 + + テーブルが更新されると、そのテーブルに対するクエリの結果は変わってしまう可能性があります。 + 不整合を防ぐために、Pgpool-IIは関連するテーブルが更新されるとクエリキャッシュデータを破棄します。 + ですから、頻繁に更新されるデータベースはインメモリクエリキャッシュに向いていません。 + クエリキャッシュを使うのに適したデータベースかどうかを調べるには、を使ってください。 + クエリキャッシュのヒット率が70%未満なら、たぶんクエリキャッシュの利用は避けたほうが良いでしょう。 + + + + + + リレーションキャッシュ + + raw mode (参照)あるいはがoffに設定されている場合を除きPgpool-IIPostgreSQLに時々、テーブルが一時テーブルかどうかなどのメタ情報を問い合わせる必要があります。 + それらの情報を得るために、Pgpool-IIはプライマリPostgreSQLにときには10本ものクエリを送信することがあります(4.1以降ではその数は大幅に減っていますが、それでも完全に問い合わせの送信がなくなったわけではありません)。 + このオーバーヘッドを減らすために、Pgpool-IIは「リレーションキャッシュ」を保持しています。 + 次にクエリに同じテーブルが含まれていると、Pgpool-IIはキャッシュからその情報を取り出します。 + + + リレーションキャッシュの性能に関する設定を行うためのパラメータがあります。 + 詳細はをご覧ください。 + + + + 共有リレーションキャッシュ + + リレーションキャッシュは基本的にプロセス内のプライベートメモリにあり、プロセスに結びついています。 + ですから、あるセッションでテーブルのリレーションキャッシュが作られても、別のプロセスではそのリレーションキャッシュはまだ作られていないかも知れません。 + 結局すべてのプロセスでリレーションキャッシュが作成されるまで、PostgreSQLにクエリが送信され続けます。 + Pgpool-II 4.1は共有メモリにリレーションキャッシュを作ることによってこの問題を克服しました。 + 共有メモリにリレーションキャッシュが作られると、他のセッションは共有リレーションキャッシュを検索することによってキャッシュの結果を得ることができます。 + 詳細は設定パラメータを見てください。 + この機能は非常に効果的なので、この機能を有効にすることをお勧めします。 + + + + + + その他の性能考慮点 + + この節ではその他の性能考慮点を紹介します。 + + + + 大規模な群れ問題(Thundering Herd Problem) + + が大きいと、Pgpool-IIプロセスが起こされ、その結果重いコンテキストスイッチが引き起こされる可能性があります。 + これによってシステムに高負荷が生じ、システムの全体的な性能を損ないます。 + この問題は大規模な群れ問題(Thundering Herd Problem)と呼ばれます。 + を有効にすることによって、この問題を解決できます。 + 小さなでは、はシステムの性能を低下させる可能性があることに注意してください。 + 節のガイダンスを参照してください。 + + + + + ディザスタリカバリ設定 + + ディザスタリカバリ設定を行う場合、Pgpool-IIとプライマリPostgreSQLサーバから地理的に離れた場所に、もう1台のPgpool-IIとスタンバイPostgreSQLサーバを設置することが考えられます。 + そしてスタンバイサーバ側に近いクライアントは、読み出し専用のクエリに関してはスタンバイサーバに近いPgpool-IIにアクセスしたいとします。 + しかしスタンバイ側のPgpool-IIは、内部的にシステムカタログへの問い合わせをプライマリPostgreSQLサーバに発行することがあり、性能が低下してしまいます。 + この問題を回避するために、を使用して、そうした問い合わせをスタンバイサーバ側に送るようにすることができます。 + 詳細はをご覧ください。 + + + + diff --git a/doc.ja/src/sgml/pgpool.sgml b/doc.ja/src/sgml/pgpool.sgml index e000f65eb..edd5652cf 100644 --- a/doc.ja/src/sgml/pgpool.sgml +++ b/doc.ja/src/sgml/pgpool.sgml @@ -13,9 +13,9 @@ - + --> Pgpool-II &version; 文書 @@ -29,113 +29,82 @@ &intro; - + --> チュートリアル - -この章では、Pgpool-IIを使いはじめる方法を説明します。 + --> + この章では、Pgpool-IIを使いはじめる方法を説明します。 &start; - &advanced; - + --> サーバ管理 - -ここではPgpool-II管理者にとって関心のある事項を扱います。 + --> + ここではPgpool-II管理者にとって関心のある事項を扱います。 &installation; &runtime; + &advanced; &config; - &connection-settings; - &connection-pooling; - &loadbalance; - &healthcheck; - &failover; - &online-recovery; - &stream-check; - &memcache; - &ssl; - &watchdog; - &misc-config; - &config-last; + &connection-settings; + &connection-pooling; + &loadbalance; + &healthcheck; + &failover; + &online-recovery; + &stream-check; + &memcache; + &ssl; + &watchdog; + &misc-config; + &config-last; &client-auth; + &performance; &examples; &reference; - - - 付録 - + something... - + &release; + &biblio; ]]> diff --git a/doc.ja/src/sgml/problems.sgml b/doc.ja/src/sgml/problems.sgml index fee1a15be..28f6e1e25 100644 --- a/doc.ja/src/sgml/problems.sgml +++ b/doc.ja/src/sgml/problems.sgml @@ -1,15 +1,15 @@ - + --> バグ報告の指針 - -Pgpool-IIのバグを見つけたら、バグ管理システムに登録してください。 + --> + Pgpool-IIのバグを見つけたら、バグ管理システムに登録してください。 diff --git a/doc.ja/src/sgml/ref/allfiles.sgml b/doc.ja/src/sgml/ref/allfiles.sgml index a7bd715a1..7127cb553 100644 --- a/doc.ja/src/sgml/ref/allfiles.sgml +++ b/doc.ja/src/sgml/ref/allfiles.sgml @@ -1,12 +1,13 @@ + @@ -16,23 +17,32 @@ Complete list of usable sgml source files in this directory. + + + + + - - + + + + + + diff --git a/doc.ja/src/sgml/ref/pcp_attach_node.sgml b/doc.ja/src/sgml/ref/pcp_attach_node.sgml index beea679d3..9468333a1 100644 --- a/doc.ja/src/sgml/ref/pcp_attach_node.sgml +++ b/doc.ja/src/sgml/ref/pcp_attach_node.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_attach_node - - Pgpool-II にノードを復帰させる + + Pgpool-II にノードを復帰させる @@ -32,57 +32,57 @@ Pgpool-II documentation - 説明 - pcp_attach_node - - は Pgpool-II にノードを復帰させます。 + pcp_attach_node + + は Pgpool-II にノードを復帰させます。 - オプション - - + + - - - - - + + + + + - 復帰させるバックエンドノードのインデックスを指定します。 - - - + The index of backend node to attach. + --> + 復帰させるバックエンドノードのインデックスを指定します。 + + + - + - - - - - を参照してください。 - - - + + + + + を参照してください。 + + + - - + + diff --git a/doc.ja/src/sgml/ref/pcp_common_options.sgml b/doc.ja/src/sgml/ref/pcp_common_options.sgml index 8a6d0c1ba..3492bccc4 100644 --- a/doc.ja/src/sgml/ref/pcp_common_options.sgml +++ b/doc.ja/src/sgml/ref/pcp_common_options.sgml @@ -21,7 +21,7 @@ Pgpool-II documentation common options used in PCP commands --> - PCP コマンドには共通する引数 + PCP コマンドには共通する引数 @@ -33,162 +33,162 @@ Pgpool-II documentation - <!-- + <!-- Description --> 説明 - - 全てのコマンドには共通する引数があります。 - そのほとんどは認証情報を指定するもので、 他は冗長出力モードやデバッグなどに関するものです。 + + 全てのコマンドには共通する引数があります。 + そのほとんどは認証情報を指定するもので、 他は冗長出力モードやデバッグなどに関するものです。 - オプション - - + + - - - - - + + + + + - pgpool-II が稼働しているホスト名を指定します。 スラッシュから始まる場合は、 - Unix ドメインソケットのディレクトリと解釈されます。 - - - - - - - - - + The host name of the machine on which the server is running. If the + value begins with a slash, it is used as the directory for the Unix-domain socket. + --> + pgpool-II が稼働しているホスト名を指定します。 スラッシュから始まる場合は、 + Unix ドメインソケットのディレクトリと解釈されます。 + + + + + + + + + - PCP ポート番号を指定します。(デフォルト: 9898) - - - - - - - - - + The PCP port number (default:"9898"). + --> + PCP ポート番号を指定します。(デフォルト: 9898) + + + + + + + + + - PCP 認証のユーザ名を指定します。(デフォルト: OS のユーザ) - - - - - - - - - + The user name for PCP authentication (default: OS user name). + --> + PCP 認証のユーザ名を指定します。(デフォルト: OS のユーザ) + + + + + + + + + - パスワード入力プロンプトを表示しません。 もしパスワードが .pcppass ファイルから - 取得できない場合には接続は失敗します。 このオプションはバッチジョブやスクリプトなど、 - パスワード入力が行うユーザいない場合に有用です。 - - - - - - - - - + Never prompt for password (should happen automatically). And if a password is not available + by a .pcppass file, the connection + attempt will fail. This option can be useful in batch jobs + and scripts where no user is present to enter a password. + --> + パスワード入力プロンプトを表示しません(自動的に選択される動作です)。 + もしパスワードが .pcppass ファイルから取得できない場合には接続は失敗します。 + このオプションはバッチジョブやスクリプトなど、パスワード入力が行うユーザがいない場合に有用です。 + + + + + + + + + - パスワード入力プロンプトを表示します。(自動的に選択される動作です) - - - - - - - - - + Force password prompt. + --> + パスワード入力プロンプトを表示します。 + + + + + + + + + - デバッグメッセージを表示します。 - - - - - - - - - - - 冗長出力を有効にします。 - - - - - - - - - + Enable debug message. + --> + デバッグメッセージを表示します。 + + + + + + + + + - バージョンを表示して終了します。 - - - - - - - - - + Enable verbose output. + --> + 冗長出力を有効にします。 + + + + + + + + + - コマンドラインのヘルプを表示して終了します。 - - - - - - + Print the command version, then exit. + --> + バージョンを表示して終了します。 + + + + + + + + + + + コマンドラインのヘルプを表示して終了します。 + + + + + + - 環境変数 @@ -199,7 +199,7 @@ Pgpool-II documentation - pcp パスワードファイルのパスを指定します。 diff --git a/doc.ja/src/sgml/ref/pcp_detach_node.sgml b/doc.ja/src/sgml/ref/pcp_detach_node.sgml index 99883d759..cb619401f 100644 --- a/doc.ja/src/sgml/ref/pcp_detach_node.sgml +++ b/doc.ja/src/sgml/ref/pcp_detach_node.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_detach_node - - Pgpool-II からノードを切り離す + + Pgpool-II からノードを切り離す @@ -33,71 +33,77 @@ Pgpool-II documentation - 説明 - pcp_detach_node - - は Pgpool-II のノードを切り離します。すでに Pgpool-II に接続しているセッションは強制的に切断されます。 + pcp_detach_nodePgpool-II のノードを切り離します。 + あるいは が指定されていれば、それらも実行されます。 + すでに Pgpool-II に接続しているセッションは強制的に切断されます。 + + + pcp_detach_nodeは単にノードを切り離すだけで、そのノードで背後で稼働しているバックエンドには触りません。 + このコマンドは、管理者がPostgreSQLノードを保守する際に有用です。 + 管理者は好きなだけそのバックエンドを停止したり起動できます。 + + + 切り離したノードは、バックエンドを停止した上でで復帰させるのが安全ですが、レプリケーション遅延がない(もしくは後でレプリケーション遅延を回復できる)ことが確実で、ノードの役割(プライマリ/スタンバイ)の変更を伴わないことが確実なら、で復帰させることもできます。 - オプション - - + + - - - - - + + + + + - 切り離すバックエンドノードのインデックスを指定します。 - - - + The index of backend node to detach. + --> + 切り離すバックエンドノードのインデックスを指定します。 + + + - - - - - + + + + + - すべてのクライアントが接続を終了するまで待機します。 - (ただし、 が -1 あるいは、 が設定されている場合を除く) - - - + wait until all clients are disconnected (unless client_idle_limit_in_recovery is -1 or recovery_timeout is expired). + --> + すべてのクライアントが接続を終了するまで待機します。 + (ただし、 が -1 あるいは、 が設定されている場合を除く) + + + - + - - - - - を参照してください。 - - - + + + + + を参照してください。 + + + - - + + diff --git a/doc.ja/src/sgml/ref/pcp_health_check_stats.sgml b/doc.ja/src/sgml/ref/pcp_health_check_stats.sgml new file mode 100644 index 000000000..e623f06ef --- /dev/null +++ b/doc.ja/src/sgml/ref/pcp_health_check_stats.sgml @@ -0,0 +1,103 @@ + + + + + pcp_health_check_stats + + + + pcp_health_check_stats + 1 + PCP Command + + + + pcp_health_check_stats + + 与えられたノードIDのヘルスチェック統計データを表示する + + + + + + pcp_health_check_stats + option + node_id + + + + + 説明 + + pcp_health_check_stats + 与えられたノードIDのヘルスチェック統計データを表示します。 + + + + + オプション + + + + + + + + + 情報を表示するバックエンドノードのインデックスを指定します。 + + + + + + + + + を参照してください。 + + + + + + + + + + + 例を示します。 + +$ pcp_health_check_stats -h localhost -p 11001 -w 0 +0 /tmp 11002 up primary 2020-02-24 22:02:42 3 3 0 0 0 0.000000 0 5 1 3.666667 2020-02-24 22:02:47 2020-02-24 22:02:47 +$ pcp_health_check_stats -h localhost -p 11001 -w -v 0 +Node Id : 0 +Host Name : /tmp +Port : 11002 +Status : up +Role : primary +Last Status Change : 2020-02-24 22:02:42 +Total Count : 5 +Success Count : 5 +Fail Count : 0 +Skip Count : 0 +Retry Count : 0 +Average Retry Count : 0.000000 +Max Retry Count : 0 +Max Health Check Duration : 5 +Minimum Health Check Duration : 1 +Average Health Check Duration : 4.200000 +Last Health Check : 2020-02-24 22:03:07 +Last Successful Health Check : 2020-02-24 22:03:07 +Last Skip Health Check : +Last Failed Health Check : + + + + + 表示データの詳細に関してはをご覧ください。 + + + + diff --git a/doc.ja/src/sgml/ref/pcp_invalidate_query_cache.sgml b/doc.ja/src/sgml/ref/pcp_invalidate_query_cache.sgml new file mode 100644 index 000000000..235362e77 --- /dev/null +++ b/doc.ja/src/sgml/ref/pcp_invalidate_query_cache.sgml @@ -0,0 +1,93 @@ + + + + + pcp_invalidate_query_cache + + + + pcp_invalidate_query_cache + 1 + PCP Command + + + + pcp_invalidate_query_cache + + + クエリキャッシュの内容を破棄する + + + + + + pcp_invalidate_query_cache + options + + + + + + 説明 + + + pcp_invalidate_query_cacheは、共有メモリ上にクエリキャッシュの破棄リクエストをセットします。 + このリクエストは、クライアントから送られてきたメッセージが処理された時に、pgpoolとの個々のセッションに関連するPgpool-IIの子プロセスによって処理されます。 + このことは、Pgpool-IIに接続するクライアントがないか、あるいはあったしてもすべてのクライアントがアイドルのままなら、次にメッセージが到着するまでリクエストは処理されないことを意味します。 + + + + このコマンドはで表示される統計情報を変更しませんが、その元になるクエリキャッシュの内容を破棄するため、一部の表示データは影響を受けます。 + num_cache_hitsnum_selectsは、キャッシュの破棄後も増加し続けます。 + shmemの場合、used_hash_entriesnum_cache_entriesused_cache_entries_sizeは一旦0となります。 + free_cache_entries_sizeは増加するでしょう。 + + + + falseなら、このコマンドはエラーを出力して終了します。 + + + + + + オプション + + + をご覧ください。 + + + + diff --git a/doc.ja/src/sgml/ref/pcp_log_rotate.sgml b/doc.ja/src/sgml/ref/pcp_log_rotate.sgml new file mode 100644 index 000000000..f49c922bd --- /dev/null +++ b/doc.ja/src/sgml/ref/pcp_log_rotate.sgml @@ -0,0 +1,74 @@ + + + + + pcp_log_rotate + + + + pcp_log_rotate + 1 + PCP Command + + + + pcp_log_rotate + + Pgpool-IIのログファイルをローテーションします + + + + + pcp_log_rotate + options + + + + + 説明 + + pcp_log_rotate + Pgpool-IIのログファイルをローテーションします。 + + + + + オプション + + + + + + + + + コマンドの与える影響範囲を指定します。 + + +    サポートされているコマンドスコープは以下です。 + デフォルトは"local"です。 + + c, cluster : クラスタを構成するすべてのPgpool-IIのログファイルをローテーションします。 + l, local : ローカルPgpool-IIのログファイルをローテーションします。 + + + + + + + + + + を参照してください。 + + + + + + + + + diff --git a/doc.ja/src/sgml/ref/pcp_node_count.sgml b/doc.ja/src/sgml/ref/pcp_node_count.sgml index 7cbf5057c..55193e7ef 100644 --- a/doc.ja/src/sgml/ref/pcp_node_count.sgml +++ b/doc.ja/src/sgml/ref/pcp_node_count.sgml @@ -21,7 +21,7 @@ Pgpool-II documentation displays the total number of database nodes --> - Pgpool-IIpgpool.conf で定義されたノードの総数を表示する + Pgpool-IIpgpool.conf で定義されたノードの総数を表示する @@ -33,50 +33,50 @@ Pgpool-II documentation - <!-- + <!-- Description --> 説明 - pcp_node_count - - は Pgpool-IIpgpool.conf - で定義されたノードの総数を表示します。 切り離されているノードの区別はしません。 + pcp_node_count + + は Pgpool-IIpgpool.conf + で定義されたノードの総数を表示します。 切り離されているノードの区別はしません。 - オプション - + - を参照してください。 - + See . + --> + を参照してください。 + - - + - ここでは例を示します。 - -$ pcp_node_count -p 11001 -Password: -2 - - + Here is an example output: + --> + ここでは例を示します。 + + $ pcp_node_count -p 11001 + Password: + 2 + + diff --git a/doc.ja/src/sgml/ref/pcp_node_info.sgml b/doc.ja/src/sgml/ref/pcp_node_info.sgml index 03a3ddd9b..dc146cec3 100644 --- a/doc.ja/src/sgml/ref/pcp_node_info.sgml +++ b/doc.ja/src/sgml/ref/pcp_node_info.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_node_info - - 指定されたノードの情報を表示する + + 指定されたノードの情報を表示する @@ -32,140 +32,254 @@ Pgpool-II documentation - 説明 - pcp_node_info - - 指定されたノードの情報を表示します。 + pcp_node_info + + 指定されたノードの情報を表示します。 - オプション - - + + - - - - - + + + + + - 情報を表示するバックエンドノードのインデックスを指定します。 - - - + The index of backend node to get information of. + --> + 情報を表示するバックエンドノードのインデックスを指定します。 + + + - - - - - + + + + + + すべてのバックエンドノードの情報を表示します。 + + + + + + - を参照してください。 - - - - - + + + + + を参照してください。 + + + + + - - + - ここでは例を示します。 - -$ pcp_node_info -h localhost -U postgres 1 -/tmp 11003 2 0.500000 up standby 208 2018-07-03 08:26:39 - + Here is an example output: + --> + ここでは例を示します。 + +$ pcp_node_info -w -p 11001 -n 1 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 + - + 結果は以下の順のとおりです。 + + - 結果は以下の順のとおりです。 - - 1. ノードのホスト名 2. ノードのポート番号 3. ステータス 4. ロードバランスウェイト -5. バックエンド状態名 -6. バックエンドの役割 -7. レプリケーションの遅延 -8. 最終ステータス変更時刻 - +5. バックエンドステータス名 +6. 実際のバックエンドの状態 (Pgpool-II 4.3以降。PQpingParamsで取得) +7. バックエンドの役割 +8. 実際のバックエンドの役割(Pgpool-II 4.3以降。pg_is_in_recoveryで取得) +9. レプリケーションの遅延 +10. レプリケーション状態 (Pgpool-II 4.1以降。pg_stat_replicationから取得) +11. 同期レプリケーション状態 (Pgpool-II 4.1以降。pg_stat_replicationから取得) +12. 最終ステータス変更時刻 + - - ステータスは [0..3] までの数字で表わされます。各数字の意味は以下のとおりです。 - - - 0 - 初期化時のみに表われる。PCP コマンドで表示されることはない。 - 1 - ノード稼働中。接続無し - 2 - ノード稼働中。接続有り - 3 - ノードダウン - + + 3(ステータス)は [0..3] までの数字で表わされます。各数字の意味は以下のとおりです。 - - ロードバランスウェイトは Normalize されたフォーマットで出力されます。 + 0 - 初期化時のみに表われる。PCP コマンドで表示されることはない。 + 1 - ノード稼働中。接続無し + 2 - ノード稼働中。接続有り + 3 - ノードダウン + + + + 4(ロードバランスウェイト)は0から1に正規化されたフォーマットで出力されます。 + + + + 5(バックエンドステータス名)はPgpool-IIから見たPostgreSQLノードのステータス名を示します。 + これは、上記「3(ステータス)」の数値に対応する状態名(文字列)であり、Pgpool-IIが内部的に保持しているノードの状態を、可読性の高い形式で表現したものです。 + + + 6(実際のバックエンドの状態)は実際のバックエンドの状態をリアルタイムで取得して表示します。 + 情報の取得は、このコマンドが実行された時にPQpingParamsを呼び出すことによって行われます。 + PQpingParamsPostgreSQL 9.1以降でのみサポートされています。 + Pgpool-IIPostgreSQL 9.0以前とともに構築されると、この列は"unknown"と表示されます。 + また、ヘルスチェックが無効になっている場合も"unknown"と表示されます。 + でバックエンドノードを切り離すと、Pgpool-IIが管理する状態は"down"になりますが、バックエンドの実際の状態は"up"なので、5と6が一致しないことはあり得ます。 + 逆に、5が"up"なのに、6が"down"というのは起こらないはずです。 + + + 7(バックエンドの役割)はPgpool-IIから見たPostgreSQLノードの役割(primaryまたはstandby)を示します。Pgpool-IIが内部的に保持している情報に基づいて表示されます。 + + + 8(実際のバックエンドの役割)は実際のバックエンドの役割(primaryまたはstandby)をリアルタイムで取得して表示します。 + その結果はストリーミングレプリケーションモードでは、"primary"か"standby"ですが、情報が取得できなければ"unknown"と表示します。 + Pgpool-IIはノードID順にバックエンドノードを調べ、最後に見つけたスタンバイ以外のノードをプライマリとするので、誤ってスタンバイ以外のノードが複数できたときなどには、7と8が一致しないことはありえます。 + (このコマンドはそのような状態を見つけるのに役立ちます。) + それ以外のモードでは、"main"あるいは"replica"と表示されます。 + ストリーミングレプリケーションモードと違って、pg_is_in_recoveryは呼び出されず、7と8が異なる値になることはありません。 + + + 9, 10, 11を正しく表示させるに、が0以外に設定されている必要があります。 + さらに10, 11を正しく表示させるには、以下の追加設定が必要です。 + + + + パラメータを設定する必要があります。 + + + 各backend_application_nameXに設定された値が、該当ノードのprimary_conninfoapplication_nameに指定された値と一致している必要があります。 + + + 特に、Pgpool-IIコマンドを用いてスタンバイノードを構築し、コミュニティ提供のサンプルスクリプトを使用している場合は、backend_application_nameXの値をbackend_hostnameXと一致させてください。 + 具体的な設定例についてはをご参照ください。 + + + + + PostgreSQLのスーパーユーザーであるか、もしくはpg_monitorロールの権限が付与されている必要があります。 + + + + + + pg_monitorロールの権限を付与するには、以下のSQLコマンドをPostgreSQLスーパーユーザーで実行してください("sr_check_user"をの設定値で置き換えてください) + +GRANT pg_monitor TO sr_check_user; + + PostgreSQL 9.6にはpg_monitorグループがないので、PostgreSQLのスーパーユーザーでなければなりません。 + + + + - オプションは出力内容を理解するのに役に立ちます。例: + Pgpool-II 4.4から、9 (レプリケーション遅延)はバイトもしくは秒単位で表示されます。 + 詳細はを参照ください。 + + + + + または オプションはすべてのバックエンドノードの情報を表示します。 + + +$ pcp_node_info -w -p 11001 -a +/tmp 11002 1 0.500000 waiting up primary primary 0 none none 2021-02-27 14:51:30 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 + + + + + オプションは出力内容を理解するのに役に立ちます。例を示します: - -$ pcp_node_info --verbose -h localhost -U postgres 1 -Hostname : /tmp -Port : 11003 -Status : 2 -Weight : 0.500000 -Status Name : up -Role : standby -Replication Delay : 208 -Last Status Change: 2018-07-03 08:26:39 - + +$ pcp_node_info -w -p 11001 --verbose 1 +Hostname : /tmp +Port : 11003 +Status : 1 +Weight : 0.500000 +Status Name : waiting +Backend Status Name : up +Role : standby +Backend Role : standby +Replication Delay : 0 +Replication State : streaming +Replication Sync State : async +Last Status Change : 2021-02-27 14:51:30 + diff --git a/doc.ja/src/sgml/ref/pcp_pool_status.sgml b/doc.ja/src/sgml/ref/pcp_pool_status.sgml index 3336e9e38..4a28dd494 100644 --- a/doc.ja/src/sgml/ref/pcp_pool_status.sgml +++ b/doc.ja/src/sgml/ref/pcp_pool_status.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_pool_status - - pgpool.conf のパラメータ設定値を取得する + + pgpool.conf のパラメータ設定値を取得する @@ -31,60 +31,60 @@ Pgpool-II documentation - 説明 - pcp_pool_status - - は pgpool.conf のパラメータ設定値を表示します。 + pcp_pool_status + + は pgpool.conf のパラメータ設定値を表示します。 - オプション - + - を参照してください。 - + See . + --> + を参照してください。 + - - + - ここでは例を示します。 - -$ pcp_pool_status -h localhost -U postgres -name : listen_addresses -value: localhost -desc : host name(s) or IP address(es) to listen to + Here is an example output: + --> + ここでは例を示します。 + + $ pcp_pool_status -h localhost -U postgres + name : listen_addresses + value: localhost + desc : host name(s) or IP address(es) to listen to -name : port -value: 9999 -desc : pgpool accepting port number + name : port + value: 9999 + desc : pgpool accepting port number -name : socket_dir -value: /tmp -desc : pgpool socket directory + name : socket_dir + value: /tmp + desc : pgpool socket directory -name : pcp_port -value: 9898 -desc : PCP port # to bind - + name : pcp_port + value: 9898 + desc : PCP port # to bind + diff --git a/doc.ja/src/sgml/ref/pcp_proc_count.sgml b/doc.ja/src/sgml/ref/pcp_proc_count.sgml index 4af0b311c..3389a97ff 100644 --- a/doc.ja/src/sgml/ref/pcp_proc_count.sgml +++ b/doc.ja/src/sgml/ref/pcp_proc_count.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_proc_count - - Pgpool-II の子プロセスのプロセス ID を一覧表示する + + Pgpool-II の子プロセスのプロセス ID を一覧表示する @@ -31,30 +31,30 @@ Pgpool-II documentation - 説明 - pcp_proc_count - - は Pgpool-II の子プロセスのプロセス ID を一覧表示します。複数ある場合は空白文字で区切られます。 + pcp_proc_count + + は Pgpool-II の子プロセスのプロセス ID を一覧表示します。複数ある場合は空白文字で区切られます。 - オプション - + - を参照してください。 - + See . + --> + を参照してください。 + diff --git a/doc.ja/src/sgml/ref/pcp_proc_info.sgml b/doc.ja/src/sgml/ref/pcp_proc_info.sgml index 82224db26..0fc06c9d5 100644 --- a/doc.ja/src/sgml/ref/pcp_proc_info.sgml +++ b/doc.ja/src/sgml/ref/pcp_proc_info.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_proc_info - - Pgpool-II の子プロセス情報を表示する + + Pgpool-II の子プロセス情報を表示する @@ -32,168 +32,250 @@ Pgpool-II documentation - 説明 - pcp_proc_info - - は Pgpool-II の子プロセス情報を表示します。 + pcp_proc_info + + は Pgpool-II の子プロセス情報を表示します。 - オプション - - + + - - - - - - -すべての子プロセスと、それに関するコネクションスロットを表示します。 - - - + + + + + + + すべての子プロセスと、それに関するコネクションスロットを表示します。 + + + - - - - - + + + + + - Pgpool-II 子プロセスの PID を指定します。 - - - + Pgpool-II 子プロセスの PID を指定します。 + + + - + - - - + + --> + + + - を参照してください。 - - - - - -もし-aオプションも-Pオプションも指定されない場合は、すべての接続されたPgpool-II子プロセスが表示されます。 -この場合、接続された子プロセスが存在しない場合は、"No process information available"メッセージだけが表示されます。 - + See . + --> + を参照してください。 + + + + + + もし-aオプションも-Pオプションも指定されない場合は、すべての接続されたPgpool-II子プロセスが表示されます。 + この場合、接続された子プロセスが存在しない場合は、"No process information available"メッセージだけが表示されます。 + - - + - 例を示します。 - -$ pcp_proc_info -p 11001 1406 -test t-ishii 2018-07-09 16:43:53 2018-07-09 16:44:08 3 0 1 1435 1 1406 0 -test t-ishii 2018-07-09 16:43:53 2018-07-09 16:44:08 3 0 1 1436 1 1406 1 - + Here is an example output: + --> + 例を示します。 + +$ pcp_proc_info -p 11001 +test t-ishii 2025-06-24 10:53:35 0 3 0 2025-06-24 10:55:58 2025-06-24 10:55:59 0 1 1336703 1 1336537 0 Idle 0 192.168.10.11 39216 +test t-ishii 2025-06-24 10:53:35 0 3 0 2025-06-24 10:55:58 2025-06-24 10:55:59 0 1 1336704 1 1336537 1 Idle 1 192.168.10.11 39216 +test t-ishii 2025-06-24 10:53:35 (4:03 before process restarting) 1 3 0 2025-06-24 10:53:42 2025-06-24 10:53:42 0 2025-06-24 10:55:37 1 1336573 0 1336544 0 Wait for connection 0 192.168.10.11 39162 +test t-ishii 2025-06-24 10:53:35 (4:03 before process restarting) 1 3 0 2025-06-24 10:53:42 2025-06-24 10:53:42 0 2025-06-24 10:55:37 1 1336574 0 1336544 1 Wait for connection 0 192.168.10.11 39162 + - + 結果は以下の順のとおりです。 + + - 結果は以下の順のとおりです。 - - -1. 接続先のデータベース名 -2. 接続先のユーザ名 -3. Pgpool-IIプロセスの起動時刻 -4. バックエンドへの接続時刻 -5. プロトコルのメジャーバージョン -6. プロトコルのマイナーバージョン -7. 接続の再利用カウンタ値 -8. PostgreSQLバックエンドプロセスのプロセスID -9. フロントエンドが接続中なら1、そうでなければ0 -10. pgpool子プロセスID -11. PostgreSQLバックエンドID - + 1. 接続先のデータベース名 + 2. 接続先のユーザ名 + 3. Pgpool-IIプロセスの起動時刻 (が0でない場合、プロセスが再起動されるまでの時間を表示します) + 4. プロセスの利用カウンタ(を参照) + 5. プロトコルのメジャーバージョン + 6. プロトコルのマイナーバージョン + 7. バックエンドへの接続時刻 + 8. クライアントが最後に接続開始した時刻 + 9. 接続がidleとなっている時間(秒)(が0でない場合、クライアントが切断されるまでの時間を表示します) + 10. クライアントが最後に接続終了した時刻 + 11. 接続の再利用カウンタ値 + 12. PostgreSQLバックエンドプロセスのプロセスID + 13. フロントエンドが接続中なら1、そうでなければ0 + 14. pgpool子プロセスID + 15. PostgreSQLバックエンドID + 16. プロセスの状態 +  17. フロントエンドが接続中でバックエンドが負荷分散ノードならば1, そうでなければ0 + 18. クライアントのホスト名 + 19. クライアントのポート番号 (Unixドメインソケット、localhostでは表示されません) + 20. 最後に実行したSQL文 + - - コネクションがバックエンドに対して張られていない場合、データは表示されません。 コネクション情報が複数ある場合、複数行に 1 行 1 コネクション情報で表示されます。 + + -a もしくは --allオプションが指定されておらずコネクションがバックエンドに対して張られていない場合、データは表示されません。 コネクション情報が複数ある場合、複数行に 1 行 1 コネクション情報で表示されます。 - - オプションは出力内容を理解するのに役に立ちます。例: + + オプションは出力内容を理解するのに役に立ちます。例: - -$ pcp_proc_info -p 11001 --verbose 1406 -Database : test -Username : t-ishii -Start time : 2018-07-09 16:43:53 -Creation time: 2018-07-09 16:44:08 -Major : 3 -Minor : 0 -Counter : 1 -Backend PID : 1435 -Connected : 1 -PID : 1406 -Backend ID : 0 -Database : test -Username : t-ishii -Start time : 2018-07-09 16:43:53 -Creation time: 2018-07-09 16:44:08 -Major : 3 -Minor : 0 -Counter : 1 -Backend PID : 1436 -Connected : 1 -PID : 1406 -Backend ID : 1 - + +$ pcp_proc_info -p 11001 --verbose +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 +Client connection count : 0 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:55:58 +Client connection time : 2025-06-24 10:55:59 +Client idle duration : 0 +Client disconnection time : +Pool Counter : 1 +Backend PID : 1336703 +Connected : 1 +PID : 1336537 +Backend ID : 0 +Status : Idle +Load balance node : 0 +client_host : 192.168.10.11 +client_port : 39216 +statement : + +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 +Client connection count : 0 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:55:58 +Client connection time : 2025-06-24 10:55:59 +Client idle duration : 0 +Client disconnection time : +Pool Counter : 1 +Backend PID : 1336704 +Connected : 1 +PID : 1336537 +Backend ID : 1 +Status : Idle +Load balance node : 1 +client_host : 192.168.10.11 +client_port : 39216 +statement : select 1; + +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 (4:33 before process restarting) +Client connection count : 1 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:53:42 +Client connection time : 2025-06-24 10:53:42 +Client idle duration : 0 +Client disconnection time : 2025-06-24 10:55:37 +Pool Counter : 1 +Backend PID : 1336573 +Connected : 0 +PID : 1336544 +Backend ID : 0 +Status : Wait for connection +Load balance node : 0 +client_host : 192.168.10.11 +client_port : 39162 +statement : DISCARD ALL + +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 (4:33 before process restarting) +Client connection count : 1 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:53:42 +Client connection time : 2025-06-24 10:53:42 +Client idle duration : 0 +Client disconnection time : 2025-06-24 10:55:37 +Pool Counter : 1 +Backend PID : 1336574 +Connected : 0 +PID : 1336544 +Backend ID : 1 +Status : Wait for connection +Load balance node : 0 +client_host : 192.168.10.11 +client_port : 39162 +statement : + diff --git a/doc.ja/src/sgml/ref/pcp_promote_node.sgml b/doc.ja/src/sgml/ref/pcp_promote_node.sgml index b6f1e0c5b..67ccc3487 100644 --- a/doc.ja/src/sgml/ref/pcp_promote_node.sgml +++ b/doc.ja/src/sgml/ref/pcp_promote_node.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_promote_node - - Pgpool-II のノードをマスターに昇格させる + + Pgpool-II のノードをプライマリに昇格させる @@ -29,80 +29,159 @@ Pgpool-II documentation options node_id gracefully + switchover - 説明 - pcp_promote_node - - は Pgpool-II のノードをマスターに昇格させます。 - これは、マスタースレーブモードで ストリーミングレプリケーション構成の場合のみ使用できます。 - このコマンドは実際に PostgreSQL のスタンバイサーバを昇格するわけではないことに注意してください。 - 単に Pgpool-II の内部ステータスを変更し、フェイルオーバするだけです。 - ですので、ユーザはこのコマンドを使う際には自分で PostgreSQL のスタンバイを昇格させるようにしてください。 + pcp_promote_node + は Pgpool-II のノードをプライマリに昇格させます。 + これは、ストリーミングレプリケーション構成の場合のみ使用できます。 + switchoverオプションが指定されない限り、このコマンドは実際に PostgreSQL のスタンバイサーバを昇格するわけではないことに注意してください。 + 単に Pgpool-II の内部ステータスを変更するだけです。 + ですから、ユーザはこのコマンドを使う際には自分で PostgreSQL のスタンバイを昇格させるようにしてください。 + + + + switchoverが指定されると、Pgpool-IIは現在のプライマリを切り離し(内部状態をダウンにします)、新しいメインノード引数に指定されたノードIDをセットしながらを起動します。 + ほとんどのフェイルオーバースクリプトはメインノードを昇格させるので、指定されたノードは新しいプライマリになります。 + 以前のプライマリをスタンバイにするには、が正しく設定されていることが必要です。 + + + + switchoverが指定されていなければ、pcp_promote_nodeは、起動された後以下を行います。 + が設定されている場合はそれも起動されるので、十分な注意が必要です。 + 通常はを無効にしてからこのコマンドを実行することをお勧めします。 + + + + + + 指定されたスタンバイPostgreSQLのステータスをstandbyからprimaryに変更します。 + これはPgpool-II の内部ステータスを変更するだけで、実際にPostgreSQL のスタンバイサーバを昇格するわけではありません。 + + + + + + 引数で指定された以外のPostgreSQLノードのステータスをdownに変更します。 + これはPgpool-II の内部ステータスを変更するだけで、実際にPostgreSQLのスタンバイサーバをダウンさせるわけではありません。 + + + + + + が設定されている場合は、2でダウンさせたPostgreSQLノードに対してを実行します。 + + + + + + + + switchoverが指定されていれば、pcp_promote_nodeは、起動された後以下を行います。 + が設定されている場合はそれも起動されます。 + フェイルオーバースクリプトは、新しいプライマリを作り、他のノードはスタンバイになる必要があるので、このコマンドを実行する前に、を設定する必要があります。 + + + + + + プライマリPostgreSQLノードのステータスをdownに変更します。 + これにより、新しいメインノード引数に指定されたノードIDが設定された上でが起動します。 + ほとんどのフェイルオーバースクリプトはメインノードを昇格させるので、指定されたノードは新しいプライマリになります。 + + + + + + 引数で指定された以外のPostgreSQLノードのステータスをdownに変更します。 + これはPgpool-II の内部ステータスを変更するだけで、実際にPostgreSQLのスタンバイサーバをダウンさせるわけではありません。 + + + + + + が設定されている場合は、2でダウンさせたPostgreSQLノードに対してを実行します。 + + + + + - オプション - - - - - - - - - - マスターに昇格させるバックエンドノードのインデックスを指定します。 - - - - - - - - - + + + + + + + + - すべてのクライアントが接続を終了するまでノードを復帰しません。 - (ただし、 が -1 あるいは、 - が設定されている場合を除く) - - - - - + The index of backend node to promote as new main node. + The specified node must be in "up" or "waiting" status. + --> + プライマリに昇格させるバックエンドノードのインデックスを指定します。 + 指定するノードは"up"あるいは"waiting"状態でなければなりません。 + + + + + + + + + + + すべてのクライアントが接続を終了するまでノードを復帰しません。 + (ただし、 が -1 あるいは、 + が設定されている場合を除く) + + + + + + + + + + を起動することにより、指定されたノードを実際に昇格させます。 + また、現在のプライマリの状態をダウンにします。 + + + + + - - - - - を参照してください。 - - - + + + + + を参照してください。 + + + - - + + diff --git a/doc.ja/src/sgml/ref/pcp_recovery_node.sgml b/doc.ja/src/sgml/ref/pcp_recovery_node.sgml index ebdcb7e05..976b63f60 100644 --- a/doc.ja/src/sgml/ref/pcp_recovery_node.sgml +++ b/doc.ja/src/sgml/ref/pcp_recovery_node.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_recovery_node - - Pgpool-II のノードのデータを再同期させた上で復帰させる + + Pgpool-II のノードのデータを再同期させた上で復帰させる @@ -32,59 +32,59 @@ Pgpool-II documentation - 説明 - pcp_recovery_node - - は Pgpool-II のノードのデータを再同期させた上で復帰させます。 - pgpool.confに必要なパラメータを設定する方法の詳細については、をご覧ください。 + pcp_recovery_node + + は Pgpool-II のノードのデータを再同期させた上で復帰させます。 + pgpool.confに必要なパラメータを設定する方法の詳細については、をご覧ください。 - オプション - - + + - - - - - + + + + + - バックエンドノードのインデックスを指定します。 - - - + The index of backend node. + --> + バックエンドノードのインデックスを指定します。 + + + - + - - - + + --> + + + - を参照してください。 - - - + See . + --> + を参照してください。 + + + - - + + diff --git a/doc.ja/src/sgml/ref/pcp_reload_config.sgml b/doc.ja/src/sgml/ref/pcp_reload_config.sgml new file mode 100644 index 000000000..e1c4ca2f8 --- /dev/null +++ b/doc.ja/src/sgml/ref/pcp_reload_config.sgml @@ -0,0 +1,74 @@ + + + + + pcp_reload_config + + + + pcp_reload_config + 1 + PCP Command + + + + pcp_reload_config + + Pgpool-IIの設定ファイルを再読込します + + + + + pcp_reload_config + options + + + + + 説明 + + pcp_reload_config + Pgpool-IIの設定ファイルを再読込します。 + + + + + オプション + + + + + + + + + コマンドの与える影響範囲を指定します。 + + +    サポートされているコマンドスコープは以下です。 + デフォルトは"local"です。 + + c, cluster : クラスタを構成するすべてのPgpool-IIの設定ファイルを再読込みします。 + l, local : ローカルPgpool-IIの設定ファイルのみを再読込みします。 + + + + + + + + + + を参照してください。 + + + + + + + + + diff --git a/doc.ja/src/sgml/ref/pcp_stop_pgpool.sgml b/doc.ja/src/sgml/ref/pcp_stop_pgpool.sgml index b366f164a..efd8dc6aa 100644 --- a/doc.ja/src/sgml/ref/pcp_stop_pgpool.sgml +++ b/doc.ja/src/sgml/ref/pcp_stop_pgpool.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_stop_pgpool - - Pgpool-II を指定されたモードでシャットダウンする + + Pgpool-II を指定されたモードでシャットダウンする @@ -32,76 +32,95 @@ Pgpool-II documentation - 説明 - pcp_stop_pgpool - - は Pgpool-II を指定されたモードでシャットダウンします。 + pcp_stop_pgpool + + は Pgpool-II を指定されたモードで停止します。 - オプション - - + + - - - - - - - シャットダウンモードを指定します。 - - - - 指定できるモードは以下のとおりです。 - - - s, smart : smart モード - f, fast : fast モード - i, immediate : immediate モード - - - - ※ 現在は fast モードと immediate シャットダウンの処理に区別はありません。 命令を送った時点でクライアントがいる・いないに関わらずシャットダウン処理を即座に行います。 - - - + + + + + + + 停止モードを指定します。 + + + + 指定できるモードは以下のとおりです。 + デフォルトは"smart"です。 + + + s, smart : smart モード + f, fast : fast モード + i, immediate : immediate モード + + + + それぞれのモードの意味については、マニュアルをご覧ください。 + + + - + + + + + + コマンドの与える影響範囲を指定します。 + + +    サポートされているコマンドスコープは以下です。 + デフォルトは"local"です。 + + c, cluster : クラスタを構成するすべてのPgpool-IIノードを停止します。 + l, local : ローカルPgpool-IIノードのみを停止します。 + + + + + + - - - - - を参照してください。 - - - + + + + + を参照してください。 + + + - - + + diff --git a/doc.ja/src/sgml/ref/pcp_watchdog_info.sgml b/doc.ja/src/sgml/ref/pcp_watchdog_info.sgml index 033609781..61837969c 100644 --- a/doc.ja/src/sgml/ref/pcp_watchdog_info.sgml +++ b/doc.ja/src/sgml/ref/pcp_watchdog_info.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pcp_watchdog_info - - Pgpool-II の watchdog ステータスを表示します + + Pgpool-II の watchdog ステータスを表示します @@ -32,201 +32,192 @@ Pgpool-II documentation - 説明 - pcp_watchdog_info は、 - - Pgpool-IIpgpool.conf - の watchdog セクションで定義された Pgpool-II の watchdog ステータスを表示します。 - watchdog_id は情報を取得する watchdog ノードのインデックスです。 - 省略された場合には、クラスタ中の全ての Pgpool-II の watchdog ノードのステータスが表示されます。 - - - watchdog_id = 0 はローカルの Pgpool-II ノードのために予約されています。 - そのため、リモートの watchdog ノードのインデックスは 1 から始まります。 - pgpool.conf ではリモート watchdog ノードのインデックスは 0 をベースにしていますが、 - pcp_watchdog_info ではそれが 1 から始まることに注意してください。 - - - pcp_watchdog_info コマンドで情報を取得する際には、他の watchdog のインデックスに 1 を足す必要があります。 - - - 例えば、other_pgpool_hostname0 パラメータで定義されている、添字 0 である最初のリモート watchdog ノードの情報を取得するには、 - pcp_watchdog_info で watchdog_id = 1 を指定します。 - + pcp_watchdog_info は、指定されたノードIDの情報を表示します。 + - オプション - - - - - - - - + + + + + + + + - 情報を取得する他の Pgpool-II のインデックスを指定します。 - - + The index of other Pgpool-II to get information for. + --> + 情報を取得する他の Pgpool-II のインデックスを指定します。 + + - 0 の場合はローカルの watchdog の情報を取得します。 - - + Index 0 gets one's self watchdog information. + --> + 0 の場合はローカルの watchdog の情報を取得します。 + + - 省略された場合は、全ての watchdog ノードの情報を取得します。 - - - - - + If omitted then gets information of all watchdog nodes. + --> + 省略された場合は、全ての watchdog ノードの情報を取得します。 + + + + + - - - - - を参照してください。 - - - - - + + + + + を参照してください。 + + + + + - 出力例 - + - ここでは,出力例を示します。 - -$ pcp_watchdog_info -h localhost -U postgres - -3 NO Linux_host1.localdomain_9991 host1 - -Linux_host1.localdomain_9991 host1 9991 9001 7 STANDBY -Linux_host2.localdomain_9992 host2 9992 9002 4 MASTER -Linux_host3.localdomain_9993 host3 9993 9003 7 STANDBY - + Here is an example output: + --> + ここでは,出力例を示します。 + +$ pcp_watchdog_info -h localhost -p 9898 -U postgres +Password: +3 3 YES server1:9999 Linux server1.localdomain server1 + +server1:9999 Linux server1.localdomain server1 9999 9000 4 LEADER 0 MEMBER YES +server2:9999 Linux server2.localdomain server2 9999 9000 7 STANDBY 0 MEMBER YES +server3:9999 Linux server3.localdomain server3 9999 9000 7 STANDBY 0 MEMBER YES + - + 結果は以下の順のとおりです。 + + + 最初に出力される行は、watchdog クラスタの情報を示しています: + - 結果は以下の順のとおりです。 - - -最初に出力される行は、watchdog クラスタの情報を示しています: - -1. クラスタ内の全 watchdog ノード数 -2. 仮想 IP がこのノードで起動しているか? -3. マスターノード名 -4. マスターノードホスト - - - -それ以降は watchdog ノードのリストが出力されます: - -1. ノード名 -2. ホスト名 -3. pgpool ポート番号 -4. watchdog ポート番号 -5. 現在のノードステータス -6. 現在のノードステータス名 - + 1. クラスタ内の全 watchdog ノード数 + 2. アクティブなメンバーシップを持つwatchdog ノード数 + 3. 仮想 IP がこのノードで起動しているか? + 4. リーダノード名 + 5. リーダノードホスト + + + + それ以降は watchdog ノードのリストが出力されます: + + 1. ノード名 + 2. ホスト名 + 3. pgpool ポート番号 + 4. watchdog ポート番号 + 5. 現在のノードステータス + 6. 現在のノードステータス名 + 7. 現在のメンバーシップステータス + 8. 現在のメンバーシップステータス名 + 9. ライフチェックの開始状況 + - - モードは結果の詳細を表示できます。例えば: + + モードは結果の詳細を表示できます。例えば: - -$ pcp_watchdog_info -h localhost -v -U postgres - -Watchdog Cluster Information -Total Nodes : 3 -Remote Nodes : 2 -Quorum state : QUORUM EXIST -Alive Remote Nodes : 2 -VIP up on local node : NO -Master Node Name : Linux_host2.localdomain_9992 -Master Host Name : localhost - -Watchdog Node Information -Node Name : Linux_host1.localdomain_9991 -Host Name : host1 -Delegate IP : 192.168.1.10 -Pgpool port : 9991 -Watchdog port : 9001 -Node priority : 1 -Status : 7 -Status Name : STANDBY - -Node Name : Linux_host2.localdomain_9992 -Host Name : host2 -Delegate IP : 192.168.1.10 -Pgpool port : 9992 -Watchdog port : 9002 -Node priority : 1 -Status : 4 -Status Name : MASTER - -Node Name : Linux_host3.localdomain_9993 -Host Name : host3 -Delegate IP : 192.168.1.10 -Pgpool port : 9993 -Watchdog port : 9003 -Node priority : 1 -Status : 7 -Status Name : STANDBY - + +$ pcp_watchdog_info -h localhost -p 9898 -U pgpool -v +Password: +Watchdog Cluster Information +Total Nodes : 3 +Remote Nodes : 2 +Member Remote Nodes : 2 +Alive Remote Nodes : 2 +Nodes required for quorum: 2 +Quorum state : QUORUM EXIST +Local node escalation : YES +Leader Node Name : server1:9999 Linux server1.localdomain +Leader Host Name : server1 + +Watchdog Node Information +Node Name : server1:9999 Linux server1.localdomain +Host Name : server1 +Delegate IP : 192.168.56.150 +Pgpool port : 9999 +Watchdog port : 9000 +Node priority : 1 +Status : 4 +Status Name : LEADER +Membership Status : MEMBER +Lifecheck Started : YES + +Node Name : server2:9999 Linux server2.localdomain +Host Name : server2 +Delegate IP : 192.168.56.150 +Pgpool port : 9999 +Watchdog port : 9000 +Node priority : 1 +Status : 7 +Status Name : STANDBY +Membership Status : MEMBER +Lifecheck Started : YES + +Node Name : server3:9999 Linux server3.localdomain +Host Name : server3 +Delegate IP : 192.168.56.150 +Pgpool port : 9999 +Watchdog port : 9000 +Node priority : 1 +Status : 7 +Status Name : STANDBY +Membership Status : MEMBER +Lifecheck Started : YES + diff --git a/doc.ja/src/sgml/ref/pg_enc.sgml b/doc.ja/src/sgml/ref/pg_enc.sgml index 6736aa841..49d6ff7ea 100644 --- a/doc.ja/src/sgml/ref/pg_enc.sgml +++ b/doc.ja/src/sgml/ref/pg_enc.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pg_enc - - パスワードのAES256暗号化コマンド + + パスワードのAES256暗号化コマンド @@ -38,179 +38,216 @@ Pgpool-II documentation - + --> 説明 - pg_enc - - パスワードのAES256暗号化コマンド + pg_enc + + パスワードのAES256暗号化コマンド - + --> オプション - - - - - - - - - -暗号化鍵ファイルのパスをを指定します。 -デフォルトはユーザのホームディレクトリ配下の.pgpoolkeyファイルです。 - - - - - - - - - - -データベースのパスワードを暗号化するために使用する暗号化鍵です。 - - - - - - - - - - -pgpool.confファイルを指定します。 - - - - - - - - - - -標準入力からデータベースのパスワードを読み込みます。 - - - - - - - - - - -標準入力から暗号化鍵を読み込みます。 - - - - - - - - - - -pool_passwdファイルにAES256で暗号化したパスワードのエントリを作成します。 - - - - - - - - - - -your_usernameで指定したデータベースユーザ名のエントリをpool_passwdに作成します。 - - - - - - - - - - -pg_encのヘルプを表示します。 - - - - - - + + + + + + + + + + 暗号化鍵ファイルのパスを指定します。 + デフォルトはユーザのホームディレクトリ配下の.pgpoolkeyファイルですが、環境変数PGPOOLKEYFILEがあればそちらでの指定が優先されます。 + + + + + + + + + + + データベースのパスワードを暗号化するために使用する暗号化鍵です。 + + + + + + + + + + + pgpool.confファイルを指定します。 + + + + + + + + + + + 標準入力からデータベースのパスワードを読み込みます。 + + + + + + + + + + ユーザ名とパスワードのペアを含むファイルを指定します。 + + + + + + + + + + + 標準入力から暗号化鍵を読み込みます。 + + + + + + + + + + + pool_passwdファイルにAES256で暗号化したパスワードのエントリを作成します。 + + + + + + + + + + + your_usernameで指定したデータベースユーザ名のエントリをpool_passwdに作成します。 + + + + + + + + + + + pg_encのヘルプを表示します。 + + + + + + + pg_encの引数としてパスワードを指定し、パスワードに「$」文字が含まれる場合にはエスケープする必要があります。 + + + 例えば、パスワードとしてABC$123を使用する場合、 + +pg_enc -m -f /path/to/pgpool.conf -u username ABC\$123 + + + + - + --> - - -ここでは出力の例を示します。 - -pg_enc -p -db password: [your password] - + + + ここでは出力の例を示します。 + + pg_enc -p + db password: [your password] + - -または + + または -./pg_enc foo -trying to read key from file /home/pgpool/.pgpoolkey + ./pg_enc foo + trying to read key from file /home/pgpool/.pgpoolkey -jglid1QRgiCl/vfhHUDyVA== -pool_passwd string: AESjglid1QRgiCl/vfhHUDyVA== + jglid1QRgiCl/vfhHUDyVA== + pool_passwd string: AESjglid1QRgiCl/vfhHUDyVA== - -pg_encpool_passwd のパスワード生成のために使用できます。 - -pg_enc -m -f /path/to/pgpool.conf -u username -p -db password: [your password] - - -入力したパスワードとusernameのエントリが追加されます。 + + pg_encpool_passwd のパスワード生成のために使用できます。 + + pg_enc -m -f /path/to/pgpool.conf -u username -p + db password: [your password] + + + 入力したパスワードとusernameのエントリが追加されます。 + + + パスワードの入力が促されたりコマンド引数の中でパスワードを指定するのを避けたい場合はpg_encは名前:パスワードのペアをファイルから読むことができます。 + すべてのユーザ名と暗号化されたパスワードが認証ファイルに追加されます。 + + $ cat users.txt + username1:secretpassword1 + username2:secretpassword2 + + $ pg_enc -m -f /path/to/pgpool.conf -i users.txt + trying to read key from file /home/pgpool/.pgpoolkey + trying to read user:password pairs from file users.text + + $ cat /path/to/pool_passwd + username1:AESrx5QdpGyW/+4CB80KWtwhg== + username2:AESUAdohy7nCUhWliRI9WiYQA== + diff --git a/doc.ja/src/sgml/ref/pg_md5.sgml b/doc.ja/src/sgml/ref/pg_md5.sgml index ceebe39b8..677cc67c4 100644 --- a/doc.ja/src/sgml/ref/pg_md5.sgml +++ b/doc.ja/src/sgml/ref/pg_md5.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pg_md5 - - md5 暗号化したパスワードを生成する + + md5 暗号化したパスワードを生成する @@ -37,121 +37,154 @@ Pgpool-II documentation - 説明 - pg_md5 - - md5 暗号化したパスワードを生成します。 + pg_md5 + + md5 暗号化したパスワードを生成します。 - オプション - - - - - - - - + + + + + + + + - パスワードを引数に渡したくない場合は pg_md5 -p を実行すると標準入力からパスワードを読み込みます。 - - - - - - - - - + Prompt password using standard input. + --> + パスワードを引数に渡したくない場合は pg_md5 -p を実行すると標準入力からパスワードを読み込みます。 + + + + + + + + + - pool_passwd 認証ファイルに md5 認証パスワードを生成します。 - - - - - - - - - + Produce md5 authentication password. + --> + pool_passwd 認証ファイルに md5 認証パスワードを生成します。 + + + + + + + + + - md5 認証パスワードを生成する際、pool_passwdyour_username の md5 認証のエントリが登録されます。 - - - - - - - - - + When producing a md5 authentication password, create the pool_passwd entry for your_username. + --> + md5 認証パスワードを生成する際、pool_passwdyour_username の md5 認証のエントリが登録されます。 + + + + + + + + + - 設定ファイル pgpool.confへのパスを指定します。 - - - - - - + Specify the path to the pgpool.conf configuration file. + --> + 設定ファイル pgpool.confへのパスを指定します。 + + + + + + + + + + ユーザ名とパスワードのペアを含むファイルを指定します。 + + + + + + - - + - 以下は pcp.conf に登録する md5 暗号化されたパスワードを生成する例です。 - + The following are examples to encrypt your password into md5 hash format for pcp.conf. + --> + 以下は pcp.conf に登録する md5 暗号化されたパスワードを生成する例です。 + $ pg_md5 -p password: [your password] - + - または + または - + $ pg_md5 [your password] acbd18db4cc2f85cedef654fccc4a4d8 - + - + - また、pg_md5 は、 に - ユーザー名とmd5 暗号化されたパスワードのエントリを生成するためにも使用できます。 - -$pg_md5 -m -f /path/to/pgpool.conf -u username -p + pg_md5 can also be used for adding an entry of user name and + md5 encrypted password to + pool_passwd authentication file. + --> + また、pg_md5 は、 に + ユーザー名とmd5 暗号化されたパスワードのエントリを生成するためにも使用できます。 + +$ pg_md5 -m -f /path/to/pgpool.conf -u username -p password: [your password] $ cat /path/to/pool_passwd username:md55a231fcdb710d73268c4f44283487ba2 - - + + + パスワードの入力が促されたりコマンド引数の中でパスワードを指定するのを避けたい場合はpg_md5は名前:パスワードのペアをファイルから読むことができます。 + すべてのユーザ名と暗号化されたパスワードが認証ファイルに追加されます。 + +$ cat users.txt +username1:secretpassword1 +username2:secretpassword2 + +$ pg_md5 -m -f /path/to/pgpool.conf -i users.txt +trying to read username:password pairs from file users.txt + +$ cat /path/to/pool_passwd +username1:md533314126ba0b187df1e37f5ce6a489a8 +username2:md58ae92c6e1d6a48d80e2583fe715e2b36 + + + にエントリを登録せず、md5ハッシュされた文字列だけを表示させるには、引数としてパスワードとユーザ名を連結した文字列を渡します。 + 例として、パスワードに"password"、ユーザ名に"user"を渡す例を示します。 + +$ pg_md5 passworduser +4d45974e13472b5a0be3533de4666414 + + 実際にに登録するエントリは、先頭に"md5"を挿入してください。つまり、"md54d45974e13472b5a0be3533de4666414"となることに注意してください。 + diff --git a/doc.ja/src/sgml/ref/pgpool.sgml b/doc.ja/src/sgml/ref/pgpool.sgml index 59bc4a80d..b64df228a 100644 --- a/doc.ja/src/sgml/ref/pgpool.sgml +++ b/doc.ja/src/sgml/ref/pgpool.sgml @@ -11,19 +11,19 @@ Pgpool-II documentation pgpool 8 - + --> サーバコマンド pgpool - - Pgpool-IIメインサーバ + + Pgpool-IIメインサーバ @@ -47,282 +47,288 @@ Pgpool-II documentation - + --> 説明 - + Pgpool-IIメインサーバ - + --> 使用方法 - - pgpoolは3つのモードで実行されます。すなわち、start、stop、reloadです。 - stopもしくはreloadが指定されていなければ、start モードが指定されているものとします。 + + pgpoolは3つのモードで実行されます。すなわち、start、stop、reloadです。 + stopもしくはreloadが指定されていなければ、start モードが指定されているものとします。 - + --> 共通オプション - -3つのモードに共通のオプションです。 - - - - - - - - - -pool_hba.conf設定ファイルへのパスを指定します。 -そのファイルが標準の場所以外にある場合には必須です。 - - - - - - - - - - -pgpool.conf設定ファイルへのパスを指定します。 -そのファイルが標準の場所以外にある場合には必須です。 - - - - - - - - - - -pcp.conf設定ファイルへのパスを指定します。 -そのファイルが標準の場所以外にある場合には必須です。 - - - - - - - - - - -.pgpoolkeyファイルへのパスを指定します。 -AES256暗号化パスワードを使用し、このファイルが標準の場所以外にある場合には必須です。 - - - - - - - - - - -ヘルプを表示します。 - - - - - + + 3つのモードに共通のオプションです。 + + + + + + + + + + pool_hba.conf設定ファイルへのパスを指定します。 + そのファイルが標準の場所以外にある場合には必須です。 + + + + + + + + + + + pgpool.conf設定ファイルへのパスを指定します。 + そのファイルが標準の場所以外にある場合には必須です。 + + + + + + + + + + + pcp.conf設定ファイルへのパスを指定します。 + そのファイルが標準の場所以外にある場合には必須です。 + + + + + + + + + + + .pgpoolkeyファイルへのパスを指定します。 + AES256暗号化パスワードを使用し、このファイルが標準の場所以外にある場合には必須です。 + + + + + + + + + + + ヘルプを表示します。 + + + + + - + --> <productname>Pgpool-II</productname>メインサーバの起動 - - -startモードのオプションです。 - - - - - - - - - -Pgpool-IIをデバッグモードで起動します。 -大量のデバッグメッセージが出力されます。 - - - - - - - - - - -デーモンモードで起動しません。制御端末は切り離されません。 - - - - - - - - - - -アサーションチェックが有効になります。 -これはデバッグ用の機能です。 - - - - - - - - - - -の設定がmemcachedのときにクエリキャッシュのoidmapをクリアします。 - - - -の設定がshmemのときは、Pgpool-IIの起動時に常にoidmapをクリアするので、このオプションは不要です。 - - - - - - - - + + + startモードのオプションです。 + + + + + + + + + + Pgpool-IIをデバッグモードで起動します。 + 大量のデバッグメッセージが出力されます。 + + + + + + + + + + + デーモンモードで起動しません。制御端末は切り離されません。 + + + + + + + + + + + アサーションチェックが有効になります。 + これはデバッグ用の機能です。 + + + + + + + + + + + の設定がmemcachedのときにクエリキャッシュのoidmapをクリアします。 + + + + の設定がshmemのときは、Pgpool-IIの起動時に常にoidmapをクリアするので、このオプションは不要です。 + + + + + + + + + + + pgpool_statusファイルを破棄し、以前の状態を復元しません。 + + - -pgpool_statusファイルを破棄し、以前の状態を復元しません。 + このオプションは開発者向けテスト用の機能であり、それ以外の用途には使用しないでください。 + pgpool_statusファイルを不用意に削除すると、Pgpool-IIを再起動した時にsplit-brain状(primaryサーバが複数存在する状態)になることがあります。 - - - - + + + + + - + --> <productname>Pgpool-II</productname>メインサーバの停止 - - -stopモードのオプションです。 - - - - - - - - - -Pgpool-IIを停止します。 -shutdown_modeは、smartfastimmediateのいずれかです。 -smartが指定されると、Pgpool-IIはすべてのクライアントが接続を切るまで待ちます。 -fastあるいはimmediateが指定されると、すべてのクライアントが接続を切るまで待たず、直ちに終了します。 -現在の実装では、fastimmediateの間に挙動の違いはありません。 - - - - - - + + + stopモードのオプションです。 + + + + + + + + + + Pgpool-IIを停止します。 + shutdown_modeは、smartfastimmediateのいずれかです。 + smartが指定されると、Pgpool-IIはすべてのクライアントが接続を切るまで待ちます。 + fastあるいはimmediateが指定されると、すべてのクライアントが接続を切るまで待たず、直ちに終了します。 + 現在の実装では、fastimmediateの間に挙動の違いはありません。 + + + + + + - - <productname>Pgpool-II</productname>設定ファイルの再読み込み - - -Pgpool-IIの設定ファイルを再読み込みします。 -reloadモードには専用のオプションはありません。 -共通オプションが使えます。 - + + <productname>Pgpool-II</productname>設定ファイルの再読み込み + + + Pgpool-IIの設定ファイルを再読み込みします。 + reloadモードには専用のオプションはありません。 + 共通オプションが使えます。 + diff --git a/doc.ja/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml b/doc.ja/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml index 0ec1181cb..a576abf90 100644 --- a/doc.ja/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml +++ b/doc.ja/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml @@ -17,116 +17,116 @@ Pgpool-II documentation pgpool_adm_pcp_attach_node - -指定ノードをアタッチする関数 + + 指定ノードをアタッチする関数 - - - pcp_attach_node returns record - integer node_id - text host - integer port - text username - text password - out node_attached boolean - + + + pcp_attach_node returns record + integer node_id + text host + integer port + text username + text password + out node_attached boolean + - - pcp_attach_node returns record - integer node_id - text pcp_server - out node_attached boolean - + + pcp_attach_node returns record + integer node_id + text pcp_server + out node_attached boolean + - + - + --> 説明 - -pcp_attach_nodeは、ノードをPgpool-IIにアタッチします。 + + pcp_attach_nodeは、ノードをPgpool-IIにアタッチします。 - + --> 引数 - - + + - - node_id - - - -ノードをアタッチするバックエンドのインデックスです。 - - - + + node_id + + + + ノードをアタッチするバックエンドのインデックスです。 + + + - - pcp_server - - - -pcpサーバの外部サーバ名 - - - + + pcp_server + + + + pcpサーバの外部サーバ名 + + + - - - - - - -を参照ください。 - - - - - + + + + + + + を参照ください。 + + + + + - + --> 使用例 - - -使用例です。 - -test=# SELECT * FROM pcp_attach_node(1,'localhost',11001,'t-ishii','t-ishii'); - node_attached ---------------- - t -(1 row) - + + + 使用例です。 + + test=# SELECT * FROM pcp_attach_node(node_id => 1, host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + node_attached + --------------- + t + (1 row) + diff --git a/doc.ja/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml b/doc.ja/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml index cc1756484..699d02baf 100644 --- a/doc.ja/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml +++ b/doc.ja/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml @@ -17,131 +17,131 @@ Pgpool-II documentation pgpool_adm_pcp_detach_node - -指定ノードをデタッチする関数 + + 指定ノードをデタッチする関数 - - - pcp_detach_node returns record - integer node_id - boolean gracefully - text host - integer port - text username - text password - out node_detached boolean - + + + pcp_detach_node returns record + integer node_id + boolean gracefully + text host + integer port + text username + text password + out node_detached boolean + - - pcp_detach_node returns record - integer node_id - boolean gracefully - text pcp_server - out node_detached boolean - + + pcp_detach_node returns record + integer node_id + boolean gracefully + text pcp_server + out node_detached boolean + - + - + --> 説明 - - pcp_detach_nodeはノードをPgpool-IIからデタッチします。 + + pcp_detach_nodeはノードをPgpool-IIからデタッチします。 - + --> 引数 - - + + - - node_id - - - -ノードをデタッチするバックエンドのインデックスです。 - - - + + node_id + + + + ノードをデタッチするバックエンドのインデックスです。 + + + - - gracefully - - - -もし真ならpgpool-IIのすべてのセッションが終了するまで待ちます。 - - - + + gracefully + + + + もし真ならpgpool-IIのすべてのセッションが終了するまで待ちます。 + + + - - pcp_server - - - -pcpサーバの外部サーバ名 - - - + + pcp_server + + + + pcpサーバの外部サーバ名 + + + - - - - - - -を参照ください。 - - - - - + + + + + + + を参照ください。 + + + + + - + --> 使用例 - - -使用例です。 - -test=# SELECT * FROM pcp_detach_node(1, 'false', 'localhost',11001,'t-ishii','t-ishii'); - node_detached ---------------- - t -(1 row) - + + + 使用例です。 + + test=# SELECT * FROM pcp_detach_node(node_id => 1, gracefully => 'false', host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + node_detached + --------------- + t + (1 row) + diff --git a/doc.ja/src/sgml/ref/pgpool_adm_pcp_health_check_stats.sgml b/doc.ja/src/sgml/ref/pgpool_adm_pcp_health_check_stats.sgml new file mode 100644 index 000000000..4fdf72858 --- /dev/null +++ b/doc.ja/src/sgml/ref/pgpool_adm_pcp_health_check_stats.sgml @@ -0,0 +1,163 @@ + + + + + pgpool_adm_pcp_health_check_stats + + + + pgpool_adm_pcp_health_check_stats + 3 + pgpool_adm extension + + + + pgpool_adm_pcp_health_check_stats + + 与えられたノードIDのヘルスチェック統計データを表示する関数 + + + + + + + pcp_health_check_stats returns record + integer node_id + text host + integer port + text username + text password + out node_id integer + out host text + out port integer + out status text + out role text + out last_status_change timestamp + out total_count bigint + out success_count bigint + out fail_count bigint + out skip_count bigint + out retry_count bigint + out average_retry_count bigint + out max_retry_count bigint + out max_health_check_duration bigint + out min_health_check_duration bigint + out average_health_check_duration float4 + out last_health_check timestamp + out last_successful_health_check timestamp + out last_skip_health_check timestamp + out last_failed_health_check timestamp + + + + pcp_health_check_stats returns record + integer node_id + text pcp_server + out node_id integer + out host text + out port integer + out status text + out role text + out last_status_change timestamp + out total_count bigint + out success_count bigint + out fail_count bigint + out skip_count bigint + out retry_count bigint + out average_retry_count bigint + out max_retry_count bigint + out max_health_check_duration bigint + out min_health_check_duration bigint + out average_health_check_duration float4 + out last_health_check timestamp + out last_successful_health_check timestamp + out last_skip_health_check timestamp + out last_failed_health_check timestamp + + + + + + + 説明 + + pcp_health_check_stats + 与えられたノードIDのヘルスチェック統計データを表示します。 + + + + + 引数 + + + + + node_id + + + 情報を取得するバックエンドノード + + + + + + pcp_server + + + pcpサーバの外部サーバ名 + + + + + + + + + を参照ください。 + + + + + + + + + 使用例 + + 使用例です。 + +test=# select * from pcp_health_check_stats(node_id => 0, host => '', port => 11001, username => 't-ishii', password => 't-ishii'); +-[ RECORD 1 ]-----------------+-------------------- +node_id | 0 +host | /tmp +port | 11002 +status | up +role | primary +last_status_change | 2020-02-25 16:05:29 +total_count | 3 +success_count | 3 +fail_count | 0 +skip_count | 0 +retry_count | 0 +average_retry_count | 0 +max_retry_count | 0 +max_health_check_duration | 5 +min_health_check_duration | 3 +average_health_check_duration | 4.333333 +last_health_check | 2020-02-25 16:05:47 +last_successful_health_check | 2020-02-25 16:05:47 +last_skip_health_check | +last_failed_health_check | + + + + + 表示データの詳細に関してはをご覧ください。 + + + + + diff --git a/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_count.sgml b/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_count.sgml index 06c6808cb..939203253 100644 --- a/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_count.sgml +++ b/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_count.sgml @@ -17,99 +17,99 @@ Pgpool-II documentation pgpool_adm_pcp_node_count - -ノード数を取得する関数 + + ノード数を取得する関数 - - - pcp_node_count returns integer - text host - integer port - text username - text password - + + + pcp_node_count returns integer + text host + integer port + text username + text password + - - pcp_node_count returns integer - text pcp_server - + + pcp_node_count returns integer + text pcp_server + - + - + --> 説明 - -pcp_node_countはDBノードの数を取得します。 + + pcp_node_countはDBノードの数を取得します。 - + --> 引数 - - + + - - pcp_server - - - -pcpサーバの外部サーバ名 - - - + + pcp_server + + + + pcpサーバの外部サーバ名 + + + - - - - - - -を参照ください。 - - - - - + + + + + + + を参照ください。 + + + + + - + --> 使用例 - - -使用例です。 - -test=# SELECT * FROM pcp_node_count('localhost',11001,'t-ishii','t-ishii'); - node_count ------------- - 2 -(1 row) - + + + 使用例です。 + + test=# SELECT * FROM pcp_node_count(host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + node_count + ------------ + 2 + (1 row) + diff --git a/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_info.sgml b/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_info.sgml index 5867c8c87..7a206b672 100644 --- a/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_info.sgml +++ b/doc.ja/src/sgml/ref/pgpool_adm_pcp_node_info.sgml @@ -17,146 +17,179 @@ Pgpool-II documentation pgpool_adm_pcp_node_info - -指定ノードIDの情報を表示する関数 + + 指定ノードIDの情報を表示する関数 - - - pcp_node_info returns record - integer node_id - text host - integer port - text username - text password - out status text - out weight float4 - out role text - out replication_delay bigint - out last_status_change timestamp - - - - pcp_node_info returns record - integer node_id - text pcp_server - out status text - out weight float4 - out role text - out replication_delay bigint - out last_status_change timestamp - - - + + + pcp_node_info returns record + integer node_id + text host + integer port + text username + text password + out status text + out pg_status text + out weight float4 + out role text + out pg_role text + out replication_delay bigint + out replication_state text + out replication_sync_state text + out last_status_change timestamp + + + + pcp_node_info returns record + integer node_id + text pcp_server + out status text + out pg_status text + out weight float4 + out role text + out pg_role text + out replication_delay bigint + out replication_state text + out replication_sync_state text + out last_status_change timestamp + + + - + --> 説明 - - pcp_node_infoは指定されたノードIDの情報を表示します。 + + pcp_node_infoは指定されたノードIDの情報を表示します。 - + --> 引数 - - + + - - node_id - - - -情報を取得するバックエンドノード - - - - - - pcp_server - - - -pcpサーバの外部サーバ名 - - - + + node_id + + + + 情報を取得するバックエンドノード + + + - - - - - - -を参照ください。 - - - - - + + pcp_server + + + + pcpサーバの外部サーバ名 + + + + + + + + + + + を参照ください。 + + + + + - + --> 使用例 - - -使用例です。 - -test=# SELECT * FROM pcp_node_info(0,'',11001,'t-ishii','t-ishii'); - host | port | status | weight | role | replication_delay | last_status_change -------+-------+-------------------+--------+---------+-------------------+--------------------- - /tmp | 11002 | Connection in use | 0 | Primary | 0 | 2018-07-04 17:34:39 + + + 使用例です。 + +test=# SELECT * FROM pcp_node_info(node_id => 1, host => '', port => 11001, username => 't-ishii', password => 't-ishii'); + host | port | status | pg_status | weight | role | pg_role | replication_delay | replication_state | replication_sync_state | last_status_change +------+-------+-------------------+-----------+--------+---------+---------+-------------------+-------------------+------------------------+--------------------- + /tmp | 11003 | Connection in use | up | 0.5 | Standby | standby | 0 | streaming | async | 2021-02-27 15:10:19 (1 row) - + + + + + 表示データの意味については、をご覧ください。 - - -role, replication_delay, last_status_change出力パラメータはPgpool-II 4.0で追加されました。 -すでに4.0以前のpgpool_adm拡張をインストールされている場合は、ALTER EXTENSION SQLコマンドを使って更新が可能です。 - - ALTER EXTENSION pgpool_adm UPDATE; - - + + + role, replication_delay, last_status_change出力パラメータはPgpool-II 4.0で追加されました。 + すでに4.0以前のpgpool_adm拡張をインストールしている場合は、ALTER EXTENSION SQLコマンドを使って更新が可能です。 + + ALTER EXTENSION pgpool_adm UPDATE; + + + + + + replication_state, replication_sync_state出力パラメータはPgpool-II 4.1で追加されました。 + すでに4.1以前のpgpool_adm拡張をインストールしている場合は、ALTER EXTENSION SQLコマンドを使って更新が可能です。 + + ALTER EXTENSION pgpool_adm UPDATE; + + + + + + + pg_status, pg_role出力パラメータはPgpool-II 4.3で追加されました。 + すでに4.2以前のpgpool_adm拡張をインストールしている場合は、ALTER EXTENSION SQLコマンドを使って更新が可能です。 + + ALTER EXTENSION pgpool_adm UPDATE; + + + + diff --git a/doc.ja/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml b/doc.ja/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml index 46602d4a0..f6a6d47f5 100644 --- a/doc.ja/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml +++ b/doc.ja/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml @@ -17,111 +17,111 @@ Pgpool-II documentation pgpool_adm_pcp_pool_status - -pgpool.confのパラメータを取得する関数 + + pgpool.confのパラメータを取得する関数 - - - pcp_pool_status returns record - text host - integer port - text username - text password - out item text - out value text - out description text - + + + pcp_pool_status returns setof record + text host + integer port + text username + text password + out item text + out value text + out description text + - - pcp_pool_status returns record - text pcp_server - out item text - out value text - out description text - + + pcp_pool_status returns setof record + text pcp_server + out item text + out value text + out description text + - + - + --> 説明 - -pcp_pool_statusはpgpool.confのパラメータを取得します。 + + pcp_pool_statusはpgpool.confのパラメータを取得します。 - + --> 引数 - - + + - - pcp_server - - - -pcpサーバの外部サーバ名 - - - + + pcp_server + + + + pcpサーバの外部サーバ名 + + + - - - - - - -を参照ください。 - - - - - + + + + + + + を参照ください。 + + + + + - + --> 使用例 - - -使用例です。 - - test=# SELECT * FROM pcp_pool_status('localhost',11001,'t-ishii','t-ishii') WHERE item ~ 'backend.*0'; - item | value | description --------------------------+------------------------------------------------+------------------------------- - backend_hostname0 | /tmp | backend #0 hostname - backend_port0 | 11002 | backend #0 port number - backend_weight0 | 0.500000 | weight of backend #0 - backend_data_directory0 | /home/t-ishii/work/pgpool-II/current/aaa/data0 | data directory for backend #0 - backend_status0 | 2 | status of backend #0 - backend_flag0 | ALLOW_TO_FAILOVER | backend #0 flag -(6 rows) - + + + 使用例です。 + + test=# SELECT * FROM pcp_pool_status(host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii') WHERE item ~ 'backend.*0'; + item | value | description + -------------------------+------------------------------------------------+------------------------------- + backend_hostname0 | /tmp | backend #0 hostname + backend_port0 | 11002 | backend #0 port number + backend_weight0 | 0.500000 | weight of backend #0 + backend_data_directory0 | /home/t-ishii/work/pgpool-II/current/aaa/data0 | data directory for backend #0 + backend_status0 | 2 | status of backend #0 + backend_flag0 | ALLOW_TO_FAILOVER | backend #0 flag + (6 rows) + diff --git a/doc.ja/src/sgml/ref/pgpool_adm_pcp_proc_info.sgml b/doc.ja/src/sgml/ref/pgpool_adm_pcp_proc_info.sgml new file mode 100644 index 000000000..a5a82e6f8 --- /dev/null +++ b/doc.ja/src/sgml/ref/pgpool_adm_pcp_proc_info.sgml @@ -0,0 +1,257 @@ + + + + + pgpool_adm_pcp_proc_info + + + + pgpool_adm_pcp_proc_info + 3 + pgpool_adm extension + + + + pgpool_adm_pcp_proc_info + + Pgpool-IIの子プロセスの情報を表示する関数 + + + + + + + pcp_proc_info returns record + text host + integer port + text username + text password + out database text + out username text + out start_time text + out client_connection_count text + out major text + out minor text + out backend_connection_time text + out client_connection_time text + out client_idle_duration text + out client_disconnection_time text + out pool_counter text + out backend_pid text + out connected text + out pid text + out backend_id text + out status text + out load_balance_node text + out client_host text + out client_port text + out statement + + + + pcp_proc_info returns record + integer node_id + text pcp_server + out database text + out username text + out start_time text + out client_connection_count text + out major text + out minor text + out backend_connection_time text + out client_connection_time text + out client_idle_duration text + out client_disconnection_time text + out pool_counter text + out backend_pid text + out connected text + out pid text + out backend_id text + out status text + out load_balance_node text + out client_host text + out client_port text + out statement + + + + + + + 説明 + + pcp_proc_info + Pgpool-IIの子プロセスの情報を表示します。 + 表示される情報はと同じです。 + すべてのデータ型は"text"です。 + + + + + 引数 + + + + + pcp_server + + + pcpサーバの外部サーバ名 + + + + + + + + + を参照ください。 + + + + + + + + + 使用例 + + 以下の例では、検索条件で"connected"列 = '1'を指定して、現在クライアントから接続のあるプロセス情報のみを表示しています。 + このpsqlセッションでfrom pcp_proc_infoを呼び出していて、その情報は行1と2に表示されています。 + select文はbackend_id = '0'(おそらくprimaryです)にのみ送信されているので、行1の"status"列は"Execute command"となっており、"statement"列には実行したselect文が表示されていますが、backend_id = '1'にはselect文が送信されていないので、行2のstatementは空白となっています。 + + + 別psqlセッションの情報は行2, 3に表示されています。 + この例では"select 1"は"backend_id" = '1'(おそらくstandby)に送信されています。 + +test=# select * from pcp_proc_info(host => '', port => 11001, username => 't-ishii', password => 't-ishii') where connected = '1'; +-[ RECORD 1 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:37 +client_connection_time | 2025-02-22 20:58:37 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14750 +connected | 1 +pid | 14585 +backend_id | 0 +status | Execute command +load_balance_node | 1 +client_host | 127.0.0.1 +client_port | 59120 +statement | select * from pcp_proc_info(host => '', port => 11001, username => 't-ishii', password => 't-ishii') where connected = '1'; +-[ RECORD 2 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:37 +client_connection_time | 2025-02-22 20:58:37 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14751 +connected | 1 +pid | 14585 +backend_id | 1 +status | Execute command +load_balance_node | 0 +client_host | 127.0.0.1 +client_port | 59120 +statement | +-[ RECORD 3 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:56 +client_connection_time | 2025-02-22 20:58:56 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14767 +connected | 1 +pid | 14601 +backend_id | 0 +status | Idle +load_balance_node | 0 +client_host | 127.0.0.1 +client_port | 54072 +statement | +-[ RECORD 4 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:56 +client_connection_time | 2025-02-22 20:58:56 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14768 +connected | 1 +pid | 14601 +backend_id | 1 +status | Idle +load_balance_node | 1 +client_host | 127.0.0.1 +client_port | 54072 +statement | select 1; + + + + 次の例では、"pgpool_query_info"という関数を登録し、pgpool_adm_pcp_proc_info、pgpool_adm_pcp_node_info、pgpool_adm_pcp_pool_statusを結合してpgpoolの子プロセスが最後に実行したクエリを、次の情報と一緒に表示します。 + usernae, database, client host, client port, pgpool host, pgpool + port, pgpool pid, backend host, backend port, backend pid, backend + role and SQL statement。 + +create function pgpool_query_info(pcp_host text, pcp_port int, pgpool_username text, password text) +returns table (username text, database text, client_host text, client_port text, +pgpool_host text, pgpool_port text, pgpool_pid text, +backend_host text, backend_port text, backend_pid text, backend_role text, statement text) as $$ +select p.username, p.database, p.client_host,p.client_port, +$1 as pgpool_host, s.value as pgpool_port, p.pid as pgpool_pid, +b.host as backend_host, b.port as backend_port, p.backend_pid as backend_pid, +b.role as backend_role, +p.statement +from pcp_proc_info(host=> $1, port => $2, username => $3, password => $4) as p, +pcp_node_info(node_id=>p.backend_id::int, host => $1, port => $2, +username => $3, password => $4) as b, +pcp_pool_status(host=> $1, port => $2, username => $3, password => $4) as s +where p.connected = 1::text and p.statement != '' and +p.statement !~ 'pcp_proc_info' and p.statement !~ 'pgpool_query_info' and +s.item = 'port' +$$ +language SQL; +CREATE FUNCTION + +select * from pgpool_query_info('192.168.10.11', 11001, 't-ishii', 't-ishii'); + username | database | client_host | client_port | pgpool_host | pgpool_port | pgpool_pid | backend_host | backend_port | backend_pid | backend_role | statement +----------+----------+---------------+-------------+---------------+-------------+------------+--------------+--------------+-------------+--------------+----------- + t-ishii | test | 192.168.10.11 | 60542 | 192.168.10.11 | 11000 | 1356156 | localhost | 11002 | 1356240 | Primary | select 2; + t-ishii | test | 192.168.10.11 | 43856 | 192.168.10.11 | 11000 | 1356167 | localhost | 11003 | 1356255 | Standby | select 1; +(2 rows) + + + + 表示データの詳細に関してはをご覧ください。 + + + + + diff --git a/doc.ja/src/sgml/ref/pgpool_reset.sgml b/doc.ja/src/sgml/ref/pgpool_reset.sgml index 95929d57d..cb66a19b5 100644 --- a/doc.ja/src/sgml/ref/pgpool_reset.sgml +++ b/doc.ja/src/sgml/ref/pgpool_reset.sgml @@ -23,48 +23,48 @@ PostgreSQL documentation - -PGPOOL RESET configuration_parameter -PGPOOL RESET ALL - + + PGPOOL RESET configuration_parameter + PGPOOL RESET ALL + - 説明 - - PGPOOL RESETPgpool-II のパラメータの値をデフォルト値に戻します。 - デフォルト値とは、現行セッション内で PGPOOL SET - コマンドが発行されなかった場合に変数が保持していた値として定義されます。 - このコマンドは PostgreSQL の - + + PGPOOL RESETPgpool-II のパラメータの値をデフォルト値に戻します。 + デフォルト値とは、現行セッション内で PGPOOL SET + コマンドが発行されなかった場合に変数が保持していた値として定義されます。 + このコマンドは PostgreSQL の + RESET コマンドと似ていますが、 - PostgreSQLRESET コマンドと区別するために、 - PGPOOL というキーワードが追加されました。 + PostgreSQLRESET コマンドと区別するために、 + PGPOOL というキーワードが追加されました。 - パラメータ @@ -74,7 +74,7 @@ PGPOOL RESET ALL configuration_parameter - 設定可能な全ての Pgpool-II のパラメータをデフォルト値に戻します。 @@ -100,33 +100,33 @@ PGPOOL RESET ALL - - - 設定変数をデフォルト値に設定します。 - -PGPOOL RESET client_idle_limit; - + 設定変数をデフォルト値に設定します。 + + PGPOOL RESET client_idle_limit; + - 全パラメータの設定値をデフォルト値に戻します。 - -PGPOOL RESET ALL; - + + PGPOOL RESET ALL; + - 関連項目 diff --git a/doc.ja/src/sgml/ref/pgpool_set.sgml b/doc.ja/src/sgml/ref/pgpool_set.sgml index e91c86114..cd3777fb0 100644 --- a/doc.ja/src/sgml/ref/pgpool_set.sgml +++ b/doc.ja/src/sgml/ref/pgpool_set.sgml @@ -23,79 +23,79 @@ PostgreSQL documentation - -PGPOOL SET configuration_parameter { TO | = } { value | 'value' | DEFAULT } - + + PGPOOL SET configuration_parameter { TO | = } { value | 'value' | DEFAULT } + - 説明 - -PGPOOL SET は現行セッションで Pgpool-II の設定パラメータを変更します。このコマンドは PostgreSQLSET コマンドと似ていますが、PostgreSQLSET コマンドと区別するために、PGPOOL というキーワードが追加されました。 に列挙されているパラメータの多くは PGPOOL SET で変更できますが、現行セッションで使用される値にのみ影響することにご注意ください。 + PGPOOL SET は現行セッションで Pgpool-II の設定パラメータを変更します。このコマンドは PostgreSQLSET コマンドと似ていますが、PostgreSQLSET コマンドと区別するために、PGPOOL というキーワードが追加されました。 に列挙されているパラメータの多くは PGPOOL SET で変更できますが、現行セッションで使用される値にのみ影響することにご注意ください。 - + - パラメータ の設定値を変更する: -PGPOOL SET client_idle_limit = 350; + PGPOOL SET client_idle_limit = 350; - - パラメータ の値をデフォルトの設定にリセットする: + + パラメータ の値をデフォルトの設定にリセットする: -PGPOOL SET client_idle_limit TO DEFAULT; + PGPOOL SET client_idle_limit TO DEFAULT; - パラメータ の値を変更する: -PGPOOL SET log_min_messages TO INFO; + PGPOOL SET log_min_messages TO INFO; - + diff --git a/doc.ja/src/sgml/ref/pgpool_set_cache.sgml b/doc.ja/src/sgml/ref/pgpool_set_cache.sgml new file mode 100644 index 000000000..82f02359b --- /dev/null +++ b/doc.ja/src/sgml/ref/pgpool_set_cache.sgml @@ -0,0 +1,131 @@ + + + + + PGPOOL SET + + + + PGPOOL SET CACHE + 1 + SQL - Language Statements + + + + PGPOOL SET CACHE + + クエリキャッシュを削除する + + + + + PGPOOL SET CACHE DELETE 'query' + + + + + + 説明 + + + + PGPOOL SET CACHE DELETEコマンドは、以前のクエリで作成されたクエリキャッシュを削除します。 + クエリ文字列は、末尾の';'も含めて以前のクエリと完全に一致していなければなりません。 + にもかかわらず、' (単一引用符)がクエリに含まれている場合は、以下のように'を前に追加する必要があります。 + +PGPOOL SET CACHE DELETE 'SELECT ''FOO'';'; + + + このコマンドはとりわけ、クエリ中にテーブル参照を含んでいないために自動キャッシュ削除機能で削除されないクエリに有用です。 + + + + 以前のクエリが思い出せない時は、を使って、削除したいクエリキャッシュも含み、すべてのクエリキャッシュを削除することができます。 + ただし、これはPgpool-IIの管理者権限が必要になります。 + + + + クエリキャッシュの削除に成功すると、以下のNOTICEメッセージを表示します。 + +NOTICE: query cache deleted. query: "query string" + + + クエリキャッシュが存在しないか、クエリキャッシュが無効の場合には、以下のNOTICEメッセージを表示します。 + +NOTICE: query cache does not exist for query: "query string" + + + + + + + + + + + 間違って希望しないクエリキャッシュを作成してしまいました。 + 以下のコマンドで削除します。 + +test=# /*FORCE QUERY CACHE*/SELECT current_timestamp; + current_timestamp +------------------------------- + 2024-10-18 18:25:07.826423+09 +(1 row) + +test=# PGPOOL SET CACHE DELETE '/*FORCE QUERY CACHE*/SELECT current_timestamp;'; +NOTICE: query cache deleted. query: "/*FORCE QUERY CACHE*/SELECT current_timestamp;" +SET + + + + + + + + 関連項目 + + + + + + + diff --git a/doc.ja/src/sgml/ref/pgpool_setup.sgml b/doc.ja/src/sgml/ref/pgpool_setup.sgml index 6ba6adfa7..440384db6 100644 --- a/doc.ja/src/sgml/ref/pgpool_setup.sgml +++ b/doc.ja/src/sgml/ref/pgpool_setup.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation pgpool_setup - - Pgpool-II クラスタのテスト環境を構築するツール + + Pgpool-II クラスタのテスト環境を構築するツール @@ -31,400 +31,482 @@ Pgpool-II documentation - 説明 - pgpool_setup - - はカレントディレクトリで Pgpool-II - とノード数が指定できる複数の PostgreSQL - のクラスタテスト環境を構築するツールです。 - カレントディレクトリは空である必要があります。 + pgpool_setup + + はカレントディレクトリで Pgpool-II + とノード数が指定できる複数の PostgreSQL + のクラスタテスト環境を構築するツールです。 + カレントディレクトリは空である必要があります。 - - pgpool_setup はテストのために使うツールなので、 - 実際の業務システムで利用することはおすすめしません。 + + pgpool_setup はテストのために使うツールなので、 + 実際の業務システムで利用することはおすすめしません。 - - 現在、「ストリーミングレプリケーションモード」、「ネイティブレプリケーションモード」、「raw モード」及び「ロジカルレプリケーションモード」に対応しています。 - Watchdog の対応については をご参照下さい。 + pgpool_setup はlocalhostに対してsshを実行します。 + パスワード無しでsshでlocalhostにログインできるように事前に設定してください。 + + + + + 現在、「ストリーミングレプリケーションモード」、「ネイティブレプリケーションモード」、「raw モード」、「ロジカルレプリケーションモード」及び「スナップショットアイソレーションモード」に対応しています。 + Watchdog の対応については をご参照下さい。 - オプション - + - pgpool_setup は以下のコマンドライン引数を受け付けます: + pgpool_setup accepts the following command-line arguments: + --> + pgpool_setup は以下のコマンドライン引数を受け付けます: - + - - - - + + + + - 動作モードを指定します。modeは - r (ネイティブレプリケーションモード), s (ストリーミングレプリケーションモード)、n (raw モード)、l (ロジカルレプリケーションモード)またはl(slonyモード)を指定できます。 - 指定しない場合は、s (ストリーミングレプリケーションモード) を指定した見なされます。 - - - - - - - - + Specifies the running mode. mode + can be r (native replication mode), s (streaming replication mode), + n (raw mode), l + (logical replication mode) or y (slony mode). If this is + omitted, s is assumed. + --> + 動作モードを指定します。modeは + r (ネイティブレプリケーションモード), s (ストリーミングレプリケーションモード)、n (raw モード)、l (ロジカルレプリケーションモード)、y(slonyモード)及びi(スナップショットアイソレーションモード)を指定できます。 + 指定しない場合は、s (ストリーミングレプリケーションモード) を指定したと見なされます。 + + + + + + + + - PostgreSQL のノード数を指定します。指定しない場合は、ノード数が 2 です。 - - - - - - - - + Specifies the number of PostgreSQL installations. + If this is omitted, 2 is used. + --> + PostgreSQL のノード数を指定します。指定しない場合は、ノード数が 2 です。 + + + + + + + + - ベースとなるポート番号を指定します。 - Pgpool-II のポートは base_port、pcp のポートは base_port + 1、 - 最初の PostgreSQL ノードのポートは base_port + 2、 - 2 番目の PostgreSQL ノードのポートは base_port + 3 というようになります。 - - + Specify the base port number used by Pgpool-II and PostgreSQL. + Pgpool-II port is base_port. pcp port is base_port + 1. The + first PostgreSQL node's port is base_port + 2, second + PostgreSQL node's port is base_port + 3 and so on. + ベースとなるポート番号を指定します。 + --> + ベースとなるポート番号を指定します。 + Pgpool-II のポートは base_port、pcp のポートは base_port + 1、 + 最初の PostgreSQL ノードのポートは base_port + 2、 + 2 番目の PostgreSQL ノードのポートは base_port + 3 というようになります。 + + - -pg オプションを指定した場合、 最初の PostgreSQL ノードのポートは pg_base_port、 - 2 番目の PostgreSQL ノードのポートは pg_base_port + 1 というように割り当てていきます。 - - - + If -pg option is specified, the first PostgreSQL node's port is + assigned to pg_base_port, the second PostgreSQL node's port is + pg_base_port + 1 and so on. + --> + -pg オプションを指定した場合、 最初の PostgreSQL ノードのポートは pg_base_port、 + 2 番目の PostgreSQL ノードのポートは pg_base_port + 1 というように割り当てていきます。 + + + - 指定しない場合、ベースとなるポート番号は 11000 です。 - - - - - - - - + If this is omitted, 11000 is used. + --> + 指定しない場合、ベースとなるポート番号は 11000 です。 + + + + + + + + - PostgreSQL のベースとなるポート番号を指定します。 - 最初の PostgreSQL ノードのポートは pg_base_port、 - 2 番目の PostgreSQL ノードのポートは pg_base_port + 1 というようになります。 - - + Specify the base port number used by PostgreSQL. + The first PostgreSQL node's port is base_port + 2, second + PostgreSQL node's port is base_port + 3 and so on. + --> + PostgreSQL のベースとなるポート番号を指定します。 + 最初の PostgreSQL ノードのポートは pg_base_port、 + 2 番目の PostgreSQL ノードのポートは pg_base_port + 1 というようになります。 + + - 省略した場合は、 base_port+2 が使われます。 - - - - - - - - - + If this is omitted, base_port+2 is used. + --> + 省略した場合は、 base_port+2 が使われます。 + + + + + + + + + - セットアップ終了後に Pgpool-II, PostgreSQL を終了しません。 - - - - - - - - + Do not stop pgpool and PostgreSQL after the work. + --> + セットアップ終了後に Pgpool-II, PostgreSQL を終了しません。 + + + + + + + + + + デバッグモードで Pgpool-II を起動します。 + + + + + + + + - デバッグモードで Pgpool-II を起動します。 - - - - - - - - - + ストリーミングレプリケーションモードの時に、アーカイブの代わりにレプリケーションスロットを使います。 + アーカイブディレクトリはPostgreSQLクラスタに共有されているので、スタンバイが昇格すると、アーカイアブディレクトリ内のタイムラインが変わり、他のスタンバイが停止してしまいます。 + レプリケーションスロットを使うとこの問題が起きないので、レプリケーションスロットをサポートしているPostgreSQL 9.4以降が使えるのであれば、常にレプリケーションスロットを使うのがお勧めです。 + pgpool_setupが使うレプリケーションスロット名は、pgpool_setup_slotです。 + + + + + + + + + + リカバリスクリプト(basebackup.sh)中でpg_rewindを使います。 + このコマンドが失敗すると、通常のrsyncを使います。 + pg_rewindは、データベースクラスタのすべてをコピーしないので、rsyncに比べてずっと高速になることがあります。 + + + + + + + + + -ストリーミングレプリケーションモードの時に、アーカイブの代わりにレプリケーションスロットを使います。 -アーカイブディレクトリはPostgreSQLクラスタに共有されているので、スタンバイが昇格すると、アーカイアブディレクトリ内のタイムラインが変わり、他のスタンバイが停止してしまいます。 -レプリケーションスロットを使うとこの問題が起きないので、レプリケーションスロットをサポートしているPostgreSQL 9.4以降が使えるのであれば、常にレプリケーションスロットを使うのが常にお勧めです。 -pgpool_setupが使うレプリケーションスロット名は、pgpool_setup_slotです。 - - - - - - - - + PostgreSQLデータベースクラスタの作成を省略します。このオプションはwatchdog_setupで使われることを想定しており、おそらく他の目的の役には立たないでしょう。 + + + + + + + + -リカバリスクリプト(basebackup.sh)中でpg_rewindを使います。 -このコマンドが失敗すると、通常のrsyncを使います。 -pg_rewindは、データベースクラスタのすべてをコピーしないので、rsyncに比べてずっと高速になることがあります。 - - - - - - + regression testが既存のインストールに対して実行できるように、pgpool.confに追加のパラメータを設定します。 + 今の所、そのようなパラメータとしてはがあります。 + + + + + + + + + + /etc/pgpool-II/ディレクトリにインストールされているサンプルスクリプトと設定ファイルを使います。 + + + + このオプションは、Pgpool-IIのRPMパッケージに含まれているサンプルスクリプトと設定ファイルをテストする目的で追加されたオプションです。 + このオプションを指定する前に、サンプルスクリプトと設定ファイルが/etc/pgpool-II/ディレクトリにインストールされていることを確認してください。 + + + + + + - 環境変数 - + - pgpool_setup は以下の環境変数を使用します: + pgpool_setup recognizes following environment variables: + --> + pgpool_setup は以下の環境変数を使用します: - + - - - - + + + + + + Pgpool-II のインストールディレクトリを指定します。 + Pgpool-II バイナリーは PGPOOL_INSTALL_DIR/bin ディレクトリ以下、 + pgpool.confpool_hba.conf + などは PGPOOL_INSTALL_DIR/etc ディレクトリ以下にインストールされます。 + デフォルトでは /usr/local ディレクトリ以下にインストールされます。 + + + + + + + + + + Pgpool-II 設定ファイルへのパスを指定します。 + デフォルトでは PGPOOL_INSTALL_DIR/etc です。 + + + + + + + + - Pgpool-II のインストールディレクトリを指定します。 - Pgpool-II バイナリーは PGPOOL_INSTALL_DIR/bin ディレクトリ以下、 - pgpool.confpool_hba.conf - などは PGPOOL_INSTALL_DIR/etc ディレクトリ以下にインストールされます。 - デフォルトでは /usr/local ディレクトリ以下にインストールされます。 - - - - - - - - + Specifies the path to PostgreSQL commands such as initdb, pg_ctl and psql. + The default is /usr/local/pgsql/bin. + --> + initdb、pg_ctl と psql など PostgreSQL コマンドへのパスを指定します。 + デフォルトでは、/usr/local/pgsql/bin です。 + + + + + + + + - Pgpool-II 設定ファイルへのパスを指定します。 - デフォルトでは PGPOOL_INSTALL_DIR/etc です。 - - - - - - - - + Specifies the path to PostgreSQL shared libraries. + The default is /usr/local/pgsql/lib. + --> + PostgreSQL の共有ライブラリへのパスを指定します。 + デフォルトでは、/usr/local/pgsql/lib です。 + + + + + + + + - initdb、pg_ctl と psql など PostgreSQL コマンドへのパスを指定します。 - デフォルトでは、/usr/local/pgsql/bin です。 - - - - - - - - + Specifies the path to Unix socket directory. + The default is /tmp. + --> + Unixソケットのディレクトリへのパスを指定します。 + デフォルトでは /tmp です。 + + + + + + + - PostgreSQL の共有ライブラリへのパスを指定します。 - デフォルトでは、/usr/local/pgsql/lib です。 - - - - - - - - + Specifies the arguments for initdb command. + The default is "no-locale -E UTF_8". + --> + initdb コマンドの引数を指定します。 + デフォルトでは "--no-locale -E UTF_8" です。 + + + + + + + + - Unixソケットのディレクトリへのパスを指定します。 - デフォルトでは /tmp です。 - - - - - - - + If "true", in streaming replication mode, use replication slot instead + of archive. This brings the same effect as "-s" option is specified. + --> + ストリーミングレプリケーション環境において、この環境変数が"true"に指定されると、アーカイブログの代わりにレプリケーションスロットを使います。 + これは、"-s"オプションを使ったのと同じ効果をもたらします。 + + + + + + + + - initdb コマンドの引数を指定します。 - デフォルトでは "--no-locale -E UTF_8" です。 - - - - - - - - + If "true", in streaming replication mode, use pg_rewind in basebackup.sh script. + This brings the same effect as "-r" option is specified. + --> + ストリーミングレプリケーション環境において、この環境変数が"true"に指定されると、basebackup.sh中でpg_rewindを使います。 + これは、"-r"オプションを使ったのと同じ効果をもたらします。 + + + + + + + + -ストリーミングレプリケーション環境において、この環境変数が"true"に指定されると、アーカイブログの代わりにレプリケーションスロットを使います。 -これは、"-s"オプションを使ったのと同じ効果をもたらします。 - - - - - - - - + "true"ならあたかも"-t"オプションが与えられたかのように振る舞います。 + + + + + + + + -ストリーミングレプリケーション環境において、この環境変数が"true"に指定されると、basebackup.sh中でpg_rewindを使います。 -これは、"-r"オプションを使ったのと同じ効果をもたらします。 - - - + "true"ならあたかも"-c"オプションが与えられたかのように振る舞います。 + + + - + - + - 出力例 - - -$ pgpool_setup + + +$ pgpool_setup +PostgreSQL major version: 124 Starting set up in streaming replication mode creating startall and shutdownall creating failover script -creating database cluster /home/t-ishii/tmp/test/data0...done. +creating database cluster /tmp/test/data0...done. update postgresql.conf creating pgpool_remote_start creating basebackup.sh creating recovery.conf -creating database cluster /home/t-ishii/tmp/test/data1...done. +creating database cluster /tmp/test/data1...done. update postgresql.conf creating pgpool_remote_start creating basebackup.sh creating recovery.conf temporarily start data0 cluster to create extensions temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 11003 | down | 0.500000 | standby | 0 | false | 0 + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | | | 2020-08-18 13:50:19 + 1 | /tmp | 11003 | down | 0.500000 | standby | 0 | false | 0 | | | 2020-08-18 13:50:18 (2 rows) recovery node 1...pcp_recovery_node -- Command Successful done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 +creating follow primary script + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | | | 2020-08-18 13:50:19 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 | | | 2020-08-18 13:50:23 (2 rows) shutdown all pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/tmp/test/startall. -To shutdown the whole system, use /home/t-ishii/tmp/test/shutdownall. +To start the whole system, use /tmp/test/startall. +To shutdown the whole system, use /tmp/test/shutdownall. pcp command user name is "t-ishii", password is "t-ishii". Each PostgreSQL, pgpool-II and pcp port is as follows: #1 port is 11002 @@ -432,34 +514,36 @@ Each PostgreSQL, pgpool-II and pcp port is as follows: pgpool port is 11000 pcp port is 11001 The info above is in README.port. - -$ ls -README.port bashrc.ports data1 log pgpool_reload run startall -archivedir data0 etc pcppass pgpool_setup.log shutdownall - -$ ./startall -waiting for server to start....11840 2016-08-18 13:08:51 JST LOG: redirecting log output to logging collector process -11840 2016-08-18 13:08:51 JST HINT: Future log output will appear in directory "pg_log". +t-ishii$ ./startall +waiting for server to start....5744 2020-08-18 13:50:27 JST LOG: starting PostgreSQL 12.4 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit +5744 2020-08-18 13:50:27 JST LOG: listening on IPv4 address "0.0.0.0", port 11002 +5744 2020-08-18 13:50:27 JST LOG: listening on IPv6 address "::", port 11002 +5744 2020-08-18 13:50:27 JST LOG: listening on Unix socket "/tmp/.s.PGSQL.11002" +5744 2020-08-18 13:50:27 JST LOG: redirecting log output to logging collector process +5744 2020-08-18 13:50:27 JST HINT: Future log output will appear in directory "log". done server started -waiting for server to start....11853 2016-08-18 13:08:52 JST LOG: redirecting log output to logging collector process -11853 2016-08-18 13:08:52 JST HINT: Future log output will appear in directory "pg_log". +waiting for server to start....5757 2020-08-18 13:50:27 JST LOG: starting PostgreSQL 12.4 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit +5757 2020-08-18 13:50:27 JST LOG: listening on IPv4 address "0.0.0.0", port 11003 +5757 2020-08-18 13:50:27 JST LOG: listening on IPv6 address "::", port 11003 +5757 2020-08-18 13:50:27 JST LOG: listening on Unix socket "/tmp/.s.PGSQL.11003" +5757 2020-08-18 13:50:27 JST LOG: redirecting log output to logging collector process +5757 2020-08-18 13:50:27 JST HINT: Future log output will appear in directory "log". done server started -$ psql -p 11000 test -Pager usage is off. -psql (9.5.4) +t-ishii$ psql -p 11000 test +psql (12.4) Type "help" for help. test=# show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | | | 2020-08-18 13:50:32 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 | streaming | async | 2020-08-18 13:50:32 (2 rows) - - + + diff --git a/doc.ja/src/sgml/ref/pgpool_show.sgml b/doc.ja/src/sgml/ref/pgpool_show.sgml index c0bac14c4..67ae98e62 100644 --- a/doc.ja/src/sgml/ref/pgpool_show.sgml +++ b/doc.ja/src/sgml/ref/pgpool_show.sgml @@ -23,43 +23,43 @@ PostgreSQL documentation - -PGPOOL SHOW configuration_parameter -PGPOOL SHOW configuration_parameter_group -PGPOOL SHOW ALL - + + PGPOOL SHOW configuration_parameter + PGPOOL SHOW configuration_parameter_group + PGPOOL SHOW ALL + - 説明 - + This command is similar to the + + SHOW command in PostgreSQL with an addition + of PGPOOL keyword to distinguish it from the + PostgreSQL SHOW command. + --> PGPOOL SHOW は 実行時 Pgpool-II のパラメータの設定値を表示します。 このコマンドは PostgreSQL の - + SHOW コマンドと似ていますが、 - PostgreSQLSHOW コマンドと区別するために、 - PGPOOL というキーワードが追加されました。 + PostgreSQLSHOW コマンドと区別するために、 + PGPOOL というキーワードが追加されました。 - - パラメータ @@ -69,86 +69,92 @@ PGPOOL SHOW ALL configuration_parameter - + - Pgpool-II の設定パラメータ名です。指定可能なパラメータ名は - をご参照ください。 + The name of a Pgpool-II configuration parameter. + Available parameters are documented in + --> + Pgpool-II の設定パラメータ名です。指定可能なパラメータ名は + をご参照ください。 + + + + 大文字を含むパラメータ名(例えば、)の場合には、 + パラメータ名をダブルクォートで囲んで実行してください。 + - + configuration_parameter_group - + - Pgpool-II の設定パラメータのグループ名です。 - 現在、指定可能なパラメータグループは以下の 3つです。 - - - - backend - - - - すべてのバックエンドグループのパラメータの設定値。 - - - + The name of the Pgpool-II configuration parameter group. + Currently there are three parameter groups. + --> + Pgpool-II の設定パラメータのグループ名です。 + 現在、指定可能なパラメータグループは以下の 4つです。 + + + + backend + + + + すべてのバックエンドグループのパラメータの設定値。 + + + - - other_pgpool - - - - すべての watchdog ノードのパラメータの設定値。 - - - + + watchdog + + + + すべてのwatchdogノードのパラメータの設定値。 + + + - - heartbeat - - - - すべての watchdog heartbeat ノードのパラメータの設定値。 - - - + + heartbeat + + + + すべてのwatchdog heartbeatパラメータの設定値。 + + + - - health_check - - - - すべてのhealth checkパラメータの設定値。 - - - + + health_check + + + + すべてのhealth checkパラメータの設定値。 + + + - + - + ALL - すべてのパラメータの設定値と説明を表示します。 @@ -159,93 +165,92 @@ PGPOOL SHOW ALL - - パラメータ の現在の設定値を表示: - + PGPOOL SHOW port; port ------ 9999 (1 row) - + - - パラメータ の現在の設定値を表示: - -PGPOOL SHOW black_function_list; - black_function_list - --------------------- - nextval,setval - (1 row) - + パラメータ の現在の設定値を表示: + +PGPOOL SHOW write_function_list; +write_function_list +--------------------- +nextval,setval +(1 row) + - - バックエンドグループのすべてのパラメータの設定値を表示する: - - PGPOOL SHOW backend; - item | value | description - -------------------------+-------------------------+----------------------------------------------------------- - backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port0 | 5434 | port number of PostgreSQL backend. - backend_weight0 | 0 | load balance weight of backend. - backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. - backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. - backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port1 | 5432 | port number of PostgreSQL backend. - backend_weight1 | 1 | load balance weight of backend. - backend_data_directory1 | /home/work/installed/pg | data directory of the backend. - backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. - (10 rows) - + +PGPOOL SHOW backend; +item | value | description +-------------------------+-------------------------+----------------------------------------------------------- +backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port0 | 5434 | port number of PostgreSQL backend. +backend_weight0 | 0 | load balance weight of backend. +backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. +backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. +backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port1 | 5432 | port number of PostgreSQL backend. +backend_weight1 | 1 | load balance weight of backend. +backend_data_directory1 | /home/work/installed/pg | data directory of the backend. +backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. +(10 rows) + - 全設定を表示: - - PGPOOL SHOW ALL; - item | value | description - -------------------------+-------------------------+----------------------------------------------------------- - backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port0 | 5434 | port number of PostgreSQL backend. - backend_weight0 | 0 | load balance weight of backend. - backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. - backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. - backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port1 | 5432 | port number of PostgreSQL backend. - backend_weight1 | 1 | load balance weight of backend. - backend_data_directory1 | /home/work/installed/pg | data directory of the backend. - backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. - other_pgpool_hostname0 | localhost | Hostname of other pgpool node for watchdog connection. - . - . - . - ssl | off | Enables SSL support for frontend and backend connections - (138 rows) - - + +PGPOOL SHOW ALL; +item | value | description +-------------------------+-------------------------+----------------------------------------------------------- +backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port0 | 5434 | port number of PostgreSQL backend. +backend_weight0 | 0 | load balance weight of backend. +backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. +backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. +backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port1 | 5432 | port number of PostgreSQL backend. +backend_weight1 | 1 | load balance weight of backend. +backend_data_directory1 | /home/work/installed/pg | data directory of the backend. +backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. +hostname0 | localhost | Hostname of pgpool node for watchdog connection. +. +. +. +ssl | off | Enables SSL support for frontend and backend connections +(138 rows) + - 関連項目 diff --git a/doc.ja/src/sgml/ref/pgproto.sgml b/doc.ja/src/sgml/ref/pgproto.sgml index 1d6ff68ed..c55ee0606 100644 --- a/doc.ja/src/sgml/ref/pgproto.sgml +++ b/doc.ja/src/sgml/ref/pgproto.sgml @@ -11,19 +11,19 @@ Pgpool-II documentation pgproto 1 - + --> 他のコマンド pgproto - - PostgreSQL もしくはフロントエンド/バックエンドプロトコルを理解しているサーバに対してテストする + + PostgreSQL もしくはフロントエンド/バックエンドプロトコルを理解しているサーバに対してテストする @@ -35,316 +35,332 @@ Pgpool-II documentation - + --> 説明 - pgproto - - PostgreSQL もしくはフロントエンド/バックエンドプロトコルを理解しているサーバに対してテストします + pgproto + + PostgreSQL もしくはフロントエンド/バックエンドプロトコルを理解しているサーバに対してテストします - + --> オプション - - - - - - - - - サーバが稼働しているマシンのホスト名。 - "/"からホスト名が始まる場合、Unixドメインソケットのディレクトリとして使用されます (デフォルト: unixドメインソケット)。 - - - + + + + + + + + + サーバが稼働しているマシンのホスト名。 + "/"からホスト名が始まる場合、Unixドメインソケットのディレクトリとして使用されます (デフォルト: unixドメインソケット)。 + + + - - - - - - - ポート番号 (デフォルト:5432) - - - + + + + + + + ポート番号 (デフォルト:5432) + + + - - - - - - - ユーザ名 (デフォルト: OSユーザ名) - - - + + + + + + + ユーザ名 (デフォルト: OSユーザ名) + + + - - - - - - - データベース名 (デフォルト: ユーザ名) - - - + + + + + + + データベース名 (デフォルト: ユーザ名) + + + - - - - - - - サーバに送信するメッセージデータを記述したテキストファイル (デフォルト: pgproto.data)。 - - - + + + + + + + サーバに送信するメッセージデータを記述したテキストファイル (デフォルト: pgproto.data)。 + + + - - - - - - - 待ち時間、単位はマイクロ秒 (デフォルト:0)。 - 0以上が指定された場合、ソケットから各データを読み込む際にスリープを入れます。 - これは、遅いクライアントをシミュレートします。 - - - + + + + + + + 待ち時間、単位はマイクロ秒 (デフォルト:0)。 + 0より大きな値が指定された場合、ソケットから各データを読み込む際にスリープを入れます。 + これは、遅いクライアントをシミュレートします。 + + + - - - - - - - デバッグメッセージを表示します。 - - - + + + + + + + デバッグメッセージを表示します。 + + + - - - - - - - バージョンを表示して終了します。 - - - + + + + + + + バージョンを表示して終了します。 + + + - - - - - - - コマンドのヘルプを表示します。 - - - + + + + + + + コマンドのヘルプを表示します。 + + + - - + + - - + --> + - - ファイル内の最初の文字 (Q)がフロントエンド/バックエンドプロトコルのメッセージの種類を表します。 + + ファイル内の最初の文字 (Q)がフロントエンド/バックエンドプロトコルのメッセージの種類を表します。 - - 'Y'と'y'は例外です。 - 'Y'は、Ready for queryが受信されるまで、バックエンドからメッセージを読み取ります。 - 'y'は、バックエンドからメッセージを受信している間はメッセージを読み取り、1秒間メッセージを受信しなかった場合停止します。 - 'Y'は、拡張クエリのSync ('S')、簡易問い合わせ ('Q')の応答を待つために使用できます。 - 'y'は、Flush ('H')後にメッセージを受診するために使用できます。 + + 'Y'と'z'と'y'は例外です。 + 'Y'は、Ready for queryが受信されるまで、バックエンドからメッセージを読み取ります。 + 'y'は、バックエンドからメッセージを受信している間はメッセージを読み取り、1秒間メッセージを受信しなかった場合停止します。 + 'Y'は、拡張クエリのSync ('S')、簡易問い合わせ ('Q')の応答を待つために使用できます。 + 'y'は、Flush ('H')後にメッセージを受信するために使用できます。 + 'z'は、バックエンドから1つメッセージを読みます。1秒間メッセージを受信しなかった場合停止します。 + 'z'は、事前にいくつメッセージが届くかわかっている場合に'H'のテストのために利用することができます。 - - "SELECT * FROM "aaa""のように文字列にダブルクォートを含める場合、"SELECT * FROM \"aaa\""のようにバックスラッシュを使用します。 - 以下のように、\を使用して複数行にまたがるコマンド行を作成することもできます。 - -'Q' "SELECT * FROM aaa \ -WHERE a = 1" - + A command line spread over multiple lines can be created using \ as well. + --> + "SELECT * FROM "aaa""のように文字列にダブルクォートを含める場合、"SELECT * FROM \"aaa\""のようにバックスラッシュを使用します。 + 以下のように、\を使用して複数行にまたがるコマンド行を作成することもできます。 + + 'Q' "SELECT * FROM aaa \ + WHERE a = 1" + - - - ここでは入力ファイルの例を示します。 - -# -# Test data example -# -'Q' "SELECT * FROM aaa" -'Y' -'P' "S1" "BEGIN" 0 -'B' "" "S1" 0 0 0 -'E' "" 0 -'C' 'S' "S1" -'P' "foo" "SELECT 1" 0 -'B' "myportal" "foo" 0 0 0 -'E' "myportal" 0 -'P' "S2" "COMMIT" 0 -'B' "" "S2" 0 0 0 -'E' "" 0 -'C' 'S' "S2" -'S' -'Y' -'X' - + COPYコマンドのように、データに改行を含めたい場合は、"\n"を行の最後に置くことができます。 + 例を示します。 + + 'Q' "COPY t1 FROM STDIN" + 'd' "1\n" + 'd' "2\n" + 'c' + 'Y' + - - ここでは出力例を示します。 - -$ pgproto -p 11000 -d test -f sample.data -FE=> Query (query="SELECT * FROM aaa") -<= BE RowDescription -<= BE CommandComplete(SELECT 0) -<= BE ReadyForQuery(I) -FE=> Parse(stmt="S1", query="BEGIN") -FE=> Bind(stmt="S1", portal="") -FE=> Execute(portal="") -FE=> Close(stmt="S1") -FE=> Parse(stmt="foo", query="SELECT 1") -FE=> Bind(stmt="foo", portal="myportal") -FE=> Execute(portal="myportal") -FE=> Parse(stmt="S2", query="COMMIT") -FE=> Bind(stmt="S2", portal="") -FE=> Execute(portal="") -FE=> Close(stmt="S2") -FE=> Sync -<= BE ParseComplete -<= BE BindComplete -<= BE CommandComplete(BEGIN) -<= BE CloseComplete -<= BE ParseComplete -<= BE BindComplete -<= BE DataRow -<= BE CommandComplete(SELECT 1) -<= BE ParseComplete -<= BE BindComplete -<= BE CommandComplete(COMMIT) -<= BE CloseComplete -<= BE ReadyForQuery(I) -FE=> Terminate - + + ここでは入力ファイルの例を示します。 + + # + # Test data example + # + 'Q' "SELECT * FROM aaa" + 'Y' + 'P' "S1" "BEGIN" 0 + 'B' "" "S1" 0 0 0 + 'E' "" 0 + 'C' 'S' "S1" + 'P' "foo" "SELECT 1" 0 + 'B' "myportal" "foo" 0 0 0 + 'E' "myportal" 0 + 'P' "S2" "COMMIT" 0 + 'B' "" "S2" 0 0 0 + 'E' "" 0 + 'C' 'S' "S2" + 'S' + 'Y' + 'X' + - - その他のデータファイルの例です。 + + ここでは出力例を示します。 + + $ pgproto -p 11000 -d test -f sample.data + FE=> Query (query="SELECT * FROM aaa") + <= BE RowDescription + <= BE CommandComplete(SELECT 0) + <= BE ReadyForQuery(I) + FE=> Parse(stmt="S1", query="BEGIN") + FE=> Bind(stmt="S1", portal="") + FE=> Execute(portal="") + FE=> Close(stmt="S1") + FE=> Parse(stmt="foo", query="SELECT 1") + FE=> Bind(stmt="foo", portal="myportal") + FE=> Execute(portal="myportal") + FE=> Parse(stmt="S2", query="COMMIT") + FE=> Bind(stmt="S2", portal="") + FE=> Execute(portal="") + FE=> Close(stmt="S2") + FE=> Sync + <= BE ParseComplete + <= BE BindComplete + <= BE CommandComplete(BEGIN) + <= BE CloseComplete + <= BE ParseComplete + <= BE BindComplete + <= BE DataRow + <= BE CommandComplete(SELECT 1) + <= BE ParseComplete + <= BE BindComplete + <= BE CommandComplete(COMMIT) + <= BE CloseComplete + <= BE ReadyForQuery(I) + FE=> Terminate + + + + + その他のデータファイルの例です。 - Copy - -# -# Test data example -# + Copy + + # + # Test data example + # -# CopyIn -# -'Q' "COPY t1 FROM STDIN" -# CopyData -'d' "abc" -# CopyDone -'c' -'Y' + # CopyIn + # + 'Q' "COPY t1 FROM STDIN" + # CopyData + 'd' "abc\n" + # CopyDone + 'c' + 'Y' -# CopyOut -# -'Q' "COPY t1 TO STDOUT" -'Y' + # CopyOut + # + 'Q' "COPY t1 TO STDOUT" + 'Y' -# -# Copy fail case -# -'Q' "COPY t1 FROM STDIN" -# CopyData -'d' "abc" -# CopyFail -'f' "pgproto copy fail test" -'Y' -'X' - + # + # Copy fail case + # + 'Q' "COPY t1 FROM STDIN" + # CopyData + 'd' "abc\n" + # CopyFail + 'f' "pgproto copy fail test" + 'Y' + 'X' + - Function Call - -# -# Test data example -# + Function Call + + # + # Test data example + # -# Function call (lo_creat) -# from PostgreSQL's src/include/catalog/pg_proc.data -# { oid => '957', descr => 'large object create', -# proname => 'lo_creat', provolatile => 'v', proparallel => 'u', -# prorettype => 'oid', proargtypes => 'int4', prosrc => 'be_lo_creat' }, + # Function call (lo_creat) + # from PostgreSQL's src/include/catalog/pg_proc.data + # { oid => '957', descr => 'large object create', + # proname => 'lo_creat', provolatile => 'v', proparallel => 'u', + # prorettype => 'oid', proargtypes => 'int4', prosrc => 'be_lo_creat' }, -'F' 957 1 0 1 1 "0" 0 -'Y' -'X' - + 'F' 957 1 0 1 1 "0" 0 + 'Y' + 'X' + diff --git a/doc.ja/src/sgml/ref/show_pool_backend_stats.sgml b/doc.ja/src/sgml/ref/show_pool_backend_stats.sgml new file mode 100644 index 000000000..12cbc91c7 --- /dev/null +++ b/doc.ja/src/sgml/ref/show_pool_backend_stats.sgml @@ -0,0 +1,57 @@ + + + + + SHOW POOL_BACKEND_STATS + + + + SHOW POOL_BACKEND_STATS + 1 + SQL - Language Statements + + + + SHOW POOL_BACKEND_STATS + + SQLコマンドの統計情報を表示する + + + + + + SHOW POOL_BACKEND_STATS + + + + + 説明 + + + SHOW POOL_BACKEND_STATSはノードID、ホスト名、ポート番号、状態、ノードの役割、SELECT/INSERT/UPDATE/DELETE/DDL/それ以外のコマンドがそれぞれのノードに発行された数を表示します。 + また、バックエンドが返したエラーの数を深刻度に分類して表示します。 + ノードID、ホスト名、ポート番号、状態、ノードの役割はと同じです。 + + + select_cnt、insert_cnt、update_cnt、delete_cnt、ddl_cnt、other_cntはPgpool-IIが起動してからのSQLコマンド: SELECT、INSERT、UPDATE、DELETE、DDL、そして他のコマンドの数です。 + 失敗したコマンド(たとえば存在しないテーブルからのSELECT)は数えられます。 + ロールバックされたコマンドも数えられます。 + 今の所SELECT/WITH/INSERT/UPDATE/DELETE/CHECKPOINT/DEALLOCATE/DISCARD/EXECUTE/EXPLAIN/LISTEN/LOAD/LOCK/NOTIFY/PREPARE/SET/SHOW/トランザクションコマンド/UNLISTEN以外のコマンドがDDLであると見なされます。 + + + 例をここに示します。 + +test=# show pool_backend_stats; + node_id | hostname | port | status | role | select_cnt | insert_cnt | update_cnt | delete_cnt | ddl_cnt | other_cnt | panic_cnt | fatal_cnt | error_cnt +---------+----------+-------+--------+---------+------------+------------+------------+------------+---------+-----------+-----------+-----------+----------- + 0 | /tmp | 11002 | up | primary | 12 | 10 | 30 | 0 | 2 | 30 | 0 | 0 | 1 + 1 | /tmp | 11003 | up | standby | 12 | 0 | 0 | 0 | 0 | 23 | 0 | 0 | 1 +(2 rows) + + + + + diff --git a/doc.ja/src/sgml/ref/show_pool_cache.sgml b/doc.ja/src/sgml/ref/show_pool_cache.sgml index fa803281f..53d8602b0 100644 --- a/doc.ja/src/sgml/ref/show_pool_cache.sgml +++ b/doc.ja/src/sgml/ref/show_pool_cache.sgml @@ -4,66 +4,156 @@ --> - - SHOW - - - - SHOW POOL_CACHE - 1 - SQL - Language Statements - - - - SHOW POOL_CACHE - - - クエリキャッシュのヒット率や、キャッシュストレージの状況を表示する - - - - - -SHOW POOL_CACHE - - - - + + SHOW + + + + SHOW POOL_CACHE + 1 + SQL - Language Statements + + + + SHOW POOL_CACHE + + + クエリキャッシュのヒット率や、キャッシュストレージの状況を表示する + + + + + + SHOW POOL_CACHE + + + + - 説明 - - - SHOW POOL_CACHE - - は インメモリクエリキャッシュ が有効である場合に、 - クエリキャッシュのヒット率や、キャッシュストレージの状況を表示します。 例を示します。 - -test=# \x -\x -Expanded display is on. -test=# show pool_cache; -show pool_cache; --[ RECORD 1 ]---------------+--------- -num_cache_hits | 891703 -num_selects | 99995 -cache_hit_ratio | 0.90 -num_hash_entries | 131072 -used_hash_entries | 99992 -num_cache_entries | 99992 -used_cache_enrties_size | 12482600 -free_cache_entries_size | 54626264 -fragment_cache_entries_size | 0 - - - - + Description + --> + 説明 + + + SHOW POOL_CACHE + + は インメモリクエリキャッシュ が有効である場合に、 + クエリキャッシュのヒット率や、キャッシュストレージの状況を表示します。 例を示します。 + 各項目の説明はをご覧ください。 + + test=# \x + \x + Expanded display is on. + test=# show pool_cache; + show pool_cache; + -[ RECORD 1 ]---------------+--------- + num_cache_hits | 891703 + num_selects | 99995 + cache_hit_ratio | 0.90 + num_hash_entries | 131072 + used_hash_entries | 99992 + num_cache_entries | 99992 + used_cache_entries_size | 12482600 + free_cache_entries_size | 54626264 + fragment_cache_entries_size | 0 + + + + + + + + キャッシュストレージがmemcachedのときは、num_cache_hits, num_selects, cache_hit_ratio以外の列の値は0になります。 + + + + + show pool_cacheの表示項目 + + + + 名称 + 説明 + + + + + + + num_cache_hits + クエリキャッシュにヒットした回数です。 + + + + num_selects + キャッシュにヒットしなかったSELECTクエリの回数です。 + + + + cache_hit_ratio + キャッシュのヒット率です。 + num_cache_hits/(num_cache_hits+num_selects)で計算されます。 + + + + num_hash_entries + キャッシュを管理するハッシュテーブルのエントリ数です。 + 大量のキャッシュを効率よく管理するため、Pgpool-IIはハッシュテーブルを使っています。 + ハッシュテーブルのエントリ数は、以上で、かつその数に最も近い2のべき乗になる数が自動的に設定されます。 + たとえば、のデフォルトである100,000では、131,072 (2の17乗)が設定されます。 + + + + + used_hash_entries + + 使用済みのハッシュエントリ数です。 + これがnum_hash_entriesに近くなる場合は、num_hash_entriesを増やすことをお勧めします。 + ハッシュテーブルを使い切ってもエラーにはなりませんが、登録済みのハッシュテーブルエントリとキャッシュを削除して新しいキャッシュを登録するため、性能が低下します。 + + + + + num_cache_entries + + 使用済みのキャッシュエントリ数です。 + 現在の実装ではused_hash_entriesと同じ値になります。 + + + + + free_cache_entries_size + + 未使用のキャッシュのバイト単位のサイズです。 + この値が0に近づくと、登録済みのキャッシュを削除して新しいキャッシュを登録するため、エラーにはなりませんが性能が低下します。 + を増やすことを検討してください。 + + + + + fragment_cache_entries_size + + 断片化しているキャッシュのバイト単位のサイズです。 + Pgpool-IIで指定される固定長のブロックにキャッシュを書き込みます。 + 登録されたキャッシュが削除されると、次にそのブロックを再利用するまではその領域は断片化します。 + fragment_cache_entries_sizeはそうした断片化した領域の合計サイズを表示します。 + + + + + +
+ +
diff --git a/doc.ja/src/sgml/ref/show_pool_health_check_stats.sgml b/doc.ja/src/sgml/ref/show_pool_health_check_stats.sgml new file mode 100644 index 000000000..f5f03f2bb --- /dev/null +++ b/doc.ja/src/sgml/ref/show_pool_health_check_stats.sgml @@ -0,0 +1,263 @@ + + + + + SHOW POOL_HEALTH_CHECK_STATS + + + + SHOW POOL_HEALTH_CHECK_STATS + 1 + SQL - Language Statements + + + + SHOW POOL_HEALTH_CHECK_STATS + + ヘルスチェックの統計情報を表示する + + + + + + SHOW POOL_HEALTH_CHECK_STATS + + + + + Description + + + SHOW POOL_HEALTH_CHECK_STATSは、主にヘルスチェックプロセスが収集したヘルスチェック(参照)の統計情報データを表示します。 + このコマンドは、Pgpool-II管理者がヘルスチェックに関連したイベントを調べるのに役立ちます。 + たとえば、"last_failed_health_check"列を見ることにより、フェイルオーバイベントをログファイルの中から容易に発見することができます。 + 他の例としては、"average_retry_count"列を評価することにより、不安定なバックエンドへのコネクションを見つけることができます。 + ある特定のノードが他のノードよりもリトライ率が高ければ、バックエンドへの接続に問題があるかも知れません。 + + + + に各々の列名と説明を示します。 + + + + pool_health_check_statsコマンドが表示する統計情報 + + + + 列名 + 説明 + + + + + + + node_id + + バックエンドノードID。 + + + + + hostname + + バックエンドホスト名あるいはUNIXドメインソケットのパス。 + + + + + port + + バックエンドのポート番号。 + + + + + status + + バックエンドの状態。up, down, waiting, unused, quarantineのいずれか。 + + + + + role + + このノードの役割。ストリーミングレプリケーションモードではprimaryあるいはstandbyです。 + 他のモードでは、mainあるいはreplicaです。 + + + + + last_status_change + + バックエンドの状態の最終変更時刻。 + + + + + total_count + + ヘルスチェックの合計回数。 + + + + + success_count + + 成功したヘルスチェックの合計回数。 + + + + + fail_count + + 失敗したヘルスチェックの合計回数。 + + + + + skip_count + + ヘルスチェックをスキップした合計回数。そのノードがすでにダウン状態の場合、ヘルスチェックはそのノードをスキップします。 + + + + + retry_count + + ヘルスチェックの合計リトライ回数。 + + + + + average_retry_count + + 一回のヘルスチェックセッションの平均リトライ回数。 + + + + + max_retry_count + + 一回のヘルスチェックセッションの中での最大リトライ回数。 + + + + + max_duration + + ヘルスチェックに要した時間の最大値をミリ秒で表示。 + ヘルスチェックセッションがリトライを行った場合、各々のリトライしたヘルスチェックの時間の合計がヘルスチェックに要した時間になります。 + + + + + min_duration + + ヘルスチェックに要した時間の最小値をミリ秒で表示。 + ヘルスチェックセッションがリトライを行った場合、各々のリトライしたヘルスチェックの時間の合計がヘルスチェックに要した時間になります。 + + + + + average_duration + + ヘルスチェックに要した時間の平均値をミリ秒で表示。 + ヘルスチェックセッションがリトライを行った場合、各々のリトライしたヘルスチェックの時間の合計がヘルスチェックに要した時間になります。 + + + + + last_health_check + + 最後にヘルスチェックを行った時刻。 + まだヘルスチェックを行っていない場合は空文字です。 + + + + + last_successful_health_check + + 最後にヘルスチェックに成功した時刻。 + まだヘルスチェックが成功していない場合は空文字です。 + + + + + last_skip_health_check + + 最後にヘルスチェックをスキップした時刻。 + まだヘルスチェックがスキップされていない場合は空文字です。 + ステータスがdownであっても、このフィールドが空文字であることがあり得ることに注意してください。 + この場合は、ヘルスチェックプロセス以外でフェイルオーバが起きています。 + + + + + last_failed_health_check + + 最後にヘルスチェックに失敗した時刻。 + まだヘルスチェックが失敗していない場合は空文字です。 + ステータスがdownであっても、このフィールドが空文字であることがあり得ることに注意してください。 + この場合は、ヘルスチェックプロセス以外でフェイルオーバが起きています。 + + + + + +
+ + + セッション例を示します。 + +test=# show pool_health_check_stats; +-[ RECORD 1 ]----------------+-------------------- +node_id | 0 +hostname | /tmp +port | 11002 +status | up +role | primary +last_status_change | 2020-01-26 19:08:45 +total_count | 27 +success_count | 27 +fail_count | 0 +skip_count | 0 +retry_count | 0 +average_retry_count | 0.000000 +max_retry_count | 0 +max_duration | 9 +min_duration | 2 +average_duration | 6.296296 +last_health_check | 2020-01-26 19:12:45 +last_successful_health_check | 2020-01-26 19:12:45 +last_skip_health_check | +last_failed_health_check | +-[ RECORD 2 ]----------------+-------------------- +node_id | 1 +hostname | /tmp +port | 11003 +status | down +role | standby +last_status_change | 2020-01-26 19:11:48 +total_count | 19 +success_count | 12 +fail_count | 1 +skip_count | 6 +retry_count | 3 +average_retry_count | 0.230769 +max_retry_count | 3 +max_duration | 83003 +min_duration | 0 +average_duration | 6390.307692 +last_health_check | 2020-01-26 19:12:48 +last_successful_health_check | 2020-01-26 19:10:15 +last_skip_health_check | 2020-01-26 19:12:48 +last_failed_health_check | 2020-01-26 19:11:48 + + +
+ +
diff --git a/doc.ja/src/sgml/ref/show_pool_nodes.sgml b/doc.ja/src/sgml/ref/show_pool_nodes.sgml index aa8686096..b184daa88 100644 --- a/doc.ja/src/sgml/ref/show_pool_nodes.sgml +++ b/doc.ja/src/sgml/ref/show_pool_nodes.sgml @@ -4,84 +4,92 @@ --> - - SHOW POOL_NODES - + + SHOW POOL_NODES + - - SHOW POOL_NODES - 1 - SQL - Language Statements - + + SHOW POOL_NODES + 1 + SQL - Language Statements + - - SHOW POOL_NODES - - - DB ノードのリストを表示する - - + + SHOW POOL_NODES + + + DB ノードのリストを表示する + + - - -SHOW POOL_NODES - - + + + SHOW POOL_NODES + + - + - 説明 + Description + --> + 説明 - - - SHOW POOL_NODES はホスト名、ポート番号、状態、 - 重み(ロードバランスモードで運用しているときにのみ意味があります)、 - ノードの役割、発行された SELECT の数、ロードバランスノードであるかどうか、 - レプリケーション遅延 (ストリーミングレプリケーションモードのみ) 、最終状態変更時刻が表示されます。 - 状態(status)の意味については、 リファレンスで説明されています。 - ホスト名が "/tmp" のように表示される場合、UNIX ドメインソケットを使用して + + + SHOW POOL_NODES はホスト名、ポート番号、状態、 + 重み(ロードバランスモードで運用しているときにのみ意味があります)、 + ノードの役割、発行された SELECT の数、ロードバランスノードであるかどうか、 + レプリケーション遅延 (ストリーミングレプリケーションモードのみ) 、最終状態変更時刻が表示されます。 + + + これらに加えて、Pgpool-II 4.1以降では、スタンバイサーバの行でレプリケーション状態と、同期レプリケーション状態が表示されます。 + 更に、Pgpool-II 4.3以降では、"pg_status"と"pg_role"が追加されています。 + 表示情報の意味については、 リファレンスで説明されています。 + + + ホスト名が "/tmp" のように表示される場合、UNIX ドメインソケットを使用して Pgpool-IIPostgreSQL に接続していることを意味します。 SELECT の数には、Pgpool-II 内部で発行されるクエリの数は含まれません。 また、このカウンタは Pgpool-II がスタートした時に 0にリセットされます。 + + 最終状態変更時刻は、Pgpool-IIが起動した時にセットされたあとは、"status"あるいは"role"が変更される度に更新されます。 - - - - ここでは例を示します。 - + + + + ここでは例を示します。 + test=# show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change ----------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | 2018-06-12 21:45:59 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 | 2018-06-12 21:45:59 + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | up | 0.500000 | primary | primary | 0 | false | 0 | | | 2021-02-27 15:10:19 + 1 | /tmp | 11003 | up | up | 0.500000 | standby | standby | 0 | true | 0 | streaming | async | 2021-02-27 15:10:19 (2 rows) - - - + + + diff --git a/doc.ja/src/sgml/ref/show_pool_pools.sgml b/doc.ja/src/sgml/ref/show_pool_pools.sgml index 5548da1aa..3fd3955fb 100644 --- a/doc.ja/src/sgml/ref/show_pool_pools.sgml +++ b/doc.ja/src/sgml/ref/show_pool_pools.sgml @@ -4,440 +4,347 @@ --> - - SHOW POOL_POOLS - + + SHOW POOL_POOLS + - - SHOW POOL_POOLS - 1 - SQL - Language Statements - + + SHOW POOL_POOLS + 1 + SQL - Language Statements + - - SHOW POOL_POOLS - - - Pgpool-II のコネクションプールの状態を表示する - - + + SHOW POOL_POOLS + + + Pgpool-II のコネクションプールの状態を表示する + + - - -SHOW POOL_POOLS - - + + + SHOW POOL_POOLS + + - + - 説明 + Description + --> + 説明 - - SHOW pool_pools + + SHOW POOL_POOLS + + は Pgpool-II のコネクションプールの状態を表示します。 + + + + 20のカラムがあります。 + + + - は Pgpool-II のコネクションプールの状態を表示します。 - - - - 11のカラムがあります。 + start_time はこのプロセスが起動された時刻です。 - - + + + + が0でない場合 + プロセスが再起動されるまでの時間が表示されます。 + + + + + + + + + + client_connection_count はこのプロセスが使用された回数です。 + + + + + - pool_pidPgpool-II プロセスのプロセス ID です。 - - + pool_id is the pool identifier (should + be between 0 and - 1) + --> + pool_id はコネクションプール ID です。(0 から - 1 の値です) + + - - + + - start_time はこのプロセスが起動された時刻です (1970年1月1日からの経過秒で表示されます)。 - - + backend_id is the backend identifier (should + be between 0 and the number of configured backends minus one) + --> + backend_idPostgreSQL + バックエンドの識別子です(0 からバックエンド数 - 1 の値です) + + - - + + - pool_id はコネクションプール ID です。(0 から - 1 の値です) - - + database is the database name for this + process's pool id connection. + --> + database はこのプロセスが接続しているデータベース名です。 + + - - + + - backend_idPostgreSQL - バックエンドの識別子です(0 からバックエンド数 - 1 の値です) - - + username is the user name for this + process's pool id connection. + --> + username はこのプロセスの接続で使用しているユーザ名です。 + + - - + + - database はこのプロセスが接続しているデータベース名です。 - - + backend_connection_time is the creation time and + date of the connection. + --> + backend_connection_time はこの接続が作成された時刻です。 + + - - + + - username はこのプロセスの接続で使用しているユーザ名です。 - - + client_connection_time is the date when a client + last used this connection. + --> + client_connection_time は最後にクライアントが接続した時刻です。 + + - - + + - create_time はこの接続が作成された時刻です。 - - + client_disconnection_time is the date when a client + last disconnected from this connection. + --> + client_disconnection_time は最後にクライアントが切断した時刻です。 + + - - + + + client_idle_duration はクライアントからのコマンドを待機している時間(秒)です。 + + + + + - majorversionminorversion - はこの接続で使用されているプロトコルバージョン番号です。 - - + が0でない場合 + クライアントが切断されるまでの時間が表示されます。 + + + + - - + + - pool_counter はこの接続が使用された回数です。 - - + majorversion + and minorversion are the protocol + version numbers used in this connection. + --> + majorversionminorversion + はこの接続で使用されているプロトコルバージョン番号です。 + + - - + + - pool_backendpidPostgreSQL - のバックエンドプロセスのプロセス ID です。 - - + pool_counter counts the number of times + this pool of connections (process) has been used by + clients. + --> + pool_counter はこの接続が使用された回数です。 + + - - + + - pool_connected は真偽値で、0 ならフロントエンドからの接続無し、1 なら接続ありを表します。 - - + pool_backendpid is the PID of the + PostgreSQL process. + --> + pool_backendpidPostgreSQL + のバックエンドプロセスのプロセス ID です。 + + + + + + + pool_connected は真偽値で、0 ならフロントエンドからの接続無し、1 なら接続ありを表します。 + + + + + + + status は現在のプロセスの状態です。以下のいずれかの値を取ります: + + + + + Execute command: コマンドを実行中です。 + + + + + + Idle: クライアントからのコマンドを待機しています。 + + + + + + Idle in transaction: トランザクション中にクライアントからのコマンドを待機しています。 + + + + + + Wait for connection: クライアントからの接続を待機しています。 + + + + + + + + + + load_balance_node は真偽値で、1ならフロントエンドからの接続があり、かつバックエンドが負荷分散ノードです。 + + - - - - - 返却行数は常に * * 「バックエンドの数」になります。 - ここでは例を示します。 - + client_hostはクライアントのホスト名またはIPアドレスです。 + + + + + + + client_portはクライアントのポート番号です(Unixドメインソケット、localhostでは表示されません)。 + + + + + + statementは最後に実行したSQL文です。 + + + + + + + + 返却行数は常に * * 「バックエンドの数」になります。 + ここでは例を示します。 + test=# show pool_pools; - pool_pid | start_time | pool_id | backend_id | database | username | create_time | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected -----------+---------------------+---------+------------+----------+----------+---------------------+--------------+--------------+--------------+-----------------+---------------- - 19696 | 2016-10-17 13:24:17 | 0 | 0 | postgres | t-ishii | 2016-10-17 13:35:12 | 3 | 0 | 1 | 20079 | 1 - 19696 | 2016-10-17 13:24:17 | 0 | 1 | postgres | t-ishii | 2016-10-17 13:35:12 | 3 | 0 | 1 | 20080 | 1 - 19696 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 0 | 0 | test | t-ishii | 2016-10-17 14:30:53 | 3 | 0 | 1 | 22055 | 1 - 20024 | 2016-10-17 13:33:46 | 0 | 1 | test | t-ishii | 2016-10-17 14:30:53 | 3 | 0 | 1 | 22056 | 1 - 20024 | 2016-10-17 13:33:46 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 + pool_pid | start_time | client_connection_count | pool_id | backend_id | database | username | backend_connection_time | client_connection_time | client_disconnection_time | client_idle_duration | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected | status | load_balance_node | client_host | client_port | statement +----------+------------------------------------------------------+-------------------------+---------+------------+----------+----------+-------------------------+------------------------+---------------------------+----------------------+--------------+--------------+--------------+-----------------+----------------+---------------------+-------------------+---------------+-------------+------------- +[snip] + 1336537 | 2025-06-24 10:53:35 | 0 | 0 | 0 | test | t-ishii | 2025-06-24 10:55:58 | 2025-06-24 10:55:59 | | 0 | 3 | 0 | 1 | 1336703 | 1 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 0 | 1 | test | t-ishii | 2025-06-24 10:55:58 | 2025-06-24 10:55:59 | | 0 | 3 | 0 | 1 | 1336704 | 1 | Idle | 1 | 192.168.10.11 | 39216 | select 1; + 1336537 | 2025-06-24 10:53:35 | 0 | 1 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 1 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | select 1; + 1336537 | 2025-06-24 10:53:35 | 0 | 2 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 2 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | select 1; + 1336537 | 2025-06-24 10:53:35 | 0 | 3 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 3 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | select 1; +[snip] + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 0 | 0 | test | t-ishii | 2025-06-24 10:53:42 | 2025-06-24 10:53:42 | 2025-06-24 10:55:37 | 0 | 3 | 0 | 1 | 1336573 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 0 | 1 | test | t-ishii | 2025-06-24 10:53:42 | 2025-06-24 10:53:42 | 2025-06-24 10:55:37 | 0 | 3 | 0 | 1 | 1336574 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 1 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 1 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 2 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 2 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 3 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 3 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | +[snip] (256 rows) - + - - + + diff --git a/doc.ja/src/sgml/ref/show_pool_processes.sgml b/doc.ja/src/sgml/ref/show_pool_processes.sgml index 069b06ddb..55f055f61 100644 --- a/doc.ja/src/sgml/ref/show_pool_processes.sgml +++ b/doc.ja/src/sgml/ref/show_pool_processes.sgml @@ -4,157 +4,197 @@ --> - - SHOW POOL_PROCESSES - + + SHOW POOL_PROCESSES + - - SHOW POOL_PROCESSES - 1 - SQL - Language Statements - + + SHOW POOL_PROCESSES + 1 + SQL - Language Statements + - - SHOW POOL_PROCESSES - - - 接続待ち、あるいは接続中 Pgpool-II の子プロセスの状態を表示する - - + + SHOW POOL_PROCESSES + + + 接続待ち、あるいは接続中の Pgpool-II の子プロセスの状態を表示する + + - - -SHOW POOL_PROCESSES - - + + + SHOW POOL_PROCESSES + + - + - 説明 + Description + --> + 説明 - - + SHOW POOL_PROCESSES は接続待ち、あるいは接続中の + Pgpool-II の子プロセスの状態を表示します。 + + + + 8つのカラムがあります。 + + + + - SHOW POOL_PROCESSES は接続待ち、あるいは接続中 - Pgpool-II の子プロセスの状態を表示します。 - - - - 6つのカラムがあります。 + start_time はこのプロセスが起動された時刻です。 - - + + + + が0出ない場合 + プロセスが再起動されるまでの時間が表示されます。 + + + + + + + - pool_pidPgpool-II プロセスのプロセス ID です。 - - - - + client_connection_count counts the number of times + this process has been used by clients. + --> + client_connection_count はこのプロセスが使用された回数です。 + + + + - start_time はこのプロセスが起動された時刻です。 - - - - + database is the database name of the + currently active backend for this process. + --> + database はこのプロセスが接続しているデータベース名です。 + + + + - database はこのプロセスが接続しているデータベース名です。 - - - - + username is the user name used in the + connection of the currently active backend for this + process. + --> + username はこのプロセスの接続で使用しているユーザ名です。 + + + + - username はこのプロセスの接続で使用しているユーザ名です。 - - - - + backend_connection_time is the creation time and + date of the connection. + --> + backend_connection_time はこの接続が作成された時刻です。 + + + + - create_time はこの接続が作成された時刻です。 - - - - + pool_counter counts the number of times + this pool of connections (process) has been used by + clients. + --> + pool_counter はこの接続が使用された回数です。 + + + + - pool_counter はこの接続が使用された回数です。 - - - - - - - ここでは例を示します。 + status は現在のプロセスの状態です。以下のいずれかの値を取ります: + + + + + Execute command: コマンドを実行中です。 + + + + + + Idle: クライアントからのコマンドを待機しています。 + + + + + + Idle in transaction: トランザクション中にクライアントからのコマンドを待機しています。 + + + + + + Wait for connection: クライアントからの接続を待機しています。 + + + + + + + + + + ここでは例を示します。 - + test=# show pool_processes; - pool_pid | start_time | database | username | create_time | pool_counter -----------+---------------------+----------+----------+---------------------+-------------- - 19696 | 2016-10-17 13:24:17 | postgres | t-ishii | 2016-10-17 13:35:12 | 1 - 19697 | 2016-10-17 13:24:17 | | | | - 19698 | 2016-10-17 13:24:17 | | | | - 19699 | 2016-10-17 13:24:17 | | | | - 19700 | 2016-10-17 13:24:17 | | | | - 19701 | 2016-10-17 13:24:17 | | | | - 19702 | 2016-10-17 13:24:17 | | | | - 19703 | 2016-10-17 13:24:17 | | | | - 19704 | 2016-10-17 13:24:17 | | | | - 19705 | 2016-10-17 13:24:17 | | | | - 19706 | 2016-10-17 13:24:17 | | | | - 19707 | 2016-10-17 13:24:17 | | | | - 19708 | 2016-10-17 13:24:17 | | | | - 19709 | 2016-10-17 13:24:17 | | | | - 19710 | 2016-10-17 13:24:17 | | | | - 19711 | 2016-10-17 13:24:17 | | | | - 19712 | 2016-10-17 13:24:17 | | | | - 19713 | 2016-10-17 13:24:17 | | | | - 19714 | 2016-10-17 13:24:17 | | | | - 19715 | 2016-10-17 13:24:17 | | | | - 19716 | 2016-10-17 13:24:17 | | | | - 19717 | 2016-10-17 13:24:17 | | | | - 19718 | 2016-10-17 13:24:17 | | | | - 19719 | 2016-10-17 13:24:17 | | | | - 19720 | 2016-10-17 13:24:17 | | | | - 20024 | 2016-10-17 13:33:46 | | | | - 19722 | 2016-10-17 13:24:17 | test | t-ishii | 2016-10-17 13:34:42 | 1 - 19723 | 2016-10-17 13:24:17 | | | | - 19724 | 2016-10-17 13:24:17 | | | | - 19725 | 2016-10-17 13:24:17 | | | | - 19726 | 2016-10-17 13:24:17 | | | | - 19727 | 2016-10-17 13:24:17 | | | | -(32 rows) - - - + pool_pid | start_time | client_connection_count | database | username | backend_connection_time | pool_counter | status +----------+------------------------------------------------------+-------------------------+----------+----------+-------------------------+--------------+--------------------- + 32641 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32642 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32643 | 2021-09-28 04:40:45 | 0 | test | kawamoto | 2021-09-28 04:40:48 | 1 | Idle + 32644 | 2021-09-28 04:40:45 | 0 | test | kawamoto | 2021-09-28 04:43:15 | 1 | Execute command + 32645 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32646 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32647 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32648 | 2021-09-28 04:40:45 (3:15 before process restarting) | 2 | | | | | Wait for connection +(8 rows) + + + diff --git a/doc.ja/src/sgml/ref/show_pool_status.sgml b/doc.ja/src/sgml/ref/show_pool_status.sgml index 44639169c..9b2f084f5 100644 --- a/doc.ja/src/sgml/ref/show_pool_status.sgml +++ b/doc.ja/src/sgml/ref/show_pool_status.sgml @@ -4,69 +4,69 @@ --> - - SHOW POOL_STATUS - + + SHOW POOL_STATUS + - - SHOW POOL_STATUS - 1 - SQL - Language Statements - + + SHOW POOL_STATUS + 1 + SQL - Language Statements + - - SHOW POOL_STATUS - - - 設定パラメータの名前と値、説明を表示する - - + + SHOW POOL_STATUS + + + 設定パラメータの名前と値、説明を表示する + + - - -SHOW POOL_STATUS - - + + + SHOW POOL_STATUS + + - + - 説明 + Description + --> + 説明 - - SHOW POOL_STATUS - - は Pgpool-II の設定パラメータの名前と値、説明を表示します。 - - - - このコマンドは と似ていますが、 + + SHOW POOL_STATUS + + は Pgpool-II の設定パラメータの名前と値、説明を表示します。 + + + + このコマンドは と似ていますが、 古いバージョンのコマンドです。SHOW POOL_STATUS の代わりに、 を使うことを推奨します。 - - + + - + - 関連項目 + See Also + --> + 関連項目 - - - - + + + + diff --git a/doc.ja/src/sgml/ref/show_pool_version.sgml b/doc.ja/src/sgml/ref/show_pool_version.sgml index 03150f8b7..5b53c9e53 100644 --- a/doc.ja/src/sgml/ref/show_pool_version.sgml +++ b/doc.ja/src/sgml/ref/show_pool_version.sgml @@ -4,57 +4,57 @@ --> - - SHOW POOL_VERSION - - - - SHOW POOL_VERSION - 1 - SQL - Language Statements - - - - SHOW POOL_VERSION - - - Pgpool-II のバージョン情報を表示する - - - - - -SHOW POOL_VERSION - - - - + + SHOW POOL_VERSION + + + + SHOW POOL_VERSION + 1 + SQL - Language Statements + + + + SHOW POOL_VERSION + + + Pgpool-II のバージョン情報を表示する + + + + + + SHOW POOL_VERSION + + + + - 説明 - - - SHOW POOL_VERSION - - は Pgpool-II のバージョン情報を表示します。 - ここでは例を示します。 - -test=# show pool_version; - pool_version --------------------------- - 3.6.0 (subaruboshi) -(1 row) - - - - + Description + --> + 説明 + + + SHOW POOL_VERSION + + は Pgpool-II のバージョン情報を表示します。 + ここでは例を示します。 + + test=# show pool_version; + pool_version + -------------------------- + 3.6.0 (subaruboshi) + (1 row) + + + + diff --git a/doc.ja/src/sgml/ref/watchdog_setup.sgml b/doc.ja/src/sgml/ref/watchdog_setup.sgml index d8a2a16af..fc75c16cf 100644 --- a/doc.ja/src/sgml/ref/watchdog_setup.sgml +++ b/doc.ja/src/sgml/ref/watchdog_setup.sgml @@ -17,10 +17,10 @@ Pgpool-II documentation watchdog_setup - - watchdog 機能を有効にした Pgpool-II クラスタのテスト環境を構築するツール + + watchdog 機能を有効にした Pgpool-II クラスタのテスト環境を構築するツール @@ -31,492 +31,507 @@ Pgpool-II documentation - 説明 - watchdog_setup - - はカレントディレクトリで、watchdog 機能を有効にした Pgpool-II - とノード数が指定できる複数の PostgreSQL - のクラスタテスト環境を構築するツールです。 - カレントディレクトリは空である必要があります。 + watchdog_setup + + はカレントディレクトリで、watchdog 機能を有効にした Pgpool-II + とノード数が指定できる複数の PostgreSQL + のクラスタテスト環境を構築するツールです。 + カレントディレクトリは空である必要があります。 - - watchdog_setup はテストのために使うツールなので、 - 実際の業務システムで利用することはおすすめしません。また、heartbeat が使用されていないことにもご注意ください。 + + watchdog_setup はテストのために使うツールなので、実際の業務システムで利用することはおすすめしません。 - - watchdog_setup をベースとしたツールです。 + + watchdog_setup をベースとしたツールです。 - - 現在、watchdog_setup は「ストリーミングレプリケーションモード」、「ネイティブレプリケーションモード」、「ロジカルレプリケーションモード」及び「raw モード」に対応しています。 + + 現在、watchdog_setup は「ストリーミングレプリケーションモード」、「スナップショットアイソレーションモード」、「ネイティブレプリケーションモード」、「ロジカルレプリケーションモード」、及び「raw モード」に対応しています。 - オプション - + - watchdog_setup は以下のコマンドライン引数を受け付けます: + watchdog_setup accepts the following command-line arguments: + --> + watchdog_setup は以下のコマンドライン引数を受け付けます: - + - - - - + + + + - Pgpool-II の数を指定します。 - 指定しない場合は 3 です。 - - - - - - - - + Specifies the number of Pgpool-II installations. + If this is omitted, 3 is used. + --> + Pgpool-II の数を指定します。 + 指定しない場合は 3 です。 + + + + + + + + - Pgpool-IIPostgreSQL のベースとなるポート番号を指定します。 - 最初の Pgpool-II のポートは watchdog_base_port となります。 - pcp のポートは watchdog_base_port + 1、watchdog のポートは watchdog_base_port + 2 となります。wd_heartbeat_port は watchdog_base_port + 3 (heartbeat が使われていない場合でも)。 - 1 番目の PostgreSQL ノードのポートは watchdog_base_port + 4、 - 2 番目の PostgreSQL ノードのポートは watchdog_base_port + 5 というようになります。 - - - 省略した場合、50000 が使われます。 - - - - - - - - + Specify the starting base port number used by Pgpool-II and + PostgreSQL. For the first Pgpool-II, Pgpool-II port is + watchdog_base_port. pcp port is u watchdog port is + watchdog_base_port + 2. wd_heartbeat_port is + watchdog_base_port + 3 (though heartbeat is not used). The + first PostgreSQL node's port is watchdog_base_port + 4, + second PostgreSQL node's port is watchdog_base_port + 5 and + so on. + --> + Pgpool-IIPostgreSQL のベースとなるポート番号を指定します。 + 最初の Pgpool-II のポートは watchdog_base_port となります。 + pcp のポートは watchdog_base_port + 1、watchdog のポートは watchdog_base_port + 2 となります。wd_heartbeat_port は watchdog_base_port + 3 (heartbeat が使われていない場合でも)。 + 1 番目の PostgreSQL ノードのポートは watchdog_base_port + 4、 + 2 番目の PostgreSQL ノードのポートは watchdog_base_port + 5 というようになります。 + + + 省略した場合、50000 が使われます。 + + + + + + + + - 動作モードを指定します。modeは - r (ネイティブレプリケーションモード), s (ストリーミングレプリケーションモード)、または - n (raw モード)を指定できます。 - 指定しない場合は、s (ストリーミングレプリケーションモード) が使われます。 - - - - - - - - + Specifies the running mode. mode + can be r (native replication mode), s (streaming replication mode), or + n (raw mode). + If this is omitted, s is used. + --> + 動作モードを指定します。modeは + r (ネイティブレプリケーションモード)、i (スナップショットアイソレーションモード)、s (ストリーミングレプリケーションモード)、l (ロジカルレプリケーションモード)またはn (raw モード)を指定できます。 + 指定しない場合は、s (ストリーミングレプリケーションモード) が使われます。 + + + + + + + + - PostgreSQL のノード数を指定します。指定しない場合は、ノード数が 2 です。 - - - - - - - - + Specifies the number of PostgreSQL installations. + If this is omitted, 2 is used. + --> + PostgreSQL のノード数を指定します。指定しない場合は、ノード数が 2 です。 + + + + + + + + + 仮想IPを指定します。 + ipを省略した場合は、'127.0.0.1'を指定したものと見なされます。 + ここで指定した仮想IPは、パラメータに設定されます。 + 仮想IPを指定しても、実際に仮想IPがシステムに設定されるわけではなく、単にや、ログファイルで仮想IPを設定する動作が確認できるだけですが、Pgpool-IIの仮想IPに関する挙動をテストするのに役立ちます。 + また、以下のパラメータも設定されます。 + + if_up_cmd = '/usr/bin/echo "if_up_cmd executed"' + if_down_cmd = 'usr/bin/echo "if_down_cmd executed"' + arping_cmd = '/usr/bin/true' + + + + + + + + + - セットアップ終了後に Pgpool-II, PostgreSQL を終了しません。 - - - - - - - - + Do not stop pgpool and PostgreSQL after the work. + --> + セットアップ終了後に Pgpool-II, PostgreSQL を終了しません。 + + + + + + + + - デバッグモードで Pgpool-II を起動します。 - - - - - + Start pgpool with debug mode. + --> + デバッグモードで Pgpool-II を起動します。 + + + + + - 環境変数 - + - watchdog_setup は以下の環境変数を使用します: + watchdog_setup recognizes following environment variables: + --> + watchdog_setup は以下の環境変数を使用します: - + - - - - + + + + - pgpool_setup コマンドへのパスを指定します。 - デフォルトでは "pgpool_setup" であり、 - pgpool_setup がコマンドサーチパスに入っていなければなりません。 - - - - - - - - + Specifies the path to pgpool_setup command. The default is + "pgpool_setup", thus it is assumed that pgpool_setup is in the + command search path. + --> + pgpool_setup コマンドへのパスを指定します。 + デフォルトでは "pgpool_setup" であり、 + pgpool_setup がコマンドサーチパスに入っていなければなりません。 + + + + + + + + - Pgpool-II のインストールディレクトリを指定します。 - Pgpool-II バイナリーは PGPOOL_INSTALL_DIR/bin ディレクトリ以下、 - pgpool.confpool_hba.conf - などは PGPOOL_INSTALL_DIR/etc ディレクトリ以下にインストールされます。 - デフォルトでは /usr/local ディレクトリ以下にインストールされます。 - - - - - - - - + Specifies the Pgpool-II installation directory. Pgpool-II + binaries is expected to be placed under PGPOOL_INSTALL_DIR/bin + and pgpool.conf and pool_hba.conf etc. are expected to be placed under + PGPOOL_INSTALL_DIR/etc. The default is /usr/local. + --> + Pgpool-II のインストールディレクトリを指定します。 + Pgpool-II バイナリーは PGPOOL_INSTALL_DIR/bin ディレクトリ以下、 + pgpool.confpool_hba.conf + などは PGPOOL_INSTALL_DIR/etc ディレクトリ以下にインストールされます。 + デフォルトでは /usr/local ディレクトリ以下にインストールされます。 + + + + + + + + - Pgpool-II 設定ファイルへのパスを指定します。 - デフォルトでは PGPOOL_INSTALL_DIR/etc です。 - - - - - - - - + Specifies the path to Pgpool-II configuration files. + The default is PGPOOL_INSTALL_DIR/etc. + --> + Pgpool-II 設定ファイルへのパスを指定します。 + デフォルトでは PGPOOL_INSTALL_DIR/etc です。 + + + + + + + + - initdb、pg_ctl と psql など PostgreSQL コマンドへのパスを指定します。 - デフォルトでは、/usr/local/pgsql/bin です。 - - - - - - - - + Specifies the path to PostgreSQL commands such as initdb, pg_ctl and psql. + The default is /usr/local/pgsql/bin. + --> + initdb、pg_ctl と psql など PostgreSQL コマンドへのパスを指定します。 + デフォルトでは、/usr/local/pgsql/bin です。 + + + + + + + + - PostgreSQL の共有ライブラリへのパスを指定します。 - デフォルトでは、/usr/local/pgsql/lib です。 - - - - - - - - + Specifies the path to PostgreSQL shared libraries. + The default is /usr/local/pgsql/lib. + --> + PostgreSQL の共有ライブラリへのパスを指定します。 + デフォルトでは、/usr/local/pgsql/lib です。 + + + + + + + + - Unix ソケットのディレクトリへのパスを指定します。 - デフォルトでは /tmp です。 - - - - - - - + Specifies the path to Unix socket directory. + The default is /tmp. + --> + Unix ソケットのディレクトリへのパスを指定します。 + デフォルトでは /tmp です。 + + + + + + + - initdb コマンドの引数を指定します。 - デフォルトでは "--no-locale -E UTF_8" です。 - - - - - - - + Specifies the arguments for initdb command. + The default is "no-locale -E UTF_8". + --> + initdb コマンドの引数を指定します。 + デフォルトでは "--no-locale -E UTF_8" です。 + + + + + + + - 出力例 - - -$ watchdog_setup -Starting set up -============= setting up pgpool 0 ============= -Starting set up in streaming replication mode -creating startall and shutdownall -creating failover script -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data0...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data1...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -temporarily start data0 cluster to create extensions -temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) - -recovery node 1...pcp_recovery_node -- Command Successful -done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | true | 0 -(2 rows) - -shutdown all - -pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/startall. -To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/shutdownall. -pcp command user name is "t-ishii", password is "t-ishii". -Each PostgreSQL, pgpool-II and pcp port is as follows: -#1 port is 51000 -#2 port is 51001 -pgpool port is 50000 -pcp port is 50001 -The info above is in README.port. -============= setting up pgpool 1 ============= -Starting set up in streaming replication mode -creating startall and shutdownall -creating failover script -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data0...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data1...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -temporarily start data0 cluster to create extensions -temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) - -recovery node 1...pcp_recovery_node -- Command Successful -done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 -(2 rows) - -shutdown all - -pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/startall. -To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/shutdownall. -pcp command user name is "t-ishii", password is "t-ishii". -Each PostgreSQL, pgpool-II and pcp port is as follows: -#1 port is 51000 -#2 port is 51001 -pgpool port is 50004 -pcp port is 50005 -The info above is in README.port. -============= setting up pgpool 2 ============= -Starting set up in streaming replication mode -creating startall and shutdownall -creating failover script -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data0...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data1...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -temporarily start data0 cluster to create extensions -temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) - -recovery node 1...pcp_recovery_node -- Command Successful -done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 -(2 rows) - -shutdown all - -pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/startall. -To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/shutdownall. -pcp command user name is "t-ishii", password is "t-ishii". -Each PostgreSQL, pgpool-II and pcp port is as follows: -#1 port is 51000 -#2 port is 51001 -pgpool port is 50008 -pcp port is 50009 -The info above is in README.port. - -$ ls -pgpool0 pgpool1 pgpool2 shutdownall startall - -$ sh startall -waiting for server to start....16123 2016-08-18 16:26:53 JST LOG: redirecting log output to logging collector process -16123 2016-08-18 16:26:53 JST HINT: Future log output will appear in directory "pg_log". - done -server started -waiting for server to start....16136 2016-08-18 16:26:54 JST LOG: redirecting log output to logging collector process -16136 2016-08-18 16:26:54 JST HINT: Future log output will appear in directory "pg_log". - done -server started - -t-ishii@localhost: psql -p 50000 test - -Pager usage is off. -psql (9.5.4) -Type "help" for help. - -test=# \q - -$ pcp_watchdog_info -p 50001 -v -Password: -Watchdog Cluster Information -Total Nodes : 3 -Remote Nodes : 2 -Quorum state : QUORUM EXIST -Alive Remote Nodes : 2 -VIP up on local node : NO -Master Node Name : Linux_tishii-CF-SX3HE4BP_50004 -Master Host Name : localhost - -Watchdog Node Information -Node Name : Linux_tishii-CF-SX3HE4BP_50000 -Host Name : localhost -Delegate IP : Not_Set -Pgpool port : 50000 -Watchdog port : 50002 -Node priority : 1 -Status : 7 -Status Name : STANDBY - -Node Name : Linux_tishii-CF-SX3HE4BP_50004 -Host Name : localhost -Delegate IP : Not_Set -Pgpool port : 50004 -Watchdog port : 50006 -Node priority : 1 -Status : 4 -Status Name : MASTER - -Node Name : Linux_tishii-CF-SX3HE4BP_50008 -Host Name : localhost -Delegate IP : Not_Set -Pgpool port : 50008 -Watchdog port : 50010 -Node priority : 1 -Status : 7 -Status Name : STANDBY - - - + + + $ watchdog_setup + Starting set up + ============= setting up pgpool 0 ============= + Starting set up in streaming replication mode + creating startall and shutdownall + creating failover script + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data0...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data1...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + temporarily start data0 cluster to create extensions + temporarily start pgpool-II to create standby nodes + INFO: unrecognized configuration parameter "debug_level" + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 + (2 rows) + + recovery node 1...pcp_recovery_node -- Command Successful + done. + creating follow primary script + Pager usage is off. + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | false | 0 + 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | true | 0 + (2 rows) + + shutdown all + + pgpool-II setting for streaming replication mode is done. + To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/startall. + To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/shutdownall. + pcp command user name is "t-ishii", password is "t-ishii". + Each PostgreSQL, pgpool-II and pcp port is as follows: + #1 port is 51000 + #2 port is 51001 + pgpool port is 50000 + pcp port is 50001 + The info above is in README.port. + ============= setting up pgpool 1 ============= + Starting set up in streaming replication mode + creating startall and shutdownall + creating failover script + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data0...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data1...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + temporarily start data0 cluster to create extensions + temporarily start pgpool-II to create standby nodes + INFO: unrecognized configuration parameter "debug_level" + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 + (2 rows) + + recovery node 1...pcp_recovery_node -- Command Successful + done. + creating follow primary script + Pager usage is off. + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 + (2 rows) + + shutdown all + + pgpool-II setting for streaming replication mode is done. + To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/startall. + To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/shutdownall. + pcp command user name is "t-ishii", password is "t-ishii". + Each PostgreSQL, pgpool-II and pcp port is as follows: + #1 port is 51000 + #2 port is 51001 + pgpool port is 50004 + pcp port is 50005 + The info above is in README.port. + ============= setting up pgpool 2 ============= + Starting set up in streaming replication mode + creating startall and shutdownall + creating failover script + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data0...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data1...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + temporarily start data0 cluster to create extensions + temporarily start pgpool-II to create standby nodes + INFO: unrecognized configuration parameter "debug_level" + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 + (2 rows) + + recovery node 1...pcp_recovery_node -- Command Successful + done. + creating follow primary script + Pager usage is off. + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 + (2 rows) + + shutdown all + + pgpool-II setting for streaming replication mode is done. + To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/startall. + To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/shutdownall. + pcp command user name is "t-ishii", password is "t-ishii". + Each PostgreSQL, pgpool-II and pcp port is as follows: + #1 port is 51000 + #2 port is 51001 + pgpool port is 50008 + pcp port is 50009 + The info above is in README.port. + + $ ls + pgpool0 pgpool1 pgpool2 shutdownall startall + + $ sh startall + waiting for server to start....16123 2016-08-18 16:26:53 JST LOG: redirecting log output to logging collector process + 16123 2016-08-18 16:26:53 JST HINT: Future log output will appear in directory "pg_log". + done + server started + waiting for server to start....16136 2016-08-18 16:26:54 JST LOG: redirecting log output to logging collector process + 16136 2016-08-18 16:26:54 JST HINT: Future log output will appear in directory "pg_log". + done + server started + + t-ishii@localhost: psql -p 50000 test + + Pager usage is off. + psql (9.5.4) + Type "help" for help. + + test=# \q + + $ pcp_watchdog_info -p 50001 -v + Password: + Watchdog Cluster Information + Total Nodes : 3 + Remote Nodes : 2 + Quorum state : QUORUM EXIST + Alive Remote Nodes : 2 + VIP up on local node : NO + Leader Node Name : Linux_tishii-CF-SX3HE4BP_50004 + Leader Host Name : localhost + + Watchdog Node Information + Node Name : Linux_tishii-CF-SX3HE4BP_50000 + Host Name : localhost + Delegate IP : Not_Set + Pgpool port : 50000 + Watchdog port : 50002 + Node priority : 1 + Status : 7 + Status Name : STANDBY + + Node Name : Linux_tishii-CF-SX3HE4BP_50004 + Host Name : localhost + Delegate IP : Not_Set + Pgpool port : 50004 + Watchdog port : 50006 + Node priority : 1 + Status : 4 + Status Name : LEADER + + Node Name : Linux_tishii-CF-SX3HE4BP_50008 + Host Name : localhost + Delegate IP : Not_Set + Pgpool port : 50008 + Watchdog port : 50010 + Node priority : 1 + Status : 7 + Status Name : STANDBY + + + diff --git a/doc.ja/src/sgml/ref/wd_cli.sgml b/doc.ja/src/sgml/ref/wd_cli.sgml new file mode 100644 index 000000000..267585af0 --- /dev/null +++ b/doc.ja/src/sgml/ref/wd_cli.sgml @@ -0,0 +1,364 @@ + + + + + wd_cli + + + + wd_cli + 1 + Other Commands + + + + wd_cli + + +外部ヘルスチェックシステムとの統合に用いるためのWatchdog Command Line Interface (CLI)ユーティリティ + + + + + + wd_cli + operation + node search option + option + + + + + 説明 + + wd_cli + +watchdogとヘルスチェック関連のノード操作を行うための便利で使いやすいインターフェイスを提供します。 + + + + + + 操作 + + + + + + + + + +ノードの検索条件に基づいてノード状態を取得します。 + + + + + + + + + + +watchdogノード状態を更新します。 +受付可能な値はDEADALIVEです。 + + + + + + + + + + + ノード検索オプション + + + + + + + + + +すべてのノードを選択します。(--info操作でのみ可能です) + + + + + + + + + + +node_idでwatchdogノードを検索します。 + + + + + + + + + + +名前でwatchdogノードを検索します。 + + + + + + + + + + +ホスト名でwatchdogノードを検索します。 + + + + + + + + + + +ポート番号でwatchdogノードを検索します。 + + + + + + + + + + + + オプション + + + + + + + + + +watchdog認証キー。 +この認証キーを指定するとpgpool.conf->wd_authkeyの値に優先します。 + + + + + + + + + + +pgpool.confファイル. + + + + + + + + + + +watchdog IPCソケットディレクトリのパスです。 +このパスを指定するとpgpool.conf->wd_ipc_socket_dirの値に優先します。 + + + + + + + + + + +watchdog IPCソケットのポート番号です。 +このポート番号を指定するとpgpool.conf->wd_portの値に優先します。 + + + + + + + + + + + +ノード状態とともにPgpool-IIに渡す追加のメッセージ文字列です。 + + + + + + + + + + +冗長なメッセージを有効にします。 + + + + + + + + + + +バージョン情報を表示します。 + + + + + + + + + + +デバッグ表示を有効にします。 + + + + + + + + + + +wd_cliのヘルプを表示します。 + + + + + + + + + + + + + +Pgpool-IIクラスタを監視するために外部ヘルスチェックシステムが設定されていて、ノード障害を検出しました。 +この情報をPgpool-IIクラスタに渡して適切な対応を行うことができるようにwd_cliユーティリティを使用することができます。 + + + #inform Pgpool-II about node named RN-110 failure + wd_cli --inform DEAD -N 'RN-110' -p 9001 -m 'Pgpool node with name RN-110 is not reachable' + + + #inform Pgpool-II about node-id 10 failure + wd_cli --inform DEAD -n 10 -m 'Pgpool node with ID 10 is not responding' + + +同様にノードが再び復帰したことをPgpool-IIに知らせます。 + + #inform Pgpool-II about node-id 10 re-joining + wd_cli --inform ALIVE -n 10 -m 'Pgpool node with ID 10 is reachable again' + + + +また、wd_cliはノードの現在の状態を取得するために使用することができます。 + + wd_cli -f simple_conf/watchdog/pgpool_wd1.conf --info -v --all + + Total Watchdog nodes configured for lifecheck: 2 + ***************** + Node ID: 0 + Node Status code 4 + Node Status: LEADER + Node Name: localhost:9991 Linux localhost.localdomain + Node Host: localhost + Node WD Port: 9001 + Node Pgpool Port: 9991 + + Node ID: 1 + Node Status code 7 + Node Status: STANDBY + Node Name: localhost:9992 Linux localhost.localdomain + Node Host: localhost + Node WD Port: 9002 + Node Pgpool Port: 9992 + + + + + diff --git a/doc.ja/src/sgml/reference.sgml b/doc.ja/src/sgml/reference.sgml index 101c77996..410556167 100644 --- a/doc.ja/src/sgml/reference.sgml +++ b/doc.ja/src/sgml/reference.sgml @@ -1,352 +1,367 @@ - + --> リファレンス - - ここには Pgpool-II のリファレンス情報があります。 + + ここには Pgpool-II のリファレンス情報があります。 - - このリファレンスは伝統的な man ページとしても入手できます。 + + このリファレンスは伝統的な man ページとしても入手できます。 - - サーバコマンド + + サーバコマンド - - - -ここには、サーバコマンドの情報があります。 -いまのところ、pgpoolだけがここに所属しています。 - - - &pgpool; + + + + ここには、サーバコマンドの情報があります。 + いまのところ、pgpoolだけがここに所属しています。 + + + &pgpool; - - PCP コマンド + + PCP コマンド - - - - ここには Pgpool-II の PCP コマンドのリファレンス情報があります。 - PCP コマンドはネットワーク経由で複数の Pgpool-II を操作する UNIX コマンドです。 - 注意:Pgpool-II 3.5 より、全ての PCP コマンドのパラメータ書式が変更されています。 - + + + + ここには Pgpool-II の PCP コマンドのリファレンス情報があります。 + PCP コマンドはネットワーク経由で複数の Pgpool-II を操作する UNIX コマンドです。 + 注意:Pgpool-II 3.5 より、全ての PCP コマンドのパラメータ書式が変更されています。 + - - - PCP 接続認証 - + + PCP 接続認証 + + PCP ユーザ名とパスワードが $prefix/etc ディレクトリ内の pcp.conf - で宣言されている必要があります。pcp.conf が他の場所にある場合には、 - Pgpool-II の起動時に オプションで指定することができます。 - - + で宣言されている必要があります(このファイルを作る方法についてはを参照してください)。 + pcp.conf が他の場所にある場合には、 + Pgpool-II の起動時に オプションで指定することができます。 + + - - - PCP パスワードファイル - + + + PCP パスワードファイル + - PCP 接続時にパスワードが指定されなかった場合、ユーザのホームディレクトリに配置された .pcppass ファイルか、 - 環境変数 PCPPASSFILE で参照されるファイルに格納されたパスワードが使用可能です。 - - - このファイルの各行の書式は以下のとおりです: - -hostname:port:username:password - - + + hostname:port:username:password + + - - (この文字列の行頭に # を付けてからファイルにコピーしておけば備忘録のコメントになります。) 最初の3つのフィールドはそれぞれリテラル値か、任意のものにマッチする * を指定します。 現在の接続パラメータにマッチした最初の行の password フィールドが使用されます。 (したがって、ワイルドーカードを使用する場合には、具体的なエントリーの方を先に書きます。) エントリーの中に 「:」 か 「\」 を含む必要がある場合には、その文字を 「\」 をつかってエスケープしてください。 - ホスト名 localhost はローカルマシンからの TCP と Unix ドメインソケットの両方の接続にマッチします。 - + hostname フィールドは、host 接続パラメータとマッチします。host パラメータが指定されていなければ、ホスト名localhostがマッチします。 + 接続が Unix ドメインソケット接続で、host パラメータがデフォルトの PCP ソケットディレクトリパスに一致した場合も、ホスト名localhostがマッチします。 + - - .pcppass のパーミッションはグループおよび全ユーザからのアクセスを許してはいけません。 chmod 0600 ~/.pcppass を実行してください。これよりパーミッションの制限が弱い場合には、 このファイルは無視されます。 - + - + - + - &pcpCommonOptions; - &pcpNodeCount; - &pcpNodeInfo; - &pcpWatchdogInfo; - &pcpProcCount; - &pcpProcInfo; - &pcpPoolStatus; - &pcpDetachNode; - &pcpAttachNode; - &pcpPromoteNode; - &pcpStopPgpool; - &pcpRecoveryNode; + &pcpCommonOptions; + &pcpNodeCount; + &pcpNodeInfo; + &pcpHealthCheckStats; + &pcpWatchdogInfo; + &pcpProcCount; + &pcpProcInfo; + &pcpPoolStatus; + &pcpDetachNode; + &pcpAttachNode; + &pcpPromoteNode; + &pcpStopPgpool; + &pcpReloadConfig; + &pcpRecoveryNode; + &pcpLogRotate; + &pcpInvalidateCache; - - - 他のコマンド + + + 他のコマンド - - - - ここには、他の Pgpool-II コマンドのリファレンス情報があります。 - + + + + ここには、他の Pgpool-II コマンドのリファレンス情報があります。 + - + - &pgMd5; - &pgEnc; - &pgproto; - &pgpoolSetup; - &watchdoglSetup; + &pgMd5; + &pgEnc; + &pgproto; + &pgpoolSetup; + &watchdogSetup; + &wdCli; - - - SQL 型コマンド - - - - - ここには、SQL 型の Pgpool-II コマンドのリファレンス情報があります。 - これらのコマンドは、psql のような標準 PostgreSQL - のクライアントのSQLセッションで発行できますが、バックエンド DB に転送されず、 - Pgpool-II サーバで処理されます。 - また、拡張クエリモードでは利用することができません。 - + + + SQL 型コマンド - + + + + ここには、SQL 型の Pgpool-II コマンドのリファレンス情報があります。 + これらのコマンドは、psql のような標準 PostgreSQL + のクライアントのSQLセッションで発行できますが、バックエンド DB に転送されず、 + Pgpool-II サーバで処理されます。 + また、拡張クエリモードでは利用することができません。 + - &pgpoolShow - &pgpoolSet - &pgpoolReset - &showPoolStatus - &showPoolNodes - &showPoolProcesses - &showPoolPools - &showPoolVersion - &showPoolCache + - - - - pgpool_admエクステンション - - - -pgpool_admは、 (実際には, pcp -ライブラリ)にアクセスできるようにするための一連のエクステンションです。 - - -
- - <command>pgpool_adm</command>が動く仕組み - - - - - -
-
+ &pgpoolShow + &pgpoolSet + &pgpoolSetCache + &pgpoolReset + &showPoolStatus + &showPoolNodes + &showPoolProcesses + &showPoolPools + &showPoolVersion + &showPoolCache + &showPoolHealthCheckStats + &showPoolBackendStats +
+ + + pgpool_admエクステンション + + + + pgpool_admは、 (実際には, pcp + ライブラリ)にアクセスできるようにするための一連のエクステンションです。 + + +
+ + <command>pgpool_adm</command>が動く仕組み + + + + + +
+
- - -Pgpool-II経由でも(1)、あるいは直接PostgreSQLに対しても(2)、関数を呼び出すことができます。 -(1)の場合には、Pgpool-IIはユーザからクエリを受け付け(1)、PostgreSQLに転送します(3)。 -PostgreSQLは、Pgpool-IIに接続し(5)、Pgpool-IIPostgreSQLに(3)の結果を返します。 -PostgreSQLPgpool-IIに結果を返し(5)、Pgpool-IIはそのデータをユーザに転送します(6)。 - - - -(2)の場合には、PostgreSQLがクエリをユーザから受け付けます(2)。 -PostgreSQLPgpool-IIに接続し(5)、Pgpool-IIPostgreSQLに(3)の結果を返します。 -PostgreSQLはそのデータをユーザに返します(6)。 - - - -pgpool_adm関数の呼び出し形式は2種類あります。 -最初の形式はPgpool-IIのホスト名(またはIPアドレス)、pcpポート番号、pcpユーザ名、パスワード、それ以外のパラメータです。 - - - -2番目の形式では、Pgpool-IIサーバ名が必要になります。 -サーバ名はPostgreSQLの"CREATE FOREIGN SERVER"コマンドで定義済みでなければなりません。 -pcpポート番号は9898に固定されています。 -pcpユーザ名は、呼び出し元のPostgreSQLユーザ名と同じであると見なされます。 -パスワードは$HOME/.pcppassから取得します。 - + + + Pgpool-II経由でも(1)、あるいは直接PostgreSQLに対しても(2)、関数を呼び出すことができます。 + (1)の場合には、Pgpool-IIはユーザからクエリを受け付け(1)、PostgreSQLに転送します(3)。 + PostgreSQLは、Pgpool-IIに接続し(5)、Pgpool-IIPostgreSQLに(3)の結果を返します。 + PostgreSQLPgpool-IIに結果を返し(5)、Pgpool-IIはそのデータをユーザに転送します(6)。 + + + + (2)の場合には、PostgreSQLがクエリをユーザから受け付けます(2)。 + PostgreSQLPgpool-IIに接続し(5)、Pgpool-IIPostgreSQLに(3)の結果を返します。 + PostgreSQLはそのデータをユーザに返します(4)。 + + + + pgpool_adm関数の呼び出し形式は2種類あります。 + 最初の形式はPgpool-IIのホスト名(またはIPアドレス)、pcpポート番号、pcpユーザ名、パスワード、それ以外のパラメータです。 + + + + 2番目の形式では、Pgpool-IIサーバ名が必要になります。 + サーバ名はPostgreSQLの"CREATE FOREIGN SERVER"コマンドで定義済みでなければなりません。 + pcpポート番号は9898に固定されています。 + pcpユーザ名は、呼び出し元のPostgreSQLユーザ名と同じであると見なされます。 + パスワードは$HOME/.pcppassから取得します。 + - - - pgpool_admのインストール - - -pgpool_admはエクステンションであり、すべてのPostgreSQLサーバにインストールする必要があります。 - -$ cd src/sql/pgpool_adm -$ make -$ make install - - -次のSQLコマンドをアクセスしたいすべてのデータベースに発行します。 - + + + pgpool_admのインストール + + + pgpool_admはエクステンションであり、すべてのPostgreSQLサーバにインストールする必要があります。 + + $ cd src/sql/pgpool_adm + $ make + $ make install + + + 次のSQLコマンドをアクセスしたいすべてのデータベースに発行します。 + $ psql ... -$ CREATE EXTENSION pgpool_adm - - - - -
+=# CREATE EXTENSION pgpool_adm + + + + + - &pgpoolAdmPcpNodeInfo - &pgpoolAdmPcpPoolStatus - &pgpoolAdmPcpNodeCount - &pgpoolAdmPcpAttachNode - &pgpoolAdmPcpDetachNode + &pgpoolAdmPcpNodeInfo + &pgpoolAdmPcpHealthCheckStats + &pgpoolAdmPcpPoolStatus + &pgpoolAdmPcpNodeCount + &pgpoolAdmPcpAttachNode + &pgpoolAdmPcpDetachNode + &pgpoolAdmPcpProcInfo -
+
diff --git a/doc.ja/src/sgml/release-3.1.sgml b/doc.ja/src/sgml/release-3.1.sgml index e627755e9..632f2e112 100644 --- a/doc.ja/src/sgml/release-3.1.sgml +++ b/doc.ja/src/sgml/release-3.1.sgml @@ -2,82 +2,82 @@ - - リリース 3.1.21 + + リリース 3.1.21 - + - リリース日 - 2016-12-26 - + Release Date + --> + リリース日 + 2016-12-26 + - + - 不具合修正 + Bug fixes + --> + 不具合修正 - + - - - + -ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) - - - -本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 - - + + + ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) + + + + 本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 + + - - - - -MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) - - + -random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 -random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 - - + + + MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) + + + + random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 + random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 + + - - - + -クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) - - + 2016-09-06 [891ce0f] + --> + + + クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) + + - + - + diff --git a/doc.ja/src/sgml/release-3.2.sgml b/doc.ja/src/sgml/release-3.2.sgml index 2f8cb3e4b..928184dba 100644 --- a/doc.ja/src/sgml/release-3.2.sgml +++ b/doc.ja/src/sgml/release-3.2.sgml @@ -2,376 +2,376 @@ - リリース 3.2.22 - - - リリース日 - 2017-09-05 - - - - 不具合修正 - - - - - - -Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) - - - - - - -pool_unread() の不具合を修正しました。(Tatsuo Ishii) - - -pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 - - - - - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 - - -この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 - - - - - - -SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) - - - - - - -ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) - - -詳細は [pgpool-general: 5621] をご参照ください。 - - - - - + リリース 3.2.22 + + + リリース日 + 2017-09-05 + + + + 不具合修正 + + + + + + + Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) + + + + + + + pool_unread() の不具合を修正しました。(Tatsuo Ishii) + + + pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 + + + + + + + workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) + + + workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 + + + この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 + + + + + + + SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) + + + + + + + ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) + + + 詳細は [pgpool-general: 5621] をご参照ください。 + + + + + - リリース 3.2.21 + リリース 3.2.21 - - リリース日 - 2017-07-11 - + + リリース日 + 2017-07-11 + - - 不具合修正 + + 不具合修正 - - + + - [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) + [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) - + - + - PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) + PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn - + - + - node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) + node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) - 詳細は[pgpool-general: 5511]を参照してください。 + 詳細は[pgpool-general: 5511]を参照してください。 - + - + - PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) + PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) - + - + - クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) + クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) - oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 + oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 - - - + + + - リリース 3.2.20 + リリース 3.2.20 - - リリース日 - 2017-04-28 - + + リリース日 + 2017-04-28 + - - 不具合修正 + + 不具合修正 - - + + pool_hba.confファイルのリロード時に発生するエラーを修正しました。(Bug 299) (Muhammad Usama) - + - + - + - リリース 3.2.19 + リリース 3.2.19 - - リリース日 - 2017-03-17 - + + リリース日 + 2017-03-17 + - - 不具合修正 + + 不具合修正 - + - + - pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) + pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) -失敗したときのエラーメッセージは以下のとおりです。 + 失敗したときのエラーメッセージは以下のとおりです。 - FATAL: invalid pgpool mode for process recovery request - DETAIL: specified node is already primary node, can't promote node id 0 + FATAL: invalid pgpool mode for process recovery request + DETAIL: specified node is already primary node, can't promote node id 0 -ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 + ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 -この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 -失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 + この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 + 失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 -これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 + これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 - + - + + 2017-02-28 [5b4f78c] + --> -READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) + READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) - + - + -特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。 -(bug 272) (Tatsuo Ishii) + 特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。 + (bug 272) (Tatsuo Ishii) - + - + -シグナルハンドラがpool_log/pool_errorを呼び出さないように修正しました。(Tatsuo Ishii) + シグナルハンドラがpool_log/pool_errorを呼び出さないように修正しました。(Tatsuo Ishii) -詳しくは[pgpool-hackers: 1950]をご参照ください。 + 詳しくは[pgpool-hackers: 1950]をご参照ください。 - + - + -特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 -(bug 249)(Muhammad Usama) + 特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 + (bug 249)(Muhammad Usama) -WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 + WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 - + - + -authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) + authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) - + - + -クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) + クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) - + - + - + - - リリース 3.2.18 + + リリース 3.2.18 - + - リリース日 - 2016-12-26 - + Release Date + --> + リリース日 + 2016-12-26 + - + - 不具合修正 + Bug fixes + --> + 不具合修正 - + - - - + -クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) - - - - - - + + + クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) + + + + -ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) - - - -本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 - - - - - - + + + ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) + + + + 本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 + + + + -MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) - - + + + MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) + + + + random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 + random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 + + + + -random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 -random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 - - - - - - - -クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) - - + + + クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) + + - + - + diff --git a/doc.ja/src/sgml/release-3.3.sgml b/doc.ja/src/sgml/release-3.3.sgml index a3e7cae53..9606c837f 100644 --- a/doc.ja/src/sgml/release-3.3.sgml +++ b/doc.ja/src/sgml/release-3.3.sgml @@ -2,818 +2,818 @@ - - リリース 3.3.22 - - - - リリース日 - 2018-07-31 - - - - - 不具合修正 - - - - - -「write on backend 0 failed with error :"Success"」エラーを修正しました。 -(bug 403) (Tatsuo Ishii) - - -write() が 0 を返した場合、エラーとして扱わないように修正しました。 - - - - - - - -armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。( Tatsuo Ishii) - - - -修正パッチは Christian Ehrhardt によって提供されました。 - - - - + + リリース 3.3.22 + + + + リリース日 + 2018-07-31 + + + + + 不具合修正 + + + + + + 「write on backend 0 failed with error :"Success"」エラーを修正しました。 + (bug 403) (Tatsuo Ishii) + + + write() が 0 を返した場合、エラーとして扱わないように修正しました。 + + + + + + + + armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。( Tatsuo Ishii) + + + + 修正パッチは Christian Ehrhardt によって提供されました。 + + + + - - リリース 3.3.21 + + リリース 3.3.21 - - - リリース日 - 2018-04-17 - + + + リリース日 + 2018-04-17 + - - 不具合修正 - + + 不具合修正 + - + - - to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) + + to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) - - - + + + - - リリース 3.3.20 + + リリース 3.3.20 - - - リリース日 - 2018-02-13 - + + + リリース日 + 2018-02-13 + - - 変更点 - + + 変更点 + - + - -systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + + systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) - + - + + + pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + + + + + + + 不具合修正 + + -pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + + + 拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) - - - + + + + + + + + + リリース 3.3.19 + + + + リリース日 + 2018-01-09 + - - 不具合修正 - - + + 不具合修正 + + + + + ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) + + + + ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 + + + + -拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + + ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) - + + + PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 + + - - - + + + + + "ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) + + + + 今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 + ほとんどの場合、問題がありませんでした。 + ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 + + - - - リリース 3.3.19 - - - - リリース日 - 2018-01-09 - - - - 不具合修正 - - - - - - -ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) - - - -ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 - - - - - - - -ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) - - - -PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 - - - - - - - -"ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) - - - -今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 -ほとんどの場合、問題がありませんでした。 -ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 - - - - - + + - リリース 3.3.18 + リリース 3.3.18 - - リリース日 - 2017-11-01 - + + リリース日 + 2017-11-01 + - - 不具合修正 + + 不具合修正 - - + + + + /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) + + + + RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 + + + + - /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) + + + フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) + 詳細は [pgpool-general: 5728]を参照してください。 + + + + - RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 + + + OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) - + - + + + + + + リリース 3.3.17 + + + リリース日 + 2017-09-05 + + + + 不具合修正 + + + + Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) + + + + -フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) + + pool_unread() の不具合を修正しました。(Tatsuo Ishii) -詳細は [pgpool-general: 5728]を参照してください。 + pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 - + - + + Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) + + + + -OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) + + workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) - + + workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 + + + この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 + + - - - + + + + SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) + + - - リリース 3.3.17 - - - リリース日 - 2017-09-05 - - - - 不具合修正 - - - - - -Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) - - - - - - -pool_unread() の不具合を修正しました。(Tatsuo Ishii) - - -pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 - - - - - - -Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) - - - - - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 - - -この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 - - - - - - -SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) - - - - - - -ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) - - -詳細は [pgpool-general: 5621] をご参照ください。 - - - - - + + + + ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) + + + 詳細は [pgpool-general: 5621] をご参照ください。 + + + + + - リリース 3.3.16 + リリース 3.3.16 - - リリース日 - 2017-07-11 - + + リリース日 + 2017-07-11 + - - 不具合修正 + + 不具合修正 - - + + - [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) + [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) - + - + - PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) + PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn - + - + - node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) + node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) - 詳細は[pgpool-general: 5511]を参照してください。 + 詳細は[pgpool-general: 5511]を参照してください。 - + - + - PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) + PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) - + - + - クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) + クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) - oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 + oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 - - - + + + - リリース 3.3.15 + リリース 3.3.15 - - リリース日 - 2017-04-28 - + + リリース日 + 2017-04-28 + - - 不具合修正 + + 不具合修正 - - + + pool_hba.confファイルのリロード時に発生するエラーを修正しました。(Bug 299) (Muhammad Usama) - + - + coverity警告を修正しました。(Muhammad Usama) - + - + - [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 - (Bug 296) (Muhammad Usama) + [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 + (Bug 296) (Muhammad Usama) - + - + - + - リリース 3.3.14 + リリース 3.3.14 - - リリース日 - 2017-03-17 - + + リリース日 + 2017-03-17 + - - 不具合修正 + + 不具合修正 - + - + - pgpool.serviceファイルに"Wants=network.target"を追加しました。 - (bug 294) (Bo Peng) + pgpool.serviceファイルに"Wants=network.target"を追加しました。 + (bug 294) (Bo Peng) - + - + - pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) + pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) -失敗したときのエラーメッセージは以下のとおりです。 + 失敗したときのエラーメッセージは以下のとおりです。 - FATAL: invalid pgpool mode for process recovery request - DETAIL: specified node is already primary node, can't promote node id 0 + FATAL: invalid pgpool mode for process recovery request + DETAIL: specified node is already primary node, can't promote node id 0 -ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 + ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 -この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 -失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 + この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 + 失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 -これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 + これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 - + - + + 2017-02-28 [5b4f78c] + --> -READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) + READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) - + - + -特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。 -(bug 272) (Tatsuo Ishii) + 特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。 + (bug 272) (Tatsuo Ishii) - + - + -ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) + ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) - + - + -wd_get_cmd関数のバッファオーバーフローを修正しました。 -(bug 280)(Muhammad Usama) + wd_get_cmd関数のバッファオーバーフローを修正しました。 + (bug 280)(Muhammad Usama) - + - + -シグナルハンドラがpool_log/pool_errorを呼び出さないように修正しました。(Tatsuo Ishii) + シグナルハンドラがpool_log/pool_errorを呼び出さないように修正しました。(Tatsuo Ishii) -詳しくは[pgpool-hackers: 1950]をご参照ください。 + 詳しくは[pgpool-hackers: 1950]をご参照ください。 - + - + -特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 -(bug 249)(Muhammad Usama) + 特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 + (bug 249)(Muhammad Usama) -WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 + WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 - + - + -authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) + authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) - + - + -クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) + クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) - + - + - + - + リリース 3.3.13 + + + - リリース 3.3.13 + リリース日 + 2016-12-26 + - + + 不具合修正 + + + + + - リリース日 - 2016-12-26 - + + + watchdog のセキュリティを強化しました。(Muhammad Usama) + - - + wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 + + + + + - 不具合修正 + + + Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) + + + + + + + + クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) + + + + + + + + ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) + + + + 本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 + + + + + + + + のデフォルト値を10から300に変更しました。(Tatstuo Ishii) + + + + これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 + + + + + + + + すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(bug 248) (Tatsuo Ishii) + + + + すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 + その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 + そしてこのコマンドは成功しました。 + しかし、新しい接続が拒否されました。 + これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 + ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 + (ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) + 解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 + + + + + + + + MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) + + + + random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 + random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 + + + + + + + + クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) + + - + - - - - -watchdog のセキュリティを強化しました。(Muhammad Usama) - - - - -wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 - - - - - - - -Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) - - - - - - - -クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) - - - - - - - -ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) - - - -本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 - - - - - - - -のデフォルト値を10から300に変更しました。(Tatstuo Ishii) - - - -これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 - - - - - - - -すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(bug 248) (Tatsuo Ishii) - - - -すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 -その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 -そしてこのコマンドは成功しました。 -しかし、新しい接続が拒否されました。 -これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 -ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 -(ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) -解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 - - - - - - - -MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) - - - -random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 -random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 - - - - - - - -クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) - - - - - - + diff --git a/doc.ja/src/sgml/release-3.4.sgml b/doc.ja/src/sgml/release-3.4.sgml index 4631fce1f..d8a9a613e 100644 --- a/doc.ja/src/sgml/release-3.4.sgml +++ b/doc.ja/src/sgml/release-3.4.sgml @@ -1,1475 +1,2136 @@ - - - リリース 3.4.21 - - - リリース日 - 2018-11-22 - - - - - 不具合修正 + + + リリース 3.4.26 + + + リリース日 + 2019-10-31 + + + + + 不具合修正 + + + + + + レプリケーションモードでの誤ったクエリの書き換えを修正しました。 (Bo Peng) + + + + + + + + 各種のv2プロトコルのバグを修正しました。(Tatsuo Ishii) + + + + + + + + の変更がリロードによって反映されない不具合を修正しました。 + (bug 548) (Takuma Hoshiai) + + + + + + + + 特定の場合にPgpool-IIのシャットダウンが失敗する不具合を修正しました。(Tatsuo Ishii) + + + + + + + + 名前付きステートメントをDEALLOCATEした後に、誤ったクエリを実行すると + セグメンテーション違反が発生する不具合を修正しました。 + (bug 546) (Tatsuo Ishii) + + + + + + + + + リリース 3.4.25 + + + リリース日 + 2019-08-15 + + + + + 改善点 + + + + + + PostgreSQLからメモリマネージャデバッグ機能の一部をインポートしました。(Tatsuo Ishii) + + + + + + + PostgreSQL 12に対応するために、pg_attrdef.adsrcのかわりに + pg_get_expr()を使用するように修正しました。(Bo Peng) + + + + + + + のshutdownスクリプトを改良しました。(Tatsuo Ishii) + + + + + shutdownスクリプトがPgpool-IIのシャットダウン完了を待つように修正しました。 + + + + + + 環境変数CHECK_TIME_WAITtrueに設定されているとき、shutdownスクリプト実行時にnetstatコマンドでTCP/IPポートの使用を確認するように修正しました。 + + + + + + + + + + pgpool_adm拡張がPostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + + + が正しいfollow master commandを生成するように修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュモジュールでoid配列の境界をチェックするように修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュモジュールのOff-by-oneエラーを修正しました。(Tatsuo Ishii) + + + + + + + + pool_hba.confsamenetが指定されている場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 詳細は[pgpool-general: 6601]をご参照ください。 + + + + + + + + ネイティブレプリケーションモードの場合、standard_conforming_stringsの設定に応じてバックスラッシュを処理するように修正しました。 + (bug 467) (Bo Peng) + + + + + + + + いくつかのメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.4.24 + + + リリース日 + 2019-05-16 + + + + + 改善点 + + + + + + すべてのバックエンドが停止しているときのフェイルオーバをスピードアップします。(Tatsuo Ishii) + + + + すべてのバックエンドが停止状態になった場合、search_primary_node_timeoutの値に関わらずプライマリノードの検索を中止し、 + 直ちにフェールオーバプロセスを終了するように修正しました。 + + + + ディスカッション: [pgpool-hackers: 3321] + + + + + + + + pgpool-recovery拡張とpgpool_setupを次期バージョンであるPostgreSQL12に対応しました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + + すべてのバックエンドがダウンした場合には表示される不適切なエラーメッセージ"ERROR: connection cache is full"を修正しました。 + (bug 487) (Bo Peng) + + + + すべてのバックエンドがダウンした場合に、Pgpool-IIが不適切なエラーメッセージ"ERROR: connection cache is full"を投げています。 + このエラーを"all backend nodes are down, pgpool requires at least one valid node"に修正しました。 + + + + + + + + pool_worker_childプロセスの終了/フォークの繰り返しを避けるために修正しました。(Tatsuo Ishii) + + + + pool_worker_childはdo_query()を使用してWAL位置を取得するためのクエリを発行します。 + これにより、致命的エラーが発生した場合、pool_worker_childプロセスを終了し、 + Pgpool-IIの親プロセスは直ちに新しいプロセスをフォークするようにしています。 + このサイクルは無限に繰り返され、システムに大きな負荷を与える可能性があります。 + 無限に繰り返される終了/フォーク処理を回避するために、sr_check_periodをスリープさせるように修正しました。 + + + + + + + + のデフォル値が間違っていた不具合を修正しました。(Tatsuo Ishii) + + + + + + + + 「not enough space in buffer」エラーを修正しました。 + (bug 499) (Tatsuo Ishii) + + + + バックエンドから返されたエラーメッセージサイズが固定バッファサイズ (8192 bytes)を超えた場合、 + 「not enough space in buffer」エラーが発生していました。 + 固定サイズのバッファの使用を廃止し、動的にバッファサイズを割り当てるように修正しました。 + + + + + + + + DROP DATABASEの失敗を修正しました。 (Tatsuo Ishii) + + + + + + + + read_status_file()関数の間違った変数名を修正しました。 + (bug 493) (Takuma Hoshiai) + + + + + + + + コンパイル時に発生するワーニング を修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.4.23 + + + リリース日 + 2019-03-29 + + + + + 改善点 + + + + + 新しい設定パラメータを追加しました。(Muhammad Usama) + + + + ユーザがサーバ側のSSL暗号設定をクライアントに優先して使うかどうかを設定できるように、新しい設定パラメータを追加しました。 + + + + この設定はデフォルトでオフで、従来と同じようにクライアント側のリクエストが優先されます。 + しかしこれはあくまで過去の挙動との互換性のための設定であり、悪意のあるクライアントが弱い暗号を利用できる可能性があります。 + ですから、常にこのパラメータをオンにしておくことを推奨します。 + + + + + + + + client cipher リストの設定が可能になりました。(Tatsuo Ishii, Yugo Nagata) + + + + Pgpool-IIがクライアントからのSSL接続を受け付ける際に受け入れる暗号のリストを指定する新しいパラメータ、 + を追加しました。これはすでにPostgreSQLに実装されていて、 + SSLが有効なときにセキュリティを強化するのに役立ちます。 + + + + + + + + 不具合修正 + + + + + + 不要なpgpool_statusファイルへの書き込みが減らしました。(Tatsuo Ishii) + + + + 今まではPostgreSQLバックエンドへの新しい接続が作成されるたびに、 + pgpool_statusファイルに書き込むためにfsync()が実行されていましたが、 + これにより、特定の条件で過剰なI/Oを発生させる可能性がありました。 + そのため、バックエンドの状況が変更されたときにのみfsync()を実行するように修正しました。 + + + + ディスカッション: [pgpool-general: 6436] + + + + + + + + + リリース 3.4.22 + + + リリース日 + 2019-02-21 + + + + + 不具合修正 + + + + + + Doc: パラメータはサーバ起動時にのみ設定可能なことをドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + 特定の場合に、によって、オンラインリカバリが失敗する不具合を修正しました。(bug 431)(Tatsuo Ishii) + + + + + + + + strip_quote()が空のクエリを処理するときに発生するセグメンテーション違反を修正しました。(bug 458) (Tatsuo Ishii) + + + + + + + + 接続を確立しようとするとき、フェイルオーバが発生する場合に発生しうるセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + 参照: [pgpool-hackers: 3214] + + + + + + + + PostgreSQLidle_in_transaction_session_timeoutが有効な場合に発生しうるPgpool-IIのハングアップを修正しました。(bug 448)(Tatsuo Ishii) + + + + + + + + + リリース 3.4.21 + + + リリース日 + 2018-11-22 + + + + + 不具合修正 + + + + + + + クライアントから送信された startup パケットのパラメータをソートするように修正します。 + (bug 444)(Takuma Hoshiai) + + + + キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 + コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + + + + + + + + ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 + (bug 443) (Bo Peng) + + + + パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 + bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 + これによりセグメンテーション違反が発生していました。 + + + + パッチがYugo Nagataにより提供されました。 + + + + + + + + スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.4.20 + + + + リリース日 + 2018-10-31 + + + + + 変更点 + + + + + + LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) + + + + + + + + Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + + Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 + + + + + + + + 不具合修正 + + + + + + SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) + + + + パッチはPhil Ramirezにより提供されました。 + + + + + + + + ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 + (bug 434) (Takuma Hoshiai) + + + + ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 + + + + + + + + ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) + + + + ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 + タイムスタンプ型の定数に書き換えるようになっています。 + しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 + + + + + + + + trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) + + + + + + + + ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) + + + + 明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 + テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 + + - + - -クライアントから送信された startup パケットのパラメータをソートするように修正します。 -(bug 444)(Takuma Hoshiai) + + Test: 時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) + + + + - -キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 -コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + + pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) - + - + - -ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 -(bug 443) (Bo Peng) + + パスワードの長さが正しくない場合、を更新しないように修正しました。 + (bug 419) (Takuma Hoshiai, Tatsuo Ishii) - -パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 -bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 -これによりセグメンテーション違反が発生していました。 + + Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 + ファイルのパスワードの長さをチェックするように修正しました。 + + + + - -パッチがYugo Nagataにより提供されました。 + + Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 - + - + - -スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + + .gitignoreファイルを追加しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 - + - + - -クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + + ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - + + + + + + + リリース 3.4.19 + + + + リリース日 + 2018-07-31 + + + + 不具合修正 + - + - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - - - リリース 3.4.20 - - - - リリース日 - 2018-10-31 - - - - - 変更点 - - - - - -LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) - - - - - - - -Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) - - - - - - - -Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - - 不具合修正 - - - - - -SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) - - - -パッチはPhil Ramirezにより提供されました。 - - - - - - - -ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 -(bug 434) (Takuma Hoshiai) - - - -ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 - - - - - - - -ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) - - - -ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 -タイムスタンプ型の定数に書き換えるようになっています。 -しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 - - - - - - - -trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) - - - - - - - -ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) - - - -明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 -テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 - - - - - - - -Test: 時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) - - - - - - - -pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) - - - - - - - -パスワードの長さが正しくない場合、を更新しないように修正しました。 -(bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - -Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 -ファイルのパスワードの長さをチェックするように修正しました。 - - - - - - - -Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -.gitignoreファイルを追加しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - - - + + 「write on backend 0 failed with error :"Success"」エラーを修正しました。 + (bug 403) (Tatsuo Ishii) + + + write() が 0 を返した場合、エラーとして扱わないように修正しました。 + + - - - リリース 3.4.19 - - - - リリース日 - 2018-07-31 - - - - 不具合修正 - - - - - -「write on backend 0 failed with error :"Success"」エラーを修正しました。 -(bug 403) (Tatsuo Ishii) - - -write() が 0 を返した場合、エラーとして扱わないように修正しました。 - - - - - - - -pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - -pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。 (Tatsuo Ishii) - - - -これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 - - - - - - - -armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - -修正パッチは Christian Ehrhardt によって提供されました。 - - - - - - - -Test: テスト006.memqcache の失敗を修正しました。(Tatsuo Ishii) - - - - + + + + + pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。 (Tatsuo Ishii) + + + + これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 + + + + + + + + armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 修正パッチは Christian Ehrhardt によって提供されました。 + + + + + + + + Test: テスト006.memqcache の失敗を修正しました。(Tatsuo Ishii) + + + + - - リリース 3.4.18 - - - - リリース日 - 2018-06-12 - - - - 不具合修正 - - - - - - -pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) - - - -これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 - - - -詳細は -[pgpool-general: 5963] -をご参照してください。 - - - -また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 - - - - + + リリース 3.4.18 + + + + リリース日 + 2018-06-12 + + + + 不具合修正 + + + + + + + pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) + + + + これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 + + + + 詳細は + [pgpool-general: 5963] + をご参照してください。 + + + + また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 + + + + - - リリース 3.4.17 + + リリース 3.4.17 - - - リリース日 - 2018-04-17 - + + + リリース日 + 2018-04-17 + - - 不具合修正 - + + 不具合修正 + - + + + Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + + + - Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + + to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) - + - + + + Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + + + + - to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) + + + PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) - + - + + + + レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.4.16 + + + + リリース日 + 2018-02-13 + + + + 変更点 + + + + + + PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + + + + - Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + + + systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) - + - + + + + pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + + + + + + + 不具合修正 + + + + + + デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + + + + + + + + 拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + + + + + + + + + リリース 3.4.15 + + + + リリース日 + 2018-01-09 + + + + 不具合修正 + + + + + + + スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) + + + /bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 + + + + + + + + ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) + + + + ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 + + + + + + + + ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) + + + + PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 + + + + + - - PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) + + "ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) + + + + 今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 + ほとんどの場合、問題がありませんでした。 + ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 - + - + - - レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + + pgpool 開始メッセージが複数回出力されるのを修正しました。(Tatsuo Ishii) - - - + + + + - - - リリース 3.4.16 + + リリース 3.4.14 - - - リリース日 - 2018-02-13 - + + リリース日 + 2017-11-01 + - - 変更点 - + + 不具合修正 + - + - -PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + + /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) - - - - - -systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + + RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 - + - + - -pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + + 3.4.12、3.4.13 で発生する、プライマリノードを検出できない不具合を修正しました。(Tatsuo Ishii) - - - + - - 不具合修正 - - + - -デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) - - - - - - -拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + 詳細は [pgpool-general: 5728]を参照してください。 - - - - - + - - - リリース 3.4.15 - - - - リリース日 - 2018-01-09 - - - - 不具合修正 - - - - - - - スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) - - -/bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 - - - - - - - -ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) - - - -ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 - - - - - - - -ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) - - - -PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 - - - - - - - -"ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) - - - -今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 -ほとんどの場合、問題がありませんでした。 -ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 - - - - + - -pgpool 開始メッセージが複数回出力されるのを修正しました。(Tatsuo Ishii) + + OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) - + + - - + - - リリース 3.4.14 + + リリース 3.4.13 + + + リリース日 + 2017-09-05 + - - リリース日 - 2017-11-01 - + + 不具合修正 - - 不具合修正 - + - + + Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) + + + + - /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) + + pool_unread() の不具合を修正しました。(Tatsuo Ishii) - - RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 + pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 - + - + + Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) + + + + -3.4.12、3.4.13 で発生する、プライマリノードを検出できない不具合を修正しました。(Tatsuo Ishii) + + workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) + + + workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 - + + この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 + + - + + SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) + + + + -フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) + + ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) -詳細は [pgpool-general: 5728]を参照してください。 + 詳細は [pgpool-general: 5621] をご参照ください。 - + - + - -OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) + 配布物にpgpool.serviceが含まれるように修正しました。(Yugo Nagata) - - - - - + + - - リリース 3.4.13 - - - リリース日 - 2017-09-05 - - - - 不具合修正 - - - - - - -Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) - - - - - - -pool_unread() の不具合を修正しました。(Tatsuo Ishii) - - -pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 - - - - - - -Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) - - - - - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 - - -この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 - - - - - - -SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) - - - - - - -ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) - - -詳細は [pgpool-general: 5621] をご参照ください。 - - - - - - -配布物にpgpool.serviceが含まれるように修正しました。(Yugo Nagata) - - - - - + - リリース 3.4.12 + リリース 3.4.12 - - リリース日 - 2017-07-11 - + + リリース日 + 2017-07-11 + - - 不具合修正 + + 不具合修正 - - + + - PostgreSQLMemoryManager APIに関する最新の変更をインポートしました。(Muhammad Usama) + PostgreSQLMemoryManager APIに関する最新の変更をインポートしました。(Muhammad Usama) - + - + - [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) + [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) - + - + - PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) + PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn - + - + - node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) + node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) - 詳細は[pgpool-general: 5511]を参照してください。 + 詳細は[pgpool-general: 5511]を参照してください。 - + - + - PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) + PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) - + - + - クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) + クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) - oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 + oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 - + - + - 滅多に発生しないPgpool-II起動時のバグを修正しました。(Tatsuo Ishii) + 滅多に発生しないPgpool-II起動時のバグを修正しました。(Tatsuo Ishii) - プライマリノードが見つかる前にフェールオーバーの要求が受け入れられる可能性がありました。 - これにより、Pgpool-IIは奇妙な状態に陥ります。障害が発生したノードはプライマリノードの場合、 - プライマリノードは存在しないと判断していました。(既存のスタンバイが昇格し新しいプライマリノードになった場合でも) + プライマリノードが見つかる前にフェールオーバーの要求が受け入れられる可能性がありました。 + これにより、Pgpool-IIは奇妙な状態に陥ります。障害が発生したノードはプライマリノードの場合、 + プライマリノードは存在しないと判断していました。(既存のスタンバイが昇格し新しいプライマリノードになった場合でも) - 詳細は[pgpool-hackers: 2321] をご参照下さい。 + 詳細は[pgpool-hackers: 2321] をご参照下さい。 - - - + + + - リリース 3.4.11 + リリース 3.4.11 - - リリース日 - 2017-04-28 - + + リリース日 + 2017-04-28 + - - 不具合修正 + + 不具合修正 - - + + pool_hba.confファイルのリロード時に発生するエラーを修正しました。(Bug 299) (Muhammad Usama) - + - + coverity警告を修正しました。(Muhammad Usama) - + - + [pgpool-general: 5396] - pam ldapが失敗する不具合を修正しました。(Muhammad Usama) + pam ldapが失敗する不具合を修正しました。(Muhammad Usama) - + - + - [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 - (Bug 296) (Muhammad Usama) + [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 + (Bug 296) (Muhammad Usama) - + - + - + - リリース 3.4.10 + リリース 3.4.10 - - リリース日 - 2017-03-17 - + + リリース日 + 2017-03-17 + - - 不具合修正 + + 不具合修正 - + - + - pgpool.serviceファイルに"Wants=network.target"を追加しました。 - (bug 294) (Bo Peng) + pgpool.serviceファイルに"Wants=network.target"を追加しました。 + (bug 294) (Bo Peng) - + - + - pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) + pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) -失敗したときのエラーメッセージは以下のとおりです。 + 失敗したときのエラーメッセージは以下のとおりです。 - FATAL: invalid pgpool mode for process recovery request - DETAIL: specified node is already primary node, can't promote node id 0 + FATAL: invalid pgpool mode for process recovery request + DETAIL: specified node is already primary node, can't promote node id 0 -ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 + ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 -この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 -失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 + この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 + 失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 -これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 + これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 - + - + + 2017-02-28 [5b4f78c] + --> -READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) + READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) - + - + -特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。 -(bug 272) (Tatsuo Ishii) + 特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。 + (bug 272) (Tatsuo Ishii) - + - + -ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) + ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) - + - + -wd_get_cmd関数のバッファオーバーフローを修正しました。 -(bug 280)(Muhammad Usama) + wd_get_cmd関数のバッファオーバーフローを修正しました。 + (bug 280)(Muhammad Usama) - + - + -シグナルハンドラがelog/ereportを呼び出さないように修正しました。(Tatsuo Ishii) + シグナルハンドラがelog/ereportを呼び出さないように修正しました。(Tatsuo Ishii) -詳しくは[pgpool-hackers: 1950]をご参照ください。 + 詳しくは[pgpool-hackers: 1950]をご参照ください。 - + - + -FreeBSDでlisten_addresses = '*'の場合、INETドメインソケットが作成できない不具合を修正しました。(bug 202)(Bo Peng) + FreeBSDでlisten_addresses = '*'の場合、INETドメインソケットが作成できない不具合を修正しました。(bug 202)(Bo Peng) - + - + -特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 -(bug 249)(Muhammad Usama) + 特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 + (bug 249)(Muhammad Usama) -WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 + WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 - + - + -authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) + authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) - + - + -クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) + クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) - + - + - + - - リリース 3.4.9 + + リリース 3.4.9 - + - リリース日 - 2016-12-26 - + Release Date + --> + リリース日 + 2016-12-26 + - + - 不具合修正 + Bug fixes + --> + 不具合修正 - + - - - + -watchdog のセキュリティを強化しました。(Muhammad Usama) + + + watchdog のセキュリティを強化しました。(Muhammad Usama) - -wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 - - + + wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 + + - - - - -Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) - - + + + Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) + + - - - + -クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) - - + + + クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) + + - - - + -ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) - - - -本来は一貫性を維持するためにキャセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャセルする必要がないので、修正しました。 - - + + + ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) + + + + 本来は一貫性を維持するためにキャセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャセルする必要がないので、修正しました。 + + - - - - -pgpool コマンドで廃止されたオプション"-c"を削除しました。(Tatsuo Ishii) - - + -また、helpメッセージのタイポを修正しました。 - - + 2016-10-27 [46579d6] + --> + + + pgpool コマンドで廃止されたオプション"-c"を削除しました。(Tatsuo Ishii) + + + + また、helpメッセージのタイポを修正しました。 + + - - - + -のデフォルト値を10から300に変更しました。(Tatstuo Ishii) - - - -これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 - - + + + のデフォルト値を10から300に変更しました。(Tatstuo Ishii) + + + + これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 + + - - - + -すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(bug 248) (Tatsuo Ishii) - - - -すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 -その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 -そしてこのコマンドは成功しました。 -しかし、新しい接続が拒否されました。 -これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 -ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 -(ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) -解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 - - + + + すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(bug 248) (Tatsuo Ishii) + + + + すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 + その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 + そしてこのコマンドは成功しました。 + しかし、新しい接続が拒否されました。 + これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 + ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 + (ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) + 解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 + + - - - + -MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) - - - -random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 -random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 - - + + + MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) + + + + random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 + random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 + + - - - + -クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) - - + 2016-09-06 [f9f098f] + --> + + + クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) + + - + - + diff --git a/doc.ja/src/sgml/release-3.5.sgml b/doc.ja/src/sgml/release-3.5.sgml index 606e21cbc..2db450965 100644 --- a/doc.ja/src/sgml/release-3.5.sgml +++ b/doc.ja/src/sgml/release-3.5.sgml @@ -1,2633 +1,3965 @@ - - - リリース 3.5.18 - - - リリース日 - 2018-11-22 - - - - - 不具合修正 - + + + リリース 3.5.28 + + + リリース日 + 2020-11-19 + + + + 変更点 + - + - -クライアントから送信された startup パケットのパラメータをソートするように修正します。 -(bug 444)(Takuma Hoshiai) + フロントエンドがGSSAPI暗号化接続を要求した場合、 + Pgpool-IIGSSAPIをサポートしていないため、 + これまでエラーを返していましたが、他の方式での接続を要求するように変更しました。(Tatsuo Ishii) - -キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 -コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + パッチはTatsuo Ishiiにより作成され、Umar Hayatによりレビュー・テストされました。 - + + + + + + 不具合修正 + - + - -ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 -(bug 443) (Bo Peng) + ネイティブレプリケーションモードで「INSERT ... ON CONFLICT」クエリ書換えの不具合を修正しました。 + (bug 654) (Bo Peng) + + + + - -パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 -bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 -これによりセグメンテーション違反が発生していました。 + クエリがキャンセルされたときにコネクションカウントが減少しない不具合を修正しました。 + (bug 656) (Tatsuo Ishii) + + + + - -パッチがYugo Nagataにより提供されました。 + pgpool_setupのPostgreSQLのバージョンチェックの不具合を修正しました。(Bo Peng) - + + + + + + + リリース 3.5.27 + + + リリース日 + 2020-09-17 + + + + + 変更点 + - + - -スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + + PostgreSQL 12.4 のガイドラインに従ってPgpool-IIの拡張機能のスクリプトを修正しました。(Tatsuo Ishii) + + + + CREATE OR REPLACE FUNCTIONの使用を避けて、代わりにCREATE FUNCTIONを使用するように修正しました。 - + + + + + + 不具合修正 + - + - -クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + + いくつかの不要なチェックをソースコードから削除しました。(Tatsuo Ishii) + + + + パッチはby Hou, Zhijieにより提供されました。 - + - + - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + relcacheクエリがプライマリ以外に送信される不具合を修正しました。(Tatsuo Ishii) + + + + ストリーミングレプリケーションモードでは、relcacheクエリはプライマリノードに送信されるようになっています。 + しかし、実際には、プライマリノードがマスターノードでない場合、relcacheクエリはプライマリノードに送信されませんでした。 + 通常、これはプライマリがノード0でない場合に発生する可能性があります。 - + - + - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - - - リリース 3.5.17 - - - - リリース日 - 2018-10-31 - - - - - 変更点 - - - - - -フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) - - - - - - - -LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) - - - - - - - -Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) - - - - - - - -Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - - 不具合修正 - - - - - -SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) - - - -パッチはPhil Ramirezにより提供されました。 - - - - - - - -ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 -(bug 434) (Takuma Hoshiai) - - - -ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 - - - - - - - -ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) - - - -ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 -タイムスタンプ型の定数に書き換えるようになっています。 -しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 - - - - - - - -拡張問い合わせの場合、時々期待される応答がフロントエンドに返されないことがあったので、修正しました。 -(bug 432) (Tatsuo Ishii) - - - -解決策は、保留中のメッセージデータリストを使用することです。それはフロントエンドからのメッセージを記録し、同じ数のメッセージを受け取ることが期待されます。 - - - -パッチは Yugo Nagata によって作成され、Tatsuo Ishii により修正されました。 - - - - - - - -trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) - - - - - - - -ストリーミングレプリケーションモードかつ拡張問い合わせの場合、クエリキャッシュを有効にするときに発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - -ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) - - - -明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 -テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 - - - - - - - -Test: 時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) - - - - - - - -Test: EXECUTE/DEALLOCATEのレグレッションテストを追加しました。(Takuma Hoshiai) - - - - - - - -pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) - - - - - - - -DEALLOCATEステートメントが発行された場合に発生するkind mismatchエラーを修正しました。(Bo Peng) - - - -EXECUTEDEALLOCATEPREPAREと同じノードに送信されるために、PREPAREをpool_add_sent_messageに追加するように修正しました。 - - - -詳細は[pgpool-general: 6226]を参照してください。 - - - - - - - -パスワードの長さが正しくない場合、を更新しないように修正しました。 -(bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - -Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 -ファイルのパスワードの長さをチェックするように修正しました。 - - - - - - - -Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -.gitignoreファイルを追加しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - - - - - - - リリース 3.5.16 - - - - リリース日 - 2018-07-31 - - - - 不具合修正 - - - - - -「write on backend 0 failed with error :"Success"」エラーを修正しました。 -(bug 403) (Tatsuo Ishii) - - -write() が 0 を返した場合、エラーとして扱わないように修正しました。 - - - - - - - -pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - -pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。(Tatsuo Ishii) - - - -これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 - - - - - - - -armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - -修正パッチは Christian Ehrhardt によって提供されました。 - - - - - - - -Test: テスト006.memqcache の失敗を修正しました。( Tatsuo Ishii) - - - - - + + が有効になっているときにが機能しない問題を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] + + - - - - リリース 3.5.15 - - - - リリース日 - 2018-06-12 - - - - 不具合修正 - - - - - -拡張問合せ、かつクエリキャッシュが有効の場合、レプリケーション遅延が大きすぎるときに発生しうる Pgpool-II のハングアップを修正しました。(Tatsuo Ishii) - - - -詳細は [pgpool-general-jp: 1534] -を参考してください。 - - + + + + + 認証処理において有益なエラーメッセージを表示するように修正しました。(Tatsuo Ishii) + + + + + + + 特定の場合に発生するpgpool子プロセスのセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 以下の方法で再現できます。 + - - - -拡張問合せでは、SET TRANSACTION READ ONLY の場合、書き込みトランザクションフラグを立てないように修正しました。 (Tatsuo Ishii) - + + + すべてのバックエンドを停止します。 + - - - - -pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) - - - -これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 - - - -詳細は -[pgpool-general: 5963] -をご参照してください。 - - - -また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 - + + + 無効なクライアントでpgpoolに接続します。例えば、pcpのポートではなく、pgpoolのポート番号を使用してpcp_attach_nodeを実行します。 + - - + + + + + + + + リリース 3.5.26 + + + リリース日 + 2020-08-20 + - - - - リリース 3.5.14 - - - - リリース日 - 2018-04-17 - - - - 不具合修正 - - - + + + 変更点 + + - - Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) + pool_hba.confサンプルファイルにhostssl/hostnosslに関する説明を追加しました。(Tatsuo Ishii) - + + + - + + + 不具合修正 + + - - to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) + pgpoolの起動時に、pidファイルが存在する場合、書き込む前にpidファイルを長さゼロに切り詰めるように修正しました。(Bo Peng) - - - - - - Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + パッチはmaliangzhuにより提供されました。 - + - + - - 「unable to bind D cannot get parse message "S1"」エラーによるハングアップを修正しました。(Tatsuo Ishii) + ストリーミングレプリケーションモードでプライマリノードが0以外の場合、が機能しない問題を修正しました。(Tatsuo Ishii) - + - + - - レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + -rオプション及びPostgreSQL 12でのpgpool_setupの問題を修正しました。(Tatsuo Ishii) - + - + - - PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) + RPMパッケージのPCPコマンドのUNIX_DOMAIN_PATH/var/run/postgresqlに変更します。(Bo Peng) - - - - + - - - リリース 3.5.13 - - - - リリース日 - 2018-02-13 - - - - このリリースでは、Pgpool-II 3.7.0、3.6.6、3.5.10で追加された、ソケット - への書き込み不具合を修正しています。この障害により、ネットワーク負荷が - 高い状態でのフロントエンド、バックエンドへのメッセージ送信の際に、不正 - なメッセージが送信される可能性があります。3.7.x、3.6.6以降、3.5.10以降 - のバージョンを利用中のユーザは、できるだけ早くアップグレードすることを - お勧めします。 - - - - - 変更点 - - + - -Pgpool-II が libressl の環境でビルドできるようになりました。(Tatsuo Ishii) + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) -詳細は [pgpool-hackers: 2714] を参照してください。パッチは Sandino Araico Sanchez により提供されました。 + クエリキャッシュが有効な場合、あるテーブルが更新された場合、Pgpool-IIは自動的にそのテーブルに関係する全てのキャッシュを削除するようになっています。 + しかし、EXPLAIN ANALYZEまたはCTEで更新クエリを実行した場合に、 + これらのクエリが誤って参照クエリとして扱われ、キャッシュが削除されませんでした。 - + + パッチはHou, Zhijieにより作成され、Tatsuo Ishiiにより修正されました。 + + - + - -PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + コーナーケースで発生するPgpool-IIのハングアップを修正しました。(Tatsuo Ishii) - + - + - -systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + user、database、application_name以外のパラメータが指定された場合、startupパケットの読み取りが失敗する不具合を修正しました。(Tatsuo Ishii) - + - + - -pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + pg_terminate_backendを実行した時にコネクションのカウントがずれる不具合を修正しました。(Takuma Hoshiai) - - - + - - 不具合修正 - - + + アプリケーション名がに含まれている場合に発生するセグメンテーション違反を修正しました。 (bug 615) (Tatsuo Ishii) + + + + + + + + + リリース 3.5.25 + + + リリース日 + 2020-05-21 + + + + + 不具合修正 + + -コミットまたはロールバック時に誤って書き込みトランザクションフラグをセットする不具合を修正しました。 (Tatsuo Ishii) + + + 一部のシステム(Fedora 32)で発生するビルドエラーを修正しました。(Tatsuo Ishii) - + - + + + 不要なチェックを削除しました。(Tatsuo Ishii) + + + + パッチはsherlockcppによって提供されました。Discussion: [pgpool-general: 7004] + + + + -ソケット書き込みの不具合を修正しました。 (Tatsuo Ishii) - -ネットワーク負荷が高い場合に、フロントエンド、バックエンドへのメッセージ送信の際に、 -不正なメッセージが送信される可能性があるのを修正しました。 + + ホスト名が長い場合、バッファサイズの制限によってWatchdogのpingが失敗する問題を修正しました。(bug 516) (Bo Peng) + + + + + + + + リリース 3.5.24 + + + リリース日 + 2020-02-20 + + + + + 変更点 + + + -このバグは 3.6.6、3.5.10 がリリースされた際に追加されたものです。 + + 起動時のbind()エラーを回避するために、ソケットファイルが存在するかどうかを確認し、 + PIDファイルが存在しない場合、それらのソケットファイルを削除するように修正しました。(Bo Peng) - + + + - + + + 不具合修正 + + + + レプリケーションモードの場合に、クエリのタイムスタンプがリライトされない不具合を修正しました。 + (bug 551) (Bo Peng) + + + -デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + + PostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) - - - - + + + + 時々起こるリグレッションテストの失敗を修正しました。(Tatsuo Ishii) + + + -拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + Fix replication delay worker segfault when application_name in primary_conninfo is an empty string. + (bug 565) (Tatsuo Ishii) + --> + primary_conninfoのapplication_nameが空の場合に発生するレプリケーション遅延チェックワーカープロセスのセグメンテーション違反を修正しました。 + (bug 565) (Tatsuo Ishii) - - - - + + + + + + syslogが出力されない不具合を修正しました。(Bo Peng) + + + + - - - リリース 3.5.12 - - - - リリース日 - 2018-01-09 - - - - 不具合修正 - - - - - - - スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) - - -/bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 - - - - - - - -ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) - - - -ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 - - - - - - - -ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) - - - -PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 - - - - - - - -一部のログメッセージをデバッグメッセージにダウングレードしました。(Tatsuo Ishii) - - - -前回の開発で誤って残していました。 - - - - - - - -バックエンドからのパケットを読み込む際の再同期のロジックを修正しました。(Tatsuo Ishii) - - - -read_kind_from_backend() は、バックエンドからメッセージを読み取り、"ready for query" メッセージが受信されたときにバックエンドノードを再同期します。 -しかし、pool_pending_message_pull_out() を呼び出して「sync メッセージを受信した」を削除することを忘れていました。 -これによって、バックエンドからのパケットの読み取り中に Popool-II がハングアップする可能性がありました。 -pool_pending_message_pull_out()を呼び出し、「sync メッセージを受信した」を削除するように修正しました。 - - - - - - - -問い合わせ中に Pgpool-II がハングアップする不具合を修正しました。(bug 370) (Tatsuo Ishii) - - - -エラークエリがプライマリに送信され、sync メッセージを送信せずに、次のクエリを実行するときに、 -PostgreSQL のシステムカタログへの問い合わせが必要な場合、Pgpool-IIdo_query() 関数でハングアップしていました。 - - + + + リリース 3.5.23 + + + リリース日 + 2019-10-31 + - + + + 不具合修正 + + + + レプリケーションモードでの誤ったクエリの書き換えを修正しました。 (Bo Peng) + + + + -Pgpool-II 3.7 以降の上位互換性のために SL_MODE マクロを追加しました。(Tatsuo Ishii) + + + 各種のv2プロトコルのバグを修正しました。(Tatsuo Ishii) - + - - - - -"ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) - - - -今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 -ほとんどの場合、問題がありませんでした。 -ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 - - + + + + + の変更がリロードによって反映されない不具合を修正しました。 + (bug 548) (Takuma Hoshiai) + + - + + + 特定の場合にPgpool-IIのシャットダウンが失敗する不具合を修正しました。(Tatsuo Ishii) + + + + -pgpool 開始メッセージが複数回出力されるのを修正しました。(Tatsuo Ishii) + + + 名前付きステートメントをDEALLOCATEした後に、誤ったクエリを実行すると + セグメンテーション違反が発生する不具合を修正しました。 + (bug 546) (Tatsuo Ishii) - + - - + + + + + パラメータのデフォルト値にネットワークインターフェイスオプション -I を含めるように修正しました。(Bo Peng) + + + + - - リリース 3.5.11 - - - リリース日 - 2017-11-01 - - - - 不具合修正 - + + + リリース 3.5.22 + + + リリース日 + 2019-08-15 + - + + + 改善点 + + + + PostgreSQLからメモリマネージャデバッグ機能の一部をインポートしました。(Tatsuo Ishii) + + + - /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) + + + PostgreSQL 12に対応するために、pg_attrdef.adsrcのかわりに + pg_get_expr()を使用するように修正しました。(Bo Peng) + + + + + のshutdownスクリプトを改良しました。(Tatsuo Ishii) + + + + + shutdownスクリプトがPgpool-IIのシャットダウン完了を待つように修正しました。 + + + + + + 環境変数CHECK_TIME_WAITtrueに設定されているとき、shutdownスクリプト実行時にnetstatコマンドでTCP/IPポートの使用を確認するように修正しました。 + + + + + + - RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 + + + pgpool_adm拡張がPostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) - + + + + + + 不具合修正 - + + + + + "unable to bind. cannot get parse message"エラーを修正しました。 + (bug 531) (Tatsuo Ishii) + + + + -たまににフェイルオーバが実行されない watchdog の不具合を修正しました。(Muhammad Usama) - + + ネイティブレプリケーションモードかつWatchdogが有効な場合、 + 子プロセスが異常終了した後に、オンラインリカバリが失敗する不具合を修正しました。 + (bug 483) (Muhammad Usama) + + + + -今までは、watchdog プロセスは、自分の状態のみを考慮し、フェイルオーバおよびフェイルオーバロック要求の処理を判断していました。 - + + が正しいfollow master commandを生成するように修正しました。(Tatsuo Ishii) + + + + -しかし、この処理の問題点は、ある watchdog が自分をクラスタのマスター/コーディネーターとして通知し、スタンバイノードが自分をマスターノードとして認識するのを待っている間に、自分の状態はマスター/コーディネータですが、まだフェイルオーバおよびフェイルオーバロック要求処理することはできませんでした。 - + + クエリキャッシュモジュールでoid配列の境界をチェックするように修正しました。(Tatsuo Ishii) + + + + -そのため、たまに watchdog クラスタがリーダーを選出している間にフェイルオーバが実行されないことがありました。 - + + クエリキャッシュモジュールのOff-by-oneエラーを修正しました。(Tatsuo Ishii) + + + + - 修正案としては、ノードがフェイルオーバおよびフェイルオーバーロック要求を受け入れる前に、完全にマスター状態を取得したことを確認するように修正しました。 + + + クエリキャッシュが有効な場合に発生するセグメンテーション違反を修正しました。(bug 525) (Tatsuo Ishii) - + - + + + LOG "checking zapping sent message ..."をDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + + 詳細は[pgpool-general: 6620]をご参照ください。 + + + + - ストリーミングレプリケーションモードで 'H'(フラッシュ) メッセージの処理に関するバグを修正しました。(bug 345) (Tatsuo Ishii) + + + pool_hba.confsamenetが指定されている場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + 詳細は[pgpool-general: 6601]をご参照ください。 + + + + + + + + ネイティブレプリケーションモードの場合、standard_conforming_stringsの設定に応じてバックスラッシュを処理するように修正しました。 + (bug 467) (Bo Peng) + + + + -ユーザが 'H' メッセージの直後に応答を読み込もうとすると、Pgpool-IIはハングアップしまていました。 -因は、'H' が受信されたときに拡張クエリモードがリセットされ、保留メッセージが使用されなかったためです。 + + + いくつかのメモリリークを修正しました。(Tatsuo Ishii) - + - + + + 潜在的なセグメンテーション違反を回避するために、フェイルオーバ実行中であるかどうかのチェックをより積極的に行うように修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.5.21 + + + リリース日 + 2019-05-16 + + + + + 改善点 + + -フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) + + + すべてのバックエンドが停止しているときのフェイルオーバをスピードアップします。(Tatsuo Ishii) -詳細は [pgpool-general: 5728]を参照してください。 + + すべてのバックエンドが停止状態になった場合、search_primary_node_timeoutの値に関わらずプライマリノードの検索を中止し、 + 直ちにフェールオーバプロセスを終了するように修正しました。 + + + + ディスカッション: [pgpool-hackers: 3321] - + - + + + pgpool-recovery拡張とpgpool_setupを次期バージョンであるPostgreSQL12に対応しました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + -exit シグナルハンドラが ereport を呼び出さないように修正しました。(Tatsuo Ishii) + + + すべてのバックエンドがダウンした場合には表示される不適切なエラーメッセージ"ERROR: connection cache is full"を修正しました。 + (bug 487) (Bo Peng) -詳細は [pgpool-hackers: 2545]を参照してください。 + + すべてのバックエンドがダウンした場合に、Pgpool-IIが不適切なエラーメッセージ"ERROR: connection cache is full"を投げています。 + このエラーを"all backend nodes are down, pgpool requires at least one valid node"に修正しました。 - + - + + + pool_worker_childプロセスの終了/フォークの繰り返しを避けるために修正しました。(Tatsuo Ishii) + + + + pool_worker_childはdo_query()を使用してWAL位置を取得するためのクエリを発行します。 + これにより、致命的エラーが発生した場合、pool_worker_childプロセスを終了し、 + Pgpool-IIの親プロセスは直ちに新しいプロセスをフォークするようにしています。 + このサイクルは無限に繰り返され、システムに大きな負荷を与える可能性があります。 + 無限に繰り返される終了/フォーク処理を回避するために、sr_check_periodをスリープさせるように修正しました。 + + + + -OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) + + + のデフォル値が間違っていた不具合を修正しました。(Tatsuo Ishii) - - - - - - - - リリース 3.5.10 - - - リリース日 - 2017-09-05 - - - - 不具合修正 + - - - - - -ストリーミングレプリケーションモード/拡張クエリで発生する可能性のあるハングアップを修正しました。 (Tatsuo Ishii) - - -エラーが発生すると、Pgpool-IIはフロントエンドから送られてきたSyncメッセージを読み取ります。しかし、タイミングによってはまれにSyncメッセージがまだ送出されていないことがあり、syncが送られるまで待つように修正しました。 - - - - - - -watchdogが新しいノードを追加しようとした時にmasterに拒否される問題を修正しました。 (Yugo Nagata) - - -watchdogの間の認証の際に、秒を元にした文字列が使われていたため、watchdogノードの間で秒単位の時刻同期ができていないときに、この問題が発生します。修正は、単に秒を元にした文字列を認証キーに使わないようにしました。 - - - これは3.5.6, 3.6.3で追加された問題です。 - - - - - - -Test: 001.load_balance のテストスクリプトを修正しました。(Tatsuo Ishii) - - -ネイティブレプリケーションモードのみで実行される一部のテストが、ストリーミングレプリケーションモードでも実行されていたので、修正しました。 - - - - - - -拡張クエリでslonyモードが動かなくなっていたのを修正しました。(Tatsuo Ishii) - - -slonyモードの場合、応答がバックエンドから返されたときに、進行中フラグがリセットされず、バックエンドからの次のメッセージ待ち状態になり、ハングアップしていました。 - - - - - - -ストリーム書き込みモジュールのバグを修正しました。(Tatsuo Ishii) - - -要求された長さが残りの書き込みバッファサイズを超えた場合に発生するpool_write_noerror()の不具合を修正しました。この不具合はバッファオーバーランの問題につながる可能性がありました。 - - -書き込みバッファがいっぱいになると、pool_flush_it()を呼び出し、バッファをフラッシュし、要求されたデータを直接書き込むように修正しました。 - - -さらに、pool_unread()のパフォーマンスが向上しました。 - - - - - - -Test: レグレッションテストスクリプトを修正しました。(Muhammad Usama) - - - - - - -Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) - - - - - - -コアダンプが発生する可能性があったのと、一時テーブルの扱いに関するバグを修正しました。(Tatsuo Ishii) - - - - - - -pool_unread() の不具合を修正しました。(Tatsuo Ishii) - - -pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 - - - - - - -空文字のクエリの処理を修正しました。(bug 328) (Tatsuo Ishii) - - -空文字のクエリ (空文字列またはコメントクエリ) が送信されると、コマンド完了メッセージがフロントエンドに返されていました。この動作は正しくありません。空文字クエリのレスポンスをフロントエンドに返すように修正しました。 - - - - - - -ストリーミングレプリケーションモード/拡張クエリで発生するクエリキャッシュのバグを修正しました。(Tatsuo Ishii) - - - - - - -ストリーミングレプリケーションモード/拡張クエリで発生するメモリリークを修正しました。(bug 324)(Tatsuo Ishii) - - - - - - -Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) - - - - - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 - - -この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 - - - - - - -SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) - - - - - - -ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) - - -詳細は [pgpool-general: 5621] をご参照ください。 - - - - - - -ストリーミングレプリケーションモード/拡張クエリの場合、フロントエンドが 'S' (同期) メッセージを送信する前に、バックエンドからエラーレスポンスを受信するときに発生するハングアップを修正しました。 - - -さらに、以下の修正を行いました。 - - -- ストリーミングレプリケーションモードで ErrorResponse3() 関数が意図的にエラークエリをバックエンドに送信しないように修正しました。 - - -- クエリが進行中でクエリコンテキストが存在する場合のみ、virtual_master_node_idを返すように pool_virtual_master_db_node_id()関数を修正しました。 - - - - - - -配布物にpgpool.serviceが含まれるように修正しました。(Yugo Nagata) - - - - - - - - 改善点 - - - - - -Test: ビルド時のログがファイルに出力されるように修正しました。 (Tatsuo Ishii) - - - - - - -Test: メモリリークのレグレッションテストを追加しました。(Tatsuo Ishii) - - - - - - - - リリース 3.5.9 - - - リリース日 - 2017-07-11 - - - - 不具合修正 - - - + - [pgpool-hackers: 2400]で報告された、ログ出力中の不正なバイトを修正しました。(Muhammad Usama) + + 「not enough space in buffer」エラーを修正しました。 + (bug 499) (Tatsuo Ishii) - ほとんどログメッセージの修正でした。 + + バックエンドから返されたエラーメッセージサイズが固定バッファサイズ (8192 bytes)を超えた場合、 + 「not enough space in buffer」エラーが発生していました。 + 固定サイズのバッファの使用を廃止し、動的にバッファサイズを割り当てるように修正しました。 - + - + - PostgreSQLMemoryManager APIに関する最新の変更をインポートしました。(Muhammad Usama) + + DROP DATABASEの失敗を修正しました。 (Tatsuo Ishii) - + - + - [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) + + read_status_file()関数の間違った変数名を修正しました。 + (bug 493) (Takuma Hoshiai) - + - + - PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) + + failover/failback実行中に接続があった場合に発生しうるセグメンテーション違反を回避するために、セッションを終了するように修正しました。 + (bug 481, + bug 482) (Tatsuo Ishii) - - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn - - + - + - ストリーミングレプリケーションと拡張プロトコルで発生するハングアップを修正しました。(Yugo Nagata) - - - 以下の例で再現できます。 - - - - pgpool.confですべての読み取りクエリをスタンバイに送信するように設定しています。 - - まず、トランザクションブロックで書き込みクエリを発行します。 - - トランザクションをコミットした後、SELECTクエリを発行します。 - - クエリを処理するときに、Parseの直後にDescribe(statement)メッセージを送信します。 - + + コンパイル時に発生するワーニング を修正しました。(Tatsuo Ishii) + + + - JDBCを使用せず、pgprotoを利用し以下のデータでこの問題を再現できます。 + + 拡張問い合わせかつ"batch"モードで発生するメモリリークを修正しました。 + (bug 468) (Tatsuo Ishii) + + + + - - 'Q' "DROP TABLE IF EXISTS test_tbl" - 'Y' - 'Q' "CREATE TABLE test_tbl(i int)" - 'Y' - 'Q' "INSERT INTO test_tbl VALUES(1)" - 'Y' - - 'P' "" "BEGIN" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "COMMIT" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "S_1" "SELECT * FROM test_tbl" 0 - 'D' 'S' "S_1" - 'B' "C_1" "S_1" 0 0 0 - 'E' "C_1" 0 - 'S' - 'Y' - - 'X' - + + + リリース 3.5.20 + + + リリース日 + 2019-03-29 + + + + 改善点 + + + + + + 新しい設定パラメータを追加しました。(Muhammad Usama) + + + + ユーザがサーバ側のSSL暗号設定をクライアントに優先して使うかどうかを設定できるように、新しい設定パラメータを追加しました。 + - BindExecuteを適切なバックエンドに送信するように、parse_before_bind()は、トランザクション中にのみ呼び出されるように修正しました。 + + この設定はデフォルトでオフで、従来と同じようにクライアント側のリクエストが優先されます。 + しかしこれはあくまで過去の挙動との互換性のための設定であり、悪意のあるクライアントが弱い暗号を利用できる可能性があります。 + ですから、常にこのパラメータをオンにしておくことを推奨します。 - + - + - erlangアプリケーションを使用する場合、Pgpool-II がハングする不具合を修正しました。(Tatsuo Ishii) + + client cipher リストの設定が可能になりました。(Tatsuo Ishii, Yugo Nagata) - Erlangクライアントは "Describe"メッセージの後に "Flush"を送信し、バックエンドは "Row description" を返します。しかし、Pgpool-IIは、"Row description" メッセージを受信した後、進行中のクエリフラグをリセットすることを忘れてしまい、Pgpool-IIはバックエンドからの応答を待っていました。これがerlangクライアントのハングアップの原因でした。 + + Pgpool-IIがクライアントからのSSL接続を受け付ける際に受け入れる暗号のリストを指定する新しいパラメータ、 + を追加しました。これはすでにPostgreSQLに実装されていて、 + SSLが有効なときにセキュリティを強化するのに役立ちます。 + + + + + + + 不具合修正 + + + + + + 不要なpgpool_statusファイルへの書き込みが減らしました。(Tatsuo Ishii) - Pgpool-IIが "Row description" メッセージを受信した際に、クエリ処理中のフラグをリセットするように修正しました。"no data" メッセージと同じ扱いにする必要がありました。 + + 今まではPostgreSQLバックエンドへの新しい接続が作成されるたびに、 + pgpool_statusファイルに書き込むためにfsync()が実行されていましたが、 + これにより、特定の条件で過剰なI/Oを発生させる可能性がありました。 + そのため、バックエンドの状況が変更されたときにのみfsync()を実行するように修正しました。 - 詳細は[pgpo ol-general: 5555]を参照してください。 + + ディスカッション: [pgpool-general: 6436] - + + + + + + + + リリース 3.5.19 + + + リリース日 + 2019-02-21 + - + + + 不具合修正 + + - 間違ったターゲットノードにバインドメッセージを送信するバグを修正しました。 (bug 306) (Tatsuo Ishii) + + Test: レグレッションテスト068.memqcache_bugの古いJDBCの関数及びタイポを修正しました。(Takuma Hoshiai) - + - + - node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) + + Doc: パラメータはサーバ起動時にのみ設定可能なことをドキュメントに追加しました。(Tatsuo Ishii) + + + + - 詳細は[pgpool-general: 5511]を参照してください。 + + 特定の場合に、によって、オンラインリカバリが失敗する不具合を修正しました。(bug 431)(Tatsuo Ishii) - - - + + - PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) + + strip_quote()が空のクエリを処理するときに発生するセグメンテーション違反を修正しました。(bug 458) (Tatsuo Ishii) - + - + + - クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) + + 接続を確立しようとするとき、フェイルオーバが発生する場合に発生しうるセグメンテーション違反を修正しました。(Tatsuo Ishii) - oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 + 参照: [pgpool-hackers: 3214] - + - + - 特定の場合に発生する拡張クエリのハングアップを修正しました。(Tatsuo Ishii) - - - erlang PostgreSQL APIはParse ('P')Describe ('D')Flush ('H')Bind (B)Execute('E')を生成します。この"H"はJDBCにはありませんので、今まで問題が起こらなかったと思われます。その後、Pgpool-IIは拡張クエリモードを削除し、データを読み取るバックエンドを見つけることができませんでした。したがって、Pgpool-IIはバックエンドの一部にメッセージを送信していない可能性があるため、ハングアップを引き起こすすべてのバックエンドを読み取ろうとします。 + + クライアントがsyncメッセージの後、次の簡易問い合わせの前にcloseメッセージを送ると発生しうるハングアップを修正しました。(Tatsuo Ishii) - この問題を避けるために、Flushメッセージを受信後拡張クエリフラグを設定するように修正しました。 + 参照: [pgpool-hackers: 3164] - + - + - 滅多に発生しないPgpool-II起動時のバグを修正しました。(Tatsuo Ishii) - - - プライマリノードが見つかる前にフェールオーバーの要求が受け入れられる可能性がありました。 - これにより、Pgpool-IIは奇妙な状態に陥ります。障害が発生したノードはプライマリノードの場合、 - プライマリノードは存在しないと判断していました。(既存のスタンバイが昇格し新しいプライマリノードになった場合でも) + + PostgreSQLidle_in_transaction_session_timeoutが有効な場合に発生しうるPgpool-IIのハングアップを修正しました。(bug 448)(Tatsuo Ishii) - - 詳細は[pgpool-hackers: 2321] をご参照下さい。 - - - - + + + - - リリース 3.5.8 - - - リリース日 - 2017-05-11 - - - - 不具合修正 + + + リリース 3.5.18 + + + リリース日 + 2018-11-22 + - + + + 不具合修正 + - + - ノード 0 がフェイルオーバーするレグレッションテストを追加しました。(Tatsuo Ishii) + + クライアントから送信された startup パケットのパラメータをソートするように修正します。 + (bug 444)(Takuma Hoshiai) - - - - - [pgpool-hackers:2312] で報告された -Pgpool-IIノード 0 がフェイルオーバーするときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 + コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 - - - - - - - - - - リリース 3.5.7 - - - リリース日 - 2017-04-28 - - - - 不具合修正 - - - - + + + - Watchdogのソースコードのミスを修正し、いくつかのdebugメッセージを追加しました。(Muhammad Usama) + + ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 + (bug 443) (Bo Peng) - - - - - pool_hba.confファイルのリロード時に発生するエラーを修正しました。(Bug 299) (Muhammad Usama) + + パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 + bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 + これによりセグメンテーション違反が発生していました。 - - - - - watchdog 使用時に Pgpool-II 間でバックエンドの状態が一致しない不具合を修正しました。 - (Bug 289) (Muhammad Usama) + + パッチがYugo Nagataにより提供されました。 - - - + + + - Watchdogによるスプリットブレインシナリオの処理を強化しました。(Muhammad Usama) - - - - watchdogクラスタを使用しmaster/coordinatorノードの再選出が呼び出されていました。その結果、すべてのノードがウォッチドッグネットワークに再結合する必要がありました。これはwatchdogクラスタ全体の再起動と本質的に同じでした。 - - - 今回の修正では、master/coordinatorノードの候補は、次の基準で選択されるようになりました。 - - - (1) 2つのウォッチドッグノードがクラスタマスターであると主張している場合、エスカレーションを実行したマスターノードはマスター状態を保持し、他のノードはステップダウンするように要求されます。 - - - (2) 競合がノードのエスカレーション状況によって解決できない場合、クォーラムを保持するノードはマスター/コーディネータのままです。 - - - (3) 両方の候補のクォーラムステータスが同じ場合、接続されたアライブノードの数が多いノードが優先されます。 - - - (4) 最後に、上記3つでマスターノードを選出できなかった場合、古いマスター(長期間コーディネーターステータスを持つノード) はマスターのままです。 + + スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) - - - + + + - 複数の並行コマンドを処理するためにwatchdog内部コマンドのメカニズムを強化しました。(Muhammad Usama) + + クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) - - - + + + - コードの互換性のためにboolエンコードおよびデコード関数をJSONフレームワークに追加します。(Muhammad Usama) + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - + + + - リグレッションの失敗を防ぐために、サポートされていないJavaメソッドを新しいJDBCドライバでコメントアウトしました。(Tatsu Ishii) + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) - + + + + + + + + リリース 3.5.17 - + + + リリース日 + 2018-10-31 + + + + + 変更点 + + - parse_before_bind() のログメッセージを debug1 にダウングレードしました。(Tatsuo Ishii) + + フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) - + - + - coverity警告を修正しました。(Muhammad Usama, Tatsuo Ishii) + + LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) - + - + - [pgpool-general: 5396] - pam ldapが失敗する不具合を修正しました。(Muhammad Usama) + + Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) - + - + - SHOWコマンドを読み込みクエリの一つとして認識するようにしました。(Tatsuo Ishii) + + Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) - ストリーミングレプリケーションモードでは、SHOWが発行されるとその後のSELECTは明示的なトランザクションでプライマリノードに送信されていました。この制限は不適切でした。また、parseコマンドがエラーを返すときに発生するハングアップを修正しました。 + + パッチはJesper Pedersenにより提供されました。 - + + + - + + + 不具合修正 + + - コミットadcb636によって引き起こされたメモリリークの問題を修正しました。(Tatsuo Ishii) + + SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) - Commit adcb636では"pending message queue"を導入しました。メッセージを受信すると、情報がキューに追加され、オブジェクトのコピーが同時に作成されますが、オブジェクトを解放するのを忘れてしまいました。 - - - 今回の修正では、新しい関数pool_pending_message_free_pending_message()を作成し、pool_pending_message_add()pool_pending_message_get()およびpool_pending_message_pull_out()の後に呼び出すように修正しました。 + + パッチはPhil Ramirezにより提供されました。 - + - + - ストリーミングレプリケーションモードで「kind mismatch」(またはそれに関連する)エラーが修正されました。 - (Bug 271) (Tatsuo Ishii) - - - このエラー原因はデータベースノードがPgpool-IIに送る応答の予測が誤っていたことです。以前使用した「sync map」の実装は弱く、予測に失敗することがありました。今回の修正では、送信されたすべてのメッセージをバックエンドに記録する"pending message queue"を導入しました。このキューの要素には、メッセージのタイプ(parse/bind/execute/describe/close/sync)、メッセージが送信されたデータベースノードの情報などが格納されます。これは単純なFIFOキューです。バックエンドからメッセージが到着すると、"pending message queue"の先頭を見れば、受信したメッセージの種類やデータベースノードを確実に予測できます。 メッセージを受信した後、この要素はキューから削除されます。 - - - 一連のパッチをテストしてくれたSergey Kimさんに感謝します。 + + ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 + (bug 434) (Takuma Hoshiai) - 詳細は Bug 271、 - [pgpool-hackers: 2043] と - [pgpool-hackers: 2140] をご参照下さい。 + + ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 - + - + - [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 - (Bug 296) (Muhammad Usama) + + ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) - - - - - - - - - リリース 3.5.6 - - - リリース日 - 2017-03-17 - - - - 不具合修正 - - - - - - pgpool.serviceファイルに"Wants=network.target"を追加しました。 - (bug 294) (Bo Peng) + + ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 + タイムスタンプ型の定数に書き換えるようになっています。 + しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 - + - + - pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) - - -失敗したときのエラーメッセージは以下のとおりです。 + + 拡張問い合わせの場合、時々期待される応答がフロントエンドに返されないことがあったので、修正しました。 + (bug 432) (Tatsuo Ishii) - - - FATAL: invalid pgpool mode for process recovery request - DETAIL: specified node is already primary node, can't promote node id 0 - - -ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 + + 解決策は、保留中のメッセージデータリストを使用することです。それはフロントエンドからのメッセージを記録し、同じ数のメッセージを受け取ることが期待されます。 - -この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 -失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 + + パッチは Yugo Nagata によって作成され、Tatsuo Ishii により修正されました。 + + + -これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 + + trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) - + - + + 2018-10-11 [ebbdd6f] + --> -READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) + + ストリーミングレプリケーションモードかつ拡張問い合わせの場合、クエリキャッシュを有効にするときに発生するメモリリークを修正しました。(Tatsuo Ishii) - + - + -Pgpool-IIがVIPを解除した後にpingテストを続けている不具合を修正しました。(Muhammad Usama) + + ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) -[pgpool-hackers: 1611] により報告されました。 + + 明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 + テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 - + - + -特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。(bug 272) (Tatsuo Ishii) + + Test: 時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) - + - + -ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) + + Test: EXECUTE/DEALLOCATEのレグレッションテストを追加しました。(Takuma Hoshiai) - + - + -pcp_attach_nodeを実行するときのセグメンテーション違反を修正しました。 -(bug 281)(Muhammad Usama) + + pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) - + - + -ストリーミングレプリケーションモードでロードバランスのバグを修正しました。(Tatsuo Ishii) + + DEALLOCATEステートメントが発行された場合に発生するkind mismatchエラーを修正しました。(Bo Peng) -明示的なトランザクションでは、書き込みクエリが送信されるまで、SELECTはロードバランスされます。書込みクエリが送信された後、SELECTがプライマリノードに送信されます。しかし、syncメッセージが送信される前にSELECTが送信された場合、これは正しく動作しませんでした。 + + EXECUTEDEALLOCATEPREPAREと同じノードに送信されるために、PREPAREをpool_add_sent_messageに追加するように修正しました。 -書き込みクエリが実行されると書き込みクエリの処理が行われるように修正しました。 + + 詳細は[pgpool-general: 6226]を参照してください。 - + - + -ストリーミングレプリケーションモードでのkind mismatchエラーを修正しました。(Tatsuo Ishii) + + パスワードの長さが正しくない場合、を更新しないように修正しました。 + (bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - - -closeメッセージの後にdo_query()がハングする問題を修正しました。(Tatsuo Ishii) + + Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 + ファイルのパスワードの長さをチェックするように修正しました。 - + - + -wd_get_cmd関数のバッファオーバーフローを修正しました。 -(bug 280)(Muhammad Usama) + + Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 - + - + -watchdogプロセスを再起動する時の不具合を修正しました。(Muhammad Usama) + + .gitignoreファイルを追加しました。(Bo Peng) -watchdogプロセスが何らかの問題(例えばセグメンテーションフォルト)によって異常終了した場合、新たに生成されたwatchdogプロセスの起動が失敗し、"bind on ... failed with reason: Address already in use"とのエラーを返しました。 + + パッチはJesper Pedersenにより提供されました。 + + + -理由は、異常終了したwatchdogプロセスはIPCに使用するソケットをクリーンアップする時間がなかったからです。 + + ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - + + + + + + + + リリース 3.5.16 + + + + リリース日 + 2018-07-31 + + + + 不具合修正 + + + + + + 「write on backend 0 failed with error :"Success"」エラーを修正しました。 + (bug 403) (Tatsuo Ishii) + + + write() が 0 を返した場合、エラーとして扱わないように修正しました。 + + + + + -この不具合を修正するために、Pgpoolのメインプロセスは、watchdogプロセスが異常終了したときに共有メモリにフラグを設定するように修正しました。 -watchdogプロセスが再起動されるとき、フラグがセットされたら、ソケットファイルをクリーンアップするようにしました。 + + pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) - + - + -特定の条件下で、ストリーミングレプリケーションモードでクエリキャッシュが有効な場合、SELECTがハングアップする不具合を修正しました。(Tatsuo Ishii) + + pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。(Tatsuo Ishii) - pgpool-general-jp:1441により報告されました。 + + これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 - + - + -シグナルハンドラがelog/ereportを呼び出さないように修正しました。(Tatsuo Ishii) + + armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) -詳しくは[pgpool-hackers: 1950]をご参照ください。 + + 修正パッチは Christian Ehrhardt によって提供されました。 - + - + -FreeBSDでlisten_addresses = '*'の場合、INETドメインソケットが作成できない不具合を修正しました。 -(bug 202)(Bo Peng) + + Test: テスト006.memqcache の失敗を修正しました。( Tatsuo Ishii) - + + + + + + + + + リリース 3.5.15 + + + + リリース日 + 2018-06-12 + - + + 不具合修正 + + -特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 -(bug 249)(Muhammad Usama) + + 拡張問合せ、かつクエリキャッシュが有効の場合、レプリケーション遅延が大きすぎるときに発生しうる Pgpool-II のハングアップを修正しました。(Tatsuo Ishii) - -WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 + + 詳細は [pgpool-general-jp: 1534] + を参考してください。 - + - + -authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) + + 拡張問合せでは、SET TRANSACTION READ ONLY の場合、書き込みトランザクションフラグを立てないように修正しました。 (Tatsuo Ishii) - + - + -クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) + + pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) + + + + これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 + + + + 詳細は + [pgpool-general: 5963] + をご参照してください。 + + + + また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 - + + + + - - - + + + リリース 3.5.14 - - - リリース 3.5.5 + リリース日 + 2018-04-17 + - - - リリース日 - 2016-12-26 - + + 不具合修正 + - - - 不具合修正 + + + Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + - - - - + -watchdog のセキュリティを強化しました。(Muhammad Usama) + + + to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) + - + -wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 - - + + + Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + + - - - - -Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) - - + + + 「unable to bind D cannot get parse message "S1"」エラーによるハングアップを修正しました。(Tatsuo Ishii) + + - - - + -クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) - - + + + レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + + - - - + -拡張プロトコルにおいて発生しうるkind mismatchエラーを修正しました。(bug 231) (Tatsuo Ishii) - - - -bug 231によると、以下の条件がすべて満たされていると、このバグが発生する可能性がありました。 - - - - - -ストリーミングレプリケーションモード - - - - - - ロードバランスノードがnode 0ではない - - - - - -拡張プロトコルを使用している - - - - - -SELECTが実行され、ステートメントがクローズされた後、トランザクションコマンドが実行されている - - - - + + + PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.5.13 + + + + リリース日 + 2018-02-13 + + + + このリリースでは、Pgpool-II 3.7.0、3.6.6、3.5.10で追加された、ソケット + への書き込み不具合を修正しています。この障害により、ネットワーク負荷が + 高い状態でのフロントエンド、バックエンドへのメッセージ送信の際に、不正 + なメッセージが送信される可能性があります。3.7.x、3.6.6以降、3.5.10以降 + のバージョンを利用中のユーザは、できるだけ早くアップグレードすることを + お勧めします。 + + + + + 変更点 + + -問題の発生順序: - - - - -ロードバランスノード1でステートメントS1のSELECTが実行されます。 - - - - - -フロントエンドがクローズステートメントを送ります。 - - - - - -Pgpool-IIはそれをバックエンド1に転送します。 - - - - - -フロントエンドは、COMMITのParse、Bind、Executeを送信します。 - - - - - -Pgpool-IIはそれをバックエンド0と1に転送します。 - - - - - -フロントエンドが同期メッセージを送信します。 - - - - - -Pgpool-IIはそれをバックエンド0と1に転送します。 - - - - - -バックエンド0はParse complete( "1")を返しますが、バックエンド1は#3によりclose complete( "3")を返します。 - - - - - -Kind mismatch が発生します。 - - - + + + Pgpool-II が libressl の環境でビルドできるようになりました。(Tatsuo Ishii) + + + 詳細は [pgpool-hackers: 2714] を参照してください。パッチは Sandino Araico Sanchez により提供されました。 + + - - - -解決策は、#3では、Pgpool-IIがバックエンド1からの応答を待つようにしますが、応答メッセージは読み取らないようにします。 その後、Pgpool-IIの状態マシンは、#6で同期メッセージが送信される前に、その応答を読み込みます。 これによりバックエンド1は#8で "1"を返信し、kind mismatchエラーは発生しなくなります。 - - - -また、Closeメッセージを受け取ったときにpool_set_doing_extended_query_message()が呼び出されない不具合を修正しました。 - - + -新しいリグレッションテスト "067.bug231"が追加されました。 - - + 2018-01-29 [ca57328] + --> + + + PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + + - - - - -シグナルハンドラでの競合状態を修正しました。(bug 265) (Tatsuo Ishii) - - - -child.cには、elogを呼び出すシグナルハンドラがあります。 シグナルハンドラは処理中に他のシグナルに対してブロックされないため、pgpoolのシャットダウンシーケンスでシステムコールにデッドロックが発生する可能性がありました。 この問題を解決するために、シグナルハンドラはPOOL_SETMASKを使用してブロックされるように修正されました。 - - + -理想的にはシグナルハンドラでelogを呼び出すことを避けるべきです。 - - + 2018-01-19 [e2be15a] + --> + + + systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + + - - - + -Pgpool-II 3.6 でのフェイルオーバーコマンドの転送処理の改善がバックポートされました。(Muhammad Usama) - - - -これまでは、Pgpool-II ノードの watchdogがすべての接続されたノードにフェイルオーバーコマンド(failover、 failback 及び promote node)を転送していました。多数のノードが含まれているwatchdogクラスタでは、フェールオーバーコマンドが複数のPgpool-IIによって実行されることによって、データの同期問題を引き起こす可能性がありました。このコミットでは、すべてのフェイルオーバーコマンド(failover、 failback 及び promote node)が master/coordinator watchdog に転送され、master/coordinator watchdogはすべてのスタンバイノードに転送するようになりました。 - - - -また、今回の修正では、インターロック機能も変更されました。master/coordinatorノードのみがロックホルダになり、フェイルオーバコマンドはmaster/coordinatorノードでのみ実行されます。 - - + + + pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + + + + - - - + + 不具合修正 + + -ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) - - - -本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 - - + + + コミットまたはロールバック時に誤って書き込みトランザクションフラグをセットする不具合を修正しました。 (Tatsuo Ishii) + + - - - + + + + + ソケット書き込みの不具合を修正しました。 (Tatsuo Ishii) + + + ネットワーク負荷が高い場合に、フロントエンド、バックエンドへのメッセージ送信の際に、 + 不正なメッセージが送信される可能性があるのを修正しました。 + + + このバグは 3.6.6、3.5.10 がリリースされた際に追加されたものです。 + + + + + + + + デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + + + + + + + + 拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + + + + + + + + + リリース 3.5.12 + + + + リリース日 + 2018-01-09 + + + + 不具合修正 + + + + + + + スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) + + + /bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 + + + + + + + + ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) + + + + ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 + + + + + + + + ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) + + + + PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 + + + + + + + + 一部のログメッセージをデバッグメッセージにダウングレードしました。(Tatsuo Ishii) + + + + 前回の開発で誤って残していました。 + + + + + + + + バックエンドからのパケットを読み込む際の再同期のロジックを修正しました。(Tatsuo Ishii) + + + + read_kind_from_backend() は、バックエンドからメッセージを読み取り、"ready for query" メッセージが受信されたときにバックエンドノードを再同期します。 + しかし、pool_pending_message_pull_out() を呼び出して「sync メッセージを受信した」を削除することを忘れていました。 + これによって、バックエンドからのパケットの読み取り中に Pgpool-II がハングアップする可能性がありました。 + pool_pending_message_pull_out()を呼び出し、「sync メッセージを受信した」を削除するように修正しました。 + + + + + + + + 問い合わせ中に Pgpool-II がハングアップする不具合を修正しました。(bug 370) (Tatsuo Ishii) + + + + エラークエリがプライマリに送信され、sync メッセージを送信せずに、次のクエリを実行するときに、 + PostgreSQL のシステムカタログへの問い合わせが必要な場合、Pgpool-IIdo_query() 関数でハングアップしていました。 + + + + + + + + Pgpool-II 3.7 以降の上位互換性のために SL_MODE マクロを追加しました。(Tatsuo Ishii) + + + + + + + + "ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) + + + + 今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 + ほとんどの場合、問題がありませんでした。 + ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 + + + + + + + + pgpool 開始メッセージが複数回出力されるのを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.5.11 + + + リリース日 + 2017-11-01 + + + + 不具合修正 + + + + + + + /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) + + + + RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 + + + + + + + + たまににフェイルオーバが実行されない watchdog の不具合を修正しました。(Muhammad Usama) + + + + 今までは、watchdog プロセスは、自分の状態のみを考慮し、フェイルオーバおよびフェイルオーバロック要求の処理を判断していました。 + + + + しかし、この処理の問題点は、ある watchdog が自分をクラスタのマスター/コーディネーターとして通知し、スタンバイノードが自分をマスターノードとして認識するのを待っている間に、自分の状態はマスター/コーディネータですが、まだフェイルオーバおよびフェイルオーバロック要求処理することはできませんでした。 + + + + そのため、たまに watchdog クラスタがリーダーを選出している間にフェイルオーバが実行されないことがありました。 + + + + 修正案としては、ノードがフェイルオーバおよびフェイルオーバーロック要求を受け入れる前に、完全にマスター状態を取得したことを確認するように修正しました。 + + + + + + + + ストリーミングレプリケーションモードで 'H'(フラッシュ) メッセージの処理に関するバグを修正しました。(bug 345) (Tatsuo Ishii) + + + + ユーザが 'H' メッセージの直後に応答を読み込もうとすると、Pgpool-IIはハングアップしまていました。 + 因は、'H' が受信されたときに拡張クエリモードがリセットされ、保留メッセージが使用されなかったためです。 + + + + + + + + フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) + + + 詳細は [pgpool-general: 5728]を参照してください。 + + + + + + + + exit シグナルハンドラが ereport を呼び出さないように修正しました。(Tatsuo Ishii) + + + 詳細は [pgpool-hackers: 2545]を参照してください。 + + + + + + + + OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) + + + + + + + + + リリース 3.5.10 + + + リリース日 + 2017-09-05 + + + + 不具合修正 + + + + + + + ストリーミングレプリケーションモード/拡張クエリで発生する可能性のあるハングアップを修正しました。 (Tatsuo Ishii) + + + エラーが発生すると、Pgpool-IIはフロントエンドから送られてきたSyncメッセージを読み取ります。しかし、タイミングによってはまれにSyncメッセージがまだ送出されていないことがあり、syncが送られるまで待つように修正しました。 + + + + + + + watchdogが新しいノードを追加しようとした時にmasterに拒否される問題を修正しました。 (Yugo Nagata) + + + watchdogの間の認証の際に、秒を元にした文字列が使われていたため、watchdogノードの間で秒単位の時刻同期ができていないときに、この問題が発生します。修正は、単に秒を元にした文字列を認証キーに使わないようにしました。 + + + これは3.5.6, 3.6.3で追加された問題です。 + + + + + + + Test: 001.load_balance のテストスクリプトを修正しました。(Tatsuo Ishii) + + + ネイティブレプリケーションモードのみで実行される一部のテストが、ストリーミングレプリケーションモードでも実行されていたので、修正しました。 + + + + + + + 拡張クエリでslonyモードが動かなくなっていたのを修正しました。(Tatsuo Ishii) + + + slonyモードの場合、応答がバックエンドから返されたときに、進行中フラグがリセットされず、バックエンドからの次のメッセージ待ち状態になり、ハングアップしていました。 + + + + + + + ストリーム書き込みモジュールのバグを修正しました。(Tatsuo Ishii) + + + 要求された長さが残りの書き込みバッファサイズを超えた場合に発生するpool_write_noerror()の不具合を修正しました。この不具合はバッファオーバーランの問題につながる可能性がありました。 + + + 書き込みバッファがいっぱいになると、pool_flush_it()を呼び出し、バッファをフラッシュし、要求されたデータを直接書き込むように修正しました。 + + + さらに、pool_unread()のパフォーマンスが向上しました。 + + + + + + + Test: レグレッションテストスクリプトを修正しました。(Muhammad Usama) + + + + + + + Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) + + + + + + + コアダンプが発生する可能性があったのと、一時テーブルの扱いに関するバグを修正しました。(Tatsuo Ishii) + + + + + + + pool_unread() の不具合を修正しました。(Tatsuo Ishii) + + + pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 + + + + + + + 空文字のクエリの処理を修正しました。(bug 328) (Tatsuo Ishii) + + + 空文字のクエリ (空文字列またはコメントクエリ) が送信されると、コマンド完了メッセージがフロントエンドに返されていました。この動作は正しくありません。空文字クエリのレスポンスをフロントエンドに返すように修正しました。 + + + + + + + ストリーミングレプリケーションモード/拡張クエリで発生するクエリキャッシュのバグを修正しました。(Tatsuo Ishii) + + + + + + + ストリーミングレプリケーションモード/拡張クエリで発生するメモリリークを修正しました。(bug 324)(Tatsuo Ishii) + + + + + + + Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) + + + + + + + workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) + + + workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 + + + この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 + + + + + + + SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) + + + + + + + ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) + + + 詳細は [pgpool-general: 5621] をご参照ください。 + + + + + + + ストリーミングレプリケーションモード/拡張クエリの場合、フロントエンドが 'S' (同期) メッセージを送信する前に、バックエンドからエラーレスポンスを受信するときに発生するハングアップを修正しました。 + + + さらに、以下の修正を行いました。 + + + - ストリーミングレプリケーションモードで ErrorResponse3() 関数が意図的にエラークエリをバックエンドに送信しないように修正しました。 + + + - クエリが進行中でクエリコンテキストが存在する場合のみ、virtual_master_node_idを返すように pool_virtual_master_db_node_id()関数を修正しました。 + + + + + + + 配布物にpgpool.serviceが含まれるように修正しました。(Yugo Nagata) + + + + + + + + 改善点 + + + + + + Test: ビルド時のログがファイルに出力されるように修正しました。 (Tatsuo Ishii) + + + + + + + Test: メモリリークのレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + + リリース 3.5.9 + + + リリース日 + 2017-07-11 + + + + 不具合修正 + + + + + + [pgpool-hackers: 2400]で報告された、ログ出力中の不正なバイトを修正しました。(Muhammad Usama) + + + ほとんどログメッセージの修正でした。 + + + + + + + PostgreSQLMemoryManager APIに関する最新の変更をインポートしました。(Muhammad Usama) + + + + + + + [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) + + + + + + + PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) + + + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn + + + + + + + ストリーミングレプリケーションと拡張プロトコルで発生するハングアップを修正しました。(Yugo Nagata) + + + 以下の例で再現できます。 + + + - pgpool.confですべての読み取りクエリをスタンバイに送信するように設定しています。 + - まず、トランザクションブロックで書き込みクエリを発行します。 + - トランザクションをコミットした後、SELECTクエリを発行します。 + - クエリを処理するときに、Parseの直後にDescribe(statement)メッセージを送信します。 + + + + + JDBCを使用せず、pgprotoを利用し以下のデータでこの問題を再現できます。 + + + + 'Q' "DROP TABLE IF EXISTS test_tbl" + 'Y' + 'Q' "CREATE TABLE test_tbl(i int)" + 'Y' + 'Q' "INSERT INTO test_tbl VALUES(1)" + 'Y' + + 'P' "" "BEGIN" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "COMMIT" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "S_1" "SELECT * FROM test_tbl" 0 + 'D' 'S' "S_1" + 'B' "C_1" "S_1" 0 0 0 + 'E' "C_1" 0 + 'S' + 'Y' + + 'X' + + + + BindExecuteを適切なバックエンドに送信するように、parse_before_bind()は、トランザクション中にのみ呼び出されるように修正しました。 + + + + + + + erlangアプリケーションを使用する場合、Pgpool-II がハングする不具合を修正しました。(Tatsuo Ishii) + + + Erlangクライアントは "Describe"メッセージの後に "Flush"を送信し、バックエンドは "Row description" を返します。しかし、Pgpool-IIは、"Row description" メッセージを受信した後、進行中のクエリフラグをリセットすることを忘れてしまい、Pgpool-IIはバックエンドからの応答を待っていました。これがerlangクライアントのハングアップの原因でした。 + + + + Pgpool-IIが "Row description" メッセージを受信した際に、クエリ処理中のフラグをリセットするように修正しました。"no data" メッセージと同じ扱いにする必要がありました。 + + + 詳細は[pgpool-general: 5555]を参照してください。 + + + + + + + 間違ったターゲットノードにバインドメッセージを送信するバグを修正しました。 (bug 306) (Tatsuo Ishii) + + + + + + + node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) + + + 詳細は[pgpool-general: 5511]を参照してください。 + + + + + + + PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) + + + + + + + クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) + + + oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 + + + + + + + 特定の場合に発生する拡張クエリのハングアップを修正しました。(Tatsuo Ishii) + + + erlang PostgreSQL APIはParse ('P')Describe ('D')Flush ('H')Bind (B)Execute('E')を生成します。この"H"はJDBCにはありませんので、今まで問題が起こらなかったと思われます。その後、Pgpool-IIは拡張クエリモードを削除し、データを読み取るバックエンドを見つけることができませんでした。したがって、Pgpool-IIはバックエンドの一部にメッセージを送信していない可能性があるため、ハングアップを引き起こすすべてのバックエンドを読み取ろうとします。 + + + この問題を避けるために、Flushメッセージを受信後拡張クエリフラグを設定するように修正しました。 + + + + + + + 滅多に発生しないPgpool-II起動時のバグを修正しました。(Tatsuo Ishii) + + + プライマリノードが見つかる前にフェールオーバーの要求が受け入れられる可能性がありました。 + これにより、Pgpool-IIは奇妙な状態に陥ります。障害が発生したノードはプライマリノードの場合、 + プライマリノードは存在しないと判断していました。(既存のスタンバイが昇格し新しいプライマリノードになった場合でも) + + + 詳細は[pgpool-hackers: 2321] をご参照下さい。 + + + + + + + + リリース 3.5.8 + + + リリース日 + 2017-05-11 + + + + 不具合修正 + + + + + + + ノード 0 がフェイルオーバーするレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + [pgpool-hackers:2312] で報告された + Pgpool-IIノード 0 がフェイルオーバーするときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + + + + + + + + リリース 3.5.7 + + + リリース日 + 2017-04-28 + + + + 不具合修正 + + + + + + + Watchdogのソースコードのミスを修正し、いくつかのdebugメッセージを追加しました。(Muhammad Usama) + + + + + + + pool_hba.confファイルのリロード時に発生するエラーを修正しました。(Bug 299) (Muhammad Usama) + + + + + + + watchdog 使用時に Pgpool-II 間でバックエンドの状態が一致しない不具合を修正しました。 + (Bug 289) (Muhammad Usama) + + + + + + + Watchdogによるスプリットブレインシナリオの処理を強化しました。(Muhammad Usama) + + + + watchdogクラスタを使用しmaster/coordinatorノードの再選出が呼び出されていました。その結果、すべてのノードがウォッチドッグネットワークに再結合する必要がありました。これはwatchdogクラスタ全体の再起動と本質的に同じでした。 + + + 今回の修正では、master/coordinatorノードの候補は、次の基準で選択されるようになりました。 + + + (1) 2つのウォッチドッグノードがクラスタマスターであると主張している場合、エスカレーションを実行したマスターノードはマスター状態を保持し、他のノードはステップダウンするように要求されます。 + + + (2) 競合がノードのエスカレーション状況によって解決できない場合、クォーラムを保持するノードはマスター/コーディネータのままです。 + + + (3) 両方の候補のクォーラムステータスが同じ場合、接続されたアライブノードの数が多いノードが優先されます。 + + + (4) 最後に、上記3つでマスターノードを選出できなかった場合、古いマスター(長期間コーディネーターステータスを持つノード) はマスターのままです。 + + + + + + + 複数の並行コマンドを処理するためにwatchdog内部コマンドのメカニズムを強化しました。(Muhammad Usama) + + + + + + + コードの互換性のためにboolエンコードおよびデコード関数をJSONフレームワークに追加します。(Muhammad Usama) + + + + + + + リグレッションの失敗を防ぐために、サポートされていないJavaメソッドを新しいJDBCドライバでコメントアウトしました。(Tatsuo Ishii) + + + + + + + parse_before_bind() のログメッセージを debug1 にダウングレードしました。(Tatsuo Ishii) + + + + + + + coverity警告を修正しました。(Muhammad Usama, Tatsuo Ishii) + + + + + + + [pgpool-general: 5396] + pam ldapが失敗する不具合を修正しました。(Muhammad Usama) + + + + + + + SHOWコマンドを読み込みクエリの一つとして認識するようにしました。(Tatsuo Ishii) + + + ストリーミングレプリケーションモードでは、SHOWが発行されるとその後のSELECTは明示的なトランザクションでプライマリノードに送信されていました。この制限は不適切でした。また、parseコマンドがエラーを返すときに発生するハングアップを修正しました。 + + + + + + + コミットadcb636によって引き起こされたメモリリークの問題を修正しました。(Tatsuo Ishii) + + + Commit adcb636では"pending message queue"を導入しました。メッセージを受信すると、情報がキューに追加され、オブジェクトのコピーが同時に作成されますが、オブジェクトを解放するのを忘れてしまいました。 + + + 今回の修正では、新しい関数pool_pending_message_free_pending_message()を作成し、pool_pending_message_add()pool_pending_message_get()およびpool_pending_message_pull_out()の後に呼び出すように修正しました。 + + + + + + + ストリーミングレプリケーションモードで「kind mismatch」(またはそれに関連する)エラーが修正されました。 + (Bug 271) (Tatsuo Ishii) + + + このエラー原因はデータベースノードがPgpool-IIに送る応答の予測が誤っていたことです。以前使用した「sync map」の実装は弱く、予測に失敗することがありました。今回の修正では、送信されたすべてのメッセージをバックエンドに記録する"pending message queue"を導入しました。このキューの要素には、メッセージのタイプ(parse/bind/execute/describe/close/sync)、メッセージが送信されたデータベースノードの情報などが格納されます。これは単純なFIFOキューです。バックエンドからメッセージが到着すると、"pending message queue"の先頭を見れば、受信したメッセージの種類やデータベースノードを確実に予測できます。 メッセージを受信した後、この要素はキューから削除されます。 + + + 一連のパッチをテストしてくれたSergey Kimさんに感謝します。 + + + 詳細は Bug 271、 + [pgpool-hackers: 2043] と + [pgpool-hackers: 2140] をご参照下さい。 + + + + + + + [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 + (Bug 296) (Muhammad Usama) + + + + + + + + + + リリース 3.5.6 + + + リリース日 + 2017-03-17 + + + + 不具合修正 + + + + + + + pgpool.serviceファイルに"Wants=network.target"を追加しました。 + (bug 294) (Bo Peng) + + + + + + + pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) + + + 失敗したときのエラーメッセージは以下のとおりです。 + + + + FATAL: invalid pgpool mode for process recovery request + DETAIL: specified node is already primary node, can't promote node id 0 + + + + ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 + + + + この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 + 失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 + + + + これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 + + + + + + + READMEに最新リリースノートへのリンクを追加しました。(Bo Peng) + + + + + + + Pgpool-IIがVIPを解除した後にpingテストを続けている不具合を修正しました。(Muhammad Usama) + + + [pgpool-hackers: 1611] により報告されました。 + + + + + + + 特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。(bug 272) (Tatsuo Ishii) + + + + + + + ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) + + + + + + + pcp_attach_nodeを実行するときのセグメンテーション違反を修正しました。 + (bug 281)(Muhammad Usama) + + + + + + + ストリーミングレプリケーションモードでロードバランスのバグを修正しました。(Tatsuo Ishii) + + + 明示的なトランザクションでは、書き込みクエリが送信されるまで、SELECTはロードバランスされます。書込みクエリが送信された後、SELECTがプライマリノードに送信されます。しかし、syncメッセージが送信される前にSELECTが送信された場合、これは正しく動作しませんでした。 + + + 書き込みクエリが実行されると書き込みクエリの処理が行われるように修正しました。 + + + + + + + ストリーミングレプリケーションモードでのkind mismatchエラーを修正しました。(Tatsuo Ishii) + + + + + + + closeメッセージの後にdo_query()がハングする問題を修正しました。(Tatsuo Ishii) + + + + + + + wd_get_cmd関数のバッファオーバーフローを修正しました。 + (bug 280)(Muhammad Usama) + + + + + + + watchdogプロセスを再起動する時の不具合を修正しました。(Muhammad Usama) + + + watchdogプロセスが何らかの問題(例えばセグメンテーションフォルト)によって異常終了した場合、新たに生成されたwatchdogプロセスの起動が失敗し、"bind on ... failed with reason: Address already in use"とのエラーを返しました。 + + + + 理由は、異常終了したwatchdogプロセスはIPCに使用するソケットをクリーンアップする時間がなかったからです。 + + + + この不具合を修正するために、Pgpoolのメインプロセスは、watchdogプロセスが異常終了したときに共有メモリにフラグを設定するように修正しました。 + watchdogプロセスが再起動されるとき、フラグがセットされたら、ソケットファイルをクリーンアップするようにしました。 + + + + + + + 特定の条件下で、ストリーミングレプリケーションモードでクエリキャッシュが有効な場合、SELECTがハングアップする不具合を修正しました。(Tatsuo Ishii) + + + pgpool-general-jp:1441により報告されました。 + + + + + + + シグナルハンドラがelog/ereportを呼び出さないように修正しました。(Tatsuo Ishii) + + + 詳しくは[pgpool-hackers: 1950]をご参照ください。 + + + + + + + FreeBSDでlisten_addresses = '*'の場合、INETドメインソケットが作成できない不具合を修正しました。 + (bug 202)(Bo Peng) + + + + + + + 特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。 + (bug 249)(Muhammad Usama) + + + + WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 + + + + + + + authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) + + + + -pgpool コマンドで廃止されたオプション"-c"を削除しました。(Tatsuo Ishii) - - + 2016-12-28 [afebadf] + --> + + クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) + + + + + + + + + + + + リリース 3.5.5 + + + + リリース日 + 2016-12-26 + + + + + 不具合修正 + + + -また、helpメッセージのタイポを修正しました。 - - + 2016-12-23 [4124e5e] + --> + + + watchdog のセキュリティを強化しました。(Muhammad Usama) + - - - + + + wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 + + + + - PCPコマンドがキャンセルされたときの認証失敗エラーが修正されました。(bug 252) (Muhammad Usama) - - + + + Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) + + - - - + -のデフォルト値を10から300に変更しました。(Tatstuo Ishii) - - + + + クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) + + + + -これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 - + 2016-12-20 [9274f82] + --> + + + 拡張プロトコルにおいて発生しうるkind mismatchエラーを修正しました。(bug 231) (Tatsuo Ishii) + + + + bug 231によると、以下の条件がすべて満たされていると、このバグが発生する可能性がありました。 + + + + + + ストリーミングレプリケーションモード + + + + + + ロードバランスノードがnode 0ではない + + + + + + 拡張プロトコルを使用している + + + + + + SELECTが実行され、ステートメントがクローズされた後、トランザクションコマンドが実行されている + + + + + + 問題の発生順序: + + + + + ロードバランスノード1でステートメントS1のSELECTが実行されます。 + - - - + + + フロントエンドがクローズステートメントを送ります。 + + + + + + Pgpool-IIはそれをバックエンド1に転送します。 + + + + + + フロントエンドは、COMMITのParse、Bind、Executeを送信します。 + + + + + + Pgpool-IIはそれをバックエンド0と1に転送します。 + + + + + + フロントエンドが同期メッセージを送信します。 + + + + + + Pgpool-IIはそれをバックエンド0と1に転送します。 + + + + + + バックエンド0はParse complete( "1")を返しますが、バックエンド1は#3によりclose complete( "3")を返します。 + + + + + + Kind mismatch が発生します。 + + + + + + + + 解決策は、#3では、Pgpool-IIがバックエンド1からの応答を待つようにしますが、応答メッセージは読み取らないようにします。 その後、Pgpool-IIの状態マシンは、#6で同期メッセージが送信される前に、その応答を読み込みます。 これによりバックエンド1は#8で "1"を返信し、kind mismatchエラーは発生しなくなります。 + + + + また、Closeメッセージを受け取ったときにpool_set_doing_extended_query_message()が呼び出されない不具合を修正しました。 + + + + 新しいリグレッションテスト "067.bug231"が追加されました。 + + + + -すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(bug 248) (Tatsuo Ishii) - - + + + シグナルハンドラでの競合状態を修正しました。(bug 265) (Tatsuo Ishii) + + + + child.cには、elogを呼び出すシグナルハンドラがあります。 シグナルハンドラは処理中に他のシグナルに対してブロックされないため、pgpoolのシャットダウンシーケンスでシステムコールにデッドロックが発生する可能性がありました。 この問題を解決するために、シグナルハンドラはPOOL_SETMASKを使用してブロックされるように修正されました。 + + + + 理想的にはシグナルハンドラでelogを呼び出すことを避けるべきです。 + + + + -すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 -その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 -そしてこのコマンドは成功しました。 -しかし、新しい接続が拒否されました。 -これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 -ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 -(ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) -解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 - - + 2016-11-26 [045a59f] + --> + + + Pgpool-II 3.6 でのフェイルオーバーコマンドの転送処理の改善がバックポートされました。(Muhammad Usama) + + + + これまでは、Pgpool-II ノードの watchdogがすべての接続されたノードにフェイルオーバーコマンド(failover、 failback 及び promote node)を転送していました。多数のノードが含まれているwatchdogクラスタでは、フェールオーバーコマンドが複数のPgpool-IIによって実行されることによって、データの同期問題を引き起こす可能性がありました。このコミットでは、すべてのフェイルオーバーコマンド(failover、 failback 及び promote node)が master/coordinator watchdog に転送され、master/coordinator watchdogはすべてのスタンバイノードに転送するようになりました。 + + + + また、今回の修正では、インターロック機能も変更されました。master/coordinatorノードのみがロックホルダになり、フェイルオーバコマンドはmaster/coordinatorノードでのみ実行されます。 + + - - - + -再起動が必要なパラメータの設定を変更した際のPgpool-II停止が起こらないようにしました。(Muhammad Usama) - - + + + ネイティブレプリケーションモード以外の場合、エラーが発生した場合は、クエリをキャンセルしないように修正しました。(Tatsuo Ishii) + + + + 本来は一貫性を維持するためにキャンセルされるようになっていましたが、ネイティブレプリケーションモード以外の場合ではキャンセルする必要がないので、修正しました。 + + + + -この修正のために、設定パラメータの検証機構の順序を逆にしました。 -以前はスタンバイノードがPgpool-IIマスターノードに対して設定パラメータの値を検証し、不整合が見つかった場合にはFATALエラーが出力されていました。 -この修正で、Pgpool-IIマスターノードに検証の役割が移譲されました。 -マスターノードは参加している個々のスタンバイノードの設定値をローカルの設定値と比較し、違っている場合にはエラーではなくてWARNINGメッセージを出力します。 -この方法では、ユーザは、手動でマスターPgpool-IIログの中から不整合ワーニングを見つけて、Pgpool-IIマスターのスイッチオーバが起きたときに驚くようなことが起こらないようにしなければなりません。 - - + 2016-10-27 [c9e203d] + --> + + + pgpool コマンドで廃止されたオプション"-c"を削除しました。(Tatsuo Ishii) + + + + また、helpメッセージのタイポを修正しました。 + + - - - - - コンパイルエラーを修正するために、configure.ac - ファイルにコンパイルフラグ "-fno-strict-aliasing" が追加されました。(Tatsuo Ishii) - - + + + + + PCPコマンドがキャンセルされたときの認証失敗エラーが修正されました。(bug 252) (Muhammad Usama) + + - - - + -MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) - - - -random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 -random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 - - + + + のデフォルト値を10から300に変更しました。(Tatstuo Ishii) + + + + これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 + + - - - + -クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) - - + 2016-09-21 [b306e04] + --> + + + すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(bug 248) (Tatsuo Ishii) + + + + すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 + その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 + そしてこのコマンドは成功しました。 + しかし、新しい接続が拒否されました。 + これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 + ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 + (ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) + 解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 + + - + + + + + 再起動が必要なパラメータの設定を変更した際のPgpool-II停止が起こらないようにしました。(Muhammad Usama) + + + + この修正のために、設定パラメータの検証機構の順序を逆にしました。 + 以前はスタンバイノードがPgpool-IIマスターノードに対して設定パラメータの値を検証し、不整合が見つかった場合にはFATALエラーが出力されていました。 + この修正で、Pgpool-IIマスターノードに検証の役割が移譲されました。 + マスターノードは参加している個々のスタンバイノードの設定値をローカルの設定値と比較し、違っている場合にはエラーではなくてWARNINGメッセージを出力します。 + この方法では、ユーザは、手動でマスターPgpool-IIログの中から不整合ワーニングを見つけて、Pgpool-IIマスターのスイッチオーバが起きたときに驚くようなことが起こらないようにしなければなりません。 + + + + + + + + コンパイルエラーを修正するために、configure.ac + ファイルにコンパイルフラグ "-fno-strict-aliasing" が追加されました。(Tatsuo Ishii) + + + + + + + + MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) + + + + random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 + random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 + + + + + + + + クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) + + + + - + diff --git a/doc.ja/src/sgml/release-3.6.sgml b/doc.ja/src/sgml/release-3.6.sgml index a9317a8be..5412250e5 100644 --- a/doc.ja/src/sgml/release-3.6.sgml +++ b/doc.ja/src/sgml/release-3.6.sgml @@ -1,4741 +1,6990 @@ - - - リリース 3.6.14 + + リリース 3.6.28 - リリース日 - 2018-11-22 + 2021-11-18 - - - 不具合修正 + + セキュリティリリース - - + - -クライアントから送信された startup パケットのパラメータをソートするように修正します。 -(bug 444)(Takuma Hoshiai) + SSL暗号化ハンドシェイク後の余計なデータを拒否するようにしました。(Tatsuo Ishii) - -キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 -コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + サーバサイドのSSLネゴシエーションの実装において、任意のSQLコマンドを実行できる中間者攻撃が可能でした。 + これはPgpool-IIがクライアント認証で証明書認証を使用しているか、hostssl + trust認証の場合に可能でした。 + PostgreSQLのCVE-2021-23214と似た脆弱性です。 + + + 同様に、クライアントサイドのSSLネゴシエーション実装において、任意の結果に改ざんする中間者攻撃が可能でした。 + これはPostgreSQLがクライアント認証でhostssl + trust認証を使用しているときに可能でした。 + 証明書認証の場合には、Pgpool-IIはPgpool-IIとPostgreSQL間で証明書認証を実装していないため問題ありません。 + PostgreSQLのCVE-2021-23222と似た脆弱性です。 - + + + + + 変更点 + + - + - -ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 -(bug 443) (Bo Peng) + pg_terminate_backend()の処理に関するPostgreSQL 14対応をしました。(Tatsuo Ishii) + + + + - -パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 -bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 -これによりセグメンテーション違反が発生していました。 + Pgpool-IIメインプロセスのSIGCHLDハンドラを改良しました。(Tatsuo Ishii) - -パッチがYugo Nagataにより提供されました。 + Pgpool-IIの子プロセスがSIGKILLシグナルでkillされたとき、SIGCHLDハンドラは他のシグナルと同じようにLOGレベルメッセージを発していました。 + しかし、SIGKILLシグナルはOMM killerによるkillなど重要なイベントなので、WARNINGレベルのメッセージを発するようにしました。 + Michail Alexakisから提案されました。 + Discussion: [pgpool-general: 7750] - + + + + + + 不具合修正 + + - + - -スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + COPY FROM中のハングアップを修正しました。(Tatsuo Ishii) + + + COPY FROM中にエラーが発生したとき、Pgpool-IIはフロントエンドからCOPY終了マーカーが送信されたあと、バックエンドからの応答を永遠に待っている可能性がありました。 + Bo Pengによって発見されました。 - + - + - -クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + rawモードでの誤った負荷分散ノードの表示を修正しました。(Bo Peng) + + + rawモードでは、Pgpool-IIはすべてのクエリをメインノードに送信します。 + この不具合は表示上の問題だけで、クエリの転送処理に影響はないですが、ユーザを混乱させる可能性があるので、修正しました。 - + + + + + ドキュメント修正 + + - + - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + typoを修正しました。(Bo Peng) + + + パッチはKazufumi Notoによって提供されました。 - + - + - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) + Doc: PGPOOL SHOWコマンドを実行する際に、大文字を含むパラメータ名の場合には、 + パラメータ名をダブルクォートで囲んで実行する必要があることを追加しました。(Bo Peng) - - - - - - - リリース 3.6.13 - - - - リリース日 - 2018-10-31 - - - - - 変更点 - - - - - -フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) - - - - - - - -LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) - - - - - - - -Doc: オンラインリカバリのドキュメントに注意事項を追加しました。 - - - -よりも小さな値でなければなりません。 - - - - - - - -Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) - - - - - - - -Doc: フェールオーバスクリプトに関する注意事項を追加しました。 - - - -failover/failbackスクリプトの中でPgpool-II自体にアクセスすることはお勧めしません。 - - - - - - - -Doc: のドキュメント及びエラーメッセージを改善しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供され、Bo Pengにより修正されました。 - - - - - - - -Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - - 不具合修正 - - - - - -SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) - - - -パッチはPhil Ramirezにより提供されました。 - - - - - - - -ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 -(bug 434) (Takuma Hoshiai) - - - -ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 - - - - - - - -ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) - - - -ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 -タイムスタンプ型の定数に書き換えるようになっています。 -しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 - - - - - - - -拡張問い合わせの場合、時々期待される応答がフロントエンドに返されないことがあったので、修正しました。 -(bug 432) (Tatsuo Ishii) - - - -解決策は、保留中のメッセージデータリストを使用することです。それはフロントエンドからのメッセージを記録し、同じ数のメッセージを受け取ることが期待されます。 - - - -パッチは Yugo Nagata によって作成され、Tatsuo Ishii により修正されました。 - - - - - - - -ストリーミングレプリケーションモードかつ拡張問い合わせの場合、クエリキャッシュを有効にするときに発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - -trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) - - - - - - - -ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) - - - -明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 -テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 - - - - - - - -時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) - - - - - - - -Test: EXECUTE/DEALLOCATEのレグレッションテストを追加しました。(Takuma Hoshiai) - - - - - - - -pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) - - - - - - - -DEALLOCATEステートメントが発行された場合に発生するkind mismatchエラーを修正しました。(Bo Peng) - - - -EXECUTEDEALLOCATEPREPAREと同じノードに送信されるために、PREPAREをpool_add_sent_messageに追加するように修正しました。 - - - -詳細は[pgpool-general: 6226]を参照してください。 - - - - - - - -パスワードの長さが正しくない場合、を更新しないように修正しました。 -(bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - -Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 -ファイルのパスワードの長さをチェックするように修正しました。 - - - - - - - -Doc: ドキュメントの"new master"を"new primary"に変更しました。(Bo Peng) - - - - - - - -gccの新しいバージョンで発生するwarningを修正しました。(Tatsuo Ishii) - - - - - - - -Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -.gitignoreファイルを追加しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - - - - - -Doc: ドキュメントとスクリプトのタイポを修正しました。(Tatsuo Ishii) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -Doc: のドキュメントの誤りを修正しました。 - - - - - - - - - リリース 3.6.12 - - - リリース日 - 2018-07-31 - + + - 不具合修正 - - - - - - -「write on backend 0 failed with error :"Success"」エラーを修正しました。 -(bug 403) (Tatsuo Ishii) - - -write() が 0 を返した場合、エラーとして扱わないように修正しました。 - - - - - - - -フェイルオーバ後、スタンバイ Pgpool-II で worker プロセスが起動されない不具合を修正しました。 -(bug 409) (Muhammad Usama) - - - -修正パッチは Yugo Nagataによって提供されました。 - - - - - - - -pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - -pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。(Tatsuo Ishii) - - - -これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 - - - - - - - -armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - -修正パッチは Christian Ehrhardt によって提供されました。 - - - - - - - -Doc:「クライアント認証」、「Pgpool-II のインストール」、「pg_md5」などのドキュメントを改善しました。(Bo Peng) - - - -修正パッチは Takuma Hoshiai によって提供されました。 - - - - - - - -Test: テスト006.memqcache の失敗を修正しました。( Tatsuo Ishii) - - - - - + テストツール修正 + - - - リリース 3.6.11 + + + + 新しいメインノードが利用できない場合に何もしないようにpgpool_setupを修正しました。(Tatsuo Ishii) + + - - - リリース日 - 2018-06-12 - + + - 不具合修正 - - - - - -拡張問合せ、かつクエリキャッシュが有効の場合、レプリケーション遅延が大きすぎるときに発生しうる Pgpool-II のハングアップを修正しました。(Tatsuo Ishii) - - - -詳細は [pgpool-general-jp: 1534] -を参考してください。 - - + 回帰テスト修正 + - - - - -Doc: PCP コマンドの "-U" オプションのタイポを修正しました。 (Bo Peng) - - + + + + たまに発生する073.pg_terminate_backendの失敗を修正しました。(Tatsuo Ishii) + + - - - - -デバッグ用コードを削除しました。(Bo Peng) - - + + + + テストの失敗を防ぐためにpsqlコマンドのパスを修正しました。(Bo Peng) + + - - - - -拡張問合せでは、SET TRANSACTION READ ONLY の場合、書き込みトランザクションフラグを立てないように修正しました。 (Tatsuo Ishii) - - - - - - - -Doc: 古い のドキュメントを修正しました。 (Tatsuo Ishii) - - - - - - - -Doc: recovery_2nd_stage_command はネイティブレプリケーションモードのみで設定する必要がある明確な説明をドキュメントに追加しました。(Tatsuo Ishii) - - - - - - - -pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) - - - -これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 - - - -詳細は -[pgpool-general: 5963] -をご参照してください。 - - - -また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 - - - - + + - - - リリース 3.6.10 - + + リリース 3.6.27 - - リリース日 - 2018-04-17 + リリース日 + 2021-08-05 - - 不具合修正 - + + 変更点 + - + - - Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) + ドメイン名を含めたホスト名の長さの最大値を変更しました。(Tatsuo Ishii) - + + ホスト名の長さの最大値を128にしていましたが、正しくは254でした。 + Discussion: [pgpool-hackers: 3903] + + + + + - + + 不具合修正 + + + - - to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) + SIモードにおける不正なメッセージの送信を修正しました。(Tatsuo Ishii) + + + クエリがシリアル化エラーなどの特定の理由によってアボートしたとき、Pgpool-IIは + メインノード以外で実行されているトランザクションを中止するためにエラークエリを送信します。そのメッセージ長が + 正しくなかったためバックエンドで「invalid string in message」エラーが発生していました。 - + - + - - Doc: watchdog に関するドキュメントを更新しました。(Tatsuo Ishii) + watchdog通信の競合状態を修正しました。(Tatsuo Ishii) + + + メインプロセスがwatchdogプロセスから通知された処理を実行中に、watchdogプロセスが新しいメッセージを + メインプロセスに通知したとき、新しいメッセージが処理されるまでに大幅な遅延が発生していました。 + Discussion: [pgpool-hackers: 3900] - + - + - - Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + 再起動後にwatchdogノードステータスが更新されない問題を修正しました。 + (bug 684) (Muhammad Usama) - + + + + + + + ドキュメント修正 + - + - - 「unable to bind D cannot get parse message "S1"」エラーによるハングアップを修正しました。(Tatsuo Ishii) + Doc: いくつかのドキュメントのtypoを修正しました。(Bo Peng) - + - + - - Doc: backend_flag を使用してフェイルオーバ回避できるようにする説明をドキュメントに追加しました。(Tatsuo Ishii) + Doc: インメモリクエリキャッシュのtypoを修正しました。(Tatsuo Ishii) - + - + - - Doc: ドキュメントのタイポを修正しました。(Bo Peng) + Doc: の説明を修正しました。(Masaya Kawamoto) - + + + + - + + テストツール修正 + + + - - レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + pgpool_setupで使用されるrsyncのパラメータを修正しました。(Tatsuo Ishii) - + - + - - PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) + pgpool_setup中のベースバックアップ処理を修正しました。(Tatsuo Ishii) - + - + - - Doc: pgpool_adm エクステンション関数の例を修正しました。(Tatsuo Ishii) + watchdog_setupのスクリプトを修正しました。(Tatsuo Ishii) - - - - - - - - - リリース 3.6.9 - - - - リリース日 - 2018-02-13 - - - このリリースでは、Pgpool-II 3.7.0、3.6.6、3.5.10 で追加された、ソケット - への書き込み不具合を修正しています。この障害により、ネットワーク負荷が - 高い状態でのフロントエンド、バックエンドへのメッセージ送信の際に、不正 - なメッセージが送信される可能性があります。3.7.x、3.6.6 以降、3.5.10 以降 - のバージョンを利用中のユーザは、できるだけ早くアップグレードすることを - お勧めします。 + watchdog_setupによって生成されるshutdownallスクリプトは、全体シャットダウンでは + 不必要なフェイルオーバ処理を引き起こしていました。 - + + + + - 変更点 - - + 回帰テスト修正 + + + + 031.connection_life_timeの不具合を修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 3.6.26 + + + リリース日 + 2021-05-20 + + + + + 不具合修正 + + -Pgpool-II が libressl の環境でビルドできるようになりました。(Tatsuo Ishii) + + Doc: の説明を修正しました。(Tatsuo Ishii) -詳細は [pgpool-hackers: 2714] を参照してください。パッチは Sandino Araico Sanchez により提供されました。 + パラメータは、Pgpool-IIがrootで起動する場合にのみ使用できます。 - + - + - -PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + pgpool0の配下のみにデータベースクラスタを作成するようにを修正しました。(Tatsuo Ishii) - + - + - -systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + クエリキャッシュが有効になっている場合のpgpoolのクラッシュを修正しました。 + (bug 700) (Tatsuo Ishii) - - - - - -pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + ストリーミングレプリケーションモードと論理レプリケーションモード以外でCloseCompleteを受信すると、Pgpool-IIがクラッシュしていました。 - - - + - - 不具合修正 - - + - -コミットまたはロールバック時に誤って書き込みトランザクションフラグをセットする不具合を修正しました。 (Tatsuo Ishii) + Startupパケットを受信したときのデバッグメッセージを改善しました。 (Tatsuo Ishii) - + - + - -Doc: ドキュメントのタイポを修正しました。 (Bo Peng) + Doc: 多数ドキュメントの改善を行いました。 (Tatsuo Ishii, Bo Peng) - + + + + + + + + リリース 3.6.25 + + + リリース日 + 2021-02-18 + - + + + 変更点 + + - -ソケット書き込みの不具合を修正しました。 (Tatsuo Ishii) + Pgpool-II起動時に既存のwatchdogコマンドソケットファイルを削除するように修正しました。(Muhammad Usama) -ネットワーク負荷が高い場合に、フロントエンド、バックエンドへのメッセージ送信の際に、 -不正なメッセージが送信される可能性があるのを修正しました。 + パッチはMasaya Kawamotoによって提供されました。 + + + + + + + 不具合修正 + + + -このバグは 3.6.6、3.5.10 がリリースされた際に追加されたものです。 + の誤ったweightの表示を修正しました。 (Tatsuo Ishii) - + - + + watchdog_setupの誤ったデータベースクラスタのパスを修正しました。(Tatsuo Ishii) + + + + -デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + DBノードごとに個別のアーカイブディレクトリを作成するようにpgpool_setupを修正しました。(Tatsuo Ishii) + - + + + + 共有メモリの割り当て中のエラーを修正しました。(Tatsuo Ishii) + + - + + ERRORが発生した場合、が正しくカウンタされない不具合を修正しました。(Tatsuo Ishii) + + + + -拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + backend_flag0 = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER'またはfailover_command=''の場合に発生しうるセグメンテーション違反を修正しました。 + (bug 672) (Tatsuo Ishii) - + - - + + + + Doc: のドキュメントを修正しました。(Tatsuo Ishii) + + + + - - - リリース 3.6.8 - - - - リリース日 - 2018-01-09 - - - - 不具合修正 - - - - - - -Doc: ドキュメントのミスとタイポを修正しました。(Bo Peng) - - - - - - - - スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) - - -/bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 - - - - - - - -ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) - - - -ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 - - - - - - - -Doc: 新しいドキュメント「ドキュメントのコンパイルとインストール」を追加しました。(Tatsuo Ishii) - - - - - - - -ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) - - - -PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 - - - - - - - - Doc: のドキュメントを修正しました。 (Tatsuo Ishii) - - - - ロジカルレプリケーションモードにも対応するとの説明を追加しました。 - - - - - - - -一部のログメッセージをデバッグメッセージにダウングレードしました。(Tatsuo Ishii) - - - -前回の開発で誤って残していました。 - - - - - - - -バックエンドからのパケットを読み込む際の再同期のロジックを修正しました。(Tatsuo Ishii) - - - -read_kind_from_backend() は、バックエンドからメッセージを読み取り、"ready for query" メッセージが受信されたときにバックエンドノードを再同期します。 -しかし、pool_pending_message_pull_out() を呼び出して「sync メッセージを受信した」を削除することを忘れていました。 -これによって、バックエンドからのパケットの読み取り中に Popool-II がハングアップする可能性がありました。 -pool_pending_message_pull_out()を呼び出し、「sync メッセージを受信した」を削除するように修正しました。 - - - - - - - -問い合わせ中に Pgpool-II がハングアップする不具合を修正しました。(bug 370) (Tatsuo Ishii) - - - -エラークエリがプライマリに送信され、sync メッセージを送信せずに、次のクエリを実行するときに、 -PostgreSQL のシステムカタログへの問い合わせが必要な場合、Pgpool-IIdo_query() 関数でハングアップしていました。 - - + + + リリース 3.6.24 + + + リリース日 + 2020-11-19 + - + + + 変更点 + + - -Pgpool-II 3.7 以降の上位互換性のために SL_MODE マクロを追加しました。(Tatsuo Ishii) + Doc: Pgpool-IIGSSAPIをサポートしないという注意事項を追加しました。(Tatsuo Ishii) - - - - - - -"ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) - - - -今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 -ほとんどの場合、問題がありませんでした。 -ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 - - + - + + フロントエンドがGSSAPI暗号化接続を要求した場合、 + Pgpool-IIGSSAPIをサポートしていないため、 + これまでエラーを返していましたが、他の方式での接続を要求するように変更しました。(Tatsuo Ishii) + + + パッチはTatsuo Ishiiにより作成され、Umar Hayatによりレビュー・テストされました。 + + + + + + + + 不具合修正 + + -pgpool 開始メッセージが複数回出力されるのを修正しました。(Tatsuo Ishii) + + ネイティブレプリケーションモードで「INSERT ... ON CONFLICT」クエリ書換えの不具合を修正しました。 + (bug 654) (Bo Peng) - + - + + クエリがキャンセルされたときにコネクションカウントが減少しない不具合を修正しました。 + (bug 656) (Tatsuo Ishii) + + + + - 内の start/stop スクリプトの実行権限を追加しました。(Tatsuo Ishii) + + Doc: PostgreSQLの使用可能なバージョンを7.4以降に修正しました。(Tatsuo Ishii) - - - + + + - - リリース 3.6.7 - - - リリース日 - 2017-11-01 - + + + リリース 3.6.23 + + + リリース日 + 2020-09-17 + - - 不具合修正 - - + + + 変更点 + + - - /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) + + PostgreSQL 12.4 のガイドラインに従ってPgpool-IIの拡張機能のスクリプトを修正しました。(Tatsuo Ishii) + + CREATE OR REPLACE FUNCTIONの使用を避けて、代わりにCREATE FUNCTIONを使用するように修正しました。 + + + + - RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 + + + の"PGBIN"と"LPATH"を、PostgreSQLのbin pathとlib pathにしました。(Bo Peng) - + + + - + + + 不具合修正 + + + + Doc: オンラインリカバリが利用可能なPgpool-IIの動作モードに関する誤った説明を修正しました。(Bo Peng) + + + + - pg_terminate_backend() の処理における問題を修正しました。(Muhammad Usama) + + + いくつかの不要なチェックをソースコードから削除しました。(Tatsuo Ishii) - - 特定の場合で、Pgpool-II が正常に pg_terminate_backend()を呼び出しても、フェイルオーバを引き起こす可能性がありました。 + + パッチはby Hou, Zhijieにより提供されました。 - + - + - - たまにフェイルオーバが実行されない watchdog の不具合を修正しました。(Muhammad Usama) + + relcacheクエリがプライマリ以外に送信される不具合を修正しました。(Tatsuo Ishii) + + ストリーミングレプリケーションモードでは、relcacheクエリはプライマリノードに送信されるようになっています。 + しかし、実際には、プライマリノードがマスターノードでない場合、relcacheクエリはプライマリノードに送信されませんでした。 + 通常、これはプライマリがノード0でない場合に発生する可能性があります。 + + + + - 今までは、watchdog プロセスは、自分の状態のみを考慮し、フェイルオーバおよびフェイルオーバロック要求の処理を判断していました。 + + + が有効になっているときにが機能しない問題を修正しました。(Tatsuo Ishii) + Discussion: [pgpool-general: 7175] + + + + - しかし、この処理の問題点は、ある watchdog が自分をクラスタのマスター/コーディネーターとして通知し、スタンバイノードが自分をマスターノードとして認識するのを待っている間に、自分の状態はマスター/コーディネータですが、まだフェイルオーバおよびフェイルオーバロック要求処理することができない点にありました。 - + + 認証処理において有益なエラーメッセージを表示するように修正しました。(Tatsuo Ishii) + + + + - そのため、たまに watchdog クラスタがリーダーを選出している間にフェイルオーバが実行されないことがありました。 + + + 特定の場合に発生するpgpool子プロセスのセグメンテーション違反を修正しました。(Tatsuo Ishii) - - ノードがフェイルオーバおよびフェイルオーバーロック要求を受け入れる前に、完全にマスター状態を取得したことを確認するように修正しました。 + + 以下の方法で再現できます。 + + + + + すべてのバックエンドを停止します。 + + + + + + 無効なクライアントでpgpoolに接続します。例えば、pcpのポートではなく、pgpoolのポート番号を使用してpcp_attach_nodeを実行します。 + + + - + + + + + + + + リリース 3.6.22 + + + リリース日 + 2020-08-20 + - + + + 変更点 + + + Doc: TLSバージョン1.2あるいはそれ以下のバージョンのみがの影響をうけるという説明を追加しました。(Tatsuo Ishii) + + + + - ストリーミングレプリケーションモードで 'H'(フラッシュ) メッセージの処理に関するバグを修正しました。(bug 345) (Tatsuo Ishii) + + Doc: に関する説明を改善しました。(Bo Peng) - - ユーザが 'H' メッセージの直後に応答を読み込もうとすると、Pgpool-IIはハングアップしていました。 - 原因は、'H' が受信されたときに拡張クエリモードがリセットされ、保留メッセージが使用されなかったためです。 + パッチはKenichiro Tanakaにより提供されました。 - + - + - - Doc: pcp_node_info のドキュメントのミスを修正しました。(Tatsuo Ishii) + pool_hba.confサンプルファイルにhostssl/hostnosslに関する説明を追加しました。(Tatsuo Ishii) - + - + + Doc: 多数ドキュメントの改善を行いました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + - フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) + + pgpoolの起動時に、pidファイルが存在する場合、書き込む前にpidファイルを長さゼロに切り詰めるように修正しました。(Bo Peng) - 詳細は [pgpool-general: 5728]を参照してください。 + パッチはmaliangzhuにより提供されました。 - + - + + Doc: のパラメータの説明の誤りを修正しました。(Bo Peng) + + + + - exit シグナルハンドラが ereport を呼び出さないように修正しました。(Tatsuo Ishii) - - 詳細は [pgpool-hackers: 2545]を参照してください。 + ストリーミングレプリケーションモードでプライマリノードが0以外の場合、が機能しない問題を修正しました。(Tatsuo Ishii) - + - + - - OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) + -rオプション及びPostgreSQL 12でのpgpool_setupの問題を修正しました。(Tatsuo Ishii) - + - + - - Doc: replicate_select の動作に関する説明を修正しました。(Yugo Nagata) + RPMパッケージのPCPコマンドのUNIX_DOMAIN_PATH/var/run/postgresqlに変更します。(Bo Peng) - - - - - - - リリース 3.6.6 - - - リリース日 - 2017-09-05 - - - - 不具合修正 - - - - - - -ストリーミングレプリケーションモード/拡張クエリで発生する可能性のあるハングアップを修正しました。 (Tatsuo Ishii) - - -エラーが発生すると、Pgpool-IIはフロントエンドから送られてきたSyncメッセージを読み取ります。しかし、タイミングによってはまれにSyncメッセージがまだ送出されていないことがあり、syncが送られるまで待つように修正しました。 - - - - - - -watchdogが新しいノードを追加しようとした時にmasterに拒否される問題を修正しました。 (Yugo Nagata) - - -watchdogの間の認証の際に、秒を元にした文字列が使われていたため、watchdogノードの間で秒単位の時刻同期ができていないときに、この問題が発生します。修正は、単に秒を元にした文字列を認証キーに使わないようにしました。 - - - これは3.5.6, 3.6.3で追加された問題です。 - - - - - - -Test: 001.load_balance のテストスクリプトを修正しました。(Tatsuo Ishii) - - -ネイティブレプリケーションモードのみで実行される一部のテストが、ストリーミングレプリケーションモードでも実行されていたので、修正しました。 - - - - - - -拡張クエリでslonyモードが動かなくなっていたのを修正しました。(Tatsuo Ishii) - - -slonyモードの場合、応答がバックエンドから返されたときに、進行中フラグがリセットされず、バックエンドからの次のメッセージ待ち状態になり、ハングアップしていました。 - - - - - - -ストリーム書き込みモジュールのバグを修正しました。(Tatsuo Ishii) - - -要求された長さが残りの書き込みバッファサイズを超えた場合に発生するpool_write_noerror()の不具合を修正しました。この不具合はバッファオーバーランの問題につながる可能性がありました。 - - -書き込みバッファがいっぱいになると、pool_flush_it()を呼び出し、バッファをフラッシュし、要求されたデータを直接書き込むように修正しました。 - - -さらに、pool_unread()のパフォーマンスが向上しました。 - - - - - - -Test: レグレッションテストスクリプトを修正しました。(Muhammad Usama) - - - - - - -Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) - - - - - - -コアダンプが発生する可能性があったのと、一時テーブルの扱いに関するバグを修正しました。(Tatsuo Ishii) - - - - - - -pool_unread() の不具合を修正しました。(Tatsuo Ishii) - - -pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 - - - - - - -空文字のクエリの処理を修正しました。(bug 328) (Tatsuo Ishii) - - -空文字のクエリ (空文字列またはコメントクエリ) が送信されると、コマンド完了メッセージがフロントエンドに返されていました。この動作は正しくありません。空文字クエリのレスポンスをフロントエンドに返すように修正しました。 - - - - - - -ストリーミングレプリケーションモード/拡張クエリで発生するクエリキャッシュのバグを修正しました。(Tatsuo Ishii) - - - - - - -ストリーミングレプリケーションモード/拡張クエリで発生するメモリリークを修正しました。(bug 324)(Tatsuo Ishii) - - - - - - -Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) - - - - - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) - - -workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 - - -この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 - - - - - - -SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) - - - - - - -ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) - - -詳細は [pgpool-general: 5621] をご参照ください。 - - - - - - -ストリーミングレプリケーションモード/拡張クエリの場合、フロントエンドが 'S' (同期) メッセージを送信する前に、バックエンドからエラーレスポンスを受信するときに発生するハングアップを修正しました。 - - -さらに、以下の修正を行いました。 - - -- ストリーミングレプリケーションモードで ErrorResponse3() 関数が意図的にエラークエリをバックエンドに送信しないように修正しました。 - - -- クエリが進行中でクエリコンテキストが存在する場合のみ、virtual_master_node_idを返すように pool_virtual_master_db_node_id()関数を修正しました。 - - - - - - -Doc: ドキュメントのタイポを修正しました。(Bo Peng) - - - - - - -配布物にpgpool.serviceが含まれるように修正しました。(Yugo Nagata) - - - - - - - - 改善点 - - - - - -Doc: 英語/日本語ドキュメントに 「Pgpoo-II + Watchdogの構築の例」を追加しました。(Bo Peng) - - - - - - -Test: メモリリークのレグレッションテストを追加しました。(Tatsuo Ishii) - - - - - - - - リリース 3.6.5 - - - リリース日 - 2017-07-11 - - - - 不具合修正 - - + - + - [pgpool-hackers: 2400]で報告された、ログ出力中の不正なバイトを修正しました。(Muhammad Usama) + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + クエリキャッシュが有効な場合、あるテーブルが更新された場合、Pgpool-IIは自動的にそのテーブルに関係する全てのキャッシュを削除するようになっています。 + しかし、EXPLAIN ANALYZEまたはCTEで更新クエリを実行した場合に、 + これらのクエリが誤って参照クエリとして扱われ、キャッシュが削除されませんでした。 - ほとんどログメッセージの修正でした。 + パッチはHou, Zhijieにより作成され、Tatsuo Ishiiにより修正されました。 - + - + - PostgreSQLMemoryManager APIに関する最新の変更をインポートしました。(Muhammad Usama) + コーナーケースで発生するPgpool-IIのハングアップを修正しました。(Tatsuo Ishii) - + - + - スプリットブレインが発生した場合、間違ったノードが MASTER になってしまう不具合を修正しました。 - (bug 306) (Muhammad Usama) + user、database、application_name以外のパラメータが指定された場合、startupパケットの読み取りが失敗する不具合を修正しました。(Tatsuo Ishii) - + - + - [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) + pg_terminate_backendを実行した時にコネクションのカウントがずれる不具合を修正しました。(Takuma Hoshiai) - + - + - PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) + アプリケーション名がに含まれている場合に発生するセグメンテーション違反を修正しました。 (bug 615) (Tatsuo Ishii) + - - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn - - - - + - ストリーミングレプリケーションと拡張プロトコルで発生するハングアップを修正しました。(Yugo Nagata) - - - 以下の例で再現できます。 - - - - pgpool.confですべての読み取りクエリをスタンバイに送信するように設定しています。 - - まず、トランザクションブロックで書き込みクエリを発行します。 - - トランザクションをコミットした後、SELECTクエリを発行します。 - - クエリを処理するときに、Parseの直後にDescribe(statement)メッセージを送信します。 - + ネイティブレプリケーションモードでpg_terminate_backend()を実行すると、フェイルオーバを引き起こしてしまう不具合を修正しました。(Takuma Hoshiai) + + + + - - JDBCを使用せず、pgprotoを利用し以下のデータでこの問題を再現できます。 - - - 'Q' "DROP TABLE IF EXISTS test_tbl" - 'Y' - 'Q' "CREATE TABLE test_tbl(i int)" - 'Y' - 'Q' "INSERT INTO test_tbl VALUES(1)" - 'Y' - - 'P' "" "BEGIN" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "COMMIT" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "S_1" "SELECT * FROM test_tbl" 0 - 'D' 'S' "S_1" - 'B' "C_1" "S_1" 0 0 0 - 'E' "C_1" 0 - 'S' - 'Y' - - 'X' - - - - - BindExecuteを適切なバックエンドに送信するように、parse_before_bind()は、トランザクション中にのみ呼び出されるように修正しました。 - - + + + リリース 3.6.21 + + + リリース日 + 2020-05-21 + - + + + 不具合修正 + + - erlangアプリケーションを使用する場合、Pgpool-II がハングする不具合を修正しました。(Tatsuo Ishii) - - - Erlangクライアントは "Describe"メッセージの後に "Flush"を送信し、バックエンドは "Row description" を返します。しかし、Pgpool-IIは、"Row description" メッセージを受信した後、進行中のクエリフラグをリセットすることを忘れてしまい、Pgpool-IIはバックエンドからの応答を待っていました。これがerlangクライアントのハングアップの原因でした。 - - - - Pgpool-IIが "Row description" メッセージを受信した際に、クエリ処理中のフラグをリセットするように修正しました。"no data" メッセージと同じ扱いにする必要がありました。 - - - 詳細は[pgpool-general: 5555]を参照してください。 + + 一部のシステム(Fedora 32)で発生するビルドエラーを修正しました。(Tatsuo Ishii) - + - + - 間違ったターゲットノードにバインドメッセージを送信するバグを修正しました。 (bug 306) (Tatsuo Ishii) + + 不要なチェックを削除しました。(Tatsuo Ishii) + + + + パッチはsherlockcppによって提供されました。Discussion: [pgpool-general: 7004] - + - + - node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) + + Doc: ドキュメントのタイポを修正しました。(Tatsuo Ishii) - 詳細は[pgpool-general: 5511]を参照してください。 + + パッチはUmar Hayatによって提供されました。 + Discussion: [pgpool-hackers: 3587] - + - + - PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) + + PCP プロセスのセグメンテーション違反を修正しました。(bug 598) (Muhammad Usama) - + - + - クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) + + Doc: タイポを修正しました。(Tatsuo Ishii, Bo Peng) - oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 + + パッチはsherlockcppによって提供されました。 - + - + - 特定の場合に発生する拡張クエリのハングアップを修正しました。(Tatsuo Ishii) - - - - erlang PostgreSQL APIはParse ('P')Describe ('D')Flush ('H')Bind (B)Execute('E')を生成します。この"H"はJDBCにはありませんので、今まで問題が起こらなかったと思われます。その後、Pgpool-IIは拡張クエリモードを削除し、データを読み取るバックエンドを見つけることができませんでした。したがって、Pgpool-IIはバックエンドの一部にメッセージを送信していない可能性があるため、ハングアップを引き起こすすべてのバックエンドを読み取ろうとします。 + + ネイティブレプリケーションモードで起こりうるデータの不整合を修正しました。(Tatsuo Ishii) - この問題を避けるために、Flushメッセージを受信後拡張クエリフラグを設定するように修正しました。 + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] - + - + - [pgpool-hackers: 2354]によって報告されたpg_md5 のセグメンテーション違反を修正しました。(Muhammad Usama) + + ホスト名が長い場合、バッファサイズの制限によってWatchdogのpingが失敗する問題を修正しました。(bug 516) (Bo Peng) - + + + + - + + + リリース 3.6.20 + + + リリース日 + 2020-02-20 + + + + + 変更点 + + - white/black_memcache_table_listのドキュメントを修正しました。(Tatsuo Ishii) - - - 実際の実装と異なっています。 + + 起動時のbind()エラーを回避するために、ソケットファイルが存在するかどうかを確認し、 + PIDファイルが存在しない場合、それらのソケットファイルを削除するように修正しました。(Bo Peng) - - 詳細は[pgpool-general:5479]を参照してください。 - - + + + - + + + 不具合修正 + + - 滅多に発生しないPgpool-II起動時のバグを修正しました。(Tatsuo Ishii) - - - プライマリノードが見つかる前にフェールオーバーの要求が受け入れられる可能性がありました。 - これにより、Pgpool-IIは奇妙な状態に陥ります。障害が発生したノードはプライマリノードの場合、 - プライマリノードは存在しないと判断していました。(既存のスタンバイが昇格し新しいプライマリノードになった場合でも) - - - 詳細は[pgpool-hackers: 2321] をご参照下さい。 + + レプリケーションモードの場合に、クエリのタイムスタンプがリライトされない不具合を修正しました。 + (bug 551) (Bo Peng) - - - - - - - - - - - リリース 3.6.4 - - - リリース日 - 2017-05-11 - - - - 不具合修正 - - + - + - Watchdog のフェイルオーバーリクエスト処理の不具合を修正しました。(Muhammad Usama) + + Doc: ドキュメントの更新、タイポの修正を行いました。(Takuma Hoshiai, Tatsuo Ishii, Bo Peng) - - - + + - Watchdog クラスタのメンバーの基準を改善しました。(Muhammad Usama) + + PostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) - - - + + - ロードバランスに関するドキュメントを改善しました。(Tatsuo Ishii) + + 時々起こるリグレッションテストの失敗を修正しました。(Tatsuo Ishii) - - - + + - ノード 0 がフェイルオーバーする場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + primary_conninfoのapplication_nameが空の場合に発生するレプリケーション遅延チェックワーカープロセスのセグメンテーション違反を修正しました。 + (bug 565) (Tatsuo Ishii) - - - + + - [pgpool-hackers:2312] で報告された -Pgpool-IIノード 0 がフェイルオーバーするときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + syslogが出力されない不具合を修正しました。(Bo Peng) - - - - - - + + + + + + リリース 3.6.19 + + + リリース日 + 2019-10-31 + - - リリース 3.6.3 - - - リリース日 - 2017-04-28 - - - - 不具合修正 - - - - + + + 不具合修正 + + - memcachedが使用されているときに発生する"show pool_cache"のセグメンテーション違反を修正しました。 - (Bug 301) (Tatsuo Ishii) + + レプリケーションモードでの誤ったクエリの書き換えを修正しました。 (Bo Peng) - + - + - いくつかのソースコードの警告を修正しました。(Muhammad Usama) + + Doc: すべてのスタンバイノードがダウンした場合のの説明を追加しました。(Takuma Hoshiai) - + - + - いくつかのコンパイラの警告を修正しました。(Muhammad Usama) + + Doc: PostgreSQLサーバをに指定しないように注意事項を追加しました。(Tatsuo Ishii) - + - + - pool_config_vatiable.cから「定義されたが未使用の関数」という警告を削除しました。(Muhammad Usama) + + 各種のv2プロトコルのバグを修正しました。(Tatsuo Ishii) - + - + - 古いdebug_level設定パラメーターの参照を削除しました。(Muhammad Usama) + + の変更がリロードによって反映されない不具合を修正しました。 + (bug 548) (Takuma Hoshiai) - + - + - Watchdogのソースコードのミスを修正し、いくつかのdebugメッセージを追加しました。(Muhammad Usama) + + 特定の場合にPgpool-IIのシャットダウンが失敗する不具合を修正しました。(Tatsuo Ishii) - + - + - pool_hba.confファイルをリロード時に発生するエラーを修正しました。(Bug 299) (Muhammad Usama) + + 切り離されたスタンバイノードがlifecheckによって再発見されたときに、マスターウォッチドッグノードに再参加できるように修正しました。 + (bug 545) (Muhammad Usama) - + - + - 英語/日本語のドキュメントにpgpool_adm extensionに関する情報を追加しました。(Tatsuo Ishii) + + 名前付きステートメントをDEALLOCATEした後に、誤ったクエリを実行すると + セグメンテーション違反が発生する不具合を修正しました。 + (bug 546) (Tatsuo Ishii) - + - + - ドキュメントを改善しました。(Tatsuo Ishii) + + Doc: クォーラムが存在しない場合、VIPは起動されないことをドキュメントに追加しました。(Tatsuo Ishii) - + - + - watchdog 使用時に Pgpool-II 間でバックエンドの状態が一致しない不具合を修正しました。 - (Bug 289) (Muhammad Usama) + + パラメータのデフォルト値にネットワークインターフェイスオプション -I を含めるように修正しました。(Bo Peng) - + + + + - + + + リリース 3.6.18 + + + リリース日 + 2019-08-15 + + + + + 改善点 + + - Watchdogによるスプリットブレインシナリオの処理を強化しました。(Muhammad Usama) + + PostgreSQLからメモリマネージャデバッグ機能の一部をインポートしました。(Tatsuo Ishii) + + + - - watchdogクラスタを使用しmaster/coordinatorノードの再選出が呼び出されていました。その結果、すべてのノードがウォッチドッグネットワークに再結合する必要がありました。これはwatchdogクラスタ全体の再起動と本質的に同じでした。 + + PostgreSQL 12に対応するために、pg_attrdef.adsrcのかわりに + pg_get_expr()を使用するように修正しました。(Bo Peng) + + + - 今回の修正では、master/coordinatorノードの候補は、次の基準で選択されるようになりました。 + + のshutdownスクリプトを改良しました。(Tatsuo Ishii) + + + + + shutdownスクリプトがPgpool-IIのシャットダウン完了を待つように修正しました。 + + + + + + 環境変数CHECK_TIME_WAITtrueに設定されているとき、shutdownスクリプト実行時にnetstatコマンドでTCP/IPポートの使用を確認するように修正しました。 + + + + + + - (1) 2つのウォッチドッグノードがクラスタマスターであると主張している場合、エスカレーションを実行したマスターノードはマスター状態を保持し、他のノードはステップダウンするように要求されます。 + + Doc: のドキュメントにpool_passwdハッシュ文字列を表示させる方法を追加しました。(Tatsuo Ishii) + + + + - (2) 競合がノードのエスカレーション状況によって解決できない場合、クォーラムを保持するノードはマスター/コーディネータのままです。 + + Doc: フェイルオーバに関する一般的な説明を追加しました。(Tatsuo Ishii) + + + - (3) 両方の候補のクォーラムステータスが同じ場合、接続されたアライブノードの数が多いノードが優先されます。 + + pgpool_adm拡張がPostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) + + + + + + + 不具合修正 + + + + + - (4) 最後に、上記3つでマスターノードを選出できなかった場合、古いマスター(長期間コーディネーターステータスを持つノード) はマスターのままです。 + + "unable to bind. cannot get parse message"エラーを修正しました。 + (bug 531) (Tatsuo Ishii) - + - + - 複数の並行コマンドを処理するためにwatchdog内部コマンドのメカニズムを強化しました。(Muhammad Usama) + + ネイティブレプリケーションモードかつWatchdogが有効な場合、 + 子プロセスが異常終了した後に、オンラインリカバリが失敗する不具合を修正しました。 + (bug 483) (Muhammad Usama) - + - + - コンパイラ時の警告を修正しました。(Tatsuo Ishii) + + コマンドのmodeオプションが正しく動作するように修正しました。(Takuma Hoshiai) - + - + - リグレッションの失敗を防ぐために、サポートされていないJavaメソッドを新しいJDBCドライバでコメントアウトしました。(Tatsu Ishii) + + が正しいfollow master commandを生成するように修正しました。(Tatsuo Ishii) - + - + - parse_before_bind() のログメッセージを debug1 にダウングレードしました。(Tatsuo Ishii) + + クエリキャッシュモジュールでoid配列の境界をチェックするように修正しました。(Tatsuo Ishii) - + - + - coverity警告を修正しました。(Muhammad Usama, Tatsuo Ishii) + + クエリキャッシュモジュールのOff-by-oneエラーを修正しました。(Tatsuo Ishii) - + - + - [pgpool-general: 5396] - pam ldapが失敗する不具合を修正しました。(Muhammad Usama) + + ヘルスチェックプロセスでpgpool.confがリロードされない不具合を修正しました。(Tatsuo Ishii) - + - + - 拡張クエリモードでSQL型コマンドが使用できないことをドキュメントに追加しました。(Tatsuo Ishii) + + クエリキャッシュが有効な場合に発生するセグメンテーション違反を修正しました。(bug 525) (Tatsuo Ishii) - + - + - SHOWコマンドを読み込みクエリの一つとして認識するようにしました。(Tatsuo Ishii) + + LOG "checking zapping sent message ..."をDEBUG5にダウングレードしました。(Tatsuo Ishii) - ストリーミングレプリケーションモードでは、SHOWが発行されるとその後のSELECTは明示的なトランザクションでプライマリノードに送信されていました。この制限は不適切でした。また、parseコマンドがエラーを返すときに発生するハングアップを修正しました。 + + 詳細は[pgpool-general: 6620]をご参照ください。 - + - + - コミットadcb636によって引き起こされたメモリリークの問題を修正しました。(Tatsuo Ishii) + + pool_hba.confsamenetが指定されている場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - Commit adcb636では"pending message queue"を導入しました。メッセージを受信すると、情報がキューに追加され、オブジェクトのコピーが同時に作成されますが、オブジェクトを解放するのを忘れてしまいました。 - - - 今回の修正では、新しい関数pool_pending_message_free_pending_message()を作成し、pool_pending_message_add()pool_pending_message_get()およびpool_pending_message_pull_out()の後に呼び出すように修正しました。 + + 詳細は[pgpool-general: 6601]をご参照ください。 - + - + - ストリーミングレプリケーションモードで「kind mismatch」(またはそれに関連する)エラーが修正されました。 - (Bug 271) (Tatsuo Ishii) + + Doc: ドキュメントのタイポを修正しました。(Bo Peng) + + + + - このエラー原因はデータベースノードがPgpool-IIに送る応答の予測が誤っていたことです。以前使用した「sync map」の実装は弱く、予測に失敗することがありました。今回の修正では、送信されたすべてのメッセージをバックエンドに記録する"pending message queue"を導入しました。このキューの要素には、メッセージのタイプ(parse/bind/execute/describe/close/sync)、メッセージが送信されたデータベースノードの情報などが格納されます。これは単純なFIFOキューです。バックエンドからメッセージが到着すると、"pending message queue"の先頭を見れば、受信したメッセージの種類やデータベースノードを確実に予測できます。 メッセージを受信した後、この要素はキューから削除されます。 + + ネイティブレプリケーションモードの場合、standard_conforming_stringsの設定に応じてバックスラッシュを処理するように修正しました。 + (bug 467) (Bo Peng) + + + + - 一連のパッチをテストしてくれたSergey Kimさんに感謝します。 + + FreeBSD上で発生するコンパイルエラーを修正しました。 + (bug 512, + bug 519) (Bo Peng) + + + + - 詳細は Bug 271、 - [pgpool-hackers: 2043] と - [pgpool-hackers: 2140] をご参照下さい。 + + いくつかのメモリリークを修正しました。(Tatsuo Ishii) - + - + - [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 - (Bug 296) (Muhammad Usama) + + 潜在的なセグメンテーション違反を回避するために、フェイルオーバ実行中であるかどうかのチェックをより積極的に行うように修正しました。(Tatsuo Ishii) - - - - - + + + - - リリース 3.6.2 - - - リリース日 - 2017-03-17 - - - - 不具合修正 - - + + + リリース 3.6.17 + + + リリース日 + 2019-05-16 + - + + + 改善点 + + - pgpool.serviceファイルに"Wants=network.target"を追加しました。 - (bug 294) (Bo Peng) + + Doc: ドキュメントリファレンスII, PCP コマンドを改善しました。(Tatsuo Ishii) - + - + - pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) - - -失敗したときのエラーメッセージは以下のとおりです。 + + すべてのバックエンドが停止しているときのフェイルオーバをスピードアップします。(Tatsuo Ishii) - - - FATAL: invalid pgpool mode for process recovery request - DETAIL: specified node is already primary node, can't promote node id 0 - - -ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 + + すべてのバックエンドが停止状態になった場合、search_primary_node_timeoutの値に関わらずプライマリノードの検索を中止し、 + 直ちにフェールオーバプロセスを終了するように修正しました。 - -この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 -失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 + + ディスカッション: [pgpool-hackers: 3321] + + + -これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 + + pgpool-recovery拡張とpgpool_setupを次期バージョンであるPostgreSQL12に対応しました。(Tatsuo Ishii) - + + + + + + Doc: ドキュメントのの項目を追加しました。(Takuma Hoshiai) + + + + - + + + 不具合修正 + + -Pgpool-IIのドキュメントを修正しました。(Tatsuo Ishii, Bo Peng) + + すべてのバックエンドがダウンした場合には表示される不適切なエラーメッセージ"ERROR: connection cache is full"を修正しました。 + (bug 487) (Bo Peng) - + + すべてのバックエンドがダウンした場合に、Pgpool-IIが不適切なエラーメッセージ"ERROR: connection cache is full"を投げています。 + このエラーを"all backend nodes are down, pgpool requires at least one valid node"に修正しました。 + + + + + + + 使用されていない.sgmlファイルを削除しました。(Takuma Hoshiai) - + - + -Pgpool-IIがVIPを解除した後にpingテストを続けている不具合を修正しました。(Muhammad Usama) + + pool_worker_childプロセスの終了/フォークの繰り返しを避けるために修正しました。(Tatsuo Ishii) -[pgpool-hackers: 1611] により報告されました。 + + pool_worker_childはdo_query()を使用してWAL位置を取得するためのクエリを発行します。 + これにより、致命的エラーが発生した場合、pool_worker_childプロセスを終了し、 + Pgpool-IIの親プロセスは直ちに新しいプロセスをフォークするようにしています。 + このサイクルは無限に繰り返され、システムに大きな負荷を与える可能性があります。 + 無限に繰り返される終了/フォーク処理を回避するために、sr_check_periodをスリープさせるように修正しました。 - + - + -特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。(bug 272) (Tatsuo Ishii) + + のデフォル値が間違っていた不具合を修正しました。(Tatsuo Ishii) - + - + -pg_terminate_backend関数を実行するときに発生する不具合を修正しました。(Muhammad Usama) + + 「not enough space in buffer」エラーを修正しました。 + (bug 499) (Tatsuo Ishii) -[pgpool-general: 5315]により報告されました。 + + バックエンドから返されたエラーメッセージサイズが固定バッファサイズ (8192 bytes)を超えた場合、 + 「not enough space in buffer」エラーが発生していました。 + 固定サイズのバッファの使用を廃止し、動的にバッファサイズを割り当てるように修正しました。 - + - + -ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) + + DROP DATABASEの失敗を修正しました。 (Tatsuo Ishii) - + - + -pcp_attach_nodeを実行するときのセグメンテーション違反を修正しました。(bug 281)(Muhammad Usama) + + read_status_file()関数の間違った変数名を修正しました。 + (bug 493) (Takuma Hoshiai) - + - + -ストリーミングレプリケーションモードでロードバランスのバグを修正しました。(Tatsuo Ishii) + + 漏れていたtest/watchdog_setupをEXTRA_DISTに追加しました。(bug 470) (Bo Peng) + + + + -明示的なトランザクションでは、書き込みクエリが送信されるまで、SELECTはロードバランスされます。書込みクエリが送信された後、SELECTがプライマリノードに送信されます。しかし、syncメッセージが送信される前にSELECTが送信された場合、これは正しく動作しませんでした。 + + Doc: マルチステートメントクエリはプライマリノードにのみ送信されるという説明をドキュメントに追加しました。(bug 492) (Tatsuo Ishii) + + + + -書き込みクエリが実行されると書き込みクエリの処理が行われるように修正しました。 + + failover/failback実行中に接続があった場合に発生しうるセグメンテーション違反を回避するために、セッションを終了するように修正しました。 + (bug 481, + bug 482) (Tatsuo Ishii) - + - + -ストリーミングレプリケーションモードでのkind mismatchエラーを修正しました。(Tatsuo Ishii) + + コンパイル時に発生するワーニング を修正しました。(Tatsuo Ishii) - + - + -closeメッセージの後にdo_query()がハングする問題を修正しました。(Tatsuo Ishii) + + 拡張問い合わせかつ"batch"モードで発生するメモリリークを修正しました。 + (bug 468) (Tatsuo Ishii) - + + + + + + + + リリース 3.6.16 + + + リリース日 + 2019-03-29 + - + + + 改善点 + + -wd_get_cmd関数のバッファオーバーフローを修正しました。(bug 280)(Muhammad Usama) + + 新しい設定パラメータを追加しました。(Muhammad Usama) + + + + ユーザがサーバ側のSSL暗号設定をクライアントに優先して使うかどうかを設定できるように、新しい設定パラメータを追加しました。 + + + + この設定はデフォルトでオフで、従来と同じようにクライアント側のリクエストが優先されます。 + しかしこれはあくまで過去の挙動との互換性のための設定であり、悪意のあるクライアントが弱い暗号を利用できる可能性があります。 + ですから、常にこのパラメータをオンにしておくことを推奨します。 - + - + -watchdogプロセスを再起動する時の不具合を修正しました。(Muhammad Usama) + + client cipher リストの設定が可能になりました。(Tatsuo Ishii, Yugo Nagata) -watchdogプロセスが何らかの問題(例えばセグメンテーションフォルト)によって異常終了した場合、新たに生成されたwatchdogプロセスの起動が失敗し、"bind on ... failed with reason: Address already in use"とのエラーを返しました。 + + Pgpool-IIがクライアントからのSSL接続を受け付ける際に受け入れる暗号のリストを指定する新しいパラメータ、 + を追加しました。これはすでにPostgreSQLに実装されていて、 + SSLが有効なときにセキュリティを強化するのに役立ちます。 + + + + + + 不具合修正 + + + + + + 不要なpgpool_statusファイルへの書き込みが減らしました。(Tatsuo Ishii) + + + + 今まではPostgreSQLバックエンドへの新しい接続が作成されるたびに、 + pgpool_statusファイルに書き込むためにfsync()が実行されていましたが、 + これにより、特定の条件で過剰なI/Oを発生させる可能性がありました。 + そのため、バックエンドの状況が変更されたときにのみfsync()を実行するように修正しました。 + -理由は、異常終了したwatchdogプロセスはIPCに使用するソケットをクリーンアップする時間がなかったからです。 + + ディスカッション: [pgpool-general: 6436] + + + + + + + + リリース 3.6.15 + + + リリース日 + 2019-02-21 + + + + 不具合修正 + + + -この不具合を修正するために、Pgpoolのメインプロセスは、watchdogプロセスが異常終了したときに共有メモリにフラグを設定するように修正しました。 -watchdogプロセスが再起動されるとき、フラグがセットされたら、ソケットファイルをクリーンアップするようにしました。 + + Test: レグレッションテスト068.memqcache_bugの古いJDBCの関数及びタイポを修正しました。(Takuma Hoshiai) - + - + -特定の条件下で、ストリーミングレプリケーションモードでクエリキャッシュが有効な場合、SELECTがハングアップする不具合を修正しました。(Tatsuo Ishii) + + Doc: パラメータはサーバ起動時にのみ設定可能なことをドキュメントに追加しました。(Tatsuo Ishii) + + + + - pgpool-general-jp:1441により報告されました。 + + 特定の場合に、によって、オンラインリカバリが失敗する不具合を修正しました。(bug 431)(Tatsuo Ishii) - + - + -シグナルハンドラがelog/ereportを呼び出さないように修正しました。(Tatsuo Ishii) + + strip_quote()が空のクエリを処理するときに発生するセグメンテーション違反を修正しました。(bug 458) (Tatsuo Ishii) + + + + -詳しくは[pgpool-hackers: 1950]をご参照ください。 + + Doc: white/black_function_list 設定パラメータでスキーマ修飾が使えないという説明を追加しました。(Tatsuo Ishii) - + - + -FreeBSDでlisten_addresses = '*'の場合、INETドメインソケットが作成できない不具合を修正しました。(bug 202)(Bo Peng) + + watchdog_setupスクリプトのに関するタイポを修正しました。(Takuma Hoshiai) - + - + -特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。(bug 249)(Muhammad Usama) + + 接続を確立しようとするとき、フェイルオーバが発生する場合に発生しうるセグメンテーション違反を修正しました。(Tatsuo Ishii) + + 参照: [pgpool-hackers: 3214] + + + + -WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 + + Doc: logdirに関するドキュメントのタイポを修正しました。(bug 453)(Tatsuo Ishii) - + - + -authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) + + クライアントがsyncメッセージの後、次の簡易問い合わせの前にcloseメッセージを送ると発生しうるハングアップを修正しました。(Tatsuo Ishii) + + + 参照: [pgpool-hackers: 3164] - + - + + + + PostgreSQLidle_in_transaction_session_timeoutが有効な場合に発生しうるPgpool-IIのハングアップを修正しました。(bug 448)(Tatsuo Ishii) + + + + -クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) + + Doc: 日本語ドキュメントのタイポを修正しました。(Bo Peng) - + + + + - + + + リリース 3.6.14 + + + リリース日 + 2018-11-22 + - + + + 不具合修正 + + + + + + クライアントから送信された startup パケットのパラメータをソートするように修正します。 + (bug 444)(Takuma Hoshiai) + + + + キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 + コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + + + + + + + + ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 + (bug 443) (Bo Peng) + + + + パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 + bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 + これによりセグメンテーション違反が発生していました。 + + + + パッチがYugo Nagataにより提供されました。 + + + + + + + + スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + リリース 3.6.13 - - - リリース 3.6.1 + リリース日 + 2018-10-31 + - - リリース日 - 2016-12-26 - - - + + 変更点 + + + - 不具合修正 - - + + + フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) + + - - - + -watchdog のセキュリティを強化しました。(Muhammad Usama) + + + LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) + - + -wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 - - + + + Doc: オンラインリカバリのドキュメントに注意事項を追加しました。 + + + + よりも小さな値でなければなりません。 + + - - - - -Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) - - + + + Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) + + - - - + -クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) - - + + + Doc: フェールオーバスクリプトに関する注意事項を追加しました。 + + + + failover/failbackスクリプトの中でPgpool-II自体にアクセスすることはお勧めしません。 + + - - - + -拡張プロトコルにおいて発生しうるkind mismatchエラーを修正しました。(bug 231) (Tatsuo Ishii) - - - -bug 231によると、以下の条件がすべて満たされていると、このバグが発生する可能性がありました。 - - - - - -ストリーミングレプリケーションモード - - - - - - ロードバランスノードがnode 0ではない - - - - - -拡張プロトコルを使用している - - - - - -SELECTが実行され、ステートメントがクローズされた後、トランザクションコマンドが実行されている - - - - + + + Doc: のドキュメント及びエラーメッセージを改善しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供され、Bo Pengにより修正されました。 + + + + -問題の発生順序: - - - - -ロードバランスノード1でステートメントS1のSELECTが実行されます。 - - - - - -フロントエンドがクローズステートメントを送ります。 - - - - - -Pgpool-IIはそれをバックエンド1に転送します。 - - - - - -フロントエンドは、COMMITのParse、Bind、Executeを送信します。 - - - - - -Pgpool-IIはそれをバックエンド0と1に転送します。 - - - - - -フロントエンドが同期メッセージを送信します。 - - - - - -Pgpool-IIはそれをバックエンド0と1に転送します。 - - - - - -バックエンド0はParse complete( "1")を返しますが、バックエンド1は#3によりclose complete( "3")を返します。 - - - - - -Kind mismatch が発生します。 - - - + + + Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 + + + + - - - -解決策は、#3では、Pgpool-IIがバックエンド1からの応答を待つようにしますが、応答メッセージは読み取らないようにします。 その後、Pgpool-IIの状態マシンは、#6で同期メッセージが送信される前に、その応答を読み込みます。 これによりバックエンド1は#8で "1"を返信し、kind mismatchエラーは発生しなくなります。 - - - -また、Closeメッセージを受け取ったときにpool_set_doing_extended_query_message()が呼び出されない不具合を修正しました。 - - + + + 不具合修正 + + -新しいリグレッションテスト "067.bug231"を追加しました。 - - + 2018-10-25 [f043360] + --> + + + SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) + + + + パッチはPhil Ramirezにより提供されました。 + + - - - + -シグナルハンドラでの競合状態を修正しました。(bug 265) (Tatsuo Ishii) - - - -child.cには、elogを呼び出すシグナルハンドラがあります。 シグナルハンドラは処理中に他のシグナルに対してブロックされないため、pgpoolのシャットダウンシーケンスでシステムコールにデッドロックが発生する可能性がありました。 この問題を解決するために、シグナルハンドラはPOOL_SETMASKを使用してブロックされるように修正されました。 - - - -理想的にはシグナルハンドラでelogを呼び出すことを避けるべきです。 - - + + + ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 + (bug 434) (Takuma Hoshiai) + + + + ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 + + - - - + -誤ったclient_idle_limit_in_recoveryの最小設定値を修正しました。(bug 264) (Tatsuo Ishii) - - + + + ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) + + + + ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 + タイムスタンプ型の定数に書き換えるようになっています。 + しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 + + - - - + -doc.jaの下で "make xslthtml"を実行できるように修正しました。(Tatsuo Ishii) - - - - - - - - - - - - - - - - - - リリース 3.6 - - - Release Date - 2016-11-21 - - - - - 概要 - - - Pgpool-II 3.6 の主な改善点は以下のとおりです。 + + 拡張問い合わせの場合、時々期待される応答がフロントエンドに返されないことがあったので、修正しました。 + (bug 432) (Tatsuo Ishii) + + + 解決策は、保留中のメッセージデータリストを使用することです。それはフロントエンドからのメッセージを記録し、同じ数のメッセージを受け取ることが期待されます。 + + + + パッチは Yugo Nagata によって作成され、Tatsuo Ishii により修正されました。 + + - - - - - + - - failover の挙動が改善されました。 - - - Streaming Replicationモードで、フェイルオーバーが発生した時に、ダウンしたスタンバイサーバを利用しなければ、クライアントセッションが切断されなくなります。 - プライマリサーバがダウンした場合、すべてのセッションが切断されます。 - また、ヘルスチェックのリトライの最中でも Pgpool-IIに接続することが可能です。 -Pgpool-IIへの接続リトライする最大回数までヘルスチェックのリトライが続きます。 - - + 2018-10-11 [4d6371a] + --> + + + ストリーミングレプリケーションモードかつ拡張問い合わせの場合、クエリキャッシュを有効にするときに発生するメモリリークを修正しました。(Tatsuo Ishii) + + - - + - 新しいコマンド PGPOOL SET が追加されました。 - このコマンドを使用することで、現行セッション内で設定パラメータを変更することができるようになりました。 - - + 2018-10-11 [88f63b0] + --> + + + trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) + + - - + -Watchdogが大幅に改善されました。 -以前のバージョンよりも信頼性が向上しています。 - - + 2018-10-09 [eee60a0] + --> + + + ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) + + + + 明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 + テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 + + - - + -問合せから大量の行が返される場合、ストリーミングレプリケーション時の拡張問い合わせプロトコル(例えば、Java アプリケーションで使用される場合)の処理速度が改善されました。 - - + 2018-10-09 [6406b3b] + --> + + + 時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) + + - - + - PostgreSQL 9.6 のパーサを取り込みました。 - - + 2018-09-21 [3a56b21] + --> + + + Test: EXECUTE/DEALLOCATEのレグレッションテストを追加しました。(Takuma Hoshiai) + + - - + -特定の場合にpg_terminate_backend()がフェイルオーバを起こさないようになりました。 - - + 2018-09-19 [e3cd328] + --> + + + pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) + + - - + - ドキュメントの形式が HTML から SGML に変更されました。 - - - - - + 2018-09-13 [4bdf973] + --> - - 上記の項目は以下のセクションで詳しく説明します。 + + DEALLOCATEステートメントが発行された場合に発生するkind mismatchエラーを修正しました。(Bo Peng) + + + EXECUTEDEALLOCATEPREPAREと同じノードに送信されるために、PREPAREをpool_add_sent_messageに追加するように修正しました。 + + + + 詳細は[pgpool-general: 6226]を参照してください。 + + - - - - - 主な改善点 - - + + + パスワードの長さが正しくない場合、を更新しないように修正しました。 + (bug 419) (Takuma Hoshiai, Tatsuo Ishii) + + + + Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 + ファイルのパスワードの長さをチェックするように修正しました。 + + - - - + - failover の挙動が改善されました。(Tatsuo Ishii) - - - - Streaming Replication モードで、フェイルオーバーが発生した時に、ダウンしたスタンバイサーバがそのセッションで使用されていなければ、クライアントセッションが切断されなくなりました。 -プライマリサーバがダウンした場合は、すべてのセッションが切断されます。 -ヘルスチェックタイムアウトした場合でも、すべてのセッションが切断されます。 -リトライ最大回数を超えた場合を含めて、他のヘルスチェックエラーではすべてのセッションは切断されません。 - + + + Doc: ドキュメントの"new master"を"new primary"に変更しました。(Bo Peng) + + - + -failover が発生する場合にローカル負荷分散ノードの情報が重要なので、show pool_nodes コマンドで、ローカル負荷分散ノードの情報が利用者の便宜のために表示されるようになりました。 -負荷分散ノードがダウンしたノードではない場合、フェイルオーバーによる影響はありません。 - + 2018-08-16 [c7990a9] + --> + + + gccの新しいバージョンで発生するwarningを修正しました。(Tatsuo Ishii) + + - + - また、ヘルスチェックのリトライの最中でも Pgpool-II に接続できるようになりました。 -以前は、がオフの場合でもPgpool-IIへの接続は、ヘルスチェックのリトライをしている間はすべて失敗していました。 -これは、Pgpool-IIの子プロセスがまず失敗したバックエンドを含めてすべてのバックエンドへの接続を試み、失敗した場合終了するためです(これはもちろん失敗します)。 -これは一時的な状況であり、Pgpool-IIがフェールオーバーを行えば解決します。 -しかし、ヘルスチェックの再試行が行っている場合は、この一時的な状況は - の設定次第で長時間続きます。 -この状況は良くないので、以下のように修正しました。 + 2018-08-10 [58db070] + --> + + + Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 + + - - + -ストリーミングレプリケーションモードにおいて、バックエンドへの接続に失敗したら、そのダウンしたノードがプライマリではなければ、このバックエンドへの接続をあきらめて、他のノードへの接続を試みます。 - - - -ローカルノードのステータスを"down"と記録します。 -これによりプライマリーノードがロードバランスノードとして選択され、すべてのクエリがプライマリーノードへ転送されます。 -他にスタンバイのノードが存在する場合、その中からロードバランスノードが選択されます。 - - - -セッションが終了した後、ローカルの状態を保持しないように子プロセスは自殺します。 - - - - - - - - PGPOOL - SHOW, PGPOOL - SET と - PGPOOL RESET - コマンドが追加されました。 (Muhammad Usama) - - - -これはPgpool-IIに現在のセッションの設定パラメータを設定またはリセットする機能を追加するという点でPostgreSQLのSET、SHOW、RESETコマンドと似ていますが、PostgreSQLのSET、RESETコマンドコマンドと区別するために、PGPOOLというキーワードが前に挿入してあります。 - - - - 現在 PGPOOL SHOW/SET/RESET に対応している設定パラメータは以下です。 - , , - , , - , , - , , - . - - - - - - - -Pgpool-II再起動後、PostgreSQLノードの状態の不整合がある場合、これを同期するようにしました。(bug 218) (Muhammad Usama) - - - - watchdog がバックエンドノードを同期させなかったのが原因でした。 - - + + + .gitignoreファイルを追加しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 + + - - - + -多くの行が出力されるSELECTの性能を改善しました。(Tatsuo Ishii) - - - -Pgpool-II がフロントエンドに行データ("Data Row"メッセージ)を送るたびにネットワークにデータを(write(2)を呼び出して)フラッシュしていました。 -例えば、10,000行を転送する必要がある場合、write()が10,000 回呼び出されます。 -これは非常にコストが高いです。 -繰り返し行データを送信した後、"Command Complete"メッセージが送られるので、Command Completeメッセージの時に併せてwrite()を発行すれば十分です。 -また、command completeメッセージの取り扱いにおいて、不必要なフラッシュがありました。 - - - -Quick testingのテスト結果から、この修正により、特定の場合で、47%から62%の性能向上が得られたことが分かりました。 - - - -しかし、問い合わせが返す行が少ない場合は、まだ改善されていません。 -そうした行はいずれにせよネットワークへのフラッシュが必要だからです。 - - + + + ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + - - - + - PostgreSQL 9.6's のパーサを取り込みました。 (Bo Peng) - - - - これにより、Pgpool-IIPostgreSQL - 9.6 で導入された新しい構文 (COPY INSERT/UPDATE/DELETE ... RETURNING など) を理解可能です。 - - + + + Doc: ドキュメントとスクリプトのタイポを修正しました。(Tatsuo Ishii) + + + + パッチはJesper Pedersenにより提供されました。 + + - - - + -ある場合では、pg_terminate_backend() 関数が failover を引き起さないようになりました。(Muhammad Usama) - + 2018-08-01 [861d535] + --> -pg_terminate_backend()でバックエンドを終了させた場合、 -PostgreSQLがpostmasterをシャットダウンしたときと同じメッセージを返しますので、 -ユーザが望まないかもしれないフェールオーバーを発生させます。 - - -これを修正するために、Pgpool-IIは、 -pg_terminate_backend()の対象バックエンドのPIDを検出し、フェールオーバーを発生させません。 - - -この修正は単純なプロトコルの場合、またはpg_terminate_backend() -に渡されたPIDが定数の場合にのみ適用します。 -拡張プロトコル(Javaなど)の場合、pg_terminate_backend()はフェールオーバーを起こします。 - - - - - - - -HTMLドキュメントが、SGMLドキュメントから生成されるようになりました。(Muhammad Usama, Tatsuo Ishii, Bo Peng) - - - -これはより良い構成、内容、保守の容易性をもたらすためです。 -また、manページがSGMLから生成されるようになりました。 -しかし、SGMLドキュメントにはまだたくさんの改良の余地があります。 -どうか私達を助けてください! - - + + Doc: のドキュメントの誤りを修正しました。 + + + + + - - + + + リリース 3.6.12 - + - 他の改善点 - - + Release Date + --> + リリース日 + 2018-07-31 + - - + + 不具合修正 + - + - 認証エラーメッセージをわかりやすくしました。 (Tatsuo Ishii) - - - -バックエンドに接続する時に(ヘルスチェックを含む)、"invalid authentication message response type, Expecting 'R' and received '%c'" メッセージではなく"sorry, too many clients already"のようなメッセージを返すようにしました。 - - + + + 「write on backend 0 failed with error :"Success"」エラーを修正しました。 + (bug 403) (Tatsuo Ishii) + + + write() が 0 を返した場合、エラーとして扱わないように修正しました。 + + - - - + - pool_check_fd()のヘルスチェックタイマーの期限切れ条件を強化しました。(Muhammad Usama) - - + + + フェイルオーバ後、スタンバイ Pgpool-II で worker プロセスが起動されない不具合を修正しました。 + (bug 409) (Muhammad Usama) + + + + 修正パッチは Yugo Nagataによって提供されました。 + + - - - - - 新しいスクリプト "watchdog_setup" が追加されました。 (Tatstuo Ishii) - - + - は watchdog 機能を有効にしたPgpool-IIクラスタのテスト環境を構築するコマンドです。 - - + 2018-06-20 [9956328] + --> + + + pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) + + - - - - - pgpool_setup に "pg" オプションが追加されました。(Tatsuo Ishii) - - + -これはを使用する時に、PostgreSQLに特定のポート番号を割り当てたい場合に便利です。 -また、pgpool と同じように、pgpool_setupは標準binディレクトリにインストールされるようになりました。 - - + 2018-06-19 [8aadbd3] + --> + + + pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。(Tatsuo Ishii) + + + + これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 + + - - - - - show pool_nodes の出力結果に replication delay カラムが追加されました。(Tatsuo Ishii) - - + - streaming replication モードの場合、 - このカラムは replication delay の値を bytes 単位で表示します。 - - + 2018-06-19 [ff2260f] + --> + + + armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 修正パッチは Christian Ehrhardt によって提供されました。 + + - - - + - すべてのノードがダウンした場合、 status ファイルを更新しないように変更されました。(Chris Pacejo, Tatsuo Ishii) - - - -レプリケーションモードにおいて、すべてのノードがダウン状態の場合にstatusファイルに記録しないようにすることで、[pgpool-general:3918] で報告されたデータの不整合を修正しました。 -この驚ほど単純ですが、スマートな解決方法はChris Pacejoにより提供されました。 - - + + + Doc:「クライアント認証」、「Pgpool-II のインストール」、「pg_md5」などのドキュメントを改善しました。(Bo Peng) + + + + 修正パッチは Takuma Hoshiai によって提供されました。 + + - - - + - Pgpool-II が 複数 SSL cipher protocols に対応できるように修正しました。(Muhammad Usama) - - - -SSLセッションを初期化する際の処理でTLSv1_method()をSSLv23_method()で置き換えることにより、TLSv1プロトコルよりも多くのプロトコルを使うことができるようになりました。 - - + + + Test: テスト006.memqcache の失敗を修正しました。( Tatsuo Ishii) + + + + + - - - + + + リリース 3.6.11 + + + + リリース日 + 2018-06-12 + + + + 不具合修正 + + - black_function_list/white_function_list - に任意のアイテムの数が使用できるようになりました。(Muhammad Usama) - - - - これまで、このアイテムの数には固定の上限がありました。 - - + + + 拡張問合せ、かつクエリキャッシュが有効の場合、レプリケーション遅延が大きすぎるときに発生しうる Pgpool-II のハングアップを修正しました。(Tatsuo Ishii) + + + + 詳細は [pgpool-general-jp: 1534] + を参考してください。 + + - - - + - コメントのみを含む空クエリを適切に処理できるよう修正しました。(Tatsuo Ishii) - - + + + Doc: PCP コマンドの "-U" オプションのタイポを修正しました。 (Bo Peng) + + + + -この修正で、Pgpool-II"/* DBD::Pg ping test v3.5.3 */" (';' を含まないことに注意)のような空クエリを正しく識別できるようになりました。 - - + 2018-05-24 [75348b5] + --> + + + デバッグ用コードを削除しました。(Bo Peng) + + + + - これまではエラークエリとして処理していました。 - - + 2018-05-24 [b28ae33] + --> + + + 拡張問合せでは、SET TRANSACTION READ ONLY の場合、書き込みトランザクションフラグを立てないように修正しました。 (Tatsuo Ishii) + + - - - + - wd_authkey ハッシュ計算失敗時に警告メッセージを出力するようにしました。(Yugo Nagata) - - + + + Doc: 古い のドキュメントを修正しました。 (Tatsuo Ishii) + + + + - たまに、認証キー不一致以外の何らかの理由で wd_authkey 計算に失敗することがあります。 - メッセージ出力を追加することでこれらを互いに区別できるようにしました。 - - + 2018-05-04 [5231624] + --> + + + Doc: recovery_2nd_stage_command はネイティブレプリケーションモードのみで設定する必要がある明確な説明をドキュメントに追加しました。(Tatsuo Ishii) + + - + + + + + pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) + + + + これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 + + + + 詳細は + [pgpool-general: 5963] + をご参照してください。 + + + + また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 + + + + + - + + + リリース 3.6.10 - + - 変更点 + Release Date + --> + リリース日 + 2018-04-17 + - + + 不具合修正 + - - - - -log_destination = syslog 設定の不具合を修正しました。(Muhammad Usama) - - - -PGPOOL SET/SHOW コマンド追加の修正によって、ログの出力先がsyslogの場合、不具合がありましたので、修正しました。また、log_destinationパラメータがカンマ区切りで複数出力先を指定することができるようになりました。この修正によって、log_destination は "syslog" と "stderr" の任意の組み合わせに設定できるようになりました。 - - - - - - -のデフォルト値を10から300に変更しました。(Tatstuo Ishii) - - - -これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 - - + + + + + Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + - - - - - src/sql/ 配下の Makefile が修正されました。(Bo Peng) - - - 詳しくは - [pgpool-hackers: 1611] を参照してください。 - + + + + + to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) + + - - - - - - pcp_proc_count コマンドの出力結果のプロセス ID を 6 桁まで表示 できるよう修正しました。(Bo Peng) - - - - 特定の環境において、pcp_proc_count コマンドの出力結果のプロセス ID が6 桁の場合、 - 6 番目の文字が表示されませんでした。 この修正で、プロセス ID が最大 6 桁まで表示するよう変更しました。 - - - - - - - すべてのクエリがプライマリサーバに送信されるように変更しました。(Tatsuo Ishii) - - - - = off の場合でも、一部のクエリがプライマリサーバ以外にも転送されていました。 - この修正で、 streaming replication モードで load_balance_mode = off - の場合はすべてのクエリをプライマリサーバにのみ送るようにしました。 - - - - + + + + + Doc: watchdog に関するドキュメントを更新しました。(Tatsuo Ishii) + + - + + + + + Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + + + + + + + + 「unable to bind D cannot get parse message "S1"」エラーによるハングアップを修正しました。(Tatsuo Ishii) + + + + + + + + Doc: backend_flag を使用してフェイルオーバ回避できるようにする説明をドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + Doc: ドキュメントのタイポを修正しました。(Bo Peng) + + + + + + + + レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + + + + + + + + PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) + + + + + + + + Doc: pgpool_adm エクステンション関数の例を修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 3.6.9 + + + リリース日 + 2018-02-13 + + + + このリリースでは、Pgpool-II 3.7.0、3.6.6、3.5.10 で追加された、ソケット + への書き込み不具合を修正しています。この障害により、ネットワーク負荷が + 高い状態でのフロントエンド、バックエンドへのメッセージ送信の際に、不正 + なメッセージが送信される可能性があります。3.7.x、3.6.6 以降、3.5.10 以降 + のバージョンを利用中のユーザは、できるだけ早くアップグレードすることを + お勧めします。 + + + + + 変更点 + + + - 不具合修正 + + + Pgpool-II が libressl の環境でビルドできるようになりました。(Tatsuo Ishii) + + + 詳細は [pgpool-hackers: 2714] を参照してください。パッチは Sandino Araico Sanchez により提供されました。 + + - - - - - -pool_stream関数の潜在的なクラッシュを修正しました。(Muhammad Usama) - - - -POOL_CONNECTION-> con_infoは、バックエンドソケットで読み取りまたは書き込みが失敗したときに、逆参照する前にヌル値をチェックする必要があります。 - - - - - - -watchdogクラスタでのフェイルオーバーコマンドの転送処理が改善されました。(Muhammad Usama) - - - -これまでは、Pgpool-II ノードの watchdogがすべての接続されたノードにフェイルオーバーコマンド(failover、 failback 及び promote node)を転送していました。多数のノードが含まれているwatchdogクラスタでは、フェールオーバーコマンドが複数のPgpool-IIによって実行されることによって、データの同期問題を引き起こす可能性がありました。このコミットでは、すべてのフェイルオーバーコマンド(failover、 failback 及び promote node)が master/coordinator watchdog に転送され、master/coordinator watchdogはすべてのスタンバイノードに転送するようになりました。 - - - -また、今回の修正では、インターロック機能も変更されました。master/coordinatorノーのみがロックホルダになり、フェイルオーバコマンドはmaster/coordinatorノードでのみ実行されます。 - - - - - - - すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(Tatsuo Ishii) - - - -すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 -その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 -そしてこのコマンドは成功しました。 -しかし、新しい接続が拒否されました。 -これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 -ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 -(ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) -解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 - - - - - - -再起動が必要なパラメータの設定を変更した際のPgpool-II停止が起こらないようにしました。(Muhammad Usama) - - - -この修正のために、設定パラメータの検証機構の順序を逆にしました。 -以前はスタンバイノードがPgpool-IIマスターノードに対して設定パラメータの値を検証し、不整合が見つかった場合にはFATALエラーが出力されていました。 -この修正で、Pgpool-IIマスターノードに検証の役割が移譲されました。 -マスターノードは参加している個々のスタンバイノードの設定値をローカルの設定値と比較し、違っている場合にはエラーではなくてWARNINGメッセージを出力します。 -この方法では、ユーザは、手動でマスターPgpool-IIログの中から不整合ワーニングを見つけて、Pgpool-IIマスターのスイッチオーバが起きたときに驚くようなことが起こらないようにしなければなりません。 - - - - - - - watchdog が有効な場合、 コマンドのロック取得時の処理が改善されました。(Muhammad Usama) - - - - - - - コンパイルエラーを修正するために、configure.ac - ファイルにコンパイルフラグ "-fno-strict-aliasing" が追加されました。(Tatsuo Ishii) - - - - - - - MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) - - - -random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 -random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 - + + + + + PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + + - - - - - - クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) - - - - - - -が空文字の場合、Pgpool-II が起動できない不具合を修正しました。(bug 237) (Muhammad Usama) - - - - TCP listen addresses が空の場合、socket descriptor 配列(fds[])の終了マークがないのが原因でした。 - - - - - - -リグレッションログディレクトリが存在しない場合、作成されるようになりました。(Tatsuo Ishii) - - - - - - - ソケットの操作に失敗したときのエラーメッセージを修正しました。(Muhammad Usama) - - - - - - - show pool_nodes コマンドの修正を反映し、レグレッションテスト 003.failover を変更しました。 - - - - - - - Portal suspend を受け取ったときのハングが修正されました。(bug 230) (Tatsuo Ishii) - - - - - - -ネットワークが復旧した時にIPを降格しない問題を修正しました。(bug 228) (Muhammad Usama) - - - -ローカルノードの状態が調停者状態から他の状態に変わった時に降格させるために、set_state関数が実装されました。 - - - - - - - SIGUSR1 シグナルハンドラーを watchdog の初期化前にインストールするように修正しました。(Muhammad Usama) - - - - watchdog 初期化直後に 他のwatchdog ノードから failover リクエストがあった場合、 - SIGUSR1 シグナルハンドラーのインストールを待っていれば、クラッシュが発生する可能性がありました。 - - - - - - - 他のノードが利用できない場合、Pgpool-II が - IPアドレスをエスカレートしない不具合を修正しました。(bug 215) (Muhammad Usama) - - - - Heartbeat destination が IPアドレスで指定され、wd_hostname が hostname で設定される場合、 - heartbeat receiver が heartbeat sender watchdog ノードを識別できなかったのが原因でした。 - 逆の場合でも同様なエラーが起こります。 - - - - - - - watchdog に関するコーデイングミスを修正しました。(Muhammad Usama) - - - -wd_issue_failover_lock_command()関数は、渡ってきたコマンドタイプをwd_send_failover_sync_command()関数の引数に渡すように想定されていますが、その代わりにNODE_FAILBACK_CMDコマンドタイプを渡していました。 - - - - この修正で、いくつかのログメッセージも改善しました。 - - - - - - - pcp_node_info コマンドの標準出力の「Status」がわかりやすくように変更されました。(Muhammad Usama) + + + + + systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + + - - - - pcp_node_info コマンドの標準出力の「Status」が内部状態コードから人間がわかりやすい状態の文字列に変更されました。 - - - - - - - 「MAJOR」マクロによる発生しうるセグメンテーションフォルトを修正しました。(Tatsuo Ishii) - - - - MAJOR が pool_virtual_master_db_node_id() を呼出し、 - 戻り値 idを使ってbackend->slots[id]->con にアクセスします。 -可能性は低いですが、conが0を指し(DB にアクセスできない場合)、con->major にアクセスし、セグメンテーションフォルトを引き起す可能性がありました。 - - - - - - - "kind mismatch" エラーメッセージの処理について修正しました。(Muhammad Usama) - - - - 多くの"kind mismatch..."エラーは、NOTICE や WARNING メッセージが - DBノードのいくつかで起こることによるものです。 - この修正では、そうしたケースにおいて、"kind mismatch..."エラーを引き起こすのではなく、 - NOTICE や WARNINGメッセージをフロントエンドに送るようになりました。 - これにより、"kind mismatch..."エラーの発生が減少します。 - - - - - - - パラメータの処理の不具合を修正しました。(Muhammad Usama) - - - - - - - シグナルハンドラ中でエラー番号が保存されるようになりました。 (Tatsuo Ishii) - - - - - - - pgpool メインプロセスの wait(2) の扱いを修正しました。(Tatsuo Ishii) - - - -Pgpool-II メインプロセスから呼び出されるwait(2)はそのシステムコール内で永久に待つ可能性があります。 - この修正で、 wait(2) の代わりに、waitpid(2) を使うように変更しました。 - - - - - - - が off の場合、 - read(2) が -1 を返しても - pool_read() がエラーメッセージを発行しない不具合が修正されました。(Tatsuo Ishii) - - - - - - - show pool_nodes でのバッファオーバーランを修正しました。(Tatsuo Ishii) - - - - show pool_nodes を実行時、hostname に割り当てられたバッファが十分ではないのが原因でした。 - pgpool.conf のバッファサイズと同じようにしました。 - - - - - - - - [pgpool-hackers: 1638] で報告された、Pgpool-II - がデフォルトの設定を使用しない不具合が修正されました。(Muhammad Usama) - - - - 設定ファイルが見つからない場合は、 ERROR または FATAL ではなく、WARNING を返すように修正しました。 - - - - - - - 共有メモリ上のロードバランスノードの書き込みに関するバグを修正しました。(Tatsuo Ishii) - - - -2, 3の箇所で、ロードバランスノードが間違ったことろに置かれてしまいました。 - - - [正しい場所] - - -ConnectionInfo *con_info[child id, connection pool_id, backend id].load_balancing_node]. - - - - [実際に置かれた場所] - - -*con_info[child id, connection pool_id, 0].load_balancing_node]. - - - -バックエンド id が 0 の場合、上記バグが発生しませんが、Pgpool-II 3.6 のフェイルオーバーテストで、プライマリノードが 1 (ロードバランスノード)、スタンバイノードが 0 の場合、ノード1 の接続が切断され、フェイルオーバーが起きています。 -これは想定外のことだったのでこのバグが見つかりました。 - - - -このバグはかなり前からありましたが、上記の理由で、今まで見つかっておリませんでした。 - - - - - - -#197 で報告されたpgpoolのハングを修正しました。(bug 197) (Muhammad Usama) - - - -watchdog が有効で、バックエンドノードとリモート Pgpool-IIノードが同時接続できなくなった場合、クライアント接続がスタックします。 - 原因は watchdog に IPC コマンドを送信する関数を呼び出すコマンドタイムアウトがなかったからです。 - - - - - - - ヘルスチェックで発生し得るハングアップを修正しました。(bug 204) (Yugo Nagata) - - - - connect(2) が成功し、 - その後バックエンドからデータが送信されない場合、ヘルスチェックがハングしていました。 -ヘルスチェック中に、select(2)がSIGALRMのためにEINTRで終了した場合、pool_check_fd()が1を返すように修正しました。 - - - - - - - streaming replication モードで、プライマリノードが 0 ではない場合に発生する不具合が修正されました。 (Tatsuo Ishii) - - - -http://www.pgpool.net/mantisbt/view.php?id=194#c837の報告により、bug194-3.3.diff を適用しても、プライマリノードが 0 ではない場合、ステートメントタイムアウトが発生する可能性がありました。 - 調査した結果、MASTER マクロがプライマリノードまたはロードバランスノード - 以外のノードを返したからです。 -そのため、do_query()がクエリを間違ったノードに送信していました(これは報告では明確ではありませんでしが、 調査で確認できました)。 - - - -MASTER マクロから呼ばれるpool_virtual_master_db_node_id() は、クエリコンテキストが存在する場合、query_context->virtual_master_node_id を返します。 -その変数がまだ初期化されていない場合、この関数が間違ったノード を返す可能性があります。 -そのため、pool_virtual_master_db_node_id() 関数を以下のように修正しました。 -変数にプライマリノードもロード バランスノードも設定されていない場合、プライマリノードを返します。 - - - - - - -バックエンドのステートメントタイムアウトが有効で、do_query()がクエリをプライマリノードに送信し、それ以降のユーザクエリがスタンバイノードに送信された場合、次のコマンド、例えば、ENDコマンドが、プライマリノードのステートメントタイムアウトを引き起こし、kind mismatch error が発生する可能性がありました。(bug 194) (Tatsuo Ishii) - - - - この問題を軽減するために、do_query() - がフラッシュメッセージを送信する代わりに、sync メッセージ送信するように修正しました。 -明示的トランザクションのときは、sync メッセージを送信することで、ステートメントタイムアウトタイマーがリセットされます。 -暗黙的なトランザクションでは、このやり方は使えません。 -なぜなら、unnamed portal が存在する場合、sync メッセージが unnamed portalを削除するからです。 - - - -更にこれにより、pg_stat_statement が do_query() が発行したクエリを "running" で表示しなくなります。 - - - - - - - 拡張プロトコルのraw モードでのバグを修正しました。(bug 152) (Tatsuo Ishii) - - - - Bug 152の報告により、拡張プロトコルの raw モード(実は stream モード以外)で - Describe()Close() - の処理に誤りがありました。stream モードとは異なり、バックエンドからの応答を待つべきでした。 - - - - - - - pgpool.conf の不正確なコメントを修正しました。(Tatsuo Ishii) - - - - - - -日本語と中国語ドキュメントのraw モードに関する内容の誤りを修正しました。(Yugo Nagata, Bo Peng) - - - - raw モードでも、コネクションプーリングが有効です。 - - - - - - -is_set_transaction_serializable()関数のSET default_transaction_isolation TO 'serializable'の扱いに関するバグを修正しました。(bug 191) (Bo Peng) - - - - Pgpool-IISET default_transaction_isolation TO 'serializable' - をプライマリだけではなく、スタンバイにも送信してしまい、エラーが起きていました。 - この修正で、streaming replication モードの場合、SET default_transaction_isolation TO 'serializable' - がプライマリサーバのみに送信されます。 - - - - - - - 拡張プロトコルにおける空クエリの場合、発生し得るハングアップを修正しました。(Tatsuo Ishii) - - - -この修正は3.5.1で空のクエリの場合の拡張プロトコルの扱いに関係しています。 -この場合バックエンドはcommand complete messageと同じ意味を持つ"empty query response"を返します。 -問題は、"empty query response"を受信した際に、Pgpool-IIがクエリ進行中フラグをリセットせず、 バックエンドの応答を待ち続けることことです。 -しかし、バックエンドはsyncメッセージをを受け取るまではready for queryメッセージを返しません。 -解決方法は、"empty query response"を受信した際に、クエリ進行中フラグをリセットし、フロントエンドがsync メッセージを送信することを期待してフロントエンドからの応答を待つことです。 - - - - - - - - [pgpool-general: 4569] により報告された - trusted_servers チェック時のセグメンテーションフォルトを修正しました。 (Muhammad Usama) - - - - Pgpool-II 3.4 からは PostgreSQL - のメモリマネージャおよび 例外マネージャ API を流用していますが、 - それはスレッドセーフ ではありません。上位接続を確認するため ping の応答で信頼できるサーバ確認時、 - watchdog lifecheck プロセスでセグメンテ ーションフォルトを引き起こしていました。 - スレッドを削除し、 子プロセスを使うように修正しました。 - - - - - - -PCP パケットの長さを検証するよう修正しました。(Muhammad Usama) - - - - この検証がない場合、非常に巨大なデータサイズのパケットを送信することで、 - 不正な PCP パケットが PCP 子プロセスをクラッシュさせたり、サーバで out of memory を発生させることが可能でした。 - - + + + + + pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + + + + + + + 不具合修正 + + + + + + コミットまたはロールバック時に誤って書き込みトランザクションフラグをセットする不具合を修正しました。 (Tatsuo Ishii) + + + + + + + + Doc: ドキュメントのタイポを修正しました。 (Bo Peng) + + + + + + + + ソケット書き込みの不具合を修正しました。 (Tatsuo Ishii) + + + ネットワーク負荷が高い場合に、フロントエンド、バックエンドへのメッセージ送信の際に、 + 不正なメッセージが送信される可能性があるのを修正しました。 + + + このバグは 3.6.6、3.5.10 がリリースされた際に追加されたものです。 + + + + + + + + デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + + + + + + + + 拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + + + + + + + + + リリース 3.6.8 + + + + リリース日 + 2018-01-09 + + + + 不具合修正 + + + + + + + Doc: ドキュメントのミスとタイポを修正しました。(Bo Peng) + + + + + + + + スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) + + + /bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 + + + + + + + + ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) + + + + ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 + + + + + + + + Doc: 新しいドキュメント「ドキュメントのコンパイルとインストール」を追加しました。(Tatsuo Ishii) + + + + + + + + ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) + + + + PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 + + + + + + + + Doc: のドキュメントを修正しました。 (Tatsuo Ishii) + + + + ロジカルレプリケーションモードにも対応するとの説明を追加しました。 + + + + + + + + 一部のログメッセージをデバッグメッセージにダウングレードしました。(Tatsuo Ishii) + + + + 前回の開発で誤って残していました。 + + + + + + + + バックエンドからのパケットを読み込む際の再同期のロジックを修正しました。(Tatsuo Ishii) + + + + read_kind_from_backend() は、バックエンドからメッセージを読み取り、"ready for query" メッセージが受信されたときにバックエンドノードを再同期します。 + しかし、pool_pending_message_pull_out() を呼び出して「sync メッセージを受信した」を削除することを忘れていました。 + これによって、バックエンドからのパケットの読み取り中に Pgpool-II がハングアップする可能性がありました。 + pool_pending_message_pull_out()を呼び出し、「sync メッセージを受信した」を削除するように修正しました。 + + + + + + + + 問い合わせ中に Pgpool-II がハングアップする不具合を修正しました。(bug 370) (Tatsuo Ishii) + + + + エラークエリがプライマリに送信され、sync メッセージを送信せずに、次のクエリを実行するときに、 + PostgreSQL のシステムカタログへの問い合わせが必要な場合、Pgpool-IIdo_query() 関数でハングアップしていました。 + + + + + + + + Pgpool-II 3.7 以降の上位互換性のために SL_MODE マクロを追加しました。(Tatsuo Ishii) + + + + + + + + "ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) + + + + 今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 + ほとんどの場合、問題がありませんでした。 + ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 + + + + + + + + pgpool 開始メッセージが複数回出力されるのを修正しました。(Tatsuo Ishii) + + + + + + + + 内の start/stop スクリプトの実行権限を追加しました。(Tatsuo Ishii) + + + + + + + + リリース 3.6.7 + + + リリース日 + 2017-11-01 + + + + 不具合修正 + + + + + + /etc/sysconfig/pgpool を RHEL6 と RHEL7 向けに分け、RHEL6 では起動時に "-n" オプションを指定するようにしました。(bug 343) (Bo Peng) + + + + RHEL6 では、起動時のログが出力されなくなったとの報告がありました。 + + + + + + + + pg_terminate_backend() の処理における問題を修正しました。(Muhammad Usama) + + + + 特定の場合で、Pgpool-II が正常に pg_terminate_backend()を呼び出しても、フェイルオーバを引き起こす可能性がありました。 + + + + + + + + たまにフェイルオーバが実行されない watchdog の不具合を修正しました。(Muhammad Usama) + + + + 今までは、watchdog プロセスは、自分の状態のみを考慮し、フェイルオーバおよびフェイルオーバロック要求の処理を判断していました。 + + + + しかし、この処理の問題点は、ある watchdog が自分をクラスタのマスター/コーディネーターとして通知し、スタンバイノードが自分をマスターノードとして認識するのを待っている間に、自分の状態はマスター/コーディネータですが、まだフェイルオーバおよびフェイルオーバロック要求処理することができない点にありました。 + + + + そのため、たまに watchdog クラスタがリーダーを選出している間にフェイルオーバが実行されないことがありました。 + + + + ノードがフェイルオーバおよびフェイルオーバーロック要求を受け入れる前に、完全にマスター状態を取得したことを確認するように修正しました。 + + + + + + + + ストリーミングレプリケーションモードで 'H'(フラッシュ) メッセージの処理に関するバグを修正しました。(bug 345) (Tatsuo Ishii) + + + + ユーザが 'H' メッセージの直後に応答を読み込もうとすると、Pgpool-IIはハングアップしていました。 + 原因は、'H' が受信されたときに拡張クエリモードがリセットされ、保留メッセージが使用されなかったためです。 + + + + + + + + Doc: pcp_node_info のドキュメントのミスを修正しました。(Tatsuo Ishii) + + + + + + + + フェイルオーバの直後にグローバルバックエンドの状態が誤って上書きされる不具合を修正しました。(Tatsuo Ishii) + + + 詳細は [pgpool-general: 5728]を参照してください。 + + + + + + + + exit シグナルハンドラが ereport を呼び出さないように修正しました。(Tatsuo Ishii) + + + 詳細は [pgpool-hackers: 2545]を参照してください。 + + + + + + + + OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) + + + + + + + + Doc: replicate_select の動作に関する説明を修正しました。(Yugo Nagata) + + + + + + + + リリース 3.6.6 + + + リリース日 + 2017-09-05 + + + + 不具合修正 + + + + + + + ストリーミングレプリケーションモード/拡張クエリで発生する可能性のあるハングアップを修正しました。 (Tatsuo Ishii) + + + エラーが発生すると、Pgpool-IIはフロントエンドから送られてきたSyncメッセージを読み取ります。しかし、タイミングによってはまれにSyncメッセージがまだ送出されていないことがあり、syncが送られるまで待つように修正しました。 + + + + + + + watchdogが新しいノードを追加しようとした時にmasterに拒否される問題を修正しました。 (Yugo Nagata) + + + watchdogの間の認証の際に、秒を元にした文字列が使われていたため、watchdogノードの間で秒単位の時刻同期ができていないときに、この問題が発生します。修正は、単に秒を元にした文字列を認証キーに使わないようにしました。 + + + これは3.5.6, 3.6.3で追加された問題です。 + + + + + + + Test: 001.load_balance のテストスクリプトを修正しました。(Tatsuo Ishii) + + + ネイティブレプリケーションモードのみで実行される一部のテストが、ストリーミングレプリケーションモードでも実行されていたので、修正しました。 + + + + + + + 拡張クエリでslonyモードが動かなくなっていたのを修正しました。(Tatsuo Ishii) + + + slonyモードの場合、応答がバックエンドから返されたときに、進行中フラグがリセットされず、バックエンドからの次のメッセージ待ち状態になり、ハングアップしていました。 + + + + + + + ストリーム書き込みモジュールのバグを修正しました。(Tatsuo Ishii) + + + 要求された長さが残りの書き込みバッファサイズを超えた場合に発生するpool_write_noerror()の不具合を修正しました。この不具合はバッファオーバーランの問題につながる可能性がありました。 + + + 書き込みバッファがいっぱいになると、pool_flush_it()を呼び出し、バッファをフラッシュし、要求されたデータを直接書き込むように修正しました。 + + + さらに、pool_unread()のパフォーマンスが向上しました。 + + + + + + + Test: レグレッションテストスクリプトを修正しました。(Muhammad Usama) + + + + + + + Doc: ロードバランスに関するドキュメントを修正しました。(Yugo Nagata) + + + + + + + コアダンプが発生する可能性があったのと、一時テーブルの扱いに関するバグを修正しました。(Tatsuo Ishii) + + + + + + + pool_unread() の不具合を修正しました。(Tatsuo Ishii) + + + pool_unread()realloc()を呼び出すときに、バッファサイズが更新されませんでした。これにより、メモリ破損や予期しないデータの読み取りが発生する可能性がありました。 + + + + + + + 空文字のクエリの処理を修正しました。(bug 328) (Tatsuo Ishii) + + + 空文字のクエリ (空文字列またはコメントクエリ) が送信されると、コマンド完了メッセージがフロントエンドに返されていました。この動作は正しくありません。空文字クエリのレスポンスをフロントエンドに返すように修正しました。 + + + + + + + ストリーミングレプリケーションモード/拡張クエリで発生するクエリキャッシュのバグを修正しました。(Tatsuo Ishii) + + + + + + + ストリーミングレプリケーションモード/拡張クエリで発生するメモリリークを修正しました。(bug 324)(Tatsuo Ishii) + + + + + + + Test: テスト 005.jdbc の Java プログラムを修正しました。(Tatsuo Ishii) + + + + + + + workerプロセスが間違った DB ノードをフェイルオーバーさせる不具合を修正しました。 (bug 303) (Tatsuo Ishii) + + + workerプロセスが間違った DB ノードをフェイルオーバーさせる可能性がありました。原因は、POLL_CONNECTIO構造体のdb_node_idメンバがこのプロセスで初期化されていなかったからです (子プロセスでは適切に初期化されていました)。 + + + この問題を解決するには、ノード ID をセットする関数 pool_set_db_node_id()を追加し、make_persistent_db_connection()内で呼び出すように修正しました。 + + + + + + + SETコマンド発行時の不要なトランザクションの開始を修正しました。(Tatsuo Ishii) + + + + + + + ヘルスチェックアラームを無効にした状態で Failover()関数を実行するように修正しました。(Muhammad Usama) + + + 詳細は [pgpool-general: 5621] をご参照ください。 + + + + + + + ストリーミングレプリケーションモード/拡張クエリの場合、フロントエンドが 'S' (同期) メッセージを送信する前に、バックエンドからエラーレスポンスを受信するときに発生するハングアップを修正しました。 + + + さらに、以下の修正を行いました。 + + + - ストリーミングレプリケーションモードで ErrorResponse3() 関数が意図的にエラークエリをバックエンドに送信しないように修正しました。 + + + - クエリが進行中でクエリコンテキストが存在する場合のみ、virtual_master_node_idを返すように pool_virtual_master_db_node_id()関数を修正しました。 + + + + + + + Doc: ドキュメントのタイポを修正しました。(Bo Peng) + + + + + + + 配布物にpgpool.serviceが含まれるように修正しました。(Yugo Nagata) + + + + + + + + 改善点 + + + + + + Doc: 英語/日本語ドキュメントに 「Pgpool-II + Watchdogの構築の例」を追加しました。(Bo Peng) + + + + + + + Test: メモリリークのレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + + リリース 3.6.5 + + + リリース日 + 2017-07-11 + + + + 不具合修正 + + + + + + + [pgpool-hackers: 2400]で報告された、ログ出力中の不正なバイトを修正しました。(Muhammad Usama) + + + ほとんどログメッセージの修正でした。 + + + + + + + PostgreSQLMemoryManager APIに関する最新の変更をインポートしました。(Muhammad Usama) + + + + + + + スプリットブレインが発生した場合、間違ったノードが MASTER になってしまう不具合を修正しました。 + (bug 306) (Muhammad Usama) + + + + + + + [pgpool-hackers: 2390] によって報告されたデーモンモードでの相対パスの問題を修正しました。(Muhammad Usama) + + + + + + + PostgreSQL 10の変更に合わせて以下の関数名を修正しました。(Tatsuo Ishii) + + + + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn + + + + + + + ストリーミングレプリケーションと拡張プロトコルで発生するハングアップを修正しました。(Yugo Nagata) + + + 以下の例で再現できます。 + + + - pgpool.confですべての読み取りクエリをスタンバイに送信するように設定しています。 + - まず、トランザクションブロックで書き込みクエリを発行します。 + - トランザクションをコミットした後、SELECTクエリを発行します。 + - クエリを処理するときに、Parseの直後にDescribe(statement)メッセージを送信します。 + + + + + JDBCを使用せず、pgprotoを利用し以下のデータでこの問題を再現できます。 + + + 'Q' "DROP TABLE IF EXISTS test_tbl" + 'Y' + 'Q' "CREATE TABLE test_tbl(i int)" + 'Y' + 'Q' "INSERT INTO test_tbl VALUES(1)" + 'Y' + + 'P' "" "BEGIN" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "COMMIT" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "S_1" "SELECT * FROM test_tbl" 0 + 'D' 'S' "S_1" + 'B' "C_1" "S_1" 0 0 0 + 'E' "C_1" 0 + 'S' + 'Y' + + 'X' + + + + + BindExecuteを適切なバックエンドに送信するように、parse_before_bind()は、トランザクション中にのみ呼び出されるように修正しました。 + + + + + + + erlangアプリケーションを使用する場合、Pgpool-II がハングする不具合を修正しました。(Tatsuo Ishii) + + + Erlangクライアントは "Describe"メッセージの後に "Flush"を送信し、バックエンドは "Row description" を返します。しかし、Pgpool-IIは、"Row description" メッセージを受信した後、進行中のクエリフラグをリセットすることを忘れてしまい、Pgpool-IIはバックエンドからの応答を待っていました。これがerlangクライアントのハングアップの原因でした。 + + + + Pgpool-IIが "Row description" メッセージを受信した際に、クエリ処理中のフラグをリセットするように修正しました。"no data" メッセージと同じ扱いにする必要がありました。 + + + 詳細は[pgpool-general: 5555]を参照してください。 + + + + + + + 間違ったターゲットノードにバインドメッセージを送信するバグを修正しました。 (bug 306) (Tatsuo Ishii) + + + + + + + node.jsを使用する場合に発生するクエリキャッシュのハングアップの問題を修正しました。(Tatsuo Ishii) + + + 詳細は[pgpool-general: 5511]を参照してください。 + + + + + + + PostgreSQL 10のストリーミングレプリケーションの遅延チェックに関する変更に合わせて修正しました。(Tatsuo Ishii) + + + + + + + クエリキャッシュのメモリリークを修正しました。(Tatsuo Ishii) + + + oidがないクエリ(BEGINCHECKPOINTVACUUMなど)の場合キャッシュバッファがクリアされるべきでしたが、されていませんでした。 + + + + + + + 特定の場合に発生する拡張クエリのハングアップを修正しました。(Tatsuo Ishii) + + + + erlang PostgreSQL APIはParse ('P')Describe ('D')Flush ('H')Bind (B)Execute('E')を生成します。この"H"はJDBCにはありませんので、今まで問題が起こらなかったと思われます。その後、Pgpool-IIは拡張クエリモードを削除し、データを読み取るバックエンドを見つけることができませんでした。したがって、Pgpool-IIはバックエンドの一部にメッセージを送信していない可能性があるため、ハングアップを引き起こすすべてのバックエンドを読み取ろうとします。 + + + この問題を避けるために、Flushメッセージを受信後拡張クエリフラグを設定するように修正しました。 + + + + + + + [pgpool-hackers: 2354]によって報告されたpg_md5 のセグメンテーション違反を修正しました。(Muhammad Usama) + + + + + + + white/black_memcache_table_listのドキュメントを修正しました。(Tatsuo Ishii) + + + 実際の実装と異なっています。 + + + 詳細は[pgpool-general:5479]を参照してください。 + + + + + + + 滅多に発生しないPgpool-II起動時のバグを修正しました。(Tatsuo Ishii) + + + プライマリノードが見つかる前にフェールオーバーの要求が受け入れられる可能性がありました。 + これにより、Pgpool-IIは奇妙な状態に陥ります。障害が発生したノードはプライマリノードの場合、 + プライマリノードは存在しないと判断していました。(既存のスタンバイが昇格し新しいプライマリノードになった場合でも) + + + 詳細は[pgpool-hackers: 2321] をご参照下さい。 + + + + + + + + + + + + リリース 3.6.4 + + + リリース日 + 2017-05-11 + + + + 不具合修正 + + + + + + + Watchdog のフェイルオーバーリクエスト処理の不具合を修正しました。(Muhammad Usama) + + + + + + + Watchdog クラスタのメンバーの基準を改善しました。(Muhammad Usama) + + + + + + + ロードバランスに関するドキュメントを改善しました。(Tatsuo Ishii) + + + + + + + ノード 0 がフェイルオーバーする場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + [pgpool-hackers:2312] で報告された + Pgpool-IIノード 0 がフェイルオーバーするときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + + + + + + + + + リリース 3.6.3 + + + リリース日 + 2017-04-28 + + + + 不具合修正 + + + + + + + memcachedが使用されているときに発生する"show pool_cache"のセグメンテーション違反を修正しました。 + (Bug 301) (Tatsuo Ishii) + + + + + + + いくつかのソースコードの警告を修正しました。(Muhammad Usama) + + + + + + + いくつかのコンパイラの警告を修正しました。(Muhammad Usama) + + + + + + + pool_config_variable.cから「定義されたが未使用の関数」という警告を削除しました。(Muhammad Usama) + + + + + + + 古いdebug_level設定パラメーターの参照を削除しました。(Muhammad Usama) + + + + + + + Watchdogのソースコードのミスを修正し、いくつかのdebugメッセージを追加しました。(Muhammad Usama) + + + + + + + pool_hba.confファイルをリロード時に発生するエラーを修正しました。(Bug 299) (Muhammad Usama) + + + + + + + 英語/日本語のドキュメントにpgpool_adm extensionに関する情報を追加しました。(Tatsuo Ishii) + + + + + + + ドキュメントを改善しました。(Tatsuo Ishii) + + + + + + + watchdog 使用時に Pgpool-II 間でバックエンドの状態が一致しない不具合を修正しました。 + (Bug 289) (Muhammad Usama) + + + + + + + Watchdogによるスプリットブレインシナリオの処理を強化しました。(Muhammad Usama) + + + + watchdogクラスタを使用しmaster/coordinatorノードの再選出が呼び出されていました。その結果、すべてのノードがウォッチドッグネットワークに再結合する必要がありました。これはwatchdogクラスタ全体の再起動と本質的に同じでした。 + + + 今回の修正では、master/coordinatorノードの候補は、次の基準で選択されるようになりました。 + + + (1) 2つのウォッチドッグノードがクラスタマスターであると主張している場合、エスカレーションを実行したマスターノードはマスター状態を保持し、他のノードはステップダウンするように要求されます。 + + + (2) 競合がノードのエスカレーション状況によって解決できない場合、クォーラムを保持するノードはマスター/コーディネータのままです。 + + + (3) 両方の候補のクォーラムステータスが同じ場合、接続されたアライブノードの数が多いノードが優先されます。 + + + (4) 最後に、上記3つでマスターノードを選出できなかった場合、古いマスター(長期間コーディネーターステータスを持つノード) はマスターのままです。 + + + + + + + 複数の並行コマンドを処理するためにwatchdog内部コマンドのメカニズムを強化しました。(Muhammad Usama) + + + + + + + コンパイラ時の警告を修正しました。(Tatsuo Ishii) + + + + + + + リグレッションの失敗を防ぐために、サポートされていないJavaメソッドを新しいJDBCドライバでコメントアウトしました。(Tatsuo Ishii) + + + + + + + parse_before_bind() のログメッセージを debug1 にダウングレードしました。(Tatsuo Ishii) + + + + + + + coverity警告を修正しました。(Muhammad Usama, Tatsuo Ishii) + + + + + + + [pgpool-general: 5396] + pam ldapが失敗する不具合を修正しました。(Muhammad Usama) + + + + + + + 拡張クエリモードでSQL型コマンドが使用できないことをドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + SHOWコマンドを読み込みクエリの一つとして認識するようにしました。(Tatsuo Ishii) + + + ストリーミングレプリケーションモードでは、SHOWが発行されるとその後のSELECTは明示的なトランザクションでプライマリノードに送信されていました。この制限は不適切でした。また、parseコマンドがエラーを返すときに発生するハングアップを修正しました。 + + + + + + + コミットadcb636によって引き起こされたメモリリークの問題を修正しました。(Tatsuo Ishii) + + + Commit adcb636では"pending message queue"を導入しました。メッセージを受信すると、情報がキューに追加され、オブジェクトのコピーが同時に作成されますが、オブジェクトを解放するのを忘れてしまいました。 + + + 今回の修正では、新しい関数pool_pending_message_free_pending_message()を作成し、pool_pending_message_add()pool_pending_message_get()およびpool_pending_message_pull_out()の後に呼び出すように修正しました。 + + + + + + + ストリーミングレプリケーションモードで「kind mismatch」(またはそれに関連する)エラーが修正されました。 + (Bug 271) (Tatsuo Ishii) + + + このエラー原因はデータベースノードがPgpool-IIに送る応答の予測が誤っていたことです。以前使用した「sync map」の実装は弱く、予測に失敗することがありました。今回の修正では、送信されたすべてのメッセージをバックエンドに記録する"pending message queue"を導入しました。このキューの要素には、メッセージのタイプ(parse/bind/execute/describe/close/sync)、メッセージが送信されたデータベースノードの情報などが格納されます。これは単純なFIFOキューです。バックエンドからメッセージが到着すると、"pending message queue"の先頭を見れば、受信したメッセージの種類やデータベースノードを確実に予測できます。 メッセージを受信した後、この要素はキューから削除されます。 + + + 一連のパッチをテストしてくれたSergey Kimさんに感謝します。 + + + 詳細は Bug 271、 + [pgpool-hackers: 2043] と + [pgpool-hackers: 2140] をご参照下さい。 + + + + + + + [Service] が Type=forking に設定されている場合、Pgpool-II 3.6.2 が systemd によって強制終了されていた不具合を修正しました。 + (Bug 296) (Muhammad Usama) + + + + + + + + + + リリース 3.6.2 + + + リリース日 + 2017-03-17 + + + + 不具合修正 + + + + + + + pgpool.serviceファイルに"Wants=network.target"を追加しました。 + (bug 294) (Bo Peng) + + + + + + + pcp_promote_nodeを使ってノード0の昇格に失敗する不具合を修正しました。(Yugo Nagata) + + + 失敗したときのエラーメッセージは以下のとおりです。 + + + + FATAL: invalid pgpool mode for process recovery request + DETAIL: specified node is already primary node, can't promote node id 0 + + + + ストリーミングレプリケーションモードでは、Pgpool-IIがプライマリノードを何らかの理由で「スタンバイ」とみなしていました。たとえば、Pgpool-IIが起動中で、pg_ctl promoteを手動で実行したとき、Pgpool-IIはプライマリノードが存在しないと認識します。 + + + + この状態の不一致は、pcp_promote_nodeコマンドによって直されるはずですが、昇格させたいノードがマスターノード(最初のアライブノード)である場合、上記のように失敗しました。 + 失敗した理由は次のとおりです。ステータスを変更する前に、pcp_promote_nodeコマンドがPRIMARY_NODE_IDのノードIDと比較することによって、指定されたノードが既にプライマリであるかどうかをチェックします。ただし、プライマリが存在しない場合Pgpool-IIのビューでは、PRIMARY_NODE_IDが0に設定されます。これはMASTER_NODE_IDと同じです。したがって、マスタノードを昇格させるように指定する場合、pcp_promote_nodeはこのノードが既にプライマリであるとのエラーを返して終了しました。 + + + + これを修正するには、pcp_promote_nodeは指定したノードがプライマリーノードであるかどうかをチェックするとき、PRIMARY_NODE_IDではなくREAL_PRIMARY_NODE_IDを使うように修正しました。REAL_PRIMARY_NODE_IDはプライマリが存在しない場合、-1に設定されます。 + + + + + + + Pgpool-IIのドキュメントを修正しました。(Tatsuo Ishii, Bo Peng) + + + + + + + + + + Pgpool-IIがVIPを解除した後にpingテストを続けている不具合を修正しました。(Muhammad Usama) + + + [pgpool-hackers: 1611] により報告されました。 + + + + + + + 特定の場合に、Pgpool-IIが終了したときに共有メモリセグメントを解放しない不具合を修正しました。(bug 272) (Tatsuo Ishii) + + + + + + + pg_terminate_backend関数を実行するときに発生する不具合を修正しました。(Muhammad Usama) + + + [pgpool-general: 5315]により報告されました。 + + + + + + + ExecStopとExecReloadコマンドをsystemdサービス設定ファイルに追加しました。(Muhammad Usama) + + + + + + + pcp_attach_nodeを実行するときのセグメンテーション違反を修正しました。(bug 281)(Muhammad Usama) + + + + + + + ストリーミングレプリケーションモードでロードバランスのバグを修正しました。(Tatsuo Ishii) + + + 明示的なトランザクションでは、書き込みクエリが送信されるまで、SELECTはロードバランスされます。書込みクエリが送信された後、SELECTがプライマリノードに送信されます。しかし、syncメッセージが送信される前にSELECTが送信された場合、これは正しく動作しませんでした。 + + + 書き込みクエリが実行されると書き込みクエリの処理が行われるように修正しました。 + + + + + + + ストリーミングレプリケーションモードでのkind mismatchエラーを修正しました。(Tatsuo Ishii) + + + + + + + closeメッセージの後にdo_query()がハングする問題を修正しました。(Tatsuo Ishii) + + + + + + + wd_get_cmd関数のバッファオーバーフローを修正しました。(bug 280)(Muhammad Usama) + + + + + + + watchdogプロセスを再起動する時の不具合を修正しました。(Muhammad Usama) + + + watchdogプロセスが何らかの問題(例えばセグメンテーションフォルト)によって異常終了した場合、新たに生成されたwatchdogプロセスの起動が失敗し、"bind on ... failed with reason: Address already in use"とのエラーを返しました。 + + + + 理由は、異常終了したwatchdogプロセスはIPCに使用するソケットをクリーンアップする時間がなかったからです。 + + + + この不具合を修正するために、Pgpoolのメインプロセスは、watchdogプロセスが異常終了したときに共有メモリにフラグを設定するように修正しました。 + watchdogプロセスが再起動されるとき、フラグがセットされたら、ソケットファイルをクリーンアップするようにしました。 + + + + + + + 特定の条件下で、ストリーミングレプリケーションモードでクエリキャッシュが有効な場合、SELECTがハングアップする不具合を修正しました。(Tatsuo Ishii) + + + pgpool-general-jp:1441により報告されました。 + + + + + + + シグナルハンドラがelog/ereportを呼び出さないように修正しました。(Tatsuo Ishii) + + + 詳しくは[pgpool-hackers: 1950]をご参照ください。 + + + + + + + FreeBSDでlisten_addresses = '*'の場合、INETドメインソケットが作成できない不具合を修正しました。(bug 202)(Bo Peng) + + + + + + + 特定に場合にwatchdogがデエスカレーションに失敗する不具合を修正しました。(bug 249)(Muhammad Usama) + + + + WNOHANGオプションなしでwaitpid()システムコールを使用するように修正しました。 + + + + + + + authentication_timeoutが有効な場合、connection_life_timeが正しく処理されない不具合を修正しました。(Yugo Nagata) + + + + + + + クライアント接続直後に発生しうる認証タイムアウトを修正しました。(Yugo Nagata) + + + + + + + + + + + + + リリース 3.6.1 + + + リリース日 + 2016-12-26 + + + + + 不具合修正 + + + + + + + + watchdog のセキュリティを強化しました。(Muhammad Usama) + + + + + wd_authkeyは、HMAC SHA-256ハッシングを使用するようになりました。 + + + + + + + + Pgpool-IIのRPM にpgpool_adm extension が含まれるように修正しました。(Bo Peng) + + + + + + + + クエリキャッシュが有効になっている場合に、時々発生しうるセグメンテーション違反を修正しました。(bug 263) (Tatsuo Ishii) + + + + + + + + 拡張プロトコルにおいて発生しうるkind mismatchエラーを修正しました。(bug 231) (Tatsuo Ishii) + + + + bug 231によると、以下の条件がすべて満たされていると、このバグが発生する可能性がありました。 + + + + + + ストリーミングレプリケーションモード + + + + + + ロードバランスノードがnode 0ではない + + + + + + 拡張プロトコルを使用している + + + + + + SELECTが実行され、ステートメントがクローズされた後、トランザクションコマンドが実行されている + + + + + + 問題の発生順序: + - - + - pgpool_setupがログ出力を混乱させないように修正しました。(Tatsuo Ishii) - - - - 以前は Pgpool-II プロセスの stdout および stderr - は単にログファイルにリダイレクトされていました。 - これは複数プロセスが同時に書き込みを行うため競合が発生し、 - ログの文字化けや消失の原因となっていました。 - - - - - このため、pgpool_setup - が生成する startall スクリプトでは、Pgpool-II - は stdout/stderr を cat コマンドにパイプで送信し、 - cat がログファイルの書き込みを行うように修正されました。 -(パイプに書き込む際にはこの競合状態は発生しないようです) - + SELECT executes on statement S1 on the load balance node 1 + --> + ロードバランスノード1でステートメントS1のSELECTが実行されます。 + - - - -[pgpool-general: 4519] により報告されたワーカープロセスが終了し再生成されなくなる不具合を修正しました。(Muhammad Usama) - - + - この問題は watchdog が有効のときに終了した子プロセスのタイプをチェックするコードにロジック間違いがあったのが原因でした。 - また、接続が max connection に達して子プロセスが終了する際に出力されるメッセージの重要度を FATAL からLOG に変更されました。 - + Frontend send Close statement + --> + フロントエンドがクローズステートメントを送ります。 + - - + -バックエンドからエラー状態を受信した後のハングを修正しました。 (bug #169) (Tatsuo Ishii) - - - - これは拡張プロトコル問い合わせを実行しそれが失敗したときに発生し得ました。 - + Pgpool-II forward it to backend 1 + --> + Pgpool-IIはそれをバックエンド1に転送します。 + - - + - ストリーミングレプリケーションモードで拡張プロトコル問い合わせを使用したときに - スタックが発生する問題を修正しました。(bug 167, 168) (Tatsuo Ishii) - - - + Frontend sends Parse, Bind, Execute of COMMIT + --> + フロントエンドは、COMMITのParse、Bind、Executeを送信します。 + - - + - - [pgpool-hackers: 1440] により報告されたリセットクエリがスタックする問題を修正しました。(Tatsuo Ishii) - - - - フロントエンドから 'X' メッセージを受信した後、リセットクエリ送信前に Pgpool-II が - EOF をその接続で検出すると、Pgpool-II - がリセットクエリを受信していないバックエンドからの応答を待ち続けることがありました。 - EOF を受信した場合には、これを ERROR ではなく FRONTEND_ERROR として扱うことで修正しました。 - + Pgpool-II forward it to backend 0 & 1 + --> + Pgpool-IIはそれをバックエンド0と1に転送します。 + - - - - [pgpool-general: 4265] - より報告されたリセットクエリがスタックする問題を修正しました。(Muhammad Usama) - - + - フロントエンドソケットにおける pool_flush が失敗したときには、ERRORではなく FRONTEND_ERROR を発生させることで解決しました。 - + Frontend sends sync message + --> + フロントエンドが同期メッセージを送信します。 + - - - -PostgreSQL 9.6における pgpool-recovery モジュールのコンパイルエラーを修正しました。(Muhammad Usama) - - + - PostgreSQL 9.6 の GetConfigOption() - 関数の関数定義の変化に対応しました。 - + Pgpool-II forward it to backend 0 & 1 + --> + Pgpool-IIはそれをバックエンド0と1に転送します。 + - - - - FreeBSD でのコンパイルエラーを修正しました。(Muhammad Usama) - - + - 不足していた include ファイルを追加しました。 - パッチはバグ報告者によって作成され、Usama により改善されました。 - + Backend 0 replies back Parse complete ("1"), while + backend 1 replies back close complete ("3") because of + #3. + --> + バックエンド0はParse complete( "1")を返しますが、バックエンド1は#3によりclose complete( "3")を返します。 + - - + - 個々のテストのタイムアウトをチェックできるようレグレッションテストを修正しました。(Yugo Nagata) - + Kind mismatch occurs + --> + Kind mismatch が発生します。 + + + + + + + 解決策は、#3では、Pgpool-IIがバックエンド1からの応答を待つようにしますが、応答メッセージは読み取らないようにします。 その後、Pgpool-IIの状態マシンは、#6で同期メッセージが送信される前に、その応答を読み込みます。 これによりバックエンド1は#8で "1"を返信し、kind mismatchエラーは発生しなくなります。 + + + + また、Closeメッセージを受け取ったときにpool_set_doing_extended_query_message()が呼び出されない不具合を修正しました。 + + + + 新しいリグレッションテスト "067.bug231"を追加しました。 + + + + + + + + シグナルハンドラでの競合状態を修正しました。(bug 265) (Tatsuo Ishii) + + + + child.cには、elogを呼び出すシグナルハンドラがあります。 シグナルハンドラは処理中に他のシグナルに対してブロックされないため、pgpoolのシャットダウンシーケンスでシステムコールにデッドロックが発生する可能性がありました。 この問題を解決するために、シグナルハンドラはPOOL_SETMASKを使用してブロックされるように修正されました。 + + + + 理想的にはシグナルハンドラでelogを呼び出すことを避けるべきです。 + + + + + + + + 誤ったclient_idle_limit_in_recoveryの最小設定値を修正しました。(bug 264) (Tatsuo Ishii) + + + + + + + + doc.jaの下で "make xslthtml"を実行できるように修正しました。(Tatsuo Ishii) + + + + + + + + + + + + + + + + + + リリース 3.6 + + + Release Date + 2016-11-21 + + + + + 概要 + + + + Pgpool-II 3.6 の主な改善点は以下のとおりです。 + + + + + + + + + + failover の挙動が改善されました。 + + + Streaming Replicationモードで、フェイルオーバーが発生した時に、ダウンしたスタンバイサーバを利用しなければ、クライアントセッションが切断されなくなります。 + プライマリサーバがダウンした場合、すべてのセッションが切断されます。 + また、ヘルスチェックのリトライの最中でも Pgpool-IIに接続することが可能です。 + Pgpool-IIへの接続リトライする最大回数までヘルスチェックのリトライが続きます。 + + + + + + + 新しいコマンド PGPOOL SET が追加されました。 + このコマンドを使用することで、現行セッション内で設定パラメータを変更することができるようになりました。 + + + + + + + Watchdogが大幅に改善されました。 + 以前のバージョンよりも信頼性が向上しています。 + + + + + + + 問合せから大量の行が返される場合、ストリーミングレプリケーション時の拡張問い合わせプロトコル(例えば、Java アプリケーションで使用される場合)の処理速度が改善されました。 + + + + + + + PostgreSQL 9.6 のパーサを取り込みました。 + + + + + + + 特定の場合にpg_terminate_backend()がフェイルオーバを起こさないようになりました。 + + + + + + + ドキュメントの形式が HTML から SGML に変更されました。 + + + + + + + + 上記の項目は以下のセクションで詳しく説明します。 + + + + + + + 主な改善点 + + + + + + + + failover の挙動が改善されました。(Tatsuo Ishii) + + + + Streaming Replication モードで、フェイルオーバーが発生した時に、ダウンしたスタンバイサーバがそのセッションで使用されていなければ、クライアントセッションが切断されなくなりました。 + プライマリサーバがダウンした場合は、すべてのセッションが切断されます。 + ヘルスチェックタイムアウトした場合でも、すべてのセッションが切断されます。 + リトライ最大回数を超えた場合を含めて、他のヘルスチェックエラーではすべてのセッションは切断されません。 + + + + + failover が発生する場合にローカル負荷分散ノードの情報が重要なので、show pool_nodes コマンドで、ローカル負荷分散ノードの情報が利用者の便宜のために表示されるようになりました。 + 負荷分散ノードがダウンしたノードではない場合、フェイルオーバーによる影響はありません。 + + + + + また、ヘルスチェックのリトライの最中でも Pgpool-II に接続できるようになりました。 + 以前は、がオフの場合でもPgpool-IIへの接続は、ヘルスチェックのリトライをしている間はすべて失敗していました。 + これは、Pgpool-IIの子プロセスがまず失敗したバックエンドを含めてすべてのバックエンドへの接続を試み、失敗した場合終了するためです(これはもちろん失敗します)。 + これは一時的な状況であり、Pgpool-IIがフェールオーバーを行えば解決します。 + しかし、ヘルスチェックの再試行が行っている場合は、この一時的な状況は + の設定次第で長時間続きます。 + この状況は良くないので、以下のように修正しました。 + + + + + ストリーミングレプリケーションモードにおいて、バックエンドへの接続に失敗したら、そのダウンしたノードがプライマリではなければ、このバックエンドへの接続をあきらめて、他のノードへの接続を試みます。 + + + + ローカルノードのステータスを"down"と記録します。 + これによりプライマリーノードがロードバランスノードとして選択され、すべてのクエリがプライマリーノードへ転送されます。 + 他にスタンバイのノードが存在する場合、その中からロードバランスノードが選択されます。 + + + + セッションが終了した後、ローカルの状態を保持しないように子プロセスは自殺します。 + + + + + + + + PGPOOL + SHOW, PGPOOL + SET と + PGPOOL RESET + コマンドが追加されました。 (Muhammad Usama) + + + + これはPgpool-IIに現在のセッションの設定パラメータを設定またはリセットする機能を追加するという点でPostgreSQLのSET、SHOW、RESETコマンドと似ていますが、PostgreSQLのSET、RESETコマンドコマンドと区別するために、PGPOOLというキーワードが前に挿入してあります。 + + + + 現在 PGPOOL SHOW/SET/RESET に対応している設定パラメータは以下です。 + , , + , , + , , + , , + . + + + + + + + + Pgpool-II再起動後、PostgreSQLノードの状態の不整合がある場合、これを同期するようにしました。(bug 218) (Muhammad Usama) + + + + watchdog がバックエンドノードを同期させなかったのが原因でした。 + + + + + + + + 多くの行が出力されるSELECTの性能を改善しました。(Tatsuo Ishii) + + + + Pgpool-II がフロントエンドに行データ("Data Row"メッセージ)を送るたびにネットワークにデータを(write(2)を呼び出して)フラッシュしていました。 + 例えば、10,000行を転送する必要がある場合、write()が10,000 回呼び出されます。 + これは非常にコストが高いです。 + 繰り返し行データを送信した後、"Command Complete"メッセージが送られるので、Command Completeメッセージの時に併せてwrite()を発行すれば十分です。 + また、command completeメッセージの取り扱いにおいて、不必要なフラッシュがありました。 + + + + Quick testingのテスト結果から、この修正により、特定の場合で、47%から62%の性能向上が得られたことが分かりました。 + + + + しかし、問い合わせが返す行が少ない場合は、まだ改善されていません。 + そうした行はいずれにせよネットワークへのフラッシュが必要だからです。 + + + + + + + + PostgreSQL 9.6's のパーサを取り込みました。 (Bo Peng) + + + + これにより、Pgpool-IIPostgreSQL + 9.6 で導入された新しい構文 (COPY INSERT/UPDATE/DELETE ... RETURNING など) を理解可能です。 + + + + + + + + ある場合では、pg_terminate_backend() 関数が failover を引き起さないようになりました。(Muhammad Usama) + + + pg_terminate_backend()でバックエンドを終了させた場合、 + PostgreSQLがpostmasterをシャットダウンしたときと同じメッセージを返しますので、 + ユーザが望まないかもしれないフェールオーバーを発生させます。 + + + これを修正するために、Pgpool-IIは、 + pg_terminate_backend()の対象バックエンドのPIDを検出し、フェールオーバーを発生させません。 + + + この修正は単純なプロトコルの場合、またはpg_terminate_backend() + に渡されたPIDが定数の場合にのみ適用します。 + 拡張プロトコル(Javaなど)の場合、pg_terminate_backend()はフェールオーバーを起こします。 + + + + + + + + HTMLドキュメントが、SGMLドキュメントから生成されるようになりました。(Muhammad Usama, Tatsuo Ishii, Bo Peng) + + + + これはより良い構成、内容、保守の容易性をもたらすためです。 + また、manページがSGMLから生成されるようになりました。 + しかし、SGMLドキュメントにはまだたくさんの改良の余地があります。 + どうか私達を助けてください! + + + + + + + + + 他の改善点 + + + + + + + + + 認証エラーメッセージをわかりやすくしました。 (Tatsuo Ishii) + + + + バックエンドに接続する時に(ヘルスチェックを含む)、"invalid authentication message response type, Expecting 'R' and received '%c'" メッセージではなく"sorry, too many clients already"のようなメッセージを返すようにしました。 + + + + + + + + pool_check_fd()のヘルスチェックタイマーの期限切れ条件を強化しました。(Muhammad Usama) + + + + + + + + 新しいスクリプト "watchdog_setup" が追加されました。 (Tatstuo Ishii) + + + + は watchdog 機能を有効にしたPgpool-IIクラスタのテスト環境を構築するコマンドです。 + + + + + + + + pgpool_setup に "pg" オプションが追加されました。(Tatsuo Ishii) + + + + これはを使用する時に、PostgreSQLに特定のポート番号を割り当てたい場合に便利です。 + また、pgpool と同じように、pgpool_setupは標準binディレクトリにインストールされるようになりました。 + + + + + + + + show pool_nodes の出力結果に replication delay カラムが追加されました。(Tatsuo Ishii) + + + + streaming replication モードの場合、 + このカラムは replication delay の値を bytes 単位で表示します。 + + + + + + + + すべてのノードがダウンした場合、 status ファイルを更新しないように変更されました。(Chris Pacejo, Tatsuo Ishii) + + + + レプリケーションモードにおいて、すべてのノードがダウン状態の場合にstatusファイルに記録しないようにすることで、[pgpool-general:3918] で報告されたデータの不整合を修正しました。 + この驚ほど単純ですが、スマートな解決方法はChris Pacejoにより提供されました。 + + + + + + + + Pgpool-II が 複数 SSL cipher protocols に対応できるように修正しました。(Muhammad Usama) + + + + SSLセッションを初期化する際の処理でTLSv1_method()をSSLv23_method()で置き換えることにより、TLSv1プロトコルよりも多くのプロトコルを使うことができるようになりました。 + + + + + + + + black_function_list/read_only_function_list + に任意のアイテムの数が使用できるようになりました。(Muhammad Usama) + + + + これまで、このアイテムの数には固定の上限がありました。 + + + + + + + + コメントのみを含む空クエリを適切に処理できるよう修正しました。(Tatsuo Ishii) + + + + この修正で、Pgpool-II"/* DBD::Pg ping test v3.5.3 */" (';' を含まないことに注意)のような空クエリを正しく識別できるようになりました。 + + + + これまではエラークエリとして処理していました。 + + + + + + + + wd_authkey ハッシュ計算失敗時に警告メッセージを出力するようにしました。(Yugo Nagata) + + + + たまに、認証キー不一致以外の何らかの理由で wd_authkey 計算に失敗することがあります。 + メッセージ出力を追加することでこれらを互いに区別できるようにしました。 + + + + + + + + + + 変更点 + + + + + + + + log_destination = syslog 設定の不具合を修正しました。(Muhammad Usama) + + + + PGPOOL SET/SHOW コマンド追加の修正によって、ログの出力先がsyslogの場合、不具合がありましたので、修正しました。また、log_destinationパラメータがカンマ区切りで複数出力先を指定することができるようになりました。この修正によって、log_destination は "syslog" と "stderr" の任意の組み合わせに設定できるようになりました。 + + + + + + + のデフォルト値を10から300に変更しました。(Tatstuo Ishii) + + + + これまでのデフォルト値10秒は、スタンバイを昇格する際には小さすぎでした。 + + + + + + + + src/sql/ 配下の Makefile が修正されました。(Bo Peng) + + + 詳しくは + [pgpool-hackers: 1611] を参照してください。 + + + + + + + + pcp_proc_count コマンドの出力結果のプロセス ID を 6 桁まで表示 できるよう修正しました。(Bo Peng) + + + + 特定の環境において、pcp_proc_count コマンドの出力結果のプロセス ID が6 桁の場合、 + 6 番目の文字が表示されませんでした。 この修正で、プロセス ID が最大 6 桁まで表示するよう変更しました。 + + + + + + + すべてのクエリがプライマリサーバに送信されるように変更しました。(Tatsuo Ishii) + + + + = off の場合でも、一部のクエリがプライマリサーバ以外にも転送されていました。 + この修正で、 streaming replication モードで load_balance_mode = off + の場合はすべてのクエリをプライマリサーバにのみ送るようにしました。 + + + + + + + + 不具合修正 + + + + + + + pool_stream関数の潜在的なクラッシュを修正しました。(Muhammad Usama) + + + + POOL_CONNECTION-> con_infoは、バックエンドソケットで読み取りまたは書き込みが失敗したときに、逆参照する前にヌル値をチェックする必要があります。 + + + + + + + watchdogクラスタでのフェイルオーバーコマンドの転送処理が改善されました。(Muhammad Usama) + + + + これまでは、Pgpool-II ノードの watchdogがすべての接続されたノードにフェイルオーバーコマンド(failover、 failback 及び promote node)を転送していました。多数のノードが含まれているwatchdogクラスタでは、フェールオーバーコマンドが複数のPgpool-IIによって実行されることによって、データの同期問題を引き起こす可能性がありました。このコミットでは、すべてのフェイルオーバーコマンド(failover、 failback 及び promote node)が master/coordinator watchdog に転送され、master/coordinator watchdogはすべてのスタンバイノードに転送するようになりました。 + + + + また、今回の修正では、インターロック機能も変更されました。master/coordinatorノーのみがロックホルダになり、フェイルオーバコマンドはmaster/coordinatorノードでのみ実行されます。 + + + + + + + すべてのバックエンドがダウンした後に、1つのノードを復帰させる時の不具合が修正されました。(Tatsuo Ishii) + + + + すべてのノードがダウンすると、すべてのコネクションを受け付けなくなります。 + その状態で1つのPostgreSQLが起動し、pcp_attach_nodeコマンドでそのノードを復帰させます。 + そしてこのコマンドは成功しました。 + しかし、新しい接続が拒否されました。 + これはPgpool-II の子プロセスがキャッシュされた古い情報を参照したのが原因でした。 + ストリーミングレプリケーションモードでは、このキャッシュされた情報において、復帰させたノードの状態がdownのままでした。 + (ネィティブレプリケーションモード、およびそれ以外のモードでは問題ありません) + 解決法として、全ノードがダウンした場合、強制的に全 Pgpool-II子プロセスを再起動するようにしました。 + + + + + + + 再起動が必要なパラメータの設定を変更した際のPgpool-II停止が起こらないようにしました。(Muhammad Usama) + + + + この修正のために、設定パラメータの検証機構の順序を逆にしました。 + 以前はスタンバイノードがPgpool-IIマスターノードに対して設定パラメータの値を検証し、不整合が見つかった場合にはFATALエラーが出力されていました。 + この修正で、Pgpool-IIマスターノードに検証の役割が移譲されました。 + マスターノードは参加している個々のスタンバイノードの設定値をローカルの設定値と比較し、違っている場合にはエラーではなくてWARNINGメッセージを出力します。 + この方法では、ユーザは、手動でマスターPgpool-IIログの中から不整合ワーニングを見つけて、Pgpool-IIマスターのスイッチオーバが起きたときに驚くようなことが起こらないようにしなければなりません。 + + + + + + + watchdog が有効な場合、 コマンドのロック取得時の処理が改善されました。(Muhammad Usama) + + + + + + + コンパイルエラーを修正するために、configure.ac + ファイルにコンパイルフラグ "-fno-strict-aliasing" が追加されました。(Tatsuo Ishii) + + + + + + + MD5 salt を生成するときに、random() を使用しないように修正しました。(Tatsuo Ishii) + + + + random()関数はセキュリティ関連のアプリケーションで使用すべきではありません。 + random()の代わりにPostgreSQLPostmasterRandom() 使用するように変更しました。 + + + + + + + + クエリキャッシュが有効な場合、sync メッセージが廃棄されないよう修正しました。(Tatsuo Ishii) + + + + + + + が空文字の場合、Pgpool-II が起動できない不具合を修正しました。(bug 237) (Muhammad Usama) + + + + TCP listen addresses が空の場合、socket descriptor 配列(fds[])の終了マークがないのが原因でした。 + + + + + + + リグレッションログディレクトリが存在しない場合、作成されるようになりました。(Tatsuo Ishii) + + + + + + + ソケットの操作に失敗したときのエラーメッセージを修正しました。(Muhammad Usama) + + + + + + + show pool_nodes コマンドの修正を反映し、レグレッションテスト 003.failover を変更しました。 + + + + + + + Portal suspend を受け取ったときのハングが修正されました。(bug 230) (Tatsuo Ishii) + + + + + + + ネットワークが復旧した時にIPを降格しない問題を修正しました。(bug 228) (Muhammad Usama) + + + + ローカルノードの状態が調停者状態から他の状態に変わった時に降格させるために、set_state関数が実装されました。 + + + + + + + SIGUSR1 シグナルハンドラーを watchdog の初期化前にインストールするように修正しました。(Muhammad Usama) + + + + watchdog 初期化直後に 他のwatchdog ノードから failover リクエストがあった場合、 + SIGUSR1 シグナルハンドラーのインストールを待っていれば、クラッシュが発生する可能性がありました。 + + + + + + + 他のノードが利用できない場合、Pgpool-II が + IPアドレスをエスカレートしない不具合を修正しました。(bug 215) (Muhammad Usama) + + + + Heartbeat destination が IPアドレスで指定され、wd_hostname が hostname で設定される場合、 + heartbeat receiver が heartbeat sender watchdog ノードを識別できなかったのが原因でした。 + 逆の場合でも同様なエラーが起こります。 + + + + + + + watchdog に関するコーデイングミスを修正しました。(Muhammad Usama) + + + + wd_issue_failover_lock_command()関数は、渡ってきたコマンドタイプをwd_send_failover_sync_command()関数の引数に渡すように想定されていますが、その代わりにNODE_FAILBACK_CMDコマンドタイプを渡していました。 + + + + この修正で、いくつかのログメッセージも改善しました。 + + + + + + + pcp_node_info コマンドの標準出力の「Status」がわかりやすくように変更されました。(Muhammad Usama) - + + + + pcp_node_info コマンドの標準出力の「Status」が内部状態コードから人間がわかりやすい状態の文字列に変更されました。 + + + + + + + 「MAJOR」マクロによる発生しうるセグメンテーションフォルトを修正しました。(Tatsuo Ishii) + + + + MAJOR が pool_virtual_master_db_node_id() を呼出し、 + 戻り値 idを使ってbackend->slots[id]->con にアクセスします。 + 可能性は低いですが、conが0を指し(DB にアクセスできない場合)、con->major にアクセスし、セグメンテーションフォルトを引き起す可能性がありました。 + + + + + + + "kind mismatch" エラーメッセージの処理について修正しました。(Muhammad Usama) + + + + 多くの"kind mismatch..."エラーは、NOTICE や WARNING メッセージが + DBノードのいくつかで起こることによるものです。 + この修正では、そうしたケースにおいて、"kind mismatch..."エラーを引き起こすのではなく、 + NOTICE や WARNINGメッセージをフロントエンドに送るようになりました。 + これにより、"kind mismatch..."エラーの発生が減少します。 + + + + + + + パラメータの処理の不具合を修正しました。(Muhammad Usama) + + + + + + + シグナルハンドラ中でエラー番号が保存されるようになりました。 (Tatsuo Ishii) + + + + + + + pgpool メインプロセスの wait(2) の扱いを修正しました。(Tatsuo Ishii) + + + + Pgpool-II メインプロセスから呼び出されるwait(2)はそのシステムコール内で永久に待つ可能性があります。 + この修正で、 wait(2) の代わりに、waitpid(2) を使うように変更しました。 + + + + + + + が off の場合、 + read(2) が -1 を返しても + pool_read() がエラーメッセージを発行しない不具合が修正されました。(Tatsuo Ishii) + + + + + + + show pool_nodes でのバッファオーバーランを修正しました。(Tatsuo Ishii) + + + + show pool_nodes を実行時、hostname に割り当てられたバッファが十分ではないのが原因でした。 + pgpool.conf のバッファサイズと同じようにしました。 + + + + + + + + [pgpool-hackers: 1638] で報告された、Pgpool-II + がデフォルトの設定を使用しない不具合が修正されました。(Muhammad Usama) + + + + 設定ファイルが見つからない場合は、 ERROR または FATAL ではなく、WARNING を返すように修正しました。 + + + + + + + 共有メモリ上のロードバランスノードの書き込みに関するバグを修正しました。(Tatsuo Ishii) + + + + 2, 3の箇所で、ロードバランスノードが間違ったことろに置かれてしまいました。 + + + [正しい場所] + + + ConnectionInfo *con_info[child id, connection pool_id, backend id].load_balancing_node]. + + + + [実際に置かれた場所] + + + *con_info[child id, connection pool_id, 0].load_balancing_node]. + + + + バックエンド id が 0 の場合、上記バグが発生しませんが、Pgpool-II 3.6 のフェイルオーバーテストで、プライマリノードが 1 (ロードバランスノード)、スタンバイノードが 0 の場合、ノード1 の接続が切断され、フェイルオーバーが起きています。 + これは想定外のことだったのでこのバグが見つかりました。 + + + + このバグはかなり前からありましたが、上記の理由で、今まで見つかっておリませんでした。 + + + + + + + #197 で報告されたpgpoolのハングを修正しました。(bug 197) (Muhammad Usama) + + + + watchdog が有効で、バックエンドノードとリモート Pgpool-IIノードが同時接続できなくなった場合、クライアント接続がスタックします。 + 原因は watchdog に IPC コマンドを送信する関数を呼び出すコマンドタイムアウトがなかったからです。 + + + + + + + ヘルスチェックで発生し得るハングアップを修正しました。(bug 204) (Yugo Nagata) + + + + connect(2) が成功し、 + その後バックエンドからデータが送信されない場合、ヘルスチェックがハングしていました。 + ヘルスチェック中に、select(2)がSIGALRMのためにEINTRで終了した場合、pool_check_fd()が1を返すように修正しました。 + + + + + + + streaming replication モードで、プライマリノードが 0 ではない場合に発生する不具合が修正されました。 (Tatsuo Ishii) + + + + http://www.pgpool.net/mantisbt/view.php?id=194#c837の報告により、bug194-3.3.diff を適用しても、プライマリノードが 0 ではない場合、ステートメントタイムアウトが発生する可能性がありました。 + 調査した結果、MASTER マクロがプライマリノードまたはロードバランスノード + 以外のノードを返したからです。 + そのため、do_query()がクエリを間違ったノードに送信していました(これは報告では明確ではありませんでしが、 調査で確認できました)。 + + + + MASTER マクロから呼ばれるpool_virtual_master_db_node_id() は、クエリコンテキストが存在する場合、query_context->virtual_master_node_id を返します。 + その変数がまだ初期化されていない場合、この関数が間違ったノード を返す可能性があります。 + そのため、pool_virtual_master_db_node_id() 関数を以下のように修正しました。 + 変数にプライマリノードもロード バランスノードも設定されていない場合、プライマリノードを返します。 + + + + + + + バックエンドのステートメントタイムアウトが有効で、do_query()がクエリをプライマリノードに送信し、それ以降のユーザクエリがスタンバイノードに送信された場合、次のコマンド、例えば、ENDコマンドが、プライマリノードのステートメントタイムアウトを引き起こし、kind mismatch error が発生する可能性がありました。(bug 194) (Tatsuo Ishii) + + + + この問題を軽減するために、do_query() + がフラッシュメッセージを送信する代わりに、sync メッセージ送信するように修正しました。 + 明示的トランザクションのときは、sync メッセージを送信することで、ステートメントタイムアウトタイマーがリセットされます。 + 暗黙的なトランザクションでは、このやり方は使えません。 + なぜなら、unnamed portal が存在する場合、sync メッセージが unnamed portalを削除するからです。 + + + + 更にこれにより、pg_stat_statement が do_query() が発行したクエリを "running" で表示しなくなります。 + + + + + + + 拡張プロトコルのraw モードでのバグを修正しました。(bug 152) (Tatsuo Ishii) + + + + Bug 152の報告により、拡張プロトコルの raw モード(実は stream モード以外)で + Describe()Close() + の処理に誤りがありました。stream モードとは異なり、バックエンドからの応答を待つべきでした。 + + + + + + + pgpool.conf の不正確なコメントを修正しました。(Tatsuo Ishii) + + + + + + + 日本語と中国語ドキュメントのraw モードに関する内容の誤りを修正しました。(Yugo Nagata, Bo Peng) + + + + raw モードでも、コネクションプーリングが有効です。 + + + + + + + is_set_transaction_serializable()関数のSET default_transaction_isolation TO 'serializable'の扱いに関するバグを修正しました。(bug 191) (Bo Peng) + + + + Pgpool-IISET default_transaction_isolation TO 'serializable' + をプライマリだけではなく、スタンバイにも送信してしまい、エラーが起きていました。 + この修正で、streaming replication モードの場合、SET default_transaction_isolation TO 'serializable' + がプライマリサーバのみに送信されます。 + + + + + + + 拡張プロトコルにおける空クエリの場合、発生し得るハングアップを修正しました。(Tatsuo Ishii) + + + + この修正は3.5.1で空のクエリの場合の拡張プロトコルの扱いに関係しています。 + この場合バックエンドはcommand complete messageと同じ意味を持つ"empty query response"を返します。 + 問題は、"empty query response"を受信した際に、Pgpool-IIがクエリ進行中フラグをリセットせず、 バックエンドの応答を待ち続けることことです。 + しかし、バックエンドはsyncメッセージをを受け取るまではready for queryメッセージを返しません。 + 解決方法は、"empty query response"を受信した際に、クエリ進行中フラグをリセットし、フロントエンドがsync メッセージを送信することを期待してフロントエンドからの応答を待つことです。 + + + + + + + + [pgpool-general: 4569] により報告された + trusted_servers チェック時のセグメンテーションフォルトを修正しました。 (Muhammad Usama) + + + + Pgpool-II 3.4 からは PostgreSQL + のメモリマネージャおよび 例外マネージャ API を流用していますが、 + それはスレッドセーフ ではありません。上位接続を確認するため ping の応答で信頼できるサーバ確認時、 + watchdog lifecheck プロセスでセグメンテ ーションフォルトを引き起こしていました。 + スレッドを削除し、 子プロセスを使うように修正しました。 + + + + + + + PCP パケットの長さを検証するよう修正しました。(Muhammad Usama) + + + + この検証がない場合、非常に巨大なデータサイズのパケットを送信することで、 + 不正な PCP パケットが PCP 子プロセスをクラッシュさせたり、サーバで out of memory を発生させることが可能でした。 + + + + + + + pgpool_setupがログ出力を混乱させないように修正しました。(Tatsuo Ishii) + + + + 以前は Pgpool-II プロセスの stdout および stderr + は単にログファイルにリダイレクトされていました。 + これは複数プロセスが同時に書き込みを行うため競合が発生し、 + ログの文字化けや消失の原因となっていました。 + + + + + このため、pgpool_setup + が生成する startall スクリプトでは、Pgpool-II + は stdout/stderr を cat コマンドにパイプで送信し、 + cat がログファイルの書き込みを行うように修正されました。 + (パイプに書き込む際にはこの競合状態は発生しないようです) + + + + + + + [pgpool-general: 4519] により報告されたワーカープロセスが終了し再生成されなくなる不具合を修正しました。(Muhammad Usama) + + + + この問題は watchdog が有効のときに終了した子プロセスのタイプをチェックするコードにロジック間違いがあったのが原因でした。 + また、接続が max connection に達して子プロセスが終了する際に出力されるメッセージの重要度を FATAL からLOG に変更されました。 + + + + + + + バックエンドからエラー状態を受信した後のハングを修正しました。 (bug #169) (Tatsuo Ishii) + + + + これは拡張プロトコル問い合わせを実行しそれが失敗したときに発生し得ました。 + + + + + + + ストリーミングレプリケーションモードで拡張プロトコル問い合わせを使用したときに + スタックが発生する問題を修正しました。(bug 167, 168) (Tatsuo Ishii) + + + + + + + + + + [pgpool-hackers: 1440] により報告されたリセットクエリがスタックする問題を修正しました。(Tatsuo Ishii) + + + + フロントエンドから 'X' メッセージを受信した後、リセットクエリ送信前に Pgpool-II が + EOF をその接続で検出すると、Pgpool-II + がリセットクエリを受信していないバックエンドからの応答を待ち続けることがありました。 + EOF を受信した場合には、これを ERROR ではなく FRONTEND_ERROR として扱うことで修正しました。 + + + + + + + [pgpool-general: 4265] + より報告されたリセットクエリがスタックする問題を修正しました。(Muhammad Usama) + + + + フロントエンドソケットにおける pool_flush が失敗したときには、ERRORではなく FRONTEND_ERROR を発生させることで解決しました。 + + + + + + + PostgreSQL 9.6における pgpool-recovery モジュールのコンパイルエラーを修正しました。(Muhammad Usama) + + + + PostgreSQL 9.6 の GetConfigOption() + 関数の関数定義の変化に対応しました。 + + + + + + + FreeBSD でのコンパイルエラーを修正しました。(Muhammad Usama) + + + + 不足していた include ファイルを追加しました。 + パッチはバグ報告者によって作成され、Usama により改善されました。 + + + + + + + 個々のテストのタイムアウトをチェックできるようレグレッションテストを修正しました。(Yugo Nagata) + + + + - + diff --git a/doc.ja/src/sgml/release-3.7.sgml b/doc.ja/src/sgml/release-3.7.sgml index fcf513121..b84b5188f 100644 --- a/doc.ja/src/sgml/release-3.7.sgml +++ b/doc.ja/src/sgml/release-3.7.sgml @@ -1,2513 +1,5786 @@ - - - リリース 3.7.7 + + リリース 3.7.26 - リリース日 - 2018-11-22 + 2022-12-22 - - - 不具合修正 + + 変更点 - + - -クライアントから送信された startup パケットのパラメータをソートするように修正します。 -(bug 444)(Takuma Hoshiai) + ログメッセージ"new IPC connection received"をDEBUG1にダウングレードしました。 + (bug 775) (Bo Peng) - -キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 -コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + これは通常のメッセージで、LOGとして記録されるべきではありません。 + パッチはpstefによって作成され、Bo Pengによってレビューされました。 - + + + + + + 不具合修正 + + - + - -ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 -(bug 443) (Bo Peng) + pcp_proc_infoSHOW pool_poolsおよびSHOW pool_processes内のまれなセグメンテーション違反を修正しました。(Tatsuo Ishii) - -パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 -bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 -これによりセグメンテーション違反が発生していました。 + セグメンテーション違反はget_pools()とget_processes()にありました。 + それらは、最初に共有メモリ上の特定のプロセス情報スロットのpidを抽出し、次にキーとして pid を使ってスロットを再び検索していました。 + これらのステップはロックによって保護されていなかったため、プロセス終了時に新しい子プロセスのフォークを担う親プロセスによって pid が上書きされた場合、 + pid を使った検索が失敗し、NULLを返す可能性がありました。 + その結果、それに続くNULLポインタの参照によってセグメンテーション違反が発生していました。 - -パッチがYugo Nagataにより提供されました。 + 解決策は、最初にプロセス情報スロットへのポインタを取得し、次にポインタからpidメンバを抽出することです。 + この方法でも、親プロセスによる共有メモリ情報の同時更新は可能ですが(出力におかしな結果をもたらす可能性があります)、少なくともセグメンテーション違反は回避できます。 - + - + - -スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + 無効な長さのUnixドメインソケットパスを使えないように修正しました。(Masaya Kawamoto) - + + + + + + ドキュメント修正 + + - + - -クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + Doc: memqcache_methodの説明を拡充しました。(Tatsuo Ishii) - - - - - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + どの方式を使うべきかの説明を追加しました。 - + - + - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) + Doc: ヘルスチェックプロセスでSSLが使えることに言及しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションのチェックでもSSLが使えることに言及しました。 + これは2010年以降に使えていたはずです。 + + + 議論: [pgpool-hackers: 4187] - - - - - - - リリース 3.7.6 - - - リリース日 - 2018-10-31 - + + - - - 変更点 - - - - - -フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) - - - - - - - -LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) - - - - - - - -Doc: オンラインリカバリのドキュメントに注意事項を追加しました。 - - - -よりも小さな値でなければなりません。 - - - - - - - -Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) - - - - - - - -Doc: フェールオーバスクリプトに関する注意事項を追加しました。 - - - -failover/failbackスクリプトの中でPgpool-II自体にアクセスすることはお勧めしません。 - - - - - - - -Doc: のドキュメント及びエラーメッセージを改善しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供され、Bo Pengにより修正されました。 - - - - - - - -Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - - 不具合修正 - - - - - -SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) - - - -パッチはPhil Ramirezにより提供されました。 - - - - - - - -ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 -(bug 434) (Takuma Hoshiai) - - - -ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 - - - - - - - -ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) - - - -ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 -タイムスタンプ型の定数に書き換えるようになっています。 -しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 - - - - - - - -拡張問い合わせの場合、時々期待される応答がフロントエンドに返されないことがあったので、修正しました。 -(bug 432) (Tatsuo Ishii) - - - -解決策は、保留中のメッセージデータリストを使用することです。それはフロントエンドからのメッセージを記録し、同じ数のメッセージを受け取ることが期待されます。 - - - -パッチは Yugo Nagata によって作成され、Tatsuo Ishii により修正されました。 - - - - - - - -ストリーミングレプリケーションモードかつ拡張問い合わせの場合、クエリキャッシュを有効にするときに発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - -trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) - - - - - - - -ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) - - - -明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 -テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 - - - - - - - -時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) - - - - - - - -Test: EXECUTE/DEALLOCATEのレグレッションテストを追加しました。(Takuma Hoshiai) - - - - - - - -pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) - - - - - - - -DEALLOCATEステートメントが発行された場合に発生するkind mismatchエラーを修正しました。(Bo Peng) - - - -EXECUTEDEALLOCATEPREPAREと同じノードに送信されるために、PREPAREをpool_add_sent_messageに追加するように修正しました。 - - - -詳細は[pgpool-general: 6226]を参照してください。 - - - - - - - -パスワードの長さが正しくない場合、を更新しないように修正しました。 -(bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - -Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 -ファイルのパスワードの長さをチェックするように修正しました。 - - - - - - - -Doc: ドキュメントの"new master"を"new primary"に変更しました。(Bo Peng) - - - - - - - -gccの新しいバージョンで発生するwarningを修正しました。(Tatsuo Ishii) - - - - - - - -Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -.gitignoreファイルを追加しました。(Bo Peng) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - - - - - -Doc: ドキュメントとスクリプトのタイポを修正しました。(Tatsuo Ishii) - - - -パッチはJesper Pedersenにより提供されました。 - - - - - - - -Doc: のドキュメントの誤りを修正しました。 - - - - - + + 回帰テスト修正 + - - - リリース 3.7.5 + + + + 環境変数を使ってPGPOOLDIRを定義できるようにしました。 + (bug 766) (Bo Peng) + + - - - リリース日 - 2018-07-31 - - - - 不具合修正 - - - - - - -raw モードでpool_passwd を使用しないように修正しました。 -(bug 411) (Tatsuo Ishii) - - - -raw モードではバックエンドが 1つしかないので、md5 認証でpool_passwd を使用する必要はありません。 - - - - - - - -「write on backend 0 failed with error :"Success"」エラーを修正しました。 -(bug 403) (Tatsuo Ishii) - - -write() が 0 を返した場合、エラーとして扱わないように修正しました。 - - - - - - - -フェイルオーバ後、スタンバイ Pgpool-II で worker プロセスが起動されない不具合を修正しました。 -(bug 409) (Muhammad Usama) - - - -修正パッチは Yugo Nagataによって提供されました。 - - - - - - - -フェイルオーバ時に、誤ったノード ID を渡す不具合を修正しました。 -(bug 406) (Muhammad Usama) - - - - - - - -最初にダウンしたノードがフェイルバックした後にヘルスチェックプロセスが起動されない不具合を修正しました。 -(bug 407) (Tatsuo Ishii) - - - - - - - -pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) - - - - - - - -pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。(Tatsuo Ishii) - - - -これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 - - - - - - - -armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) - - - -修正パッチは Christian Ehrhardt によって提供されました。 - - - - - - - -フェイルオーバ後、スタンバイ Pgpool-II で間違ったバックエンドのロールが表示される不具合を修正しました。(Muhammad Usama) - - - - - - - -Doc:「MD5パスワード認証」、「Pgpool-II のインストール」、「pg_md5」などのドキュメントを改善しました。(Bo Peng) - - - -修正パッチは Takuma Hoshiai によって提供されました。 - - - - - - - -Test: テスト006.memqcache の失敗を修正しました。( Tatsuo Ishii) - - - - + + - - - リリース 3.7.4 - + + リリース 3.7.25 - - リリース日 - 2018-06-12 + リリース日 + 2022-08-18 - - - 不具合修正 - - - - - -拡張問合せ、かつクエリキャッシュが有効の場合、レプリケーション遅延が大きすぎるときに発生しうる Pgpool-II のハングアップを修正しました。(Tatsuo Ishii) - - - -詳細は [pgpool-general-jp: 1534] -を参考してください。 - - - - - - - -Doc: PCP コマンドの "-U" オプションのタイポを修正しました。 (Bo Peng) - - - - - - - -デバッグ用コードを削除しました。(Bo Peng) - - - - - - - -拡張問合せでは、SET TRANSACTION READ ONLY の場合、書き込みトランザクションフラグを立てないように修正しました。 (Tatsuo Ishii) - - - - - - - -3.7.2 と 3.7.3 で発生するフェイルオーバスクリプトに間違ったパラメータ %P (古いプライマリノードID) を渡す不具合を修正しました。 (Tatsuo Ishii) - - - - - - - -Doc: を使うために、ヘルスチェックが有効になっている必要がある明確な説明をドキュメントに追加しました。(Tatsuo Ishii) - - - - - - - -Doc: 古い のドキュメントを修正しました。 (Tatsuo Ishii) - - - - - - - -Test: extended_query_test のスクリプト test.sh を修正しました。 (Tatsuo Ishii) - - - - - - - -pgpool_setup に抜けていた health_check_timeout の設定を追加しました。(Tatsuo Ishii) - - - - - - - -Doc: recovery_2nd_stage_command はネイティブレプリケーションモードのみで設定する必要がある明確な説明をドキュメントに追加しました。(Tatsuo Ishii) - - - - - - - -pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) - - - -これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 - - - -詳細は -[pgpool-general: 5963] -をご参照してください。 - - - -また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 - - - - - - - - - リリース 3.7.3 - - - リリース日 - 2018-04-17 - - - 不具合修正 - + + 不具合修正 + - + - - デフォルトではノードごとヘルスチェックパラメータの設定が無効になりました。 + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) - - - - - - コマンドで -g オプションを指定した場合に発生するハングアップを修正しました。(bug 391) (Tatsuo Ishii) + + Pgpool-IIは"Select '2022-02-18 07:00:00.006547'::timestamp"のような問合せをキャッシュしていませんでした。 + TIMESTAMP、TIME、DATEを含むSELECT文はキャッシュされるようになりますが、TIMESTAMPZ、TIMEZを含むSELECT文は"SET TIME ZONE"コマンドなどで結果が変更されるためキャッシュされません。 + また、TIMESTAMPZやTIMEZ型を返す関数を含むSELECT文も同様の理由でキャッシュされません。 + Discussion: [pgpool-general: 8285] - + - - - - - Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) - - + + - - - - - to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) - - + + ドキュメント修正 + - + - - ALWAYS_MASTER が on の場合に発生する Pgpool-II 子プロセスのセグメンテーション違反を修正しました。(Tatsuo Ishii) + Doc: 特定のSELECT文がキャッシュされないことに言及しました。(Tatsuo Ishii) - Pgpool-II 3.7.1 で、以下の条件をすべて満たす場合にセグメンテーション違反が発生していました。 - + 特定のSELECT文は以下です。 + - - ストリーミングレプリケーションモード - + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を使っているSELECT + - - fail_over_on_backend_error = off - + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEへのキャストを含むSELECT + - - マスタノードが ALWAYS_MASTER に設定してある - + + SQLValueFunction (CURRENT_TIME, CURRENT_USERなど)を含むSELECT + - - - pgpool_status ファイルの上記 3)で設定したノードの状態が down である - - - + - + - + - - Doc: watchdog に関するドキュメントを更新しました。(Tatsuo Ishii) + Doc: Unixドメインソケット接続するときのPCPパスワードファイルの使用についての説明を修正しました。(Masaya Kawamoto) + + + pcppassファイルのlocalhostエントリはデフォルトのPCPソケットディレクトリパスへの接続とのみマッチして、全てのUnixソケット接続には使用されません。 + この振る舞いはpgpassファイルと同じです。 - + - + - Doc: 新しい設定パラメータの追加方法に関する README ファイルを追加しました。(Tatsuo Ishii) + Doc: の誤った説明を修正しました。(Tatsuo Ishii) + + + これらのパラメータは設定ファイルの再読み込みでは変更できず、Pgpool-IIの再起動が必要です。 + + Discussion: [pgpool-general: 8195] - + + + + - + + 回帰テスト修正 + + + - 「unable to bind D cannot get parse message "S1"」エラーによるハングアップを修正しました。(Tatsuo Ishii) + Test: 回帰テストでPgpool-IIのバージョンを表示するようになりました。(Tatsuo Ishii) - + - + - - Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + Test: 適切なinstall directoryでpgpool.confを探すように回帰テストスクリプトを修正しました。(Tatsuo Ishii) - + + + + + + + + + リリース 3.7.24 + + リリース日 + 2022-05-19 + - + + 変更点 + + - Doc: backend_flag を使用してフェイルオーバ回避できるようにする説明をドキュメントに追加しました。(Tatsuo Ishii) + Pgpool-IIメインプロセスの停止を強化しました。(Tatsuo Ishii) + 「pgpool stop」が一定期間(現在5秒)以内にメインプロセスを終了できなかった場合は、信号を再送信するように修正しました。 + + + + + + コマンドのPIDの長さを7文字に変更しました。(Bo Peng) - + - + + Parseメッセージ処理のエラーメッセージにメッセージの種類、バックエンドノードIDを含めるように改善しました。(Tatsuo Ishii) + + + + - Doc: ドキュメントのタイポを修正しました。(Bo Peng) + + ParameterStatusメッセージのログレベルをLOGからDEBUG5にダウングレードしました。(Tatsuo Ishii) - + Discussion: [pgpool-general: 8042] - + - + - Test: ノード0がプライマリではない場合のレグレッションテストを追加しました。(Tatsuo Ishii) + のデフォルト値を「*」から「localhost」に変更しました。(Tatsuo Ishii) - + - + + のフィールド名を変更しました。(Muhammad Usama) + + + + + + + + 不具合修正 + + - レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + + lost状態のリモートPgpool-IIノードが再起動後にクラスタに再参加できない問題を修正しました。(Muhammad Usama) - + + 報告: [pgpool-general: 7896] + + - + - PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) + プライマリ検索中にバックエンドが失敗またはシャットダウンした場合にPgpool-IIのメインプロセスが終了してしまう問題を修正しました。(Tatsuo Ishii) - + - + - 3.7.2 のコミット 9022ff842fb5dbbe06e2f2f4cf38fadf47b592da を取り消しました。(Tatsuo Ishii) + Watchdogで発生するセグメンテーション違反を修正しました。(Muhammad Usama) - このコミットにより、 プライマリがノード 0 以外の場合に更新クエリを実行できなくなっていました。 + Discussion: [pgpool-general: 8030] - + + + - + + ドキュメント修正 + + - Test: 拡張クエリのテストスクリプトを改善しました。(Tatsuo Ishii) + Doc: pcp_watchdog_infoの出力例を更新しました。(Bo Peng) - + + + - + + 回帰テスト修正 + + - - Doc: pgpool_adm エクステンション関数の例を修正しました。(Tatsuo Ishii) + セグメンテーション違反を検出するようにテストスクリプトを改善しました。(Bo Peng) - - - - - + + + - - - リリース 3.7.2 - + + リリース 3.7.23 - - リリース日 - 2018-02-13 - - - - このリリースでは、Pgpool-II 3.7.0、3.6.6、3.5.10 で追加された、ソケット - への書き込み不具合を修正しています。この障害により、ネットワーク負荷が - 高い状態でのフロントエンド、バックエンドへのメッセージ送信の際に、不正 - なメッセージが送信される可能性があります。3.7.x、3.6.6 以降、3.5.10 以降 - のバージョンを利用中のユーザは、できるだけ早くアップグレードすることを - お勧めします。 - + リリース日 + 2022-02-17 - - 変更点 - - + + 変更点 + + - -Pgpool-II が libressl の環境でビルドできるようになりました。(Tatsuo Ishii) + in_hot_standbyによるメッセージ長の違いに関する不要なログを抑制しました。(Tatsuo Ishii) + + + PostgreSQL 14 は新しいパラメータを導入しました: in_hot_standby -詳細は [pgpool-hackers: 2714] を参照してください。パッチは Sandino Araico Sanchez により提供されました。 + この値はスタンバイサーバの場合は "on" で、プライマリサーバの場合は "off" になります。 + その結果 pgpool のログは以下のメッセージで溢れていました。 - - - + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + - -PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + これを防ぐために、パラメータ名がin_hot_standbyでない場合にのみログを出力するようになりました。 + + + また、メッセージにパラメータ名を表示するようになりました。例を示します。 - - - + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + - -systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + Discussion: [pgpool-hackers: 4076] - + - + - -pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + パラメータステータスの取り扱いを変更しました。(Tatsuo Ishii) - - - + + バックエンドからパラメータステータスのメッセージが届いたときにただメモリー上に記憶するだけでなく、フロントエンドに転送するようになりました。 + + + + + - - 不具合修正 - - + + 不具合修正 + + + - -コミットまたはロールバック時に誤って書き込みトランザクションフラグをセットする不具合を修正しました。 (Tatsuo Ishii) + pcp_node_infoの実行の際に長時間待機する不具合を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] - + - + - -watchdog のフェイルオーバーコンセンサスの設定が異なる場合、警告メッセージを表示するように修正しました。(Muhammad Usama) + Coverityによって見つかったヘルスチェックプロセスの問題を修正しました。(Tatsuo Ishii) - + - + - -Doc: ドキュメントのタイポを修正しました。 (Bo Peng) + Coverityによって見つかったメモリリークを修正しました。(Tatsuo Ishii) - + - + - -ソケット書き込みの不具合を修正しました。 (Tatsuo Ishii) + プライマリノードが存在しない場合の対処をするようにfailover()を修正しました。(Tatsuo Ishii) -ネットワーク負荷が高い場合に、フロントエンド、バックエンドへのメッセージ送信の際に、 -不正なメッセージが送信される可能性があるのを修正しました。 + プライマリノードが存在しない場合に pgpool が起動したときなどReq_info->primary_node_idが -1 である場合にfailover()find_primary_node_repeatedly()の呼び出しをスキップしていました。 + また、follow_master_commandも実行されませんでした。 -このバグは 3.6.6、3.5.10 がリリースされた際に追加されたものです。 + Discussion: [pgpool-hackers: 4113] - + - + - -ALWAYS_MASTER がオンの場合に発生するPgpool-II の子プロセスのセグメンテーション違反を修正しました。 (Tatsuo Ishii) + バックエンドに接続できないときにストリーミングレプリケーションチェックプロセスがリトライしないように修正しました。(bug 742)(Bo Peng) + このリトライによってフェイルオーバに時間がかかっていました。 + + + + + + + + ドキュメント修正 + + -以下で条件で発生します。 - - + ParameterStatusin_hot_standbyパラメータに関する制約を追加しました。(Tatsuo Ishii) + + + + -ストリーミングレプリケーションモード - - - + set_configに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + + テストツール修正 + + + -fail_over_on_backend_error=off - - - - -マスタノードの backend_flag が ALWAYS_MASTER に設定してある - - - + pgpool_setupが作成するfailoverスクリプトを修正しました。(Tatsuo Ishii) + + pgpool_setupfailover.shを作成するとき、プライマリサーバが存在しない場合を考慮していませんでした。 + + + + + + + + 回帰テスト修正 + + + -pgpool_status ファイルで #3 のノードの状態が down である - - - + + 再コンパイルしないで既存のインストールで回帰テストを実行できるようになりました。(Tatsuo Ishii) + Discussion: [pgpool-hackers: 4077] + + + + -詳細は [pgpool-hackers: 2687][pgpool-general: 5881] を参照してください。 + + noinstall モード時のpgpool_setupwatchdog_setupのバイナリパスを修正しました。(Bo Peng) - + + + + + + + + リリース 3.7.22 + + リリース日 + 2021-12-23 + - + + 変更点 + + + + yaccとの非互換性によって出力されるbisonの警告を抑制しました。(Tatsuo Ishii) + + + + -デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + 冗長なコードを修正しました。(Tatsuo Ishii) + + + パッチはLu Chenyangによって提供されました。 + - + + - + + ドキュメント修正 + + + + Doc: pcp_watchdog_infoマニュアルの誤字を修正しました。(Tatsuo Ishii) + + + + -ノードごとのヘルスチェックパラメータのデータ型の不具合を修正しました。(Tatsuo Ishii) + + Doc: リリースノートの誤字を修正しました。(Bo Peng) - + + + + + - + + リリース 3.7.21 + + リリース日 + 2021-11-18 + + + + セキュリティリリース + + + SSL暗号化ハンドシェイク後の余計なデータを拒否するようにしました。(Tatsuo Ishii) + + + サーバサイドのSSLネゴシエーションの実装において、任意のSQLコマンドを実行できる中間者攻撃が可能でした。 + これはPgpool-IIがクライアント認証で証明書認証を使用しているか、hostssl + trust認証の場合に可能でした。 + PostgreSQLのCVE-2021-23214と似た脆弱性です。 + + + 同様に、クライアントサイドのSSLネゴシエーション実装において、任意の結果に改ざんする中間者攻撃が可能でした。 + これはPostgreSQLがクライアント認証でhostssl + trust認証を使用しているときに可能でした。 + 証明書認証の場合には、Pgpool-IIはPgpool-IIとPostgreSQL間で証明書認証を実装していないため問題ありません。 + PostgreSQLのCVE-2021-23222と似た脆弱性です。 + + + + + + + 変更点 + + + -拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + pg_terminate_backend()の処理に関するPostgreSQL 14対応をしました。(Tatsuo Ishii) - - - - - + - - - リリース 3.7.1 + + + + Pgpool-IIメインプロセスのSIGCHLDハンドラを改良しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスがSIGKILLシグナルでkillされたとき、SIGCHLDハンドラは他のシグナルと同じようにLOGレベルメッセージを発していました。 + しかし、SIGKILLシグナルはOMM killerによるkillなど重要なイベントなので、WARNINGレベルのメッセージを発するようにしました。 + Michail Alexakisから提案されました。 + Discussion: [pgpool-general: 7750] + + - - - リリース日 - 2018-01-09 - + + - - 不具合修正 - + + 不具合修正 + - - - - -Makefile を改善しました。(Bo Peng) - - - -Tomoaki Sato がパッチを提供しました。 - - + + + + COPY FROM中のハングアップを修正しました。(Tatsuo Ishii) + + + COPY FROM中にエラーが発生したとき、Pgpool-IIはフロントエンドからCOPY終了マーカーが送信されたあと、バックエンドからの応答を永遠に待っている可能性がありました。 + Bo Pengによって発見されました。 + + - - - - -Doc: ドキュメントのミスとタイポを修正しました。(Bo Peng) - - + + + + rawモードでの誤った負荷分散ノードの表示を修正しました。(Bo Peng) + + + rawモードでは、Pgpool-IIはすべてのクエリをメインノードに送信します。 + この不具合は表示上の問題だけで、クエリの転送処理に影響はないですが、ユーザを混乱させる可能性があるので、修正しました。 + + - - - - - スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) - - -/bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 - - + + + + PGPOOL SHOW ALLの実行結果にbackend_flag*が2回表示される不具合を修正しました。(Tatsuo Ishii) + - - - - -ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) - - - -ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 - - + - - - - -Doc: 新しいドキュメント「ドキュメントのコンパイルとインストール」を追加しました。(Tatsuo Ishii) - - + + - - - - -ノードごとのヘルスチェックパラメータが無視される不具合を修正しました。(bug 371) (Tatsuo Ishii) - - - -また、 がノードごとのヘルスチェックパラメータを pgpool.conf に追加するように変更しました。 - - + + ドキュメント修正 + - - - - -ヘルスチェックプロセスがエラーで終了したときに、Pgpool-II が新しいヘルスチェックプロセスをフォークするように修正しました。(Tatsuo Ishii) - - - -バックエンドソケットの読み込みに失敗した場合 (これはhealth_check_userが間違っていると発生する可能性がある)、ヘルスチェックプロセスは pool_read() でFATALエラーを発生させ、ヘルスチェックプロセスを終了させます。 -そして、Pgpool-II は、新しいヘルスチェックプロセスをフォークします。 -これは永遠に繰り返されます。 - - + + + + typoを修正しました。(Bo Peng) + + + パッチはKazufumi Notoによって提供されました。 + + - - - - -ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) - - - -PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 - - + + + + Doc: PGPOOL SHOWコマンドを実行する際に、大文字を含むパラメータ名の場合には、 + パラメータ名をダブルクォートで囲んで実行する必要があることを追加しました。(Bo Peng) + + - - - - - Doc: のドキュメントを修正しました。 (Tatsuo Ishii) - - - - ロジカルレプリケーションモードにも対応するとの説明を追加しました。 - - + + - - - - -一部のログメッセージをデバッグメッセージにダウングレードしました。(Tatsuo Ishii) - - - -前回の開発で誤って残していました。 - - + + テストツール修正 + - - - - -Test: bug370 のテスト用データを追加しました。(Tatsuo Ishii) - - + + + + 新しいメインノードが利用できない場合に何もしないようにpgpool_setupを修正しました。(Tatsuo Ishii) + + - - - - -バックエンドからのパケットを読み込む際の再同期のロジックを修正しました。(Tatsuo Ishii) - - - -read_kind_from_backend() は、バックエンドからメッセージを読み取り、"ready for query" メッセージが受信されたときにバックエンドノードを再同期します。 -しかし、pool_pending_message_pull_out() を呼び出して「sync メッセージを受信した」を削除することを忘れていました。 -これによって、バックエンドからのパケットの読み取り中に Popool-II がハングアップする可能性がありました。 -pool_pending_message_pull_out()を呼び出し、「sync メッセージを受信した」を削除するように修正しました。 - - + + - - - - -問い合わせ中に Pgpool-II がハングアップする不具合を修正しました。(bug 370) (Tatsuo Ishii) - - - -エラークエリがプライマリに送信され、sync メッセージを送信せずに、次のクエリを実行するときに、 -PostgreSQL のシステムカタログへの問い合わせが必要な場合、Pgpool-IIdo_query() 関数でハングアップしていました。 - - + + 回帰テスト修正 + - - - - -"ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) - - - -今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 -ほとんどの場合、問題がありませんでした。 -ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 - - + + + + たまに発生する073.pg_terminate_backendの失敗を修正しました。(Tatsuo Ishii) + + - - - - -Test: extended-query-test テストスクリプトを修正しました。(Tatsuo Ishii) - - + + + + テストの失敗を防ぐためにpsqlコマンドのパスを修正しました。(Bo Peng) + + - - - -Doc: ドキュメント「Pgpool-IIの動作モード」 を改善しました。 (Tatsuo Ishii) - - - - + + - - - リリース 3.7 - + + リリース 3.7.20 - - リリース日 - 2017-11-22 + リリース日 + 2021-08-05 - - - 概要 + + 変更点 + + + + - -このバージョンでは、新しいwatchdog機能とノードごとのヘルスチェックの設定により、フェイルオーバの信頼性が向上しています。また、このバージョンでは、PostgreSQL 10の新しいSQLパーサ、ロジカルレプリケーション、およびいくつかの管理関数の名前の変更に対応しています。 + ドメイン名を含めたホスト名の長さの最大値を変更しました。(Tatsuo Ishii) - -Pgpool-II 3.7 の主な改善点は以下のとおりです。 + ホスト名の長さの最大値を128にしていましたが、正しくは254でした。 + Discussion: [pgpool-hackers: 3903] + - + + - + + 不具合修正 + + + + + クエリキャッシュでSQLValueFunctionsを含むクエリをキャッシュしないようにしました。(Tatsuo Ishii) + + + SQLValueFunctionsの一覧は以下になります。 + - - -クォーラム機能によりフェイルオーバを決定するようになりました。 - + + CURRENT_DATE + - - - -pool_hbaではホスト名を指定できるようになりました。 - + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + - - - -PostgreSQLバックエンドごとにヘルスチェックパラメータを設定できるようになりました。 - + + SESSION_USER + - - - -AWS Aurora に対応しました。 - + + USER + - - - -PostgreSQL 10 のSQLパーサを取り込みました。 - + + CURRENT_CATALOG + - - -ロジカルレプリケーションに対応しました。 - + + CURRENT_SCHEMA + + + + - - - - - - 主な改善点 + + + + SIモードにおける不正なメッセージの送信を修正しました。(Tatsuo Ishii) + + + クエリがシリアル化エラーなどの特定の理由によってアボートしたとき、Pgpool-IIは + メインノード以外で実行されているトランザクションを中止するためにエラークエリを送信します。そのメッセージ長が + 正しくなかったためバックエンドで「invalid string in message」エラーが発生していました。 + + - - - - - -クォーラム機能によりフェイルオーバを決定するようになりました。(Muhammad Usama) - - - -Pgpool-IIはクォーラム機能を利用し、watchdogクラスタ内でPostgreSQLバックエンドノードのフェイルオーバを決定する機能を追加しました。この機能追加により、スプリットブレインを防止することができます。 + + + + watchdog通信の競合状態を修正しました。(Tatsuo Ishii) + + + メインプロセスがwatchdogプロセスから通知された処理を実行中に、watchdogプロセスが新しいメッセージを + メインプロセスに通知したとき、新しいメッセージが処理されるまでに大幅な遅延が発生していました。 + Discussion: [pgpool-hackers: 3900] + + - + + + + 再起動後にwatchdogノードステータスが更新されない問題を修正しました。 + (bug 684) (Muhammad Usama) + + - - -この変更により、failover、failback、promote-node コマンドの処理も変更しました。 - + + - - -また、マスタノードだけがフェイルオーバーを実行することになったので、フェイルオーバ時にロックする必要がなくなりました。 - + + ドキュメント修正 + - - -この機能追加に伴い、以下の 3つのフェイルオーバに関するパラメータを追加しました。 - - - - - failover_when_quorum_exists - - - - - - failover_require_consensus - - - - - - allow_multiple_failover_requests_from_node - - - - - + + + + Doc: いくつかのドキュメントのtypoを修正しました。(Bo Peng) + + - - - - -pool_hbaでホスト名を指定できるようになりました。(Muhammad Usama) - - - -pool_hba設定ファイルの address フィールドにおいて、以前はCIDRアドレスのみに対応していましたが、この修正により、ホスト名にも対応するようになりました。 - + + + + Doc: インメモリクエリキャッシュのtypoを修正しました。(Tatsuo Ishii) + + - - -この機能追加に伴い、以下の改善も行いました。 - + + + + Doc: の説明を修正しました。(Masaya Kawamoto) + + - - -(1) pool_hba レコードはロード時に完全に解析されるようになりました。Raw レコード行ではなく、構造化されたデータを保存します。これにより、新規接続時間が短縮され、パフォーマンスが向上します。 - - - -(2) エラー/ログメッセージが改善されました。 - + + - - -(3) auth-options フィールドの処理が改善されました。 - - + + テストツール修正 + - - - - -PostgreSQLノードごとにヘルスチェックパラメータを設定できるようになりました。(Tatsuo Ishi, Muhammad Usama) - - - -従来のヘルスチェックでは、すべてのPostgreSQLノードを順番にチェックし、パラメータはノードごとには設定できず、全ノードで共通の設定でした。 - - - -この機能追加により、Pgpool-IIの親プロセスがPostgreSQLノードごとにヘルスチェックプロセスをフォークし、ヘルスチェックに関連するパラメータがノードごとに設定できるようになりました。 - - - -例えば、PostgreSQLバックエンドノードが3台の場合、以下のように設定すると、 - - -health_check_period = 10 -health_check_period0 = 5 - + + + + pgpool_setupで使用されるrsyncのパラメータを修正しました。(Tatsuo Ishii) + + - - -ノード0にhealth_check_period = 5 が設定され、ノード1 と2 にhealth_check_period = 10が設定されます。 - - + + + + pgpool_setup中のベースバックアップ処理を修正しました。(Tatsuo Ishii) + + - - - - -PostgreSQL 10 のパーサを取り込みました。(Bo Peng) - - + + + + watchdog_setupのスクリプトを修正しました。(Tatsuo Ishii) + + + watchdog_setupによって生成されるshutdownallスクリプトは、全体シャットダウンでは + 不必要なフェイルオーバ処理を引き起こしていました。 + + - - + + - - - - -AWS Auroraに対応しました。 (Tatsuo Ishii) - - - -プライマリノード検出ロジックを制御する新しいバックエンドフラグ「ALWAYS_MASTER」を追加しました。Aurora ではpg_is_in_recovery()を使用できないため、Auroraの "writer"として指定されたバックエンドに「ALWAYS_MASTER」を割り当てます。Aurora は常にマスタに同じホスト名を使用するため、find_primary_node() は「ALWAYS_MASTER」フラグが立っているノードIDを返します。 - - - -詳細は、ALWAYS_MASTERを参照してください。 - - - -それ以外は、Auroraではストリーミングレプリケーションモードを使用することができます。 Auroraではレプリケーション遅延を検査できないことに注意してください。は常に0にする必要があります。 - - - -設定については AWS設定の例を参照してください。 - - + + 回帰テスト修正 + - - - - -ロジカルレプリケーションモードを追加しました。(Tatsuo Ishii) - - - -ロジカルレプリケーションモードはロジカルレプリケーションを使用するPostgreSQLサーバと一緒に使うことができます。このモードでは、PostgreSQLがテーブルを同期する責任を持ちます。 - - - -このモードでは負荷分散が可能です。ロジカルレプリケーションは必ずしもすべてのテーブルをレプリケーションしないので、負荷分散させるテーブルがレプリケーションされるようにするのはユーザの責任です。 - - - -サンプルの設定ファイルは $prefix/etc/pgpool.conf.sample-logicalです。 - - - -pgpool_setup もロジカルレプリケーションモードに対応しました。 - - + + + + 031.connection_life_timeの不具合を修正しました。(Tatsuo Ishii) + + - - + + + - - - 他の改善点 - - - - - - Test: Watchdog のテストケースを追加しました。 (Muhammad Usama) - - + + + リリース 3.7.19 + + + リリース日 + 2021-05-20 + + + + + 不具合修正 + + + + + Doc: の説明を修正しました。(Tatsuo Ishii) + + + パラメータは、Pgpool-IIがrootで起動する場合にのみ使用できます。 + + - - - - - Test: extended-query-test に新しいテストケース "node_js.data"を追加しました。 (Tatsuo Ishii) - - + + + + pgpool0の配下のみにデータベースクラスタを作成するようにを修正しました。(Tatsuo Ishii) + + - - - - - Doc: 「pool_hba.conf ファイル」に関するドキュメントを更新しました。(Muhammad Usama) + + + + クエリキャッシュが有効になっている場合のpgpoolのクラッシュを修正しました。 + (bug 700) (Tatsuo Ishii) + + + ストリーミングレプリケーションモードと論理レプリケーションモード以外でCloseCompleteを受信すると、Pgpool-IIがクラッシュしていました。 + + - - + + + + クエリキャッシュがストリーミングレプリケーションモードと論理レプリケーションモード以外で作成されない不具合を修正しました。(Tatsuo Ishii) + + - - - - - pgpool_setupslonyモードに対応しました。(Tatsuo Ishii) - - + + + + Startupパケットを受信したときのデバッグメッセージを改善しました。 (Tatsuo Ishii) + + - - - - -OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) - - + + + + Doc: 多数ドキュメントの改善を行いました。 (Tatsuo Ishii, Bo Peng) + + + + + - - - - -Test: 新しいレグレッションテスト「069. memory_leak_extended」を追加しました。(Tatsuo Ishii) - - + + + リリース 3.7.18 + + + リリース日 + 2021-02-18 + + + + + 変更点 + + + + + Pgpool-II起動時に既存のwatchdogコマンドソケットファイルを削除するように修正しました。(Muhammad Usama) + + + パッチはMasaya Kawamotoによって提供されました。 + + + + + + + + 不具合修正 + + + + + の誤ったweightの表示を修正しました。 (Tatsuo Ishii) + + - - - - -Doc: インメモリキャッシュに関するドキュメントを更新しました。(Tatsuo Ishii) - - - - - - -Doc: ドキュメントに「インストールのヒント」を追加しました。(Tatsuo Ishii) - - + + + + Watchdogリーダーによる同期処理後に、ヘルスチェックプロセスが起動されない不具合を修正しました。(Tatsuo Ishii) + + - - - + + + + watchdog_setupの誤ったデータベースクラスタのパスを修正しました。(Tatsuo Ishii) + + + + + + + DBノードごとに個別のアーカイブディレクトリを作成するようにpgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + 共有メモリの割り当て中のエラーを修正しました。(Tatsuo Ishii) + + + + + + + ERRORが発生した場合、が正しくカウンタされない不具合を修正しました。(Tatsuo Ishii) + + + + + + + backend_flag0 = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER'またはfailover_command=''の場合に発生しうるセグメンテーション違反を修正しました。 + (bug 672) (Tatsuo Ishii) + + + + + + + Doc: のドキュメントを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.7.17 + + + リリース日 + 2020-11-19 + + + + + 変更点 + + + + + Doc: ドキュメントの「Auroraの設定例」を更新しました。(Bo Peng) + + + + + + + Doc: Pgpool-IIGSSAPIをサポートしないという注意事項を追加しました。(Tatsuo Ishii) + + + + + + + フロントエンドがGSSAPI暗号化接続を要求した場合、 + Pgpool-IIGSSAPIをサポートしていないため、 + これまでエラーを返していましたが、他の方式での接続を要求するように変更しました。 + + + パッチはTatsuo Ishiiにより作成され、Umar Hayatによりレビュー・テストされました。 + + + + + + + + 不具合修正 + + + + + ネイティブレプリケーションモードで「INSERT ... ON CONFLICT」クエリ書換えの不具合を修正しました。 + (bug 654) (Bo Peng) + + + + + + + クエリがキャンセルされたときにコネクションカウントが減少しない不具合を修正しました。 + (bug 656) (Tatsuo Ishii) + + + + + + + Doc: PostgreSQLの使用可能なバージョンを7.4以降に修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.7.16 + + + リリース日 + 2020-09-17 + + + + 変更点 + + + + + + PostgreSQL 12.4 のガイドラインに従ってPgpool-IIの拡張機能のスクリプトを修正しました。(Tatsuo Ishii) + + + + CREATE OR REPLACE FUNCTIONの使用を避けて、代わりにCREATE FUNCTIONを使用するように修正しました。 + + + + + + + + の"PGBIN"と"LPATH"を、PostgreSQLのbin pathとlib pathにしました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + Doc: オンラインリカバリが利用可能なPgpool-IIの動作モードに関する誤った説明を修正しました。(Bo Peng) + + + + + + + + いくつかの不要なチェックをソースコードから削除しました。(Tatsuo Ishii) + + + + パッチはby Hou, Zhijieにより提供されました。 + + + + + + + + relcacheクエリがプライマリ以外に送信される不具合を修正しました。(Tatsuo Ishii) + + + + ストリーミングレプリケーションモードでは、relcacheクエリはプライマリノードに送信されるようになっています。 + しかし、実際には、プライマリノードがマスターノードでない場合、relcacheクエリはプライマリノードに送信されませんでした。 + 通常、これはプライマリがノード0でない場合に発生する可能性があります。 + + + + + + + + が有効になっているときにが機能しない問題を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] + + + + + + + + 認証処理において有益なエラーメッセージを表示するように修正しました。(Tatsuo Ishii) + + + + + + + + 特定の場合に発生するpgpool子プロセスのセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 以下の方法で再現できます。 + + + + + すべてのバックエンドを停止します。 + + + + + + 無効なクライアントでpgpoolに接続します。例えば、pcpのポートではなく、pgpoolのポート番号を使用してpcp_attach_nodeを実行します。 + + + + + + + + + + + + リリース 3.7.15 + + + リリース日 + 2020-08-20 + + + + + 変更点 + + + + + Doc: TLSバージョン1.2あるいはそれ以下のバージョンのみがの影響をうけるという説明を追加しました。(Tatsuo Ishii) + + + + + + + Doc: に関する説明を改善しました。(Bo Peng) + + + パッチはKenichiro Tanakaにより提供されました。 + + + + + + + pool_hba.confサンプルファイルにhostssl/hostnosslに関する説明を追加しました。(Tatsuo Ishii) + + + + + + + Doc: 多数ドキュメントの改善を行いました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + pgpoolの起動時に、pidファイルが存在する場合、書き込む前にpidファイルを長さゼロに切り詰めるように修正しました。(Bo Peng) + + + パッチはmaliangzhuにより提供されました。 + + + + + + + Doc: のパラメータの説明の誤りを修正しました。(Bo Peng) + + + + + + + ストリーミングレプリケーションモードでプライマリノードが0以外の場合、が機能しない問題を修正しました。(Tatsuo Ishii) + + + + + + + -rオプション及びPostgreSQL 12でのpgpool_setupの問題を修正しました。(Tatsuo Ishii) + + + + + + + RPMパッケージのPCPコマンドのUNIX_DOMAIN_PATH/var/run/postgresqlに変更します。(Bo Peng) + + + + + + + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + クエリキャッシュが有効な場合、あるテーブルが更新された場合、Pgpool-IIは自動的にそのテーブルに関係する全てのキャッシュを削除するようになっています。 + しかし、EXPLAIN ANALYZEまたはCTEで更新クエリを実行した場合に、 + これらのクエリが誤って参照クエリとして扱われ、キャッシュが削除されませんでした。 + + + パッチはHou, Zhijieにより作成され、Tatsuo Ishiiにより修正されました。 + + + + + + + コーナーケースで発生するPgpool-IIのハングアップを修正しました。(Tatsuo Ishii) + + + + + + + user、database、application_name以外のパラメータが指定された場合、startupパケットの読み取りが失敗する不具合を修正しました。(Tatsuo Ishii) + + + + + + + pg_terminate_backendを実行した時にコネクションのカウントがずれる不具合を修正しました。(Takuma Hoshiai) + + + + + + + アプリケーション名がに含まれている場合に発生するセグメンテーション違反を修正しました。 (bug 615) (Tatsuo Ishii) + + + + + + + ネイティブレプリケーションモードでpg_terminate_backend()を実行すると、フェイルオーバを引き起こしてしまう不具合を修正しました。(Takuma Hoshiai) + + + + + + + IBM Zハードウェアでの004.watchdogテストのクラッシュを修正しました。 (bug 614) (Tatsuo Ishii) + + + パッチはgregn123により作成され、Tatsuo Ishiiにより修正されました。 + + + + + + + + + リリース 3.7.14 + + + リリース日 + 2020-05-21 + + + + + 不具合修正 + + + + + + 一部のシステム(Fedora 32)で発生するビルドエラーを修正しました。(Tatsuo Ishii) + + + + + + + + 不要なチェックを削除しました。(Tatsuo Ishii) + + + + パッチはsherlockcppによって提供されました。Discussion: [pgpool-general: 7004] + + + + + + + + Doc: ドキュメントのタイポを修正しました。(Tatsuo Ishii) + + + + パッチはUmar Hayatによって提供されました。 + Discussion: [pgpool-hackers: 3587] + + + + + + + + PCP プロセスのセグメンテーション違反を修正しました。(bug 598) (Muhammad Usama) + + + + + + + + Doc: タイポを修正しました。(Tatsuo Ishii, Bo Peng) + + + + パッチはsherlockcppによって提供されました。 + + + + + + + + Syncメッセージの直後にExecuteメッセージが発行され、クエリキャッシュがヒットすると、Pgpool-IIがハングアップする不具合を修正しました。(Tatsuo Ishii) + + + + + + + + Watchdogのソースコードの不適切なJSONデータの処理を修正しました。(bug 596) (Tatsuo Ishii) + + + + パッチはGreg Nancarrow (Fujitsu Australia)によって提供されました。 + + + + + + + + ネイティブレプリケーションモードで起こりうるデータの不整合を修正しました。(Tatsuo Ishii) + + + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] + + + + + + + + ホスト名が長い場合、バッファサイズの制限によってWatchdogのpingが失敗する問題を修正しました。(bug 516) (Bo Peng) + + + + + + + + + リリース 3.7.13 + + + リリース日 + 2020-02-20 + + + + + 変更点 + + + + + + ネイティブレプリケーションモードの場合に、クォーラム合意によるフェールオーバ機能を無効にしました。(Muhammad Usama) + + + + ネイティブレプリケーションモードで、Pgpool-II + はすべてのバックエンドノードでデータをレプリケーションする役割を果たしています。 + ノードがquarantine(隔離)状態になると、Pgpool-II + はそのノードへの書き込みを停止するので、データの不整合を引き起こす可能性があります。 + + + + そのため、レプリケーションモードの場合に、バックエンドノードがquarantine(隔離)状態にならないように、 + 機能を無効にしました。 + + + + + + + 起動時のbind()エラーを回避するために、ソケットファイルが存在するかどうかを確認し、 + PIDファイルが存在しない場合、それらのソケットファイルを削除するように修正しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + レプリケーションモードの場合に、クエリのタイムスタンプがリライトされない不具合を修正しました。 + (bug 551) (Bo Peng) + + + + + + + + Doc: ドキュメントの更新、タイポの修正を行いました。(Takuma Hoshiai, Tatsuo Ishii, Bo Peng) + + + + + + + + が空の場合、リロード後に発生する子プロセスのセグメンテーション違反を修正しました。 + (bug 571) (Bo Peng) + + + + + + + + PostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) + + + + + + + 時々起こるリグレッションテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + primary_conninfoのapplication_nameが空の場合に発生するレプリケーション遅延チェックワーカープロセスのセグメンテーション違反を修正しました。 + (bug 565) (Tatsuo Ishii) + + + + + + + + = 'ALWAYS_MASTER'の場合に、コマンドの出力に ALWAYS_MASTERが表示されない不具合を修正しました。(Takuma Hoshiai) + + + + + + + + syslogが出力されない不具合を修正しました。(Bo Peng) + + + + + + + + + リリース 3.7.12 + + + リリース日 + 2019-10-31 + + + + + 不具合修正 + + + + + + レプリケーションモードでの誤ったクエリの書き換えを修正しました。 (Bo Peng) + + + + + + + + 特定の場合にヘルスチェックのタイムアウトが正しく動作しない不具合を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 3458], [pgpool-hackers: 3459] + + + + + + + + Doc: すべてのスタンバイノードがダウンした場合のの説明を追加しました。(Takuma Hoshiai) + + + + + + + + Doc: PostgreSQLサーバをに指定しないように注意事項を追加しました。(Tatsuo Ishii) + + + + + + + + いくつかのWatchdogの問題を修正しました。(Muhammad Usama) + + + + lifecheckで失敗したノードはWatchdogクラスタから接続可能であっても + 障害として扱われるように変更しました。 + + + + ネットワークパーティショニングまたは部分的なlifecheckの失敗の場合、 + 切り離されたスタンバイノードは、マスターに接続しようとしたり、 + マスターになろうとするのに積極的すぎたため、ネットワークとクラスターノードに不必要 + な負担をかける可能性がありました。 + この問題は、切り離されたノードがマスターに接続したりマスターになろうとするのを少し待機させることで修正されました。 + + + 詳細: + (bug 547)、 + [pgpool-general: 6672] + + + + + + + + 各種のv2プロトコルのバグを修正しました。(Tatsuo Ishii) + + + + + + + + の変更がリロードによって反映されない不具合を修正しました。 + (bug 548) (Takuma Hoshiai) + + + + + + + + 特定の場合にPgpool-IIのシャットダウンが失敗する不具合を修正しました。(Tatsuo Ishii) + + + + + + + + 切り離されたスタンバイノードがlifecheckによって再発見されたときに、マスターウォッチドッグノードに再参加できるように修正しました。 + (bug 545) (Muhammad Usama) + + + + + + + + ヘルスチェックのデバッグ機能を改善しました。(Tatsuo Ishii) + + + + + + + + 名前付きステートメントをDEALLOCATEした後に、誤ったクエリを実行すると + セグメンテーション違反が発生する不具合を修正しました。 + (bug 546) (Tatsuo Ishii) + + + + + + + + Doc: クォーラムが存在しない場合、VIPは起動されないことをドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + パラメータのデフォルト値にネットワークインターフェイスオプション -I を含めるように修正しました。(Bo Peng) + + + + + + + + + リリース 3.7.11 + + + リリース日 + 2019-08-15 + + + + 改善点 + + + + + + PostgreSQLからメモリマネージャデバッグ機能の一部をインポートしました。(Tatsuo Ishii) + + + + + + + PostgreSQL 12に対応するために、pg_attrdef.adsrcのかわりに + pg_get_expr()を使用するように修正しました。(Bo Peng) + + + + + + + のshutdownスクリプトを改良しました。(Tatsuo Ishii) + + + + + shutdownスクリプトがPgpool-IIのシャットダウン完了を待つように修正しました。 + + + + + + 環境変数CHECK_TIME_WAITtrueに設定されているとき、shutdownスクリプト実行時にnetstatコマンドでTCP/IPポートの使用を確認するように修正しました。 + + + + + + + + + + Doc: のドキュメントにpool_passwdハッシュ文字列を表示させる方法を追加しました。(Tatsuo Ishii) + + + + + + + + Doc: フェイルオーバに関する一般的な説明を追加しました。(Tatsuo Ishii) + + + + + + + pgpool_adm拡張がPostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + + + + "unable to bind. cannot get parse message"エラーを修正しました。 + (bug 531) (Tatsuo Ishii) + + + + + + + + ネイティブレプリケーションモードかつWatchdogが有効な場合、 + 子プロセスが異常終了した後に、オンラインリカバリが失敗する不具合を修正しました。 + (bug 483) (Muhammad Usama) + + + + + + + + 隔離(quarantine)されたバックエンドに対してヘルスチェックを続けるように修正しました。(Muhammad Usama) + + + + 隔離されたバックエンドが接続再開されたときに自動的に隔離状態から解消されるように、 + Pgpool-IIが隔離されたバックエンドに対してヘルスチェックを実行し続ける必要があります。 + + + + 詳細は[pgpool-hackers: 3295]をご参照ください。 + + + + + + + + マスターPgpool-IIでプライマリが隔離 (quarantine) されている場合、 + スタンバイPgpool-IIでプライマリノードが存在しない状態を修正しました。(Muhammad Usama) + + + + プライマリノードが隔離 (quarantine) されている場合、マスターPgpool-IIは、 + プライマリノードステータスの同期メッセージを送信します。 + スタンバイPgpool-IIでは現在のプライマリノードのステータスがDOWNでない場合、 + プライマリノードのステータスを更新しないように修正しました。 + + + + + + + + コマンドのmodeオプションが正しく動作するように修正しました。(Takuma Hoshiai) + + + + + + + + が正しいfollow master commandを生成するように修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュモジュールでoid配列の境界をチェックするように修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュモジュールのOff-by-oneエラーを修正しました。(Tatsuo Ishii) + + + + + + + + ヘルスチェックプロセスでpgpool.confがリロードされない不具合を修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュが有効な場合に発生するセグメンテーション違反を修正しました。(bug 525) (Tatsuo Ishii) + + + + + + + + LOG "checking zapping sent message ..."をDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + + 詳細は[pgpool-general: 6620]をご参照ください。 + + + + + + + + pool_hba.confsamenetが指定されている場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 詳細は[pgpool-general: 6601]をご参照ください。 + + + + + + + + Doc: 「7.3. Pgpool-II + Watchdogの構築の例」のfollow_master.shスクリプトの間違いとタイポを修正しました。(Bo Peng) + + + + + + + + 特定のケースでヘルスチェックプロセスが終了しない問題を修正しました。(Tatsuo Ishii) + + + + + + + + ネイティブレプリケーションモードの場合、standard_conforming_stringsの設定に応じてバックスラッシュを処理するように修正しました。 + (bug 467) (Bo Peng) + + + + + + + + FreeBSD上で発生するコンパイルエラーを修正しました。 + (bug 512, + bug 519) (Bo Peng) + + + + + + + + いくつかのメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + 潜在的なセグメンテーション違反を回避するために、フェイルオーバ実行中であるかどうかのチェックをより積極的に行うように修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.7.10 + + + リリース日 + 2019-05-16 + + + + + 改善点 + + + + + + Doc: ドキュメントリファレンスII, PCP コマンドを改善しました。(Tatsuo Ishii) + + + + + + + + すべてのバックエンドが停止しているときのフェイルオーバをスピードアップします。(Tatsuo Ishii) + + + + すべてのバックエンドが停止状態になった場合、search_primary_node_timeoutの値に関わらずプライマリノードの検索を中止し、 + 直ちにフェールオーバプロセスを終了するように修正しました。 + + + + ディスカッション: [pgpool-hackers: 3321] + + + + + + + + pgpool-recovery拡張とpgpool_setupを次期バージョンであるPostgreSQL12に対応しました。(Tatsuo Ishii) + + + + + + + Doc: ドキュメントのの項目を追加しました。(Takuma Hoshiai) + + + + + + + + 不具合修正 + + + + + + すべてのバックエンドがダウンした場合には表示される不適切なエラーメッセージ"ERROR: connection cache is full"を修正しました。 + (bug 487) (Bo Peng) + + + + すべてのバックエンドがダウンした場合に、Pgpool-IIが不適切なエラーメッセージ"ERROR: connection cache is full"を投げています。 + このエラーを"all backend nodes are down, pgpool requires at least one valid node"に修正しました。 + + + + + + + 使用されていない.sgmlファイルを削除しました。(Takuma Hoshiai) + + + + + + + + pool_worker_childプロセスの終了/フォークの繰り返しを避けるために修正しました。(Tatsuo Ishii) + + + + pool_worker_childはdo_query()を使用してWAL位置を取得するためのクエリを発行します。 + これにより、致命的エラーが発生した場合、pool_worker_childプロセスを終了し、 + Pgpool-IIの親プロセスは直ちに新しいプロセスをフォークするようにしています。 + このサイクルは無限に繰り返され、システムに大きな負荷を与える可能性があります。 + 無限に繰り返される終了/フォーク処理を回避するために、sr_check_periodをスリープさせるように修正しました。 + + + + + + + + のデフォル値が間違っていた不具合を修正しました。(Tatsuo Ishii) + + + + + + + + 「not enough space in buffer」エラーを修正しました。 + (bug 499) (Tatsuo Ishii) + + + + バックエンドから返されたエラーメッセージサイズが固定バッファサイズ (8192 bytes)を超えた場合、 + 「not enough space in buffer」エラーが発生していました。 + 固定サイズのバッファの使用を廃止し、動的にバッファサイズを割り当てるように修正しました。 + + + + + + + + DROP DATABASEの失敗を修正しました。 (Tatsuo Ishii) + + + + + + + + read_status_file()関数の間違った変数名を修正しました。 + (bug 493) (Takuma Hoshiai) + + + + + + + + 漏れていたtest/watchdog_setupをEXTRA_DISTに追加しました。(bug 470) (Bo Peng) + + + + + + + + Doc: マルチステートメントクエリはプライマリノードにのみ送信されるという説明をドキュメントに追加しました。(bug 492) (Tatsuo Ishii) + + + + + + + + Test: 014.watchdog_test_quorum_bypass レグレッションテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + failover/failback実行中に接続があった場合に発生しうるセグメンテーション違反を回避するために、セッションを終了するように修正しました。 + (bug 481, + bug 482) (Tatsuo Ishii) + + + + + + + + コンパイル時に発生するワーニング を修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつ"batch"モードで発生するメモリリークを修正しました。 + (bug 468) (Tatsuo Ishii) + + + + + + + + + リリース 3.7.9 + + + リリース日 + 2019-03-29 + + + + + 改善点 + + + + + + 新しい設定パラメータを追加しました。(Muhammad Usama) + + + + ユーザがサーバ側のSSL暗号設定をクライアントに優先して使うかどうかを設定できるように、新しい設定パラメータを追加しました。 + + + + この設定はデフォルトでオフで、従来と同じようにクライアント側のリクエストが優先されます。 + しかしこれはあくまで過去の挙動との互換性のための設定であり、悪意のあるクライアントが弱い暗号を利用できる可能性があります。 + ですから、常にこのパラメータをオンにしておくことを推奨します。 + + + + + + + + client cipher リストの設定が可能になりました。(Tatsuo Ishii, Yugo Nagata) + + + + Pgpool-IIがクライアントからのSSL接続を受け付ける際に受け入れる暗号のリストを指定する新しいパラメータ、 + を追加しました。これはすでにPostgreSQLに実装されていて、 + SSLが有効なときにセキュリティを強化するのに役立ちます。 + + + + + + + + 不具合修正 + + + + + + 不要なpgpool_statusファイルへの書き込みが減らしました。(Tatsuo Ishii) + + + + 今まではPostgreSQLバックエンドへの新しい接続が作成されるたびに、 + pgpool_statusファイルに書き込むためにfsync()が実行されていましたが、 + これにより、特定の条件で過剰なI/Oを発生させる可能性がありました。 + そのため、バックエンドの状況が変更されたときにのみfsync()を実行するように修正しました。 + + + + ディスカッション: [pgpool-general: 6436] + + + + + + + + + リリース 3.7.8 + + + リリース日 + 2019-02-21 + + + + + 不具合修正 + + + + + + Test: レグレッションテスト068.memqcache_bugの古いJDBCの関数及びタイポを修正しました。(Takuma Hoshiai) + + + + + + + + Doc: パラメータはサーバ起動時にのみ設定可能なことをドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + 特定の場合に、によって、オンラインリカバリが失敗する不具合を修正しました。(bug 431)(Tatsuo Ishii) + + + + + + + + 大きなデータがバックエンドから返されたときのメモリ使用量を減らすように修正しました。(bug 462) (Tatsuo Ishii) + + + + + + + + Test: 拡張問い合わせのテストスクリプトのエラーを修正しました。(Tatsuo Ishii) + + + + + + + + strip_quote()が空のクエリを処理するときに発生するセグメンテーション違反を修正しました。(bug 458) (Tatsuo Ishii) + + + + + + + + Doc: white/black_function_list 設定パラメータでスキーマ修飾が使えないという説明を追加しました。(Tatsuo Ishii) + + + + + + + + watchdog_setupスクリプトのに関するタイポを修正しました。(Takuma Hoshiai) + + + + + + + + 接続を確立しようとするとき、フェイルオーバが発生する場合に発生しうるセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + 参照: [pgpool-hackers: 3214] + + + + + + + + Doc: logdirに関するドキュメントのタイポを修正しました。(bug 453)(Tatsuo Ishii) + + + + + + + + クライアントが sync メッセージの後、次の簡易問い合わせの前に close メッセージを送ると発生しうるハングアップを修正しました。(Tatsuo Ishii) + + + 参照: [pgpool-hackers: 3164] + + + + + + + + PostgreSQLidle_in_transaction_session_timeoutが有効な場合に発生しうるPgpool-IIのハングアップを修正しました。(bug 448)(Tatsuo Ishii) + + + + + + + + Doc: 日本語ドキュメントのタイポを修正しました。(Bo Peng) + + + + + + + + + リリース 3.7.7 + + + リリース日 + 2018-11-22 + + + + + 不具合修正 + + + + + + + クライアントから送信された startup パケットのパラメータをソートするように修正します。 + (bug 444)(Takuma Hoshiai) + + + + キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 + コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + + + + + + + + ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 + (bug 443) (Bo Peng) + + + + パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 + bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 + これによりセグメンテーション違反が発生していました。 + + + + パッチがYugo Nagataにより提供されました。 + + + + + + + + スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 3.7.6 + + + + リリース日 + 2018-10-31 + + + + + 変更点 + + + + + + フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) + + + + + + + + LLVM JITをサポートするDBサーバに拡張機能をインストールするために、pgpool.specファイルを変更しました。(Bo Peng) + + + + + + + + Doc: オンラインリカバリのドキュメントに注意事項を追加しました。 + + + + よりも小さな値でなければなりません。 + + + + + + + + Test: SSL 接続のレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + + Doc: フェールオーバスクリプトに関する注意事項を追加しました。 + + + + failover/failbackスクリプトの中でPgpool-II自体にアクセスすることはお勧めしません。 + + + + + + + + Doc: のドキュメント及びエラーメッセージを改善しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供され、Bo Pengにより修正されました。 + + + + + + + + Test: regress.shにPGLIBの定義を追加しました。 (Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 + + + + + + + + 不具合修正 + + + + + + SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) + + + + パッチはPhil Ramirezにより提供されました。 + + + + + + + + ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 + (bug 434) (Takuma Hoshiai) + + + + ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 + + + + + + + + ネイティブレプリケーションモードで、クエリに時刻関数を含み、かつWHERE句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。(Bo Peng) + + + + ネイティブレプリケーションモードで、クエリにnow()CURRENT_TIMESTAMPなどの時刻関数を利用した場合、 + タイムスタンプ型の定数に書き換えるようになっています。 + しかし、Pgpool-IIは時刻関数含み、かつWHERE句にIN (SELECT ...)を含むクエリを対応しませんでした。 + + + + + + + + 拡張問い合わせの場合、時々期待される応答がフロントエンドに返されないことがあったので、修正しました。 + (bug 432) (Tatsuo Ishii) + + + + 解決策は、保留中のメッセージデータリストを使用することです。それはフロントエンドからのメッセージを記録し、同じ数のメッセージを受け取ることが期待されます。 + + + + パッチは Yugo Nagata によって作成され、Tatsuo Ishii により修正されました。 + + + + + + + + ストリーミングレプリケーションモードかつ拡張問い合わせの場合、クエリキャッシュを有効にするときに発生するメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + trigger_failover_command() 関数で発生するメモリリークを修正しました。 (Tatsuo Ishii) + + + + + + + + ストリーミングレプリケーションモードかつクエリキャッシュが有効の場合に更新クエリが発行された場合に発生するメモリリークを修正しました。(Bo Peng) + + + + 明示的なトランザクションでは、SELECTの結果は一時バッファにキャッシュされます。 + テーブルを変更する書込みSQLが送信されると、一時的なバッファをリセットしなければなりません。 + + + + + + + + 時々発生するレグレッションテスト 065.bug152 のエラーを修正しました。(Tatsuo Ishii) + + + + + + + + Test: EXECUTE/DEALLOCATEのレグレッションテストを追加しました。(Takuma Hoshiai) + + + + + + + + pgpool_recovery()関数のバージョンを1.1に更新するためのpgpool_recovery--1.0--1.1.sqlファイルを追加しました。 (Bo Peng) + + + + + + + + DEALLOCATEステートメントが発行された場合に発生するkind mismatchエラーを修正しました。(Bo Peng) + + + + EXECUTEDEALLOCATEPREPAREと同じノードに送信されるために、PREPAREをpool_add_sent_messageに追加するように修正しました。 + + + + 詳細は[pgpool-general: 6226]を参照してください。 + + + + + + + + パスワードの長さが正しくない場合、を更新しないように修正しました。 + (bug 419) (Takuma Hoshiai, Tatsuo Ishii) + + + + Pgpool-II 3.7以前では、に保存されているパスワードはMD5 パスワードのみです。 + ファイルのパスワードの長さをチェックするように修正しました。 + + + + + + + + Doc: ドキュメントの"new master"を"new primary"に変更しました。(Bo Peng) + + + + + + + + gccの新しいバージョンで発生するwarningを修正しました。(Tatsuo Ishii) + + + + + + + + Test: レグレッションテストの結果を削除するためのclean.shファイルを更新しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 + + + + + + + + .gitignoreファイルを追加しました。(Bo Peng) + + + + パッチはJesper Pedersenにより提供されました。 + + + + + + + + ヘルスチェックとの両方が無効になっている場合に、ノード0がダウンしたときに発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + + + + + Doc: ドキュメントとスクリプトのタイポを修正しました。(Tatsuo Ishii) + + + + パッチはJesper Pedersenにより提供されました。 + + + + + + + + Doc: のドキュメントの誤りを修正しました。 + + + + + + + + + リリース 3.7.5 + + + + リリース日 + 2018-07-31 + + + + 不具合修正 + + + + + + + raw モードでpool_passwd を使用しないように修正しました。 + (bug 411) (Tatsuo Ishii) + + + + raw モードではバックエンドが 1つしかないので、md5 認証でpool_passwd を使用する必要はありません。 + + + + + + + + 「write on backend 0 failed with error :"Success"」エラーを修正しました。 + (bug 403) (Tatsuo Ishii) + + + write() が 0 を返した場合、エラーとして扱わないように修正しました。 + + + + + + + + フェイルオーバ後、スタンバイ Pgpool-II で worker プロセスが起動されない不具合を修正しました。 + (bug 409) (Muhammad Usama) + + + + 修正パッチは Yugo Nagataによって提供されました。 + + + + + + + + フェイルオーバ時に、誤ったノード ID を渡す不具合を修正しました。 + (bug 406) (Muhammad Usama) + + + + + + + + 最初にダウンしたノードがフェイルバックした後にヘルスチェックプロセスが起動されない不具合を修正しました。 + (bug 407) (Tatsuo Ishii) + + + + + + + + pool_extract_error_message() で発生するメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + pool_extract_error_message() 関数での誤ったデータ型の変数宣言を修正しました。(Tatsuo Ishii) + + + + これにより、特定のプラットフォームでセグメンテーション違反が発生する可能性がありました。 + + + + + + + + armhf アーキテクチャで発生する per_node_error_log() のセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 修正パッチは Christian Ehrhardt によって提供されました。 + + + + + + + + フェイルオーバ後、スタンバイ Pgpool-II で間違ったバックエンドのロールが表示される不具合を修正しました。(Muhammad Usama) + + + + + + + + Doc:「MD5パスワード認証」、「Pgpool-II のインストール」、「pg_md5」などのドキュメントを改善しました。(Bo Peng) + + + + 修正パッチは Takuma Hoshiai によって提供されました。 + + + + + + + + Test: テスト006.memqcache の失敗を修正しました。( Tatsuo Ishii) + + + + + + + + + リリース 3.7.4 + + + + リリース日 + 2018-06-12 + + + + 不具合修正 + + + + + + 拡張問合せ、かつクエリキャッシュが有効の場合、レプリケーション遅延が大きすぎるときに発生しうる Pgpool-II のハングアップを修正しました。(Tatsuo Ishii) + + + + 詳細は [pgpool-general-jp: 1534] + を参考してください。 + + + + + + + + Doc: PCP コマンドの "-U" オプションのタイポを修正しました。 (Bo Peng) + + + + + + + + デバッグ用コードを削除しました。(Bo Peng) + + + + + + + + 拡張問合せでは、SET TRANSACTION READ ONLY の場合、書き込みトランザクションフラグを立てないように修正しました。 (Tatsuo Ishii) + + + + + + + + 3.7.2 と 3.7.3 で発生するフェイルオーバスクリプトに間違ったパラメータ %P (古いプライマリノードID) を渡す不具合を修正しました。 (Tatsuo Ishii) + + + + + + + + Doc: を使うために、ヘルスチェックが有効になっている必要がある明確な説明をドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + Doc: 古い のドキュメントを修正しました。 (Tatsuo Ishii) + + + + + + + + Test: extended_query_test のスクリプト test.sh を修正しました。 (Tatsuo Ishii) + + + + + + + + pgpool_setup に抜けていた health_check_timeout の設定を追加しました。(Tatsuo Ishii) + + + + + + + + Doc: recovery_2nd_stage_command はネイティブレプリケーションモードのみで設定する必要がある明確な説明をドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + pcp_recovery_node が "unused" 状態のノードをリカバリしないように修正しました。(Tatsuo Ishii) + + + + これにより、設定情報がないノードをリカバリしようとするときに発生する様々な問題を回避できます。 + + + + 詳細は + [pgpool-general: 5963] + をご参照してください。 + + + + また、空の文字列の引数に対応できるように引数をダブルクォートで囲むように、pgpool_recovery 関数を修正しました。 + + + + + + + + + リリース 3.7.3 + + + + リリース日 + 2018-04-17 + + + 不具合修正 + + + + + + + デフォルトではノードごとヘルスチェックパラメータの設定が無効になりました。 + + + + + + + + コマンドで -g オプションを指定した場合に発生するハングアップを修正しました。(bug 391) (Tatsuo Ishii) + + + + + + + + Test: ノード0 がダウンした場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + + to_regclass を呼び出すときにスキーマ名を含むように修正しました。(Tatsuo Ishii) + + + + + + + + ALWAYS_MASTER が on の場合に発生する Pgpool-II 子プロセスのセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + Pgpool-II 3.7.1 で、以下の条件をすべて満たす場合にセグメンテーション違反が発生していました。 + + + + ストリーミングレプリケーションモード + + + + + fail_over_on_backend_error = off + + + + + マスタノードが ALWAYS_MASTER に設定してある + + + + + pgpool_status ファイルの上記 3)で設定したノードの状態が down である + + + + + + + + + + + Doc: watchdog に関するドキュメントを更新しました。(Tatsuo Ishii) + + + + + + + Doc: 新しい設定パラメータの追加方法に関する README ファイルを追加しました。(Tatsuo Ishii) + + + + + + + 「unable to bind D cannot get parse message "S1"」エラーによるハングアップを修正しました。(Tatsuo Ishii) + + + + + + + + Test: 003.failover レグレッションテストが失敗しないように修正しました。(Bo Peng) + + + + + + + Doc: backend_flag を使用してフェイルオーバ回避できるようにする説明をドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + + + + Doc: ドキュメントのタイポを修正しました。(Bo Peng) + + + + + + + + + + Test: ノード0がプライマリではない場合のレグレッションテストを追加しました。(Tatsuo Ishii) + + + + + + + + レプリケーションモードで pgpool_setup が失敗するのを修正しました。(Tatsuo Ishii) + + + + + + + PostgreSQL 10 に対応できるように pgpool_switch_xlog を修正しました。(Tatsuo Ishii) + + + + + + + 3.7.2 のコミット 9022ff842fb5dbbe06e2f2f4cf38fadf47b592da を取り消しました。(Tatsuo Ishii) + + + このコミットにより、 プライマリがノード 0 以外の場合に更新クエリを実行できなくなっていました。 + + + + + + + Test: 拡張クエリのテストスクリプトを改善しました。(Tatsuo Ishii) + + + + + + + + Doc: pgpool_adm エクステンション関数の例を修正しました。(Tatsuo Ishii) + + + + + + + + + + + リリース 3.7.2 + + + + リリース日 + 2018-02-13 + + + + このリリースでは、Pgpool-II 3.7.0、3.6.6、3.5.10 で追加された、ソケット + への書き込み不具合を修正しています。この障害により、ネットワーク負荷が + 高い状態でのフロントエンド、バックエンドへのメッセージ送信の際に、不正 + なメッセージが送信される可能性があります。3.7.x、3.6.6 以降、3.5.10 以降 + のバージョンを利用中のユーザは、できるだけ早くアップグレードすることを + お勧めします。 + + + + + 変更点 + + + + + + Pgpool-II が libressl の環境でビルドできるようになりました。(Tatsuo Ishii) + + + 詳細は [pgpool-hackers: 2714] を参照してください。パッチは Sandino Araico Sanchez により提供されました。 + + + + + + + + PostgreSQLのようにフロントエンドソケットを TCP_NODELAY、non-blocking に設定しました。 (Tatsuo Ishii) + + + + + + + + systemd サービスを用いてPgpool-II を停止するときに fast モードで停止するように変更しました。 (Bo Peng) + + + + + + + + pgpool_setup の recovery.conf で restore_command を使用するように pgpool_setup を変更します。 (Bo Peng) + + + + + + + 不具合修正 + + + + + + コミットまたはロールバック時に誤って書き込みトランザクションフラグをセットする不具合を修正しました。 (Tatsuo Ishii) + + + + + + + + watchdog のフェイルオーバーコンセンサスの設定が異なる場合、警告メッセージを表示するように修正しました。(Muhammad Usama) + + + + + + + + Doc: ドキュメントのタイポを修正しました。 (Bo Peng) + + + + + + + + ソケット書き込みの不具合を修正しました。 (Tatsuo Ishii) + + + ネットワーク負荷が高い場合に、フロントエンド、バックエンドへのメッセージ送信の際に、 + 不正なメッセージが送信される可能性があるのを修正しました。 + + + このバグは 3.6.6、3.5.10 がリリースされた際に追加されたものです。 + + + + + + + + ALWAYS_MASTER がオンの場合に発生するPgpool-II の子プロセスのセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + + 以下で条件で発生します。 + + + + + ストリーミングレプリケーションモード + + + + + + fail_over_on_backend_error=off + + + + + + マスタノードの backend_flag が ALWAYS_MASTER に設定してある + + + + + + pgpool_status ファイルで #3 のノードの状態が down である + + + + + + + 詳細は [pgpool-hackers: 2687][pgpool-general: 5881] を参照してください。 + + + + + + + + デバッグモードがオン、かつ log_line_prefix に %a を指定した場合に発生するセグメンテーション違反を修正しました。(bug 376) (Tatsuo Ishii) + + + + + + + + + ノードごとのヘルスチェックパラメータのデータ型の不具合を修正しました。(Tatsuo Ishii) + + + + + + + + 拡張プロトコル、レプリケーションモードかつロードバランスを使用した場合に発生しうるハングアップを修正しました。(bug 377) (Tatsuo Ishii) + + + + + + + + + + リリース 3.7.1 + + + + リリース日 + 2018-01-09 + + + + 不具合修正 + + + + + + + Makefile を改善しました。(Bo Peng) + + + + Tomoaki Sato がパッチを提供しました。 + + + + + + + + Doc: ドキュメントのミスとタイポを修正しました。(Bo Peng) + + + + + + + + スクリプト内の /bin/ed/bin/sed に置き換えました。(Tatsuo Ishii) + + + /bin/sed/bin/edに比べてほとんどのディストリビューションの基本パッケージに含まれているためです。 + + + + + + + + ログを取得するために pgpool.service とsysconfig ファイルを変更しました。(Bo Peng) + + + + ログを取得するために、非デーモンモードで Pgpool-II を起動するように Type=forking を削除し、OPTS=" -n" を追加しました。journalctl コマンドで Pgpool-II の systemd のログを確認することができます。 + + + + + + + + Doc: 新しいドキュメント「ドキュメントのコンパイルとインストール」を追加しました。(Tatsuo Ishii) + + + + + + + + ノードごとのヘルスチェックパラメータが無視される不具合を修正しました。(bug 371) (Tatsuo Ishii) + + + + また、 がノードごとのヘルスチェックパラメータを pgpool.conf に追加するように変更しました。 + + + + + + + + ヘルスチェックプロセスがエラーで終了したときに、Pgpool-II が新しいヘルスチェックプロセスをフォークするように修正しました。(Tatsuo Ishii) + + + + バックエンドソケットの読み込みに失敗した場合 (これはhealth_check_userが間違っていると発生する可能性がある)、ヘルスチェックプロセスは pool_read() でFATALエラーを発生させ、ヘルスチェックプロセスを終了させます。 + そして、Pgpool-II は、新しいヘルスチェックプロセスをフォークします。 + これは永遠に繰り返されます。 + + + + + + + + ネイティブレプリケーションモードで発生するタイムスタンプデータの不整合を修正しました。 (Bo Peng) + + + + PostgreSQL 10から「CURRENT_DATE」のようなカラムのデフォルト値が変わったので、Pgpool-II はこれらのタイムスタンプをリライトしませんでした。これによって、データの不整合が発生していました。 + + + + + + + + Doc: のドキュメントを修正しました。 (Tatsuo Ishii) + + + + ロジカルレプリケーションモードにも対応するとの説明を追加しました。 + + + + + + + + 一部のログメッセージをデバッグメッセージにダウングレードしました。(Tatsuo Ishii) + + + + 前回の開発で誤って残していました。 + + + + + + + + Test: bug370 のテスト用データを追加しました。(Tatsuo Ishii) + + + + + + + + バックエンドからのパケットを読み込む際の再同期のロジックを修正しました。(Tatsuo Ishii) + + + + read_kind_from_backend() は、バックエンドからメッセージを読み取り、"ready for query" メッセージが受信されたときにバックエンドノードを再同期します。 + しかし、pool_pending_message_pull_out() を呼び出して「sync メッセージを受信した」を削除することを忘れていました。 + これによって、バックエンドからのパケットの読み取り中に Pgpool-II がハングアップする可能性がありました。 + pool_pending_message_pull_out()を呼び出し、「sync メッセージを受信した」を削除するように修正しました。 + + + + + + + + 問い合わせ中に Pgpool-II がハングアップする不具合を修正しました。(bug 370) (Tatsuo Ishii) + + + + エラークエリがプライマリに送信され、sync メッセージを送信せずに、次のクエリを実行するときに、 + PostgreSQL のシステムカタログへの問い合わせが必要な場合、Pgpool-IIdo_query() 関数でハングアップしていました。 + + + + + + + + "ready for query" メッセージを受信したときにトランザクション状態を返すように修正しました。(Tatsuo Ishii) + + + + 今まではプライマリノードまたはマスターノードの状態をフロントエンドに返していました。 + ほとんどの場合、問題がありませんでした。 + ただし、プライマリノードまたはマスターノード以外のノードがエラー状態を返した場合(ロードバランスノードがプライマリまたはマスターノード以外で、誤った SELECT クエリの場合に発生する可能性がある)、このエラー状態をフロントエンドに返す必要がありました。 + + + + + + + + Test: extended-query-test テストスクリプトを修正しました。(Tatsuo Ishii) + + + + + + + Doc: ドキュメント「Pgpool-IIの動作モード」 を改善しました。 (Tatsuo Ishii) + + + + + + + + + リリース 3.7 + + + + リリース日 + 2017-11-22 + + + + + 概要 + + + このバージョンでは、新しいwatchdog機能とノードごとのヘルスチェックの設定により、フェイルオーバの信頼性が向上しています。また、このバージョンでは、PostgreSQL 10の新しいSQLパーサ、ロジカルレプリケーション、およびいくつかの管理関数の名前の変更に対応しています。 + + + + Pgpool-II 3.7 の主な改善点は以下のとおりです。 + + + + + + + + + + クォーラム機能によりフェイルオーバを決定するようになりました。 + + + + + + + pool_hbaではホスト名を指定できるようになりました。 + + + + + + + PostgreSQLバックエンドごとにヘルスチェックパラメータを設定できるようになりました。 + + + + + + + AWS Aurora に対応しました。 + + + + + + + PostgreSQL 10 のSQLパーサを取り込みました。 + + + + + + ロジカルレプリケーションに対応しました。 + + + + + + + + + 主な改善点 + + + + + + + クォーラム機能によりフェイルオーバを決定するようになりました。(Muhammad Usama) + + + + Pgpool-IIはクォーラム機能を利用し、watchdogクラスタ内でPostgreSQLバックエンドノードのフェイルオーバを決定する機能を追加しました。この機能追加により、スプリットブレインを防止することができます。 + + + + + + この変更により、failover、failback、promote-node コマンドの処理も変更しました。 + + + + + また、マスタノードだけがフェイルオーバーを実行することになったので、フェイルオーバ時にロックする必要がなくなりました。 + + + + + この機能追加に伴い、以下の 3つのフェイルオーバに関するパラメータを追加しました。 + + + -Test: 新しいレグレッションテスト「011.watchdoc_quorum_failover」を追加しました。(Tatsuo Ishii) - + failover_when_quorum_exists + + + + + + failover_require_consensus + + + + + allow_multiple_failover_requests_from_node + + + + + + + + + + + pool_hbaでホスト名を指定できるようになりました。(Muhammad Usama) + + + + pool_hba設定ファイルの address フィールドにおいて、以前はCIDRアドレスのみに対応していましたが、この修正により、ホスト名にも対応するようになりました。 + + + + + この機能追加に伴い、以下の改善も行いました。 + + + + + (1) pool_hba レコードはロード時に完全に解析されるようになりました。Raw レコード行ではなく、構造化されたデータを保存します。これにより、新規接続時間が短縮され、パフォーマンスが向上します。 + + + + (2) エラー/ログメッセージが改善されました。 + + + + + (3) auth-options フィールドの処理が改善されました。 + + + + + + + + PostgreSQLノードごとにヘルスチェックパラメータを設定できるようになりました。(Tatsuo Ishii, Muhammad Usama) + + + + 従来のヘルスチェックでは、すべてのPostgreSQLノードを順番にチェックし、パラメータはノードごとには設定できず、全ノードで共通の設定でした。 + + + + この機能追加により、Pgpool-IIの親プロセスがPostgreSQLノードごとにヘルスチェックプロセスをフォークし、ヘルスチェックに関連するパラメータがノードごとに設定できるようになりました。 + + + + 例えば、PostgreSQLバックエンドノードが3台の場合、以下のように設定すると、 + + + health_check_period = 10 + health_check_period0 = 5 + + + + + ノード0にhealth_check_period = 5 が設定され、ノード1 と2 にhealth_check_period = 10が設定されます。 + + + + + + + + PostgreSQL 10 のパーサを取り込みました。(Bo Peng) + + + + + + + + + + + AWS Auroraに対応しました。 (Tatsuo Ishii) + + + + プライマリノード検出ロジックを制御する新しいバックエンドフラグ「ALWAYS_MASTER」を追加しました。Aurora ではpg_is_in_recovery()を使用できないため、Auroraの "writer"として指定されたバックエンドに「ALWAYS_MASTER」を割り当てます。Aurora は常にマスタに同じホスト名を使用するため、find_primary_node() は「ALWAYS_MASTER」フラグが立っているノードIDを返します。 + + + + 詳細は、ALWAYS_MASTERを参照してください。 + + + + それ以外は、Auroraではストリーミングレプリケーションモードを使用することができます。 Auroraではレプリケーション遅延を検査できないことに注意してください。は常に0にする必要があります。 + + + + 設定については AWS設定の例を参照してください。 + + + + + + + + ロジカルレプリケーションモードを追加しました。(Tatsuo Ishii) + + + + ロジカルレプリケーションモードはロジカルレプリケーションを使用するPostgreSQLサーバと一緒に使うことができます。このモードでは、PostgreSQLがテーブルを同期する責任を持ちます。 + + + + このモードでは負荷分散が可能です。ロジカルレプリケーションは必ずしもすべてのテーブルをレプリケーションしないので、負荷分散させるテーブルがレプリケーションされるようにするのはユーザの責任です。 + + + + サンプルの設定ファイルは $prefix/etc/pgpool.conf.sample-logicalです。 + + + + pgpool_setup もロジカルレプリケーションモードに対応しました。 + + + + + + + + + 他の改善点 + + + + + + Test: Watchdog のテストケースを追加しました。 (Muhammad Usama) + + + + + + + + Test: extended-query-test に新しいテストケース "node_js.data"を追加しました。 (Tatsuo Ishii) + + + + + + + + Doc: 「pool_hba.conf ファイル」に関するドキュメントを更新しました。(Muhammad Usama) + + + + + + + + + pgpool_setupslonyモードに対応しました。(Tatsuo Ishii) + + + + + + + + OpenSSL 1.1に対応しました。(Tatsuo Ishii, Muhammad Usama) + + - - - - -Test: 新しいテストケース「extended-query-test」を追加しました。(Tatsuo Ishii) - - - -この新しいテストケースは、pgprotoコマンドを使い拡張クエリをテストするために追加しました。 - - + + + + + Test: 新しいレグレッションテスト「069. memory_leak_extended」を追加しました。(Tatsuo Ishii) + + - - - - -保留中のメッセージとバックエンドの応答を確認するためのデバッグ情報を追加しました。(Tatsuo Ishii) - - - -新しい関数pool_check_pending_message_and_reply()を追加しました。保留中のメッセージの種類とバックエンドの応答メッセージの種類が一致しない場合、デバッグメッセージを出力します。今までは、read_kind_from_backend()関数のみでした。 - - + + + + + Doc: インメモリキャッシュに関するドキュメントを更新しました。(Tatsuo Ishii) + + + + + + + Doc: ドキュメントに「インストールのヒント」を追加しました。(Tatsuo Ishii) + + - - - - -ヘルスチェックのためのデバッグ情報を追加しました。(Tatsuo Ishii) - - + + + + + Test: 新しいレグレッションテスト「011.watchdoc_quorum_failover」を追加しました。(Tatsuo Ishii) + + - - + + + + + Test: 新しいテストケース「extended-query-test」を追加しました。(Tatsuo Ishii) + + + + この新しいテストケースは、pgprotoコマンドを使い拡張クエリをテストするために追加しました。 + + - - - 変更点 - - - - - -コマンドの出力に「role」フィールドを追加しました。(Tatsuo Ishii) - - - -「role」フィールドに「primary」、「standby」、「master」、「slave」のいずれかが出力されます。 - - - - - - -パラメータのデフォルト値を「stream」に変更しました。(Tatsuo Ishii) - - - -pool_config_variable.cのデフォルト値が「STREAM_MODE」であるため、この変更が必要でした。 - - + + + + + 保留中のメッセージとバックエンドの応答を確認するためのデバッグ情報を追加しました。(Tatsuo Ishii) + + + + 新しい関数pool_check_pending_message_and_reply()を追加しました。保留中のメッセージの種類とバックエンドの応答メッセージの種類が一致しない場合、デバッグメッセージを出力します。今までは、read_kind_from_backend()関数のみでした。 + + - - - - -終了時に新しいヘルスチェックプロセスをフォークするようにしました。(Tatsuo Ishii) - - + + + + + ヘルスチェックのためのデバッグ情報を追加しました。(Tatsuo Ishii) + + - - + + - - - - -Doc: PGPOOL SHOWコマンドのパラメータグループに「health_check」を追加しました。(Tatsuo Ishii) - - + + + 変更点 + + + + + + コマンドの出力に「role」フィールドを追加しました。(Tatsuo Ishii) + + + + 「role」フィールドに「primary」、「standby」、「master」、「slave」のいずれかが出力されます。 + + + + + + + master_slave_sub_modeパラメータのデフォルト値を「stream」に変更しました。(Tatsuo Ishii) + + + + pool_config_variable.cのデフォルト値が「STREAM_MODE」であるため、この変更が必要でした。 + + - - + + + + + 終了時に新しいヘルスチェックプロセスをフォークするようにしました。(Tatsuo Ishii) + + - - - - -Doc: 古いhtmlドキュメント及び関連ファイルを削除しました。(Tatsuo Ishii) - - - - + + - - - 不具合修正 - - - - - -ストリーミングレプリケーションモードで、'H' (flush) メッセージを受信した後に発生するハングアップを修正しました。 (bug 345) (Tatsuo Ishii) - - + + + + + Doc: PGPOOL SHOWコマンドのパラメータグループに「health_check」を追加しました。(Tatsuo Ishii) + + - - - - -ereportを呼び出さないように終了シグナルハンドラを修正しました。(Tatsuo Ishii) - - - -終了シグナルハンドラに競合状態が発生する可能性がありました。 - - - -詳細は、 [pgpool-hackers:2545]を参照してください。 - - + + - - - - -Doc: replicate_selectの動作に関する説明を修正しました。(Yugo Nagata) - - + + + + + Doc: 古いhtmlドキュメント及び関連ファイルを削除しました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + + ストリーミングレプリケーションモードで、'H' (flush) メッセージを受信した後に発生するハングアップを修正しました。 (bug 345) (Tatsuo Ishii) + + - - + + + + + ereportを呼び出さないように終了シグナルハンドラを修正しました。(Tatsuo Ishii) + + + + 終了シグナルハンドラに競合状態が発生する可能性がありました。 + + + + 詳細は、 [pgpool-hackers:2545]を参照してください。 + + - - - - -Test: メモリリークテストのバグを修正し、新しいメモリリークテストを追加しました。(Tatsuo Ishii) - - + + + + + Doc: replicate_selectの動作に関する説明を修正しました。(Yugo Nagata) + + - - - - -ヘルスチェック後に再試行が成功したログを記録するようになりました。 (Tatsuo Ishii) - - - -以前は、ヘルスチェックが再試行されたログだけが記録されていましたが、再試行が成功したかどうかは明らかではありませんでした。 - - + + - - - - -Doc: 「AWS設定の例」でヘルスチェックリトライの設定に関する説明を追加しました。(Tatsuo Ishii) - - + + + + + Test: メモリリークテストのバグを修正し、新しいメモリリークテストを追加しました。(Tatsuo Ishii) + + + + + + + + ヘルスチェック後に再試行が成功したログを記録するようになりました。 (Tatsuo Ishii) + + + + 以前は、ヘルスチェックが再試行されたログだけが記録されていましたが、再試行が成功したかどうかは明らかではありませんでした。 + + + + + + + + Doc: 「AWS設定の例」でヘルスチェックリトライの設定に関する説明を追加しました。(Tatsuo Ishii) + + - + - + diff --git a/doc.ja/src/sgml/release-4.0.sgml b/doc.ja/src/sgml/release-4.0.sgml index cd927e9b7..d75b3bbb6 100644 --- a/doc.ja/src/sgml/release-4.0.sgml +++ b/doc.ja/src/sgml/release-4.0.sgml @@ -1,1203 +1,5514 @@ - - - リリース 4.0.2 + + リリース 4.0.25 - リリース日 - 2018-11-22 + 2023-11-30 - - - 不具合修正 + + ドキュメント修正 - - - - -クライアントから送信された startup パケットのパラメータをソートするように修正します。 -(bug 444)(Takuma Hoshiai) - + - -キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 -コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + PCPがすべてのアドレスをリッスンするにはpcp_listen_addresses = '*'の設定が必要である旨を「Pgpool-II + Watchdogの構築の例」に記載しました。 - + + + + + + リリース 4.0.24 + + リリース日 + 2023-08-17 + + + + 変更点 + - - - -Pgpool-IIの内部接続の認証の不具合を修正しました。(Muhammad Usama) - + - -これは「SCRAM認証と証明書の認証のサポート」の機能追加による問題です。 -問題は、connection_do_auth()でバックエンドに対して認証する際に、 -バックエンドが「認証 ok」との応答を返すと -すぐに呼び出し元にもどっていました。そのため、認証自体は成功しましたが、 -connection_do_auth()は「Ready for query」を受信するまで処理を進めませんでした。 -「認証 ok」との応答を受け取った後も「Ready for query」を受信するまでデータの処理を継続するように修正しました。 + 共有メモリの初期化後にのみ、システム終了コールバックを呼び出すようにしました。(Muhammad Usama) - -パッチがTatsuo Ishiiにより提供され、Muhammad Usamaにより修正されました。 + 共有メモリの取得に失敗して、終了時コールバックが呼び出された場合、クリーンアップ関数は、共有メモリに存在するprocess_infoにアクセスする際にセグメンテーション違反を引き起こす可能性がありました。 + process_infoがNULLのときに終了コールバックからの中断で修正することもできますが、共有メモリの初期化に成功した後に関数をインストールする方がより良いアプローチです。 + なぜなら、システムの残りの部分は常にprocess_infoがNULLになることはないと想定しており、また、子プロセスが生成される前にクリーンアップをする必要はないからです。 - + - + - -gcc 8.xで発生するコンパイラの警告を修正しました。(Takuma Hoshiai) + 一部のシステムカタログ照会関数にスキーマ修飾を追加しました。(Tatsuo Ishii) - + + + + + 不具合修正 + - + - -ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 -(bug 443) (Bo Peng) + find_primary_node_repeatedlyが指定時間内で終了しない問題を修正しました。(Bo Peng) + + + + - -パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 -bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 -これによりセグメンテーション違反が発生していました。 + pgprotoをパラメータを使用するbindメッセージを処理できるようにしました。(Tatsuo Ishii) - -パッチがYugo Nagataにより提供されました。 + 以前、pgprotoはパラメータを持たないbindメッセージしか処理できませんでした。 - + + + + + ドキュメント修正 + - + - -スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + 停止モードの意味を明確にしました。(Tatsuo Ishii) - + - + - -クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + オンラインリカバリーの説明を改善しました。(Bo Peng) - - - - - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + 複数のpgpoolノードでwatchdogが有効になっていない場合、オンラインリカバリーのセカンドステージが適切に機能しないことについて言及しました。 - + + + + + 回帰テスト修正 + - + - -拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) + 時折発生する069.memory_leak_extendedテストの失敗を修正しました。(Tatsuo Ishii) + + + 偶発するテストの失敗の原因は、pgbenchが終了した後にpsコマンドを実行する前にpgpoolの子プロセスが消えてしまうことにあると判明しました。 + これにより、「DISCARD ALL cannot be executed within a pipeline」というkind mismatchのFATALエラーが発生していました。 + これを修正するために、pgbenchをバックグラウンドで実行し、pgbenchが終了する前にプロセスのサイズを取得するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html - - - + + + - - - リリース 4.0.1 + + リリース 4.0.23 - リリース日 - 2018-10-31 + 2023-05-18 - - - 変更点 - - - - - -Pgpool-IIの実行ユーザとrootユーザ以外のユーザがsslキーファイルを所有することができるようになりました。(Muhammad Usama) - - - - - - - -フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) - - - - - - - - 不具合修正 - - - - - -MD5AES及びテキストパスワードの長さが異なることによって時々発生するファイルの破損を修正しました。(Muhammad Usama) - - -パッチはTakuma Hoshiaiによって提供され、Muhammad Usamaによって修正されました。 - - - - - - - -SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) - - - -パッチはPhil Ramirezにより提供されました。 - - - - - - - -ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 -(bug 434) (Takuma Hoshiai) - - - -ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 - - - - - + + 変更点 + + + + + 内部クエリでスキーマ修飾を使用するように変更しました。(Tatsuo Ishii) + + + 関数やキャストなどの一部のオブジェクトは、「pg_catalog.」スキーマ修飾を使用していませんでした。 + これによって直ちにセキュリティ上の懸念が生じるわけではありませんが、スキーマ修飾を使用することは常に良い習慣ですので、変更しました。 + + + + - - - リリース 4.0 - - - リリース日 - 2018-10-19 - + + 不具合修正 + + + + + musl libcを使用するシステムでのコンパイルエラーを修正しました。(bug 790) (Tatsuo Ishii) + + + パッチはleimaohuiによって提供されました。 + + - - - 概要 + + - -このバージョンでは、SCRAM認証および証明書認証に対応し、ロードバランスの制御が向上しており、PostgreSQL11の新しいSQLパーサを取り込んでいます。 + 複数のクエリキャッシュの不具合を修正しました。(Tatsuo Ishii) - -Pgpool-II4.0の主な改善点は以下のとおりです。 + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + - + + + + 特殊なケースでsrワーカーが間違ったクエリをスタンバイサーバに送信する不具合を修正しました。(Tatsuo Ishii) + + + ALWAYS_PRIMARYフラグが設定されている場合、PRIMARY_NODE_IDマクロは、プライマリがダウンしている場合でも、-1ではなくノードIDを返していました。 + この場合、ストリーミングレプリケーション遅延をチェックするワーカープロセスは、PostgreSQLのバージョンに応じてSELECT pg_current_wal_lsn()またはSELECT pg_current_xlog_location()をスタンバイに送信し、当然エラーが発生していました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + - + + + + DEALLOCATEによる種類不一致エラーを修正しました。 + (bug 780) (Tatsuo Ishii) + + + 以下の条件がすべて満たされた場合、種類不一致エラーが発生していました。 + - - -SCRAM認証および証明書認証の対応 - + + ストリーミングレプリケーションモード + + + - - -PostgreSQLの偽のプライマリサーバ検出 - + + ロードバランスノードがプライマリ以外のノード + - + + - - -ロードバランスの改善: - - - - -更新を伴うクエリ実行後の更に細かい負荷分散の制御 - - - - - -特定クエリに対する負荷分散の制御 - - - - - -パラメータによる負荷分散の重み指定 - - - - - + + PREPAREがマルチステートメントクエリで使用されている + + + + + + - - - - に最終更新時刻のタイムスタンプ追加 - - + + ドキュメント修正 + + + + + の説明を追加しました。(Chen Ningwei) + + - - - -PostgreSQL11のSQLパーサの取込 - - + + + + PREPARE/EXECUTE/DEALLOCATEに関する制限を追加しました。(Tatsuo Ishii) + + - - - -クライアントメッセージのログ出力の追加 - - - - - - - - バージョン4.0への移行 - - -バージョン4.0には、以前のバージョンとの互換性に影響する多数の変更点が含まれています。 -以下の非互換性に注意してください。 - - - - - - -1st/2nd ステージのオンラインリカバリコマンドにリカバリされるノードの番号を取得するためのパラメータを追加しました。(Tatsuo Ishii) - - - -オンラインリカバリスクリプトは4つではなく5つのパラメータを受け取るようになりました(5番目のパラメータはリカバリされるノードの番号です)。 -pgpool_recoveryをバージョンアップするためには、ALTER EXTENSION pgpool_recovery UPDATE TO '1.2'を実行してください。 -5番目のパラメータの情報を必要としない場合、既存の4つのパラメータの形式でリカバリスクリプト使用することが出来ます。 - - - -詳細は、を参照してください。 - - - - - - -パラメータfail_over_on_backend_errorは、に変更されました。(Muhammad Usama) - - - -の代わりに古いパラメータ名fail_over_on_backend_errorが使われた場合、警告メッセージを出力します。 - - - - - - -pgpool.conf内でAESで暗号化されたパスワードを指定できます。(Muhammad Usama) - - - -4.0以降では、pgpool.confファイル内のおよびでAESで暗号化されたパスワードを指定することができます。 - - - -パスワード文字列の先頭にTEXTを付与した暗号化されていないクリアテキストパスワードを指定します。 -有効な接頭辞が無い場合、Pgpool-IIは文字列を平文のパスワードと見なします。 - - - -pgpool.confファイル内のおよびで指定された空のパスワード文字列は、が特定のパスワードを含まない場合だけ使われます。 -もし、これらのパラメータが空白だった場合、Pgpool-IIは空のパスワードを使用する前に最初にファイルから特定のユーザのパスワードの取得を試みます。 - - - - - - - -主要な改善点 - - - - - -SCRAM認証および証明書認証に対応しました。(Muhammad Usama) - - - - -SCRAM認証方式に対応しました。 - - - -pool_passwd認証ファイルを使用したSCRAM認証に対応しました。 - - - -詳細はを参照してください。 - - - - - -Pgpool-IIとフロントエンドの間でCERT認証を使用できます。 - - - -この認証方法を使用する場合、Pgpool-IIはクライアントが有効な証明書を提供することを必要とします。 - - - -詳細はを参照してください。 - - - - - -フロントエンド/バックエンドで異なる認証方式を利用できます。 - - - -これはクライアントとPgpool-II、およびPgpool-IIとバックエンド間で異なる認証方式を利用できます。 - - - - - - - -は、3つの形式でパスワードを保存できるようになりました。 -AES256暗号化形式、平文形式、md5形式です。 - - - -Pgpool-IIは接頭辞によってパスワードの形式を確認するため、pool_passwd内の各パスワードのエントリはパスワードの形式を接頭語として付ける必要があります。 - - - -md5ハッシュパスワードはmd5接頭辞、AES256暗号化パスワード形式はAES接頭辞を使って保存することができます。 -平文形式のパスワードの保存のためには、TEXT接頭辞を使用できます。 - - - -有効な接頭辞がない場合、Pgpool-IIは文字列を平文のパスワードとして見なします。 - - - -例: - -username1:AESIFwI86k+ZbVdf6C+t3qpGA== -username2:md59c6583185ba6a85bdcd1f129ec8cabb4 -username3:TEXTmypassword - - - - - - - - -を用いずにデータベースへの接続にMD5認証およびSCRAM認証方式を使えます。 - - - -新しい設定パラメータを追加しました。 -このパラメータは接続するユーザのパスワードがファイルに含まれていない、かつ(クライアントから提供された)パスワードがバックエンドのMD5もしくはSCRAM認証で使われる場合、Pgpool-IIがクライアントとのクリアテキストのパスワード認証を行うことを許可します。 - - - - - - - -新しいコマンドは、暗号化されたパスワードを生成します。 - - - -AESで暗号化されたパスワードを作成できるコマンドを追加しました。 - - - - - - - -詳細は、を参照してください。 - - + + + + Pgpool-IIで-Dオプションを使用する場合の注意点を追加しました。(Tatsuo Ishii) + + - - - - -新しいパラメータを追加しました。 (Tatsuo Ishii) - - - -detach_false_primary = onの場合、偽のプライマリノードを切り離します。 -デフォルトはoffです。pg_stat_wal_receiverを使用しているため、このパラメータはストリーミングレプリケーションモードかつPostgreSQL9.6以降でのみ有効です。 -PostgreSQL9.5以前のバージョンの場合、エラーは発生せずこの機能は無視されます。 - - - - - - -更新を含むクエリ実行後の負荷分散の振る舞いを指定するを追加しました。(Tatsuo Ishii) - - - -このパラメータは、更新クエリ実行後の振る舞いを指定できます。 - - - - - - -パラメータとして負荷分散の重みの割合を指定できるようになりました。(Bo Peng) - - - -新しい機能としておよびに対して負荷分散の重みを指定できます。 - - - - -特定のデータベース接続およびバックエンドノードに対して、指定した負荷分散の比でSELECTクエリを送るためのリスト"database-name:node id(ratio)"を指定できます。 - - - -特定のアプリケーション接続およびバックエンドノードに対して、指定した負荷分散の比でSELECTクエリを送るためのリスト"application-name:node id(ratio)"を指定できます。 - - - -この負荷分散の比は 0から1の間の値を指定できます。 -デフォルトは1.0です。 - - + + + + 「RPMからのインストール」セクションを強化しました。(Bo Peng) + + - - - - -負荷分散すべきではないSQLパターンのリストを指定できる を追加しました。(Bo Peng) - - - -プライマリノードだけに送るSQLのパターンをセミコロンで区切られたリストで指定できます。 -SQLのパターンには正規表現を使用することができます。 -この機能はマスタースレーブモードのみサポートします。 - - + + + + 「Pgpool-II + Watchdogの構築の例」から「-D」起動オプションの設定を削除しました。(Bo Peng) + + - - - - -クライアントのメッセージに関するログ出力を許可するを追加しました。(Takuma Hoshiai, Tatsuo Ishii) - - - -log_client_messages = onを設定すると, デバックメッセージなしでクライアントのメッセージをログ出力できます。 - - - - - - - コマンドにlast_status_change列を追加しました。 - - - -新しい列はstatusもしくはroleが変更された時刻を示します。 - - - -列を追加した理由に関しては[pgpool-hackers: 2822]を参照してください。 - - - - - - -PostgreSQL11のSQLパーサを取り込みました。(Bo Peng) - - - -Pgpool-IIPostgreSQL11で新しく追加されたSQLの構文を完全に理解できます。 -たとえば、CREATE/ALTER/DROP PROCEDURE{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ]などです。 - - - - - - - - 他の改善点 - - - - - -pgpool_setupコマンドにpg_rewindを使用するための"-r"オプションを追加しました。(Tatsuo Ishii) - - - -pgpool_setupのオンラインリカバリスクリプトbasebackup.shでは、最初にpg_rewindを試します。 -pg_rewindが失敗した場合、rsyncを使用します。 - - - -また、pgpool_setupに新しい環境変数"USE_PG_REWIND"を追加しました。 -これは"-r"オプションと同様の効果があります。 - - + + + + AES256をサポートするにはオプションが必要であることを記載しました。(Tatsuo Ishii) + + - - - - -pgpool_setupコマンドにレプリケーションスロットを使用するための"-s"オプションを追加しました。(Tatsuo Ishii) - - - -これはスタンバイを昇格する際の問題を解消します。 -スタンバイが昇格するときPITRアーカイブ中にタイムラインが変更されるため、他のスタンバイとアーカイブディレクトリを共有している場合他のスタンバイが停止していました。 - - - -また、pgpool_setupに新しい環境変数"USE_REPLICATION_SLOT"を追加しました。 -これは"-s"オプションと同様の効果があります。 - - - -"USE_REPLICATION_SLOT=true"の場合、ストリーミングレプリケーションでアーカイブの代わりにレプリケーションスロットを使用できます。 - - - -USE_REPLICATION_SLOT 環境変数を設定することにより、現在全てのテスト内のpgpool_setupでレプリケーションスロットが使われています。 -これはsrc/test/regression配下のディスクスペースを6.3GBから5.1GB減らします(1.2GBの節約)。 - - - - - - -Pgpool-IIを導入しました。(Takuma Hoshiai) - - - -新しく追加したコマンドは、PostgreSQLもしくはフロントエンド/バックエンドプロトコルを理解するその他のサーバをテストします。 - - - - - - -内でPgpool-IIの子プロセスIDとPostgreSQLのバックエンドIDを表示できます。(Tatsuo Ishii) - - - -全ての子プロセスと利用可能な接続スロットが表示される--all オプション追加しました。 - - - - - - -replication_delayとlast_status_changeを追加しました。(Tatsuo Ishii) - - - - - - -pgpool_admのrole、replication_delay、last_status_change列を追加しました。(Tatsuo Ishii) - - - - - - - - 変更点 - - - - - -大半のDBUG1のメッセージをDEBUG5に変更しました。(Tatsuo Ishii) - - - -Pgpool-IIを"-d"オプションで起動した場合のpgpoolログのサイズを大きく減らします。 -(これは = debug1と同等です)。 - - - - -[pgpool-hackers: 2794]の議論の結果です。 - - - - - - - - - 不具合修正 - - - - - -ネイティブレプリケーションモードで、SQLnow() などの時刻関数を利用した場合、WHERE 句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。 -(bug 433) (Bo Peng) - - + + + + .pcppassを使用するには、pcpコマンドの-wオプションが必要であることを記載しました。(Tatsuo Ishii) + + - - - - -HAVE_ASPRINTFが定義されていない場合のコンパイラのエラーを修正しました。(Tatsuo Ishii) - - + + + + を強化しました。(Tatsuo Ishii) + + + + - - - - -生成されるsrc/sql/pgpool_adm/Makefile.inを削除するためconfigure.acを修正しました。(Tatsuo Ishii) - - + + 回帰テスト修正 + + + + + 071.execute_and_deallocate/test.shをリファクタリングしました。(Tatsuo Ishii) + + - - - - -PostgreSQL 9.5を使っている場合、Pgpoolのメインプロセスがセグフォルトするのを修正しました。(Tatsuo Ishii) - - - -pgpool_setup -n 3(またはそれ以上)の場合にバグが発生します。 -ノード2のリカバリをしている間、バックエンド#2が稼働していない場合であってもバージョン情報を取得しようとしていました。 -これは接続がまだ確立されてないためセグフォルトを引き起こします。 -PostgreSQL 9.6以降で発生しない理由は、PostgreSQLのバージョンが9.5以降の場合すぐにループが終了していたためです。 -これを修正するため、VALID_BACKENDマクロを呼ぶ処理を追加しました。 - - + + + + いくつかの回帰テストを強化しました。(Tatsuo Ishii) + + - - - - -pgpool_setupにを追加しました。(Tatsuo Ishii) - - - -ノード毎のhealth_check_timeoutが抜けていました。 -これはノード毎のヘルスチェックのパラメータをサポートした際に追加したはずでした。 - - + + + + 時折発生する005.jdbcテストの失敗を修正しました。(Tatsuo Ishii) + + + + + - - - - -Test: リグレッションテスト 006.memcacheが失敗する可能性を減らしました。(Tatsuo Ishii) - - - -不定期にテストが失敗するのはレプリケーションラグが原因だと思われます。 -スクリプトはスタンバイからテーブルの読み込みを試しますが、まだテーブルが存在しないためエラーが返ってきます。 -そのため、テーブルの作成後pg_sleep()を挿入します。 - - + + リリース 4.0.22 + + リリース日 + 2023-01-23 + - - - - -Test: リグレッションテスト 055.backend_all_downのエラーを修正しました。(Bo Peng) - - + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + 以下の条件をすべて満たす場合、コマンドによりのパスワードが公開されます。このコマンドは、Pgpool-IIに接続できるすべてのユーザーが実行できます。(CVE-2023-22332) + - - - - -Doc: オンラインリカバリのドキュメントを改善しました。(Tatsuo Ishii) - - - -2nd stage コマンドはネイティブレプリケーションモードのみで必要であることを明確にしました。 - - + + + + バージョン3.3以降 + + - - - - -Test: ノード0がプライマリではない場合を想定した新しいリグレッションテスト 017.node_0_is_downを追加しました。(Tatsuo Ishii) - - - - + + + onに設定されている + + + + + + queryが設定されている + + + + + + にプレーンテキストのパスワードが設定されている + + + + + + 上記条件のすべてに該当するユーザは、このバージョンにアップグレードするか (show pool_statusコマンドでが表示されなくなる)、次の回避策のいずれかを使用することを強くお勧めします。 + + + + 4.0.x~4.4.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + には空文字を設定し、パスワードはpool_passwdファイルに設定する。 + + + + + + にAESで暗号化したパスワードを設定する。 + + + + + + いずれにせよ、PostgreSQLでを変更することをお勧めします。 + + + + 3.3.x~3.7.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + いずれにせよ、PostgreSQLを変更することをお勧めします。 + + + + Pgpool-II 3.7.xおよび以前のバージョンはサポートが終了しているため、これらのバージョンのマイナーアップデートはリリースされません。 + + + + + 変更点 + + + + + + およびコマンドでwd_lifecheck_passwordを表示しないように修正しました。(CVE-2023-22332) (Bo Peng) + + + + + + + ドキュメントに記載されているように、のデフォルト値を空の文字列に変更しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + pgpool-regclass.cのコンパイラ警告を修正しました。(Florian Weimer, Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + 共有メモリ使用時の設定の章のいくつかの誤りを修正し、説明を強化しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.0.21 + + リリース日 + 2022-12-22 + + + + 変更点 + + + + + + ログメッセージ"new IPC connection received"をDEBUG1にダウングレードしました。 + (bug 775) (Bo Peng) + + + これは通常のメッセージで、LOGとして記録されるべきではありません。 + パッチはpstefによって作成され、Bo Pengによってレビューされました。 + + + + + + + + 不具合修正 + + + + + + の問題を修正しました。(Muhammad Usama) + + + Watchdogクラスタ全体のヘルスチェックパラメータの最大値に基づいて、フェイルオーバコマンドのタイムアウトを動的に設定するように修正しました。 + + + Tatsuo Ishiiによってレビューおよびテストされました。 + 議論: [pgpool-hackers: 4227] + + + + + + + パーサ内でバックスラッシュを使った場合の警告を出力しないように修正しました。(Tatsuo Ishii) + + + standard_conforming_strings = offかつescape_string_warning = onの場合、PostgreSQLは文字列リテラル内でバックスラッシュを使った場合に警告を出力します。 + これは問題ありません。 + しかし、以前はPgpool-IIのパーサも同じメッセージを出力していました。 + これは冗長です。 + + + + + + + idle_session_timeoutに対応しました。(Tatsuo Ishii) + + + idle_session_timeout (PostgreSQL 14 で追加)が有効、かつ、タイムアウトが発生した場合、次のことが発生します: + + + + failover_on_backend_errorがon (デフォルト)の場合、Pgpool-IIはフェイルオーバを発生させます。 + + + + + + + PostgreSQL サーバが 1 台のみが idle_session_timeout を有効にしていると、Pgpool-II がハングする可能性があります。 + + + + + + idle_session_timeoutに対応するため、エラーコードを検出するdetect_idle_session_timeout_error()を追加しました。 + エラーを検出すると、Pgpool-II は致命的なエラーとしてフロントエンドにエラーコードを返し、セッションを切断します。 + これはidle_in_transaction_session_timeoutの実装と同じような修正です。 + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + 議論: [pgpool-hackers: 4208] + + + + + + + SSLエラーSSL_ERROR_ZERO_RETURNに対応しました。(Tatsuo Ishii) + + + 以前はこれによってフェイルオーバが発生しましたが、サーバは単に接続を閉じることを意味するため、実際には不要でした。 + + + 議論: [pgpool-general: 8366] + 議論: [pgpool-hackers: 4193] + + + + + + + メモリキャッシュサイズを2GBより多く設定した場合に発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + 問題は与えられたキャッシュブロックのメモリアドレスを返す block_address()関数にあり、 + 2GB上限まで有効な共有メモリ空間内のブロックのオフセットを計算するために32bit整数を使っていました。 + + + + + + + pcp_proc_infoSHOW pool_poolsおよびSHOW pool_processes内のまれなセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + セグメンテーション違反はget_pools()とget_processes()にありました。 + それらは、最初に共有メモリ上の特定のプロセス情報スロットのpidを抽出し、次にキーとして pid を使ってスロットを再び検索していました。 + これらのステップはロックによって保護されていなかったため、プロセス終了時に新しい子プロセスのフォークを担う親プロセスによって pid が上書きされた場合、 + pid を使った検索が失敗し、NULLを返す可能性がありました。 + その結果、それに続くNULLポインタの参照によってセグメンテーション違反が発生していました。 + + + 解決策は、最初にプロセス情報スロットへのポインタを取得し、次にポインタからpidメンバを抽出することです。 + この方法でも、親プロセスによる共有メモリ情報の同時更新は可能ですが(出力におかしな結果をもたらす可能性があります)、少なくともセグメンテーション違反は回避できます。 + + + + + + + 無効な長さのUnixドメインソケットパスを使えないように修正しました。(Masaya Kawamoto) + + + + + + + + ドキュメント修正 + + + + + + Doc: memqcache_methodの説明を拡充しました。(Tatsuo Ishii) + + + どの方式を使うべきかの説明を追加しました。 + + + + + + + Doc: ヘルスチェックプロセスでSSLが使えることに言及しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションのチェックでもSSLが使えることに言及しました。 + これは2010年以降に使えていたはずです。 + + + 議論: [pgpool-hackers: 4187] + + + + + + + + 回帰テスト修正 + + + + + + 環境変数を使ってPGPOOLDIRを定義できるようにしました。 + (bug 766) (Bo Peng) + + + + + + + + + リリース 4.0.20 + + リリース日 + 2022-08-18 + + + + 不具合修正 + + + + + + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + + Pgpool-IIは"Select '2022-02-18 07:00:00.006547'::timestamp"のような問合せをキャッシュしていませんでした。 + TIMESTAMP、TIME、DATEを含むSELECT文はキャッシュされるようになりますが、TIMESTAMPZ、TIMEZを含むSELECT文は"SET TIME ZONE"コマンドなどで結果が変更されるためキャッシュされません。 + また、TIMESTAMPZやTIMEZ型を返す関数を含むSELECT文も同様の理由でキャッシュされません。 + Discussion: [pgpool-general: 8285] + + + + + + + + ドキュメント修正 + + + + + + Doc: 特定のSELECT文がキャッシュされないことに言及しました。(Tatsuo Ishii) + + + 特定のSELECT文は以下です。 + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を使っているSELECT + + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEへのキャストを含むSELECT + + + + + SQLValueFunction (CURRENT_TIME, CURRENT_USERなど)を含むSELECT + + + + + + + + + + Doc: Unixドメインソケット接続するときのPCPパスワードファイルの使用についての説明を修正しました。(Masaya Kawamoto) + + + pcppassファイルのlocalhostエントリはデフォルトのPCPソケットディレクトリパスへの接続とのみマッチして、全てのUnixソケット接続には使用されません。 + この振る舞いはpgpassファイルと同じです。 + + + + + + + Doc: の誤った説明を修正しました。(Tatsuo Ishii) + + + これらのパラメータは設定ファイルの再読み込みでは変更できず、Pgpool-IIの再起動が必要です。 + + Discussion: [pgpool-general: 8195] + + + + + + + + テストツール修正 + + + + + + PostgreSQL 15でpgpool_setupを実行できるようになりました。(Tatsuo Ishii) + + + ticket 757を参照ください。 + + + + + + + + 回帰テスト修正 + + + + + + Test: 回帰テストでPgpool-IIのバージョンを表示するようになりました。(Tatsuo Ishii) + + + + + + + Test: 適切なinstall directoryでpgpool.confを探すように回帰テストスクリプトを修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 4.0.19 + + リリース日 + 2022-05-19 + + + + 変更点 + + + + + Pgpool-IIメインプロセスの停止を強化しました。(Tatsuo Ishii) + + + 「pgpool stop」が一定期間(現在5秒)以内にメインプロセスを終了できなかった場合は、信号を再送信するように修正しました。 + + + + + + + コマンドのPIDの長さを7文字に変更しました。(Bo Peng) + + + + + + + Parseメッセージ処理のエラーメッセージにメッセージの種類、バックエンドノードIDを含めるように改善しました。(Tatsuo Ishii) + + + + + + + ParameterStatusメッセージのログレベルをLOGからDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + のデフォルト値を「*」から「localhost」に変更しました。(Tatsuo Ishii) + + + + + + + のフィールド名を変更しました。(Muhammad Usama) + + + + + + + + 不具合修正 + + + + + lost状態のリモートPgpool-IIノードが再起動後にクラスタに再参加できない問題を修正しました。(Muhammad Usama) + + + 報告: [pgpool-general: 7896] + + + + + + + 無限待機の可能性を回避するために、Pgpool-IIメインプロセスのexit_handlerを修正しました。(Tatsuo Ishii) + + + + + + + プライマリ検索中にバックエンドが失敗またはシャットダウンした場合にPgpool-IIのメインプロセスが終了してしまう問題を修正しました。(Tatsuo Ishii) + + + + + + + Watchdogで発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + ドキュメント修正 + + + + + Doc: 設定例を更新しました。(Masaya Kawamoto) + + + + + + + Doc: pcp_watchdog_infoの出力例を更新しました。(Bo Peng) + + + + + + + Doc: pg_encの引数として「$」文字を含むパスワードを指定する場合は、エスケープする必要があることを注意事項に追加しました。(Bo Peng) + + + + + + + + 回帰テスト修正 + + + + + タイムアウトエラーを回避するために、リグレッションテスト074.bug700_memqcache_segfaultを強化しました。(Tatsuo Ishii) + + + + + + + セグメンテーション違反を検出するようにテストスクリプトを改善しました。(Bo Peng) + + + + + + + + リリース 4.0.18 + + リリース日 + 2022-02-17 + + + + 変更点 + + + + + + in_hot_standbyによるメッセージ長の違いに関する不要なログを抑制しました。(Tatsuo Ishii) + + + PostgreSQL 14 は新しいパラメータを導入しました: in_hot_standby + + + この値はスタンバイサーバの場合は "on" で、プライマリサーバの場合は "off" になります。 + その結果 pgpool のログは以下のメッセージで溢れていました。 + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + これを防ぐために、パラメータ名がin_hot_standbyでない場合にのみログを出力するようになりました。 + + + また、メッセージにパラメータ名を表示するようになりました。例を示します。 + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + パラメータステータスの取り扱いを変更しました。(Tatsuo Ishii) + + + バックエンドからパラメータステータスのメッセージが届いたときにただメモリー上に記憶するだけでなく、フロントエンドに転送するようになりました。 + + + + + + + + 不具合修正 + + + + + + pcp_node_infoの実行の際に長時間待機する不具合を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Coverityによって見つかったヘルスチェックプロセスの問題を修正しました。(Tatsuo Ishii) + + + + + + + Coverityによって見つかったメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + プライマリノードが存在しない場合の対処をするようにfailover()を修正しました。(Tatsuo Ishii) + + + プライマリノードが存在しない場合に pgpool が起動したときなどReq_info->primary_node_idが -1 である場合にfailover()find_primary_node_repeatedly()の呼び出しをスキップしていました。 + また、follow_master_commandも実行されませんでした。 + + + Discussion: [pgpool-hackers: 4113] + + + + + + + バックエンドに接続できないときにストリーミングレプリケーションチェックプロセスがリトライしないように修正しました。(bug 742)(Bo Peng) + + + このリトライによってフェイルオーバに時間がかかっていました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントの誤字を修正しました。(pengbo) + + + パッチはUmar Hayatによって提供されました。 + + + + + + + PostgreSQL YUM リポジトリからPgpool-IIがインストールされないように /etc/yum.repos.d/pgdg-redhat-all.repo を"exclude"する設定を追加しました。(Bo Peng) + + + + + + + ParameterStatusin_hot_standbyパラメータに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + set_configに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + + テストツール修正 + + + + + + pgpool_setupが作成するfailoverスクリプトを修正しました。(Tatsuo Ishii) + + + pgpool_setupfailover.shを作成するとき、プライマリサーバが存在しない場合を考慮していませんでした。 + + + + + + + + 回帰テスト修正 + + + + + + 再コンパイルしないで既存のインストールで回帰テストを実行できるようになりました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + noinstall モード時のpgpool_setupwatchdog_setupのバイナリパスを修正しました。(Bo Peng) + + + + + + + + + リリース 4.0.17 + + リリース日 + 2021-12-23 + + + + 変更点 + + + + + + yaccとの非互換性によって出力されるbisonの警告を抑制しました。(Tatsuo Ishii) + + + + + + + 冗長なコードを修正しました。(Tatsuo Ishii) + + + パッチはLu Chenyangによって提供されました。 + + + + + + + + ドキュメント修正 + + + + + + Doc: pcp_watchdog_infoマニュアルの誤字を修正しました。(Tatsuo Ishii) + + + + + + + Doc: リリースノートの誤字を修正しました。(Bo Peng) + + + + + + + + + リリース 4.0.16 + + リリース日 + 2021-11-18 + + + + セキュリティリリース + + + + + SSL暗号化ハンドシェイク後の余計なデータを拒否するようにしました。(Tatsuo Ishii) + + + サーバサイドのSSLネゴシエーションの実装において、任意のSQLコマンドを実行できる中間者攻撃が可能でした。 + これはPgpool-IIがクライアント認証で証明書認証を使用しているか、hostssl + trust認証の場合に可能でした。 + PostgreSQLのCVE-2021-23214と似た脆弱性です。 + + + 同様に、クライアントサイドのSSLネゴシエーション実装において、任意の結果に改ざんする中間者攻撃が可能でした。 + これはPostgreSQLがクライアント認証でhostssl + trust認証を使用しているときに可能でした。 + 証明書認証の場合には、Pgpool-IIはPgpool-IIとPostgreSQL間で証明書認証を実装していないため問題ありません。 + PostgreSQLのCVE-2021-23222と似た脆弱性です。 + + + + + + + 変更点 + + + + + + pg_terminate_backend()の処理に関するPostgreSQL 14対応をしました。(Tatsuo Ishii) + + + + + + + Pgpool-IIメインプロセスのSIGCHLDハンドラを改良しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスがSIGKILLシグナルでkillされたとき、SIGCHLDハンドラは他のシグナルと同じようにLOGレベルメッセージを発していました。 + しかし、SIGKILLシグナルはOMM killerによるkillなど重要なイベントなので、WARNINGレベルのメッセージを発するようにしました。 + Michail Alexakisから提案されました。 + Discussion: [pgpool-general: 7750] + + + + + + + + 不具合修正 + + + + + + COPY FROM中のハングアップを修正しました。(Tatsuo Ishii) + + + COPY FROM中にエラーが発生したとき、Pgpool-IIはフロントエンドからCOPY終了マーカーが送信されたあと、バックエンドからの応答を永遠に待っている可能性がありました。 + Bo Pengによって発見されました。 + + + + + + + rawモードでの誤った負荷分散ノードの表示を修正しました。(Bo Peng) + + + rawモードでは、Pgpool-IIはすべてのクエリをメインノードに送信します。 + この不具合は表示上の問題だけで、クエリの転送処理に影響はないですが、ユーザを混乱させる可能性があるので、修正しました。 + + + + + + + PGPOOL SHOW ALLの実行結果にbackend_flag*が2回表示される不具合を修正しました。(Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + Doc: ドキュメントのtypoを修正しました。(Bo Peng) + + + + + + + typoを修正しました。(Bo Peng) + + + パッチはKazufumi Notoによって提供されました。 + + + + + + + Doc: PGPOOL SHOWコマンドを実行する際に、大文字を含むパラメータ名の場合には、 + パラメータ名をダブルクォートで囲んで実行する必要があることを追加しました。(Bo Peng) + + + + + + + + テストツール修正 + + + + + 新しいメインノードが利用できない場合に何もしないようにpgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + + 回帰テスト修正 + + + + + + たまに発生する073.pg_terminate_backendの失敗を修正しました。(Tatsuo Ishii) + + + + + + + テスト074の名前を変更しました。(Bo Peng) + + + + + + + テストの失敗を防ぐためにpsqlコマンドのパスを修正しました。(Bo Peng) + + + + + + + + + リリース 4.0.15 + + リリース日 + 2021-08-05 + + + + 変更点 + + + + + + ドメイン名を含めたホスト名の長さの最大値を変更しました。(Tatsuo Ishii) + + + ホスト名の長さの最大値を128にしていましたが、正しくは254でした。 + Discussion: [pgpool-hackers: 3903] + + + + + + + + 不具合修正 + + + + + + クエリキャッシュでSQLValueFunctionsを含むクエリをキャッシュしないようにしました。(Tatsuo Ishii) + + + SQLValueFunctionsの一覧は以下になります。 + + + + CURRENT_DATE + + + + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + + + + + SESSION_USER + + + + + USER + + + + + CURRENT_CATALOG + + + + + CURRENT_SCHEMA + + + + + + + + + + SIモードにおける不正なメッセージの送信を修正しました。(Tatsuo Ishii) + + + クエリがシリアル化エラーなどの特定の理由によってアボートしたとき、Pgpool-IIは + メインノード以外で実行されているトランザクションを中止するためにエラークエリを送信します。そのメッセージ長が + 正しくなかったためバックエンドで「invalid string in message」エラーが発生していました。 + + + + + + + watchdog通信の競合状態を修正しました。(Tatsuo Ishii) + + + メインプロセスがwatchdogプロセスから通知された処理を実行中に、watchdogプロセスが新しいメッセージを + メインプロセスに通知したとき、新しいメッセージが処理されるまでに大幅な遅延が発生していました。 + Discussion: [pgpool-hackers: 3900] + + + + + + + 再起動後にwatchdogノードステータスが更新されない問題を修正しました。 + (bug 684) (Muhammad Usama) + + + + + + + + ドキュメント修正 + + + + + + Doc: いくつかのドキュメントのtypoを修正しました。(Bo Peng) + + + + + + + Doc: インメモリクエリキャッシュのtypoを修正しました。(Tatsuo Ishii) + + + + + + + Doc: の説明を修正しました。(Masaya Kawamoto) + + + + + + + + テストツール修正 + + + + + + pgpool_setupで使用されるrsyncのパラメータを修正しました。(Tatsuo Ishii) + + + + + + + pgpool_setup中のベースバックアップ処理を修正しました。(Tatsuo Ishii) + + + + + + + watchdog_setupのスクリプトを修正しました。(Tatsuo Ishii) + + + watchdog_setupによって生成されるshutdownallスクリプトは、全体シャットダウンでは + 不必要なフェイルオーバ処理を引き起こしていました。 + + + + + + + + 回帰テスト修正 + + + + + + 031.connection_life_timeの不具合を修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 4.0.14 + + + リリース日 + 2021-05-20 + + + + + 不具合修正 + + + + + Doc: の説明を修正しました。(Tatsuo Ishii) + + + パラメータは、Pgpool-IIがrootで起動する場合にのみ使用できます。 + + + + + + + database/app_name_redirect_preference_listがステートメントレベル負荷分散モードで正しく動作しない不具合を修正しました。 + (bug 707) (Bo Peng) + + + + + + + pgpool0の配下のみにデータベースクラスタを作成するようにを修正しました。(Tatsuo Ishii) + + + + + + + クエリキャッシュが有効になっている場合のpgpoolのクラッシュを修正しました。 + (bug 700) (Tatsuo Ishii) + + + ストリーミングレプリケーションモードと論理レプリケーションモード以外でCloseCompleteを受信すると、Pgpool-IIがクラッシュしていました。 + + + + + + + クエリキャッシュがストリーミングレプリケーションモードと論理レプリケーションモード以外で作成されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + Startupパケットを受信したときのデバッグメッセージを改善しました。 (Tatsuo Ishii) + + + + + + + Doc: 多数ドキュメントの改善を行いました。 (Tatsuo Ishii, Bo Peng) + + + + + + + + + リリース 4.0.13 + + + リリース日 + 2021-02-18 + + + + + 変更点 + + + + + Pgpool-II起動時に既存のwatchdogコマンドソケットファイルを削除するように修正しました。(Muhammad Usama) + + + パッチはMasaya Kawamotoによって提供されました。 + + + + + + + + 不具合修正 + + + + + の誤ったweightの表示を修正しました。 (Tatsuo Ishii) + + + + + + + Watchdogリーダーによる同期処理後に、ヘルスチェックプロセスが起動されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + watchdog_setupの誤ったデータベースクラスタのパスを修正しました。(Tatsuo Ishii) + + + + + + + DBノードごとに個別のアーカイブディレクトリを作成するようにpgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + ヘルスチェックプロセス起動時のメッセージを修正しました。(Tatsuo Ishii) + + + + + + + Doc: サンプルスクリプトはテーブルスペースをサポートしていないことをドキュメント「Pgpool-II + Watchdogの構築の例」に追加しました。(Bo Peng) + + + + + + + 共有メモリの割り当て中のエラーを修正しました。(Tatsuo Ishii) + + + + + + + ERRORが発生した場合、が正しくカウンタされない不具合を修正しました。(Tatsuo Ishii) + + + + + + + backend_flag0 = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER'またはfailover_command=''の場合に発生しうるセグメンテーション違反を修正しました。 + (bug 672) (Tatsuo Ishii) + + + + + + + pool_passwdのファイルスワッピングの競合状態を修正しました。(Tatsuo Ishii) + + + パッチはMasaya Kawamotoによって提供されました。 + + + + + + Doc: のドキュメントを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.0.12 + + + リリース日 + 2020-11-19 + + + + + 変更点 + + + + + Doc: ドキュメントの「Auroraの設定例」を更新しました。(Bo Peng) + + + + + + + Doc: Pgpool-IIGSSAPIをサポートしないという注意事項を追加しました。(Tatsuo Ishii) + + + + + + + フロントエンドがGSSAPI暗号化接続を要求した場合、 + Pgpool-IIGSSAPIをサポートしていないため、 + これまでエラーを返していましたが、他の方式での接続を要求するように変更しました。(Bo Peng) + + + パッチはTatsuo Ishiiにより作成され、Umar Hayatによりレビュー・テストされました。 + + + + + + + + 不具合修正 + + + + + ネイティブレプリケーションモードで「INSERT ... ON CONFLICT」クエリ書換えの不具合を修正しました。 + (bug 654) (Bo Peng) + + + + + + + クエリがキャンセルされたときにコネクションカウントが減少しない不具合を修正しました。 + (bug 656) (Tatsuo Ishii) + + + + + + + Doc: PostgreSQLの使用可能なバージョンを7.4以降に修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.0.11 + + + リリース日 + 2020-09-17 + + + + + 変更点 + + + + + + PostgreSQL 12.4 のガイドラインに従ってPgpool-IIの拡張機能のスクリプトを修正しました。(Tatsuo Ishii) + + + + CREATE OR REPLACE FUNCTIONの使用を避けて、代わりにCREATE FUNCTIONを使用するように修正しました。 + + + + + + + + の"PGBIN"と"LPATH"を、PostgreSQLのbin pathとlib pathにしました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + Doc: オンラインリカバリが利用可能なPgpool-IIの動作モードに関する誤った説明を修正しました。(Bo Peng) + + + + + + + + いくつかの不要なチェックをソースコードから削除しました。(Tatsuo Ishii) + + + + パッチはby Hou, Zhijieにより提供されました。 + + + + + + + + relcacheクエリがプライマリ以外に送信される不具合を修正しました。(Tatsuo Ishii) + + + + ストリーミングレプリケーションモードでは、relcacheクエリはプライマリノードに送信されるようになっています。 + しかし、実際には、プライマリノードがマスターノードでない場合、relcacheクエリはプライマリノードに送信されませんでした。 + 通常、これはプライマリがノード0でない場合に発生する可能性があります。 + + + + + + + + が有効になっているときにが機能しない問題を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] + + + + + + + + 認証処理において有益なエラーメッセージを表示するように修正しました。(Tatsuo Ishii) + + + + + + + + 特定の場合に発生するpgpool子プロセスのセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 以下の方法で再現できます。 + + + + + すべてのバックエンドを停止します。 + + + + + + 無効なクライアントでpgpoolに接続します。例えば、pcpのポートではなく、pgpoolのポート番号を使用してpcp_attach_nodeを実行します。 + + + + + + + + + + + + リリース 4.0.10 + + + リリース日 + 2020-08-20 + + + + + 変更点 + + + + + Doc: TLSバージョン1.2あるいはそれ以下のバージョンのみがの影響をうけるという説明を追加しました。(Tatsuo Ishii) + + + + + + + Doc: に関する説明を改善しました。(Bo Peng) + + + パッチはKenichiro Tanakaにより提供されました。 + + + + + + + pool_hba.confサンプルファイルにhostssl/hostnosslに関する説明を追加しました。(Tatsuo Ishii) + + + + + + + Doc: 多数ドキュメントの改善を行いました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + pgpoolの起動時に、pidファイルが存在する場合、書き込む前にpidファイルを長さゼロに切り詰めるように修正しました。(Bo Peng) + + + パッチはmaliangzhuにより提供されました。 + + + + + + + Doc: のパラメータの説明の誤りを修正しました。(Bo Peng) + + + + + + + ストリーミングレプリケーションモードでプライマリノードが0以外の場合、が機能しない問題を修正しました。(Tatsuo Ishii) + + + + + + + -rオプション及びPostgreSQL 12でのpgpool_setupの問題を修正しました。(Tatsuo Ishii) + + + + + + + RPMパッケージのPCPコマンドのUNIX_DOMAIN_PATH/var/run/postgresqlに変更します。(Bo Peng) + + + + + + + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + クエリキャッシュが有効な場合、あるテーブルが更新された場合、Pgpool-IIは自動的にそのテーブルに関係する全てのキャッシュを削除するようになっています。 + しかし、EXPLAIN ANALYZEまたはCTEで更新クエリを実行した場合に、 + これらのクエリが誤って参照クエリとして扱われ、キャッシュが削除されませんでした。 + + + パッチはHou, Zhijieにより作成され、Tatsuo Ishiiにより修正されました。 + + + + + + + コーナーケースで発生するPgpool-IIのハングアップを修正しました。(Tatsuo Ishii) + + + + + + + user、database、application_name以外のパラメータが指定された場合、startupパケットの読み取りが失敗する不具合を修正しました。(Tatsuo Ishii) + + + + + + + pg_terminate_backendを実行した時にコネクションのカウントがずれる不具合を修正しました。(Takuma Hoshiai) + + + + + + + アプリケーション名がに含まれている場合に発生するセグメンテーション違反を修正しました。 (bug 615) (Tatsuo Ishii) + + + + + + + ネイティブレプリケーションモードでpg_terminate_backend()を実行すると、フェイルオーバを引き起こしてしまう不具合を修正しました。(Takuma Hoshiai) + + + + + + + IBM Zハードウェアでの004.watchdogテストのクラッシュを修正しました。 (bug 614) (Tatsuo Ishii) + + + パッチはgregn123により作成され、Tatsuo Ishiiにより修正されました。 + + + + + + + + + リリース 4.0.9 + + + リリース日 + 2020-05-21 + + + + + 不具合修正 + + + + + + 一部のシステム(Fedora 32)で発生するビルドエラーを修正しました。(Tatsuo Ishii) + + + + + + + + Pgpool-IIがすべての暗号方式を受け付ける不具合を修正しました。(bug 608) (Muhammad Usama) + + + + + + + + 認証の詳細ログをダウングレードしました。(Tatsuo Ishii) + + + + + + + + 不要なチェックを削除しました。(Tatsuo Ishii) + + + + パッチはsherlockcppによって提供されました。Discussion: [pgpool-general: 7004] + + + + + + + + Doc: ドキュメントのタイポを修正しました。(Tatsuo Ishii) + + + + パッチはUmar Hayatによって提供されました。 + Discussion: [pgpool-hackers: 3587] + + + + + + + + PCP プロセスのセグメンテーション違反を修正しました。(bug 598) (Muhammad Usama) + + + + + + + + Watchdogで一部の警告メッセージが出力されない問題を修正しました。(Tatsuo Ishii) + + + + パッチはsherlockcppによって提供されました。 + Discussion: ([pgpool-general: 6956] + + + + + + + + Doc: タイポを修正しました。(Tatsuo Ishii, Bo Peng) + + + + パッチはsherlockcppによって提供されました。 + + + + + + + + Syncメッセージの直後にExecuteメッセージが発行され、クエリキャッシュがヒットすると、Pgpool-IIがハングアップする不具合を修正しました。(Tatsuo Ishii) + + + + + + + + Watchdogのソースコードの不適切なJSONデータの処理を修正しました。(bug 596) (Tatsuo Ishii) + + + + パッチはGreg Nancarrow (Fujitsu Australia)によって提供されました。 + + + + + + + + SCRAM認証処理の不具合を修正しました。(bug 596) (Tatsuo Ishii) + + + + パッチはGreg Nancarrow (Fujitsu Australia)によって提供されました。 + + + + + + + + ネイティブレプリケーションモードで起こりうるデータの不整合を修正しました。(Tatsuo Ishii) + + + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] + + + + + + + + ホスト名が長い場合、バッファサイズの制限によってWatchdogのpingが失敗する問題を修正しました。(bug 516) (Bo Peng) + + + + + + + + 「last status change」のタイムスタンプが正しく表示されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.0.8 + + + リリース日 + 2020-02-20 + + + + + 変更点 + + + + + + ネイティブレプリケーションモードの場合に、クォーラム合意によるフェールオーバ機能を無効にしました。(Muhammad Usama) + + + + ネイティブレプリケーションモードで、Pgpool-II + はすべてのバックエンドノードでデータをレプリケーションする役割を果たしています。 + ノードがquarantine(隔離)状態になると、Pgpool-II + はそのノードへの書き込みを停止するので、データの不整合を引き起こす可能性があります。 + + + + そのため、レプリケーションモードの場合に、バックエンドノードがquarantine(隔離)状態にならないように、 + 機能を無効にしました。 + + + + + + + 起動時のbind()エラーを回避するために、ソケットファイルが存在するかどうかを確認し、 + PIDファイルが存在しない場合、それらのソケットファイルを削除するように修正しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + レプリケーションモードの場合に、クエリのタイムスタンプがリライトされない不具合を修正しました。 + (bug 551) (Bo Peng) + + + + + + + Doc: ドキュメントの更新、タイポの修正を行いました。(Takuma Hoshiai, Tatsuo Ishii, Bo Peng) + + + + + + + が空の場合、リロード後に発生する子プロセスのセグメンテーション違反を修正しました。 + (bug 571) (Bo Peng) + + + + + + + PostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) + + + + + + + Doc: follow_master_command サンプルスクリプトの %M と %H パラメータの順序を変更しました。(Bo Peng) + + + + + + + 時々起こるリグレッションテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + primary_conninfoのapplication_nameが空の場合に発生するレプリケーション遅延チェックワーカープロセスのセグメンテーション違反を修正しました。 + (bug 565) (Tatsuo Ishii) + + + + + + + = 'ALWAYS_MASTER'の場合に、コマンドの出力に ALWAYS_MASTERが表示されない不具合を修正しました。(Takuma Hoshiai) + + + + + + + syslogが出力されない不具合を修正しました。(Bo Peng) + + + + + + + + + リリース 4.0.7 + + + リリース日 + 2019-10-31 + + + + + 不具合修正 + + + + + + レプリケーションモードでの誤ったクエリの書き換えを修正しました。 (Bo Peng) + + + + + + + + 特定の場合にヘルスチェックのタイムアウトが正しく動作しない不具合を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 3458], [pgpool-hackers: 3459] + + + + + + + + Doc: すべてのスタンバイノードがダウンした場合のの説明を追加しました。(Takuma Hoshiai) + + + + + + + + Doc: PostgreSQLサーバをに指定しないように注意事項を追加しました。(Tatsuo Ishii) + + + + + + + + いくつかのWatchdogの問題を修正しました。(Muhammad Usama) + + + + lifecheckで失敗したノードはWatchdogクラスタから接続可能であっても + 障害として扱われるように変更しました。 + + + + ネットワークパーティショニングまたは部分的なlifecheckの失敗の場合、 + 切り離されたスタンバイノードは、マスターに接続しようとしたり、 + マスターになろうとするのに積極的すぎたため、ネットワークとクラスターノードに不必要 + な負担をかける可能性がありました。 + この問題は、切り離されたノードがマスターに接続したりマスターになろうとするのを少し待機させることで修正されました。 + + + 詳細: + (bug 547)、 + [pgpool-general: 6672] + + + + + + + + 各種のv2プロトコルのバグを修正しました。(Tatsuo Ishii) + + + + + + + + の変更がリロードによって反映されない不具合を修正しました。 + (bug 548) (Takuma Hoshiai) + + + + + + + + 特定の場合にPgpool-IIのシャットダウンが失敗する不具合を修正しました。(Tatsuo Ishii) + + + + + + + + 切り離されたスタンバイノードがlifecheckによって再発見されたときに、マスターウォッチドッグノードに再参加できるように修正しました。 + (bug 545) (Muhammad Usama) + + + + + + + + ヘルスチェックのデバッグ機能を改善しました。(Tatsuo Ishii) + + + + + + + + 名前付きステートメントをDEALLOCATEした後に、誤ったクエリを実行すると + セグメンテーション違反が発生する不具合を修正しました。 + (bug 546) (Tatsuo Ishii) + + + + + + + + Doc: クライアントとPgpool-IIの間でのみ証明書認証が機能する注意点をドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + Doc: 設定の例「Pgpool-II + Watchdogの構築の例」を更新しました。(Bo Peng) + + + + + + + + Doc: クォーラムが存在しない場合、VIPは起動されないことをドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + PostgreSQL 9.1 に対応するために、pgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + + 接続ユーザーのパスワードがpool_passwdファイルに見つからない場合、password認証が正しく動作しない不具合を修正しました。 + (bug 534) (Muhammad Usama) + + + + + + + + パラメータのデフォルト値にネットワークインターフェイスオプション -I を含めるように修正しました。(Bo Peng) + + + + + + + + + リリース 4.0.6 + + + リリース日 + 2019-08-15 + + + + + 改善点 + + + + + + Doc: "Pgpool-II + Watchdog Setup Example"がPostgreSQL 12に対応するように修正しました。(Bo Peng) + + + + + + + PostgreSQLからメモリマネージャデバッグ機能の一部をインポートしました。(Tatsuo Ishii) + + + + + + + PostgreSQL 12に対応するために、pg_attrdef.adsrcのかわりに + pg_get_expr()を使用するように修正しました。(Bo Peng) + + + + + + + のshutdownスクリプトを改良しました。(Tatsuo Ishii) + + + + + shutdownスクリプトがPgpool-IIのシャットダウン完了を待つように修正しました。 + + + + + + 環境変数CHECK_TIME_WAITtrueに設定されているとき、shutdownスクリプト実行時にnetstatコマンドでTCP/IPポートの使用を確認するように修正しました。 + + + + + + + + + + + pgpool_adm拡張がPostgreSQL 12 に対応するように修正しました。(Tatsuo Ishii) + + + + + + + + Doc: のドキュメントにpool_passwdハッシュ文字列を表示させる方法を追加しました。(Tatsuo Ishii) + + + + + + + + Doc: フェイルオーバに関する一般的な説明を追加しました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + + + Test: disable_load_balance_on_write = off/transaction/alwaysの場合に拡張問い合わせテストが失敗するのを修正しました。(Tatsuo Ishii) + + + + + + + + "unable to bind. cannot get parse message"エラーを修正しました。 + (bug 531) (Tatsuo Ishii) + + + + + + + + ネイティブレプリケーションモードかつWatchdogが有効な場合、 + 子プロセスが異常終了した後に、オンラインリカバリが失敗する不具合を修正しました。 + (bug 483) (Muhammad Usama) + + + + + + + + 隔離(quarantine)されたバックエンドに対してヘルスチェックを続けるように修正しました。(Muhammad Usama) + + + + 隔離されたバックエンドが接続再開されたときに自動的に隔離状態から解消されるように、 + Pgpool-IIが隔離されたバックエンドに対してヘルスチェックを実行し続ける必要があります。 + + + + 詳細は[pgpool-hackers: 3295]をご参照ください。 + + + + + + + + マスターPgpool-IIでプライマリが隔離 (quarantine) されている場合、 + スタンバイPgpool-IIでプライマリノードが存在しない状態を修正しました。(Muhammad Usama) + + + + プライマリノードが隔離 (quarantine) されている場合、マスターPgpool-IIは、 + プライマリノードステータスの同期メッセージを送信します。 + スタンバイPgpool-IIでは現在のプライマリノードのステータスがDOWNでない場合、 + プライマリノードのステータスを更新しないように修正しました。 + + + + + + + + コマンドのmodeオプションが正しく動作するように修正しました。(Takuma Hoshiai) + + + + + + + + が正しいfollow master commandを生成するように修正しました。(Tatsuo Ishii) + + + + + + + + ネイティブレプリケーションモードで、クエリのframe句にGROUPSEXCLUDEが含まれている場合、 + Pgpool-IIがクエリを正しく書き換えられない不具合を修正しました。(Bo Peng) + + + + + + + + クエリキャッシュモジュールでoid配列の境界をチェックするように修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュモジュールのOff-by-oneエラーを修正しました。(Tatsuo Ishii) + + + + + + + + ヘルスチェックプロセスでpgpool.confがリロードされない不具合を修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュが有効な場合に発生するセグメンテーション違反を修正しました。(bug 525) (Tatsuo Ishii) + + + + + + + + LOG "checking zapping sent message ..."をDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + + 詳細は[pgpool-general: 6620]をご参照ください。 + + + + + + + + pool_hba.confsamenetが指定されている場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 詳細は[pgpool-general: 6601]をご参照ください。 + + + + + + + + Doc: 「7.3. Pgpool-II + Watchdogの構築の例」のfollow_master.shスクリプトの間違いとタイポを修正しました。(Bo Peng) + + + + + + + + 特定のケースでヘルスチェックプロセスが終了しない問題を修正しました。(Tatsuo Ishii) + + + + + + + + ネイティブレプリケーションモードの場合、standard_conforming_stringsの設定に応じてバックスラッシュを処理するように修正しました。 + (bug 467) (Bo Peng) + + + + + + + + FreeBSD上で発生するコンパイルエラーを修正しました。 + (bug 512, + bug 519) (Bo Peng) + + + + + + + + いくつかのメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + 潜在的なセグメンテーション違反を回避するために、フェイルオーバ実行中であるかどうかのチェックをより積極的に行うように修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.0.5 + + + リリース日 + 2019-05-16 + + + + + 改善点 + + + + + + Doc: ドキュメントリファレンスII, PCP コマンドを改善しました。(Tatsuo Ishii) + + + + + + + + すべてのバックエンドが停止しているときのフェイルオーバをスピードアップします。(Tatsuo Ishii) + + + + すべてのバックエンドが停止状態になった場合、search_primary_node_timeoutの値に関わらずプライマリノードの検索を中止し、 + 直ちにフェールオーバプロセスを終了するように修正しました。 + + + + ディスカッション: [pgpool-hackers: 3321] + + + + + + + + pgpool-recovery拡張とpgpool_setupを次期バージョンであるPostgreSQL12に対応しました。(Tatsuo Ishii) + + + + + + + Doc: ドキュメントのの項目を追加しました。(Takuma Hoshiai) + + + + + + + + 不具合修正 + + + + + + すべてのバックエンドがダウンした場合には表示される不適切なエラーメッセージ"ERROR: connection cache is full"を修正しました。 + (bug 487) (Bo Peng) + + + + すべてのバックエンドがダウンした場合に、Pgpool-IIが不適切なエラーメッセージ"ERROR: connection cache is full"を投げています。 + このエラーを"all backend nodes are down, pgpool requires at least one valid node"に修正しました。 + + + + + + + 使用されていない.sgmlファイルを削除しました。(Takuma Hoshiai) + + + + + + + + pool_worker_childプロセスの終了/フォークの繰り返しを避けるために修正しました。(Tatsuo Ishii) + + + + pool_worker_childはdo_query()を使用してWAL位置を取得するためのクエリを発行します。 + これにより、致命的エラーが発生した場合、pool_worker_childプロセスを終了し、 + Pgpool-IIの親プロセスは直ちに新しいプロセスをフォークするようにしています。 + このサイクルは無限に繰り返され、システムに大きな負荷を与える可能性があります。 + 無限に繰り返される終了/フォーク処理を回避するために、sr_check_periodをスリープさせるように修正しました。 + + + + + + + + のデフォル値が間違っていた不具合を修正しました。(Tatsuo Ishii) + + + + + + + + 「not enough space in buffer」エラーを修正しました。 + (bug 499) (Tatsuo Ishii) + + + + バックエンドから返されたエラーメッセージサイズが固定バッファサイズ (8192 bytes)を超えた場合、 + 「not enough space in buffer」エラーが発生していました。 + 固定サイズのバッファの使用を廃止し、動的にバッファサイズを割り当てるように修正しました。 + + + + + + + + DROP DATABASEの失敗を修正しました。 (Tatsuo Ishii) + + + + + + + + read_status_file()関数の間違った変数名を修正しました。 + (bug 493) (Takuma Hoshiai) + + + + + + + + 漏れていたtest/watchdog_setupをEXTRA_DISTに追加しました。(bug 470) (Bo Peng) + + + + + + + + Doc: マルチステートメントクエリはプライマリノードにのみ送信されるという説明をドキュメントに追加しました。(bug 492) (Tatsuo Ishii) + + + + + + + + rawモードかつ複数のバックエンドが設定された場合に発生するmd5認証の失敗を修正しました。 + (bug 491) (Tatsuo Ishii) + + + + + + + + Test: 014.watchdog_test_quorum_bypass レグレッションテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + failover/failback実行中に接続があった場合に発生しうるセグメンテーション違反を回避するために、セッションを終了するように修正しました。 + (bug 481, + bug 482) (Tatsuo Ishii) + + + + + + + + コンパイル時に発生するワーニング を修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつ"batch"モードで発生するメモリリークを修正しました。 + (bug 468) (Tatsuo Ishii) + + + + + + + + + リリース 4.0.4 + + + リリース日 + 2019-03-29 + + + + + 改善点 + + + + + + 新しい設定パラメータを追加しました。(Muhammad Usama) + + + + ユーザがサーバ側のSSL暗号設定をクライアントに優先して使うかどうかを設定できるように、新しい設定パラメータを追加しました。 + + + + この設定はデフォルトでオフで、従来と同じようにクライアント側のリクエストが優先されます。 + しかしこれはあくまで過去の挙動との互換性のための設定であり、悪意のあるクライアントが弱い暗号を利用できる可能性があります。 + ですから、常にこのパラメータをオンにしておくことを推奨します。 + + + + + + + + client cipher リストの設定が可能になりました。(Tatsuo Ishii, Yugo Nagata) + + + + Pgpool-IIがクライアントからのSSL接続を受け付ける際に受け入れる暗号のリストを指定する新しいパラメータ、 + を追加しました。これはすでにPostgreSQLに実装されていて、 + SSLが有効なときにセキュリティを強化するのに役立ちます。 + + + + + + + + 不具合修正 + + + + + + 不要なpgpool_statusファイルへの書き込みが減らしました。(Tatsuo Ishii) + + + + 今まではPostgreSQLバックエンドへの新しい接続が作成されるたびに、 + pgpool_statusファイルに書き込むためにfsync()が実行されていましたが、 + これにより、特定の条件で過剰なI/Oを発生させる可能性がありました。 + そのため、バックエンドの状況が変更されたときにのみfsync()を実行するように修正しました。 + + + + ディスカッション: [pgpool-general: 6436] + + + + + + + + Doc:に関する説明を追加しました。(Tatsuo Ishii) + + + + の実行条件などの説明を追加しました。 + + + + + + + + Doc: 設定パラメータに関する注意事項を追加しました。 + (bug 469) (Tatsuo Ishii) + + + + この機能を使用するには、に設定したユーザがスーパーユーザまたはpg_monitorグループに属している必要があります。 + + + + + + + + + リリース 4.0.3 + + + リリース日 + 2019-02-21 + + + + + 変更点 + + + + + + Doc: 設定の例を更新しました. (Bo Peng) + + + + + + + + 不具合修正 + + + + + + conninfoから情報を取得するときに、"host =" をスキップするように修正しました。(Bo Peng) + + + + パッチはNathan Wardによって提供されました。 + + + + + + + + Test: レグレッションテスト068.memqcache_bugの古いJDBCの関数及びタイポを修正しました。(Takuma Hoshiai) + + + + + + + + Doc: パラメータはサーバ起動時にのみ設定可能なことをドキュメントに追加しました。(Tatsuo Ishii) + + + + + + + + 特定の場合に、によって、オンラインリカバリが失敗する不具合を修正しました。(bug 431)(Tatsuo Ishii) + + + + + + + + 大きなデータがバックエンドから返されたときのメモリ使用量を減らすように修正しました。(bug 462) (Tatsuo Ishii) + + + + + + + + Test: 拡張問い合わせのテストスクリプトのエラーを修正しました。(Tatsuo Ishii) + + + + + + + + strip_quote()が空のクエリを処理するときに発生するセグメンテーション違反を修正しました。(bug 458) (Tatsuo Ishii) + + + + + + + + Doc: white/black_function_list 設定パラメータでスキーマ修飾が使えないという説明を追加しました。(Tatsuo Ishii) + + + + + + + + watchdog_setupスクリプトのに関するタイポを修正しました。(Takuma Hoshiai) + + + + + + + + wd_lifecheck_method = 'query' の場合に発生するセグメンテーション違反を修正しました。(bug 455)(Muhammad Usama) + + + + パッチがMuhammad Usama によって作成され、Yugo Nagata によってテストされました。 + + + + + + + + 接続を確立しようとするとき、フェイルオーバが発生する場合に発生しうるセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + 参照: [pgpool-hackers: 3214] + + + + + + + + Doc: logdirに関するドキュメントのタイポを修正しました。(bug 453)(Tatsuo Ishii) + + + + + + + + PAM認証が失敗する不具合を修正しました。(Takuma Hoshiai) + + + + 詳細は[pgpool-general: 6353]を参照してください。 + + + + + + + + クライアントが sync メッセージの後、次の簡易問い合わせの前に close メッセージを送ると発生しうるハングアップを修正しました。(Tatsuo Ishii) + + + 参照: [pgpool-hackers: 3164] + + + + + + + + PostgreSQLidle_in_transaction_session_timeoutが有効な場合に発生しうるPgpool-IIのハングアップを修正しました。(bug 448)(Tatsuo Ishii) + + + + + + + + + リリース 4.0.2 + + + リリース日 + 2018-11-22 + + + + + 不具合修正 + + + + + + + クライアントから送信された startup パケットのパラメータをソートするように修正します。 + (bug 444)(Takuma Hoshiai) + + + + キャッシュされたコネクションプールと接続要求のstartupパケットのパラメータの順序が異なる場合、 + コネクションプールを使用せず、新しいコネクションプールを作成しまていました。 + + + + + + + + Pgpool-IIの内部接続の認証の不具合を修正しました。(Muhammad Usama) + + + + これは「SCRAM認証と証明書の認証のサポート」の機能追加による問題です。 + 問題は、connection_do_auth()でバックエンドに対して認証する際に、 + バックエンドが「認証 ok」との応答を返すと + すぐに呼び出し元にもどっていました。そのため、認証自体は成功しましたが、 + connection_do_auth()は「Ready for query」を受信するまで処理を進めませんでした。 + 「認証 ok」との応答を受け取った後も「Ready for query」を受信するまでデータの処理を継続するように修正しました。 + + + + パッチがTatsuo Ishiiにより提供され、Muhammad Usamaにより修正されました。 + + + + + + + + gcc 8.xで発生するコンパイラの警告を修正しました。(Takuma Hoshiai) + + + + + + + + ネイティブレプリケーションモードで特定のBindメッセージが送信されたときに発生するセグメンテーション違反を修正しました。 + (bug 443) (Bo Peng) + + + + パラメータ書式コードの数が 1 に指定されて、元のクエリのパラメータの数が 0 の場合、 + bind_rewrite_timestamp()に負の値を指定してmemcpyを呼び出していました。 + これによりセグメンテーション違反が発生していました。 + + + + パッチがYugo Nagataにより提供されました。 + + + + + + + + スキーマ名で修飾されたテーブル名を使用するようにクエリキャッシュに渡されるクエリを修正しました。(Tatsuo Ishii) + + + + + + + + クエリキャッシュ無効化のバグを修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + + + + + 拡張問い合わせかつクエリキャッシュ有効の場合に発生するメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.0.1 + + + リリース日 + 2018-10-31 + + + + + 変更点 + + + + + + Pgpool-IIの実行ユーザとrootユーザ以外のユーザがsslキーファイルを所有することができるようになりました。(Muhammad Usama) + + + + + + + + フェイルオーバ時にPCP[attach/detach/promote]コマンドを許可するようになりました。(Muhammad Usama) + + + + + + + + 不具合修正 + + + + + + MD5AES及びテキストパスワードの長さが異なることによって時々発生するファイルの破損を修正しました。(Muhammad Usama) + + + パッチはTakuma Hoshiaiによって提供され、Muhammad Usamaによって修正されました。 + + + + + + + + SHOW POOL_STATUSコマンドの出力のchild_max_connectionsの説明のタイポを修正しました。(Tatsuo Ishii) + + + + パッチはPhil Ramirezにより提供されました。 + + + + + + + + ネイティブレプリケーションモードでエラークエリと同期メッセージが送信されたときのセグメンテーション違反を修正しました。 + (bug 434) (Takuma Hoshiai) + + + + ネイティブレプリケーションモードで、クエリエラーの後に同期メッセージが送信されるとセグメンテーション違反が発生していました。 + + + + + + + + + リリース 4.0 + + + リリース日 + 2018-10-19 + + + + + 概要 + + + このバージョンでは、SCRAM認証および証明書認証に対応し、ロードバランスの制御が向上しており、PostgreSQL11の新しいSQLパーサを取り込んでいます。 + + + + Pgpool-II4.0の主な改善点は以下のとおりです。 + + + + + + + + + SCRAM認証および証明書認証の対応 + + + + + + PostgreSQLの偽のプライマリサーバ検出 + + + + + + + ロードバランスの改善: + + + + + 更新を伴うクエリ実行後の更に細かい負荷分散の制御 + + + + + + 特定クエリに対する負荷分散の制御 + + + + + + パラメータによる負荷分散の重み指定 + + + + + + + + + + + に最終更新時刻のタイムスタンプ追加 + + + + + + + PostgreSQL11のSQLパーサの取込 + + + + + + + クライアントメッセージのログ出力の追加 + + + + + + + + バージョン4.0への移行 + + + バージョン4.0には、以前のバージョンとの互換性に影響する多数の変更点が含まれています。 + 以下の非互換性に注意してください。 + + + + + + + 1st/2nd ステージのオンラインリカバリコマンドにリカバリされるノードの番号を取得するためのパラメータを追加しました。(Tatsuo Ishii) + + + + オンラインリカバリスクリプトは4つではなく5つのパラメータを受け取るようになりました(5番目のパラメータはリカバリされるノードの番号です)。 + pgpool_recoveryをバージョンアップするためには、ALTER EXTENSION pgpool_recovery UPDATE TO '1.2'を実行してください。 + 5番目のパラメータの情報を必要としない場合、既存の4つのパラメータの形式でリカバリスクリプト使用することが出来ます。 + + + + 詳細は、を参照してください。 + + + + + + + パラメータfail_over_on_backend_errorは、に変更されました。(Muhammad Usama) + + + + の代わりに古いパラメータ名fail_over_on_backend_errorが使われた場合、警告メッセージを出力します。 + + + + + + + pgpool.conf内でAESで暗号化されたパスワードを指定できます。(Muhammad Usama) + + + + 4.0以降では、pgpool.confファイル内のおよびでAESで暗号化されたパスワードを指定することができます。 + + + + パスワード文字列の先頭にTEXTを付与した暗号化されていないクリアテキストパスワードを指定します。 + 有効な接頭辞が無い場合、Pgpool-IIは文字列を平文のパスワードと見なします。 + + + + pgpool.confファイル内のおよびで指定された空のパスワード文字列は、が特定のパスワードを含まない場合だけ使われます。 + もし、これらのパラメータが空白だった場合、Pgpool-IIは空のパスワードを使用する前に最初にファイルから特定のユーザのパスワードの取得を試みます。 + + + + + + + + 主要な改善点 + + + + + + SCRAM認証および証明書認証に対応しました。(Muhammad Usama) + + + + + SCRAM認証方式に対応しました。 + + + + pool_passwd認証ファイルを使用したSCRAM認証に対応しました。 + + + + 詳細はを参照してください。 + + + + + + Pgpool-IIとフロントエンドの間でCERT認証を使用できます。 + + + + この認証方法を使用する場合、Pgpool-IIはクライアントが有効な証明書を提供することを必要とします。 + + + + 詳細はを参照してください。 + + + + + + フロントエンド/バックエンドで異なる認証方式を利用できます。 + + + + これはクライアントとPgpool-II、およびPgpool-IIとバックエンド間で異なる認証方式を利用できます。 + + + + + + + + は、3つの形式でパスワードを保存できるようになりました。 + AES256暗号化形式、平文形式、md5形式です。 + + + + Pgpool-IIは接頭辞によってパスワードの形式を確認するため、pool_passwd内の各パスワードのエントリはパスワードの形式を接頭語として付ける必要があります。 + + + + md5ハッシュパスワードはmd5接頭辞、AES256暗号化パスワード形式はAES接頭辞を使って保存することができます。 + 平文形式のパスワードの保存のためには、TEXT接頭辞を使用できます。 + + + + 有効な接頭辞がない場合、Pgpool-IIは文字列を平文のパスワードとして見なします。 + + + + 例: + + username1:AESIFwI86k+ZbVdf6C+t3qpGA== + username2:md59c6583185ba6a85bdcd1f129ec8cabb4 + username3:TEXTmypassword + + + + + + + + + を用いずにデータベースへの接続にMD5認証およびSCRAM認証方式を使えます。 + + + + 新しい設定パラメータを追加しました。 + このパラメータは接続するユーザのパスワードがファイルに含まれていない、かつ(クライアントから提供された)パスワードがバックエンドのMD5もしくはSCRAM認証で使われる場合、Pgpool-IIがクライアントとのクリアテキストのパスワード認証を行うことを許可します。 + + + + + + + + 新しいコマンドは、暗号化されたパスワードを生成します。 + + + + AESで暗号化されたパスワードを作成できるコマンドを追加しました。 + + + + + + + + 詳細は、を参照してください。 + + + + + + + + 新しいパラメータを追加しました。 (Tatsuo Ishii) + + + + detach_false_primary = onの場合、偽のプライマリノードを切り離します。 + デフォルトはoffです。pg_stat_wal_receiverを使用しているため、このパラメータはストリーミングレプリケーションモードかつPostgreSQL9.6以降でのみ有効です。 + PostgreSQL9.5以前のバージョンの場合、エラーは発生せずこの機能は無視されます。 + + + + + + + 更新を含むクエリ実行後の負荷分散の振る舞いを指定するを追加しました。(Tatsuo Ishii) + + + + このパラメータは、更新クエリ実行後の振る舞いを指定できます。 + + + + + + + パラメータとして負荷分散の重みの割合を指定できるようになりました。(Bo Peng) + + + + 新しい機能としておよびに対して負荷分散の重みを指定できます。 + + + + + 特定のデータベース接続およびバックエンドノードに対して、指定した負荷分散の比でSELECTクエリを送るためのリスト"database-name:node id(ratio)"を指定できます。 + + + + 特定のアプリケーション接続およびバックエンドノードに対して、指定した負荷分散の比でSELECTクエリを送るためのリスト"application-name:node id(ratio)"を指定できます。 + + + + この負荷分散の比は 0から1の間の値を指定できます。 + デフォルトは1.0です。 + + + + + + + + 負荷分散すべきではないSQLパターンのリストを指定できる を追加しました。(Bo Peng) + + + + プライマリノードだけに送るSQLのパターンをセミコロンで区切られたリストで指定できます。 + SQLのパターンには正規表現を使用することができます。 + この機能はマスタースレーブモードのみサポートします。 + + + + + + + + クライアントのメッセージに関するログ出力を許可するを追加しました。(Takuma Hoshiai, Tatsuo Ishii) + + + + log_client_messages = onを設定すると, デバックメッセージなしでクライアントのメッセージをログ出力できます。 + + + + + + + コマンドにlast_status_change列を追加しました。 + + + + 新しい列はstatusもしくはroleが変更された時刻を示します。 + + + + 列を追加した理由に関しては[pgpool-hackers: 2822]を参照してください。 + + + + + + + PostgreSQL11のSQLパーサを取り込みました。(Bo Peng) + + + + Pgpool-IIPostgreSQL11で新しく追加されたSQLの構文を完全に理解できます。 + たとえば、CREATE/ALTER/DROP PROCEDURE{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ]などです。 + + + + + + + + 他の改善点 + + + + + + pgpool_setupコマンドにpg_rewindを使用するための"-r"オプションを追加しました。(Tatsuo Ishii) + + + + pgpool_setupのオンラインリカバリスクリプトbasebackup.shでは、最初にpg_rewindを試します。 + pg_rewindが失敗した場合、rsyncを使用します。 + + + + また、pgpool_setupに新しい環境変数"USE_PG_REWIND"を追加しました。 + これは"-r"オプションと同様の効果があります。 + + + + + + + + pgpool_setupコマンドにレプリケーションスロットを使用するための"-s"オプションを追加しました。(Tatsuo Ishii) + + + + これはスタンバイを昇格する際の問題を解消します。 + スタンバイが昇格するときPITRアーカイブ中にタイムラインが変更されるため、他のスタンバイとアーカイブディレクトリを共有している場合他のスタンバイが停止していました。 + + + + また、pgpool_setupに新しい環境変数"USE_REPLICATION_SLOT"を追加しました。 + これは"-s"オプションと同様の効果があります。 + + + + "USE_REPLICATION_SLOT=true"の場合、ストリーミングレプリケーションでアーカイブの代わりにレプリケーションスロットを使用できます。 + + + + USE_REPLICATION_SLOT 環境変数を設定することにより、現在全てのテスト内のpgpool_setupでレプリケーションスロットが使われています。 + これはsrc/test/regression配下のディスクスペースを6.3GBから5.1GB減らします(1.2GBの節約)。 + + + + + + + Pgpool-IIを導入しました。(Takuma Hoshiai) + + + + 新しく追加したコマンドは、PostgreSQLもしくはフロントエンド/バックエンドプロトコルを理解するその他のサーバをテストします。 + + + + + + + 内でPgpool-IIの子プロセスIDとPostgreSQLのバックエンドIDを表示できます。(Tatsuo Ishii) + + + + 全ての子プロセスと利用可能な接続スロットが表示される--all オプション追加しました。 + + + + + + + replication_delayとlast_status_changeを追加しました。(Tatsuo Ishii) + + + + + + + pgpool_admのrole、replication_delay、last_status_change列を追加しました。(Tatsuo Ishii) + + + + + + + + 変更点 + + + + + + 大半のDEBUG1のメッセージをDEBUG5に変更しました。(Tatsuo Ishii) + + + + Pgpool-IIを"-d"オプションで起動した場合のpgpoolログのサイズを大きく減らします。 + (これは = debug1と同等です)。 + + + + + [pgpool-hackers: 2794]の議論の結果です。 + + + + + + + + + 不具合修正 + + + + + + ネイティブレプリケーションモードで、SQLnow() などの時刻関数を利用した場合、WHERE 句にIN (SELECT ...)を含むと構文エラーになる不具合を修正しました。 + (bug 433) (Bo Peng) + + + + + + + + HAVE_ASPRINTFが定義されていない場合のコンパイラのエラーを修正しました。(Tatsuo Ishii) + + + + + + + + 生成されるsrc/sql/pgpool_adm/Makefile.inを削除するためconfigure.acを修正しました。(Tatsuo Ishii) + + + + + + + + PostgreSQL 9.5を使っている場合、Pgpoolのメインプロセスがセグフォルトするのを修正しました。(Tatsuo Ishii) + + + + pgpool_setup -n 3(またはそれ以上)の場合にバグが発生します。 + ノード2のリカバリをしている間、バックエンド#2が稼働していない場合であってもバージョン情報を取得しようとしていました。 + これは接続がまだ確立されてないためセグフォルトを引き起こします。 + PostgreSQL 9.6以降で発生しない理由は、PostgreSQLのバージョンが9.5以降の場合すぐにループが終了していたためです。 + これを修正するため、VALID_BACKENDマクロを呼ぶ処理を追加しました。 + + + + + + + + pgpool_setupにを追加しました。(Tatsuo Ishii) + + + + ノード毎のhealth_check_timeoutが抜けていました。 + これはノード毎のヘルスチェックのパラメータをサポートした際に追加したはずでした。 + + + + + + + + Test: リグレッションテスト 006.memcacheが失敗する可能性を減らしました。(Tatsuo Ishii) + + + + 不定期にテストが失敗するのはレプリケーションラグが原因だと思われます。 + スクリプトはスタンバイからテーブルの読み込みを試しますが、まだテーブルが存在しないためエラーが返ってきます。 + そのため、テーブルの作成後pg_sleep()を挿入します。 + + + + + + + + Test: リグレッションテスト 055.backend_all_downのエラーを修正しました。(Bo Peng) + + + + + + + + Doc: オンラインリカバリのドキュメントを改善しました。(Tatsuo Ishii) + + + + 2nd stage コマンドはネイティブレプリケーションモードのみで必要であることを明確にしました。 + + + + + + + + Test: ノード0がプライマリではない場合を想定した新しいリグレッションテスト 017.node_0_is_downを追加しました。(Tatsuo Ishii) + + + + diff --git a/doc.ja/src/sgml/release-4.1.sgml b/doc.ja/src/sgml/release-4.1.sgml new file mode 100644 index 000000000..acaed5158 --- /dev/null +++ b/doc.ja/src/sgml/release-4.1.sgml @@ -0,0 +1,5644 @@ + + + + + リリース 4.1.23 + + リリース日 + 2024-11-28 + + + + 不具合修正 + + + + + + バックエンドがエラーメッセージを送信した場合に、SSLネゴシエーションを中止するよう修正しました。(Tatsuo Ishii) + + + SSLネゴシエーションのクライアント側実装(pool_ssl_negotiate_clientserver())では、 + 中間者攻撃者がSSLネゴシエーションフェーズ中に長いエラーメッセージを送信することで、 + Pgpool-IIやクライアントを混乱させる可能性がありました。 + このコミットでは、ネゴシエーションを直ちに拒否(FATALエラーを発行)し、 + そのような攻撃を防ぐためにセッションを終了するよう修正しました。 + + + これは、PostgreSQLのCVE-2024-10977に似ています。 + + + + + + + リロード処理がWatchdogプロセスに反映されない問題を修正しました。(Bo Peng) + + + Pgpool-IIの + reload_config()関数は、 + WatchdogププロセスにSIGHUPシグナルを送信する必要がありました。 + + + + + + + do_query関数の不具合を修正しました。(Tatsuo Ishii) + + + htons/htonlの代わりにntohs/ntohlを使用するようにdo_queryを修正しました。 + + + + + + + pool_passwdを更新してリロードした後の認証失敗問題を修正しました。(Tatsuo Ishii) + + + pool_hba.confが無効になっている場合、Pgpool-IIのリロードが実行されても、Pgpool-IIの子プロセスはpool_passwdの更新を認識しませんでした。 + リロード処理関数check_config_reload()は、が有効な場合にのみpool_passwdを再オープンする必要があると誤って判断していたことが原因でした。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html + + + + + + + COPYがハングする問題を修正しました。(#79) (Tatsuo Ishii) + + + COPY IN状態(つまり、COPY FROM STDIN)中、フロントエンドはFlushまたはSyncメッセージを送信できます。 + F/Bプロトコル仕様によると、これらは無視されるはずですが、Pgpool-IIは無効なメッセージとして処理し、これがCOPYのハングの原因でした。 + + + リグレッションテストも追加しました。 + + + + + + + 認証失敗による散発的なヘルスチェックの失敗を修正しました。(Tatsuo Ishii) + + + が空文字列の場合、ヘルスチェックプロセスはpool_passwdファイルからパスワードを検索します。 + 問題は、このファイルのファイルディスクリプタが親pgpoolプロセスから継承されている点です。 + pgpoolメインプロセスとヘルスチェックプロセス(複数存在する可能性あり)が同じディスクリプタを共有するため、さまざまな問題が発生していました。 + この問題を解決するために、ヘルスチェックプロセスが開始される際にファイルを再度開き、 + それぞれのヘルスチェックプロセスが独自のファイルディスクリプタを持つようにしました。 + + + なお、pgpoolの子プロセス(フロントエンドセッションを担当)はすでにファイルディスクリプタを再度開く処理を行っており、これが今回の問題には関連していません。 + + + この問題は、Emond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + ALTER ROLEのクエリキャッシュ無効化を最適化しました。(Tatsuo Ishii) + + + コミット6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89は、ALTER ROLE/USERステートメントが使用される際にクエリキャッシュを無効にしています。 + しかし、実際にはこれが過剰です。 + 次のクエリはロールの権限に影響を与えないため、クエリキャッシュを無効にする必要はありません。 + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + したがって、これらのコマンドが使用される場合には、クエリキャッシュを無効にしないようにしました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードのバグを修正しました。(#69) (Tatsuo Ishii) + + + INSERTコマンドを受信すると、Pgpool-IIはターゲットテーブルに対して自動的にテーブルLOCKコマンドを発行しますが、メインノード以外のノードにコマンドを送信し忘れていました。 + この問題は拡張クエリモードの場合にのみ発生していました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードの別のバグを修正しました。(Tatsuo Ishii) + + + insert_lock()は、メインノード以外のノードに行ロックコマンド(lock_kind == 3 の場合)を送信するのを忘れていました。 + + + + + + + pool_memqcache.cのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はコミット6fdba5c33によって導入されました。 + + + + + + + + ドキュメント修正 + + + + + ドキュメントとサンプル設定ファイルのタイポを修正しました。(Bo Peng) + + + + + + + + リリース 4.1.22 + + リリース日 + 2024-09-09 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + クエリキャッシュ機能()が有効な時に、データベースユーザがクエリキャッシュ経由で本来読み出せない行を読むことが可能でした。(CVE-2024-45624) + + + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22より古く、クエリキャッシュ機能を持つすべてのバージョン(クエリキャッシュ機能は3.2で実装されました)がこの脆弱性の影響を受けます。 + + + + + + あるユーザのクエリキャッシュがテーブルに対して作成されていると、そのテーブルへのアクセス権がREVOKEコマンドで剥奪されても、アクセス権を持たないそのユーザがクエリキャッシュを通じてテーブルにアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュがテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、アクセス権を持たないBがクエリキャッシュを通じてアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュが行セキュリティが有効なテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、本来Bが見えない行をクエリキャッシュを通じて取り出すことが可能でした。 + + + + + Pgpool-II 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22以降へのアップグレードを強くお勧めします。 + それができない場合は、クエリキャッシュ機能を無効にしてください。 + + + なお、この脆弱性を修正するために、いくつかのコマンド(ALTER DATABASE, ALTER ROLE, ALTER TABLE, REVOKE)を実行すると、クエリキャッシュのすべてのデータを削除するようになりました。 + これにより、クエリキャッシュの性能に影響があるかも知れません。 + + + + + 変更点 + + + + + をバックポートしました。 (Tatsuo Ishii) + + + これは主にテストのためです。v4.1までバックポートしました。 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + 不具合修正 + + + + + + レプリケーションモードとスナップショットアイソレーションモードで発生する複数の不具合を修正しました。(Tatsuo Ishii) + + + 次の不具合を修正しました。 + + + + + レプリケーションモードおよびスナップショットアイソレーションモードでコマンドを実行すると、Pgpool-IIはクエリ準備完了メッセージを待ちますが、一部のコマンド(SET ROLEなど)がパラメータステータスメッセージを生成することを忘れていました。 + その結果、Pgpool-IIはクエリ準備完了メッセージの前に他のメッセージが到着したことをエラーとして出力していました。 + + + + + + 前のクエリがパラメータステータスメッセージを生成した場合、後続のparse()はそれを読み取って処理する必要があります。 + これは、パラメータステータスメッセージの後に続くはずのクエリ準備完了メッセージを読み取る必要があるためです。 + + + ただし、ParameterStatus()が呼び出されると、クエリ進行中フラグが設定され、このparse()呼び出しで処理されるクエリが負荷分散されている場合、バックエンドからのパラメータステータスメッセージの1つだけが処理される可能性がありました。 + パラメータステータスメッセージはSETコマンドによって生成され、SETコマンドはレプリケーションモードおよびスナップショットアイソレーションモードのすべての生きているバックエンドに送信されるため、すべての生きているバックエンドから送信される可能性がありました。 + そのため、ParameterStatus()を呼び出す前に、クエリ進行中フラグを設定解除するように修正しました。 + + + + + + + + + + + リリース 4.1.21 + + リリース日 + 2024-08-15 + + + + 変更点 + + + + + + サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 (Bo Peng) + + + postgresqlxx-serverがインストールされていない可能性があるため、サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 + + + + + + + + 不具合修正 + + + + + + フラッシュメッセージを受信した後にハングする問題を修正しました。 (#59) (Tatsuo Ishii) + + + + + + + セグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Pgpool-IIの子プロセスがpool_do_authでセグメント違反になることがありました。 + 原因はMAIN_CONNECTION()がNULLを返すことでした。 + my_main_node_idが不正なノードID 0に設定されていたようですが、これは実際にはダウン状態でした。 + そのため、cp->slots[0]には接続がありませんでした。 + + + この問題はEmond Papegaaijによって報告されました。 + Discussion: [pgpool-general: 9175] + + + + + + + MAIN_NODEマクロを使用しないようにセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 一部の関数 (close_idle_connection()、new_connection()、pool_create_cp())では、MAIN*とVALID_BACKENDが不適切な場所で使用されていました。 + MAIN*とVALID_BACKENDは、バックエンドへの現在の接続に対してのみ有効であり、プールされた接続には有効ではありません。 + プールされた接続では、どのバックエンドがメインノードであるか、または稼働中であるかは、バックエンドへの現在の接続と必ず同じであるためです。 + これらのマクロを誤って使用すると、セグメンテーション違反が発生することがありました。 + + + この問題はEmond Papegaaij によって報告されました。 + Discussion: [pgpool-general: 9114] + + + + + + + MAIN_NODEマクロ(実際は pool_virtual_main_db_node_id())を修正しました。 (Tatsuo Ishii) + + + セッションコンテキストがない場合、マクロはREAL_MAIN_NODE_IDに使用されます。 + フェイルオーバー/フェイルバックが発生すると、いつでもREAL_MAIN_NODE_IDが変更される可能性があるため、これは誤りでした。 + + + REAL_MAIN_NODE_ID == my_main_node_id == 1と仮定します。 + その後、フェイルバックにより、REAL_MAIN_NODE_IDは0に変更されます。 + その後、MAIN_CONNECTION(cp)はNULLを返し、これへの参照はセグメンテーションエラーを引き起こします。 + この問題を回避するには、代わりにmy_main_node_idを返すように修正しました。 + + + + + + + 子プロセスでのセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + ネットワークが短時間中断されると、Watchdogが停止し、Pgpool-IIが強制終了する問題を修正しました。 (#823) (Muhammad Usama) + + + ネットワーク監視を有効にすると、Pgpool-IIノードはすべてのネットワークインターフェイスまたは割り当てられたIPアドレスを失った場合に直ちにシャットダウンし、通信できないノードをクラスタからすばやく削除することで追加の保護を提供します。 + + + 問題は、ネットワーク監視が無効になっている場合でも、Pgpool-IIがネットワークブラックアウトイベントに応答していたことです。 + この修正により、ネットワーク監視が有効になっていない場合にネットワーク監視ソケットがオープンされなくなり、不要なシャットダウンが防止されます。 + + + + + + + psql_scanのクラッシュを修正しました。 (#54) (Tatsuo Ishii) + + + 長いクエリ内の文字列がpsql変数(つまり「:」で始まる)であるかどうかを判別しているときに、psql_scanがクラッシュする問題がありました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントとプログラムソースコードの大量なタイポミスを修正しました。(Tatsuo Ishii) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + 仮想IP関連パラメータのデフォルト値をドキュメントに追加しました。(Bo Peng) + + + + + + + + + リリース 4.1.20 + + リリース日 + 2024-05-16 + + + + 不具合修正 + + + + + + セグメンテーション違反のさまざまな原因を修正しました。(Tatsuo Ishii) + + + フェイルオーバーが関与している特定のケースでは、Pgpool-IIとその子プロセスのセグメント違反が発生していました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + 初期化されていないメモリエラーを修正しました。(Tatsuo Ishii) + + + read_startup_packetの初期化されていないメモリエラーを含むいくつかのエラーがvalgrindによって報告されました。 + valgrindは、キャンセルまたはSSL要求の場合にpallocを使用してスタートアップパケット内のユーザー名にメモリを割り当て、その後、そのメモリがpstrdupによって使用されます。 + pallocによって割り当てられたメモリは未定義であったため、これをpalloc0に修正しました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + load_balance_modeがオフの場合に発生するエラー/ハングアップを修正しました。(Tatsuo Ishii) + + + load_balance_modeがオフで、プライマリノードIDが0でない場合には、BEGINなどクエリでエラー/ハングアップが発生していました。 + コミット 3f3c1656の修正によって導入された問題です。 + + + バグはEmond Papegaaijによって発見・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + 特定のCFLAGSによるコンパイルエラーを修正しました。(Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42によって報告されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + サンプルpgpool.conf内のコメントを修正しました。(Bo Peng) + + + sr_check_periodのデフォルト値は10秒であるため、修正しました。コメント内のいくつかのタイポも修正しました。 + + + パッチはhiroinによって作成され、Bo Pengによって修正されました。 + + + + + + + 拡張クエリが終了していない場合でもリセットクエリを実行できるようにしました。(Tatsuo Ishii) + + + コミット240c668dが原因で、拡張クエリメッセージが終了していない場合、リセットクエリが失敗していました。 + このコミットでは、SimpleQuery()でリセットクエリを実行しているかどうかをチェックすることで、この問題を修正しました。 + また、テストケースも追加しました。 + + + + + + + 不適切なプロトコルデータから保護するように修正しました。(Tatsuo Ishii) + + + 拡張クエリメッセージのシーケンスが終了する前にシンプルクエリメッセージが到着すると、Pgpool-IIがハングする可能性がありました。 + これは、シンプルクエリのセッションコンテキスト内のクエリコンテキストが、拡張クエリメッセージのクエリコンテキストによって上書きされたためです。 + + + このコミットでは、拡張クエリプロトコルメッセージが終了したかどうかをチェックするように実装しました。 + 終了していない場合は、FATALエラーを発生させます。このチェックによって検出された既知の例は、JDBCドライバーの「autosave=always」オプションです。 + つまり、このコミットの後、問題(拡張クエリメッセージプロトコルが終了する前にシンプルプロトコルメッセージを送信する)がJDBCドライバー側で修正されるまで、 + Pgpool-IIはこのオプションを受け入れません。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + ドキュメント修正 + + + + + + 「上位サーバへの接続」ドキュメントを改善します。(Bo Peng) + + + + + + + 日本語ドキュメントの言語クリーンアップしました。(Masaya Kawamoto) + + + + + + + + 回帰テスト修正 + + + + + + Java 21での非推奨警告を回避するために回帰テスト005.jdbcを修正しました。(Bo Peng) + + + Java 21での非推奨警告を回避するには、Runtime.exec(String)をRuntime.exec(String[])に置き換えました。 + + + パッチはVladimir Petkoによって作成され、Bo Pengによって修正されました。 + + + + + + + + + リリース 4.1.19 + + リリース日 + 2024-02-29 + + + + 変更点 + + + + + サンプルスクリプトからrestore_commandの設定を削除しました。 (Bo Peng) + + + レプリケーションスロットが有効になっているため、restore_commandは不要です。 + この設定により、フェールオーバーが失敗するケースがあるからです。 + + + + + + + 不具合修正 + + + + + のデフォルト値を修正しました。 (Bo Peng) + + + recovery_userデフォルト値はと同じである必要があるため、 + デフォルト値を''から'nobody'に変更しました。 + + + + + + + BEGINなどでのの不具合を修正しました。 (Tatsuo Ishii) + + + statement_level_load_balanceが有効な場合、 + が無効であっても、 + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE ALL/DISCARDがプライマリノードとすべてのスタンバイノードに送信されていました。 + これは明らかに間違っているだけでなく、スタンバイノードの1つがリモートネットワークにある場合、速度が低下する原因となります。 + + + load_balance_modeがオフの場合、 + Pgpool-IIはそのようなクエリをプライマリノードにのみ送信するように修正しました。 + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + ドキュメント修正 + + + + + 日本語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + Watchdog「リーダー」ではなく「マスター」を誤って使用していました。 + + + + + + + 英語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + PostgreSQL「プライマリ」ではなく「メイン」を誤って使用していました。 + + + + + + + + リリース 4.1.18 + + リリース日 + 2023-11-30 + + + + 変更点 + + + + + 大文字のホスト名をサポートするようにサンプルスクリプトのレプリケーションスロット名の変換処理を変更しました。(Bo Peng) + + + フェイルオーバやオンラインリカバリの時に実行されるスクリプトで、自動的にレプリケーションスロットを削除/作成しています。 + レプリケーションスロット名には大文字を使用できないため、ホスト名を小文字に変換するようにこれらのスクリプトを修正しました。 + + + パッチはSheikh Wasiu Al Hasibによって作成され、Bo Pengによって修正されました。 + + + + + + + 不具合修正 + + + + + 不要なログ行を削除しました。(Tatsuo Ishii) + + + デバッグメッセージ「unset_tx_started_by_multi_statement_query is called in CommandComplete」が誤って残っていました。 + + + + + + + DECLAREによって作成されたポータルでアボートしないようにDescribe()を修正しました。(Tatsuo Ishii) + + + DECLARE foo CURSOR FORを実行すると、PostgreSQLによって「foo」という名前のポータルが自動的に作成されます。 + このポータルはPgpool-IIによって管理されないため、Describe fooメッセージは「unable to execute Describe. unable to get the bind message」エラーで失敗していました。 + + + これを修正するため、Describe()でダミーの書き込みクエリコンテキストを作成し、Describeメッセージをプライマリ(ストリーミングレプリケーションモード)またはすべてのノード(レプリケーション/スナップショットアイソレーションモード)に送信するようにしました。 + + + 新たなテストケース080も追加しました。 + + + この問題はHeather Lapointeによって報告・分析されました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + NAMEDATALENの重複定義を削除しました。(Tatsuo Ishii) + + + src/include/pg_config_manual.hのみでNAMEDATALENを定義するようにしました。 + また、src/utils/pool_select_walker.c内のPOOL_NAMEDATALENNAMEDATALENに置き換えました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + ドキュメント修正 + + + + + PCPがすべてのアドレスをリッスンするにはpcp_listen_addresses = '*'の設定が必要である旨を「Pgpool-II + Watchdogの構築の例」に記載しました。 + + + + + + + + リリース 4.1.17 + + リリース日 + 2023-08-17 + + + + 変更点 + + + + + 共有メモリの初期化後にのみ、システム終了コールバックを呼び出すようにしました。(Muhammad Usama) + + + 共有メモリの取得に失敗して、終了時コールバックが呼び出された場合、クリーンアップ関数は、共有メモリに存在するprocess_infoにアクセスする際にセグメンテーション違反を引き起こす可能性がありました。 + process_infoがNULLのときに終了コールバックからの中断で修正することもできますが、共有メモリの初期化に成功した後に関数をインストールする方がより良いアプローチです。 + なぜなら、システムの残りの部分は常にprocess_infoがNULLになることはないと想定しており、また、子プロセスが生成される前にクリーンアップをする必要はないからです。 + + + + + + + 一部のシステムカタログ照会関数にスキーマ修飾を追加しました。(Tatsuo Ishii) + + + + + + + 不具合修正 + + + + + Coverityの警告を修正しました。(Tatsuo Ishii) + + + クエリキャッシュのモジュールで、time_tの値がint32変数に割り当てられる問題を修正しました。 + Coverityの指摘に従いまして、変数の型をint64に変更しました。 + また、time_tの差分を計算するためにdifftime()を使用しました。これは推奨される方法です。 + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + find_primary_node_repeatedlyが指定時間内で終了しない問題を修正しました。(Bo Peng) + + + + + + + マルチステートメントにおけるPREPAREの利用を修正しました。(Tatsuo Ishii) + + + マルチステートメントの二番目以降の位置にPREPAREが含まれている場合、その後のbindメッセージでプリペアドステートメントを利用すると、送信されたメッセージにプリペアドステートメントが保存されな +いため、「unable to bind」エラーが発生していました。 + + + この問題を修正するために、ステートメントを解析した後にそのようなケースが見つかった場合、名前付きステートメントのクエリコンテキストを作成し、送信メッセージのリストに追加するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + この修正のため、リグレッションテスト079..multi_prepareを追加しました。 + + + + + + + pgprotoをパラメータを使用するbindメッセージを処理できるようにしました。(Tatsuo Ishii) + + + 以前、pgprotoはパラメータを持たないbindメッセージしか処理できませんでした。 + + + + + + + ドキュメント修正 + + + + + 停止モードの意味を明確にしました。(Tatsuo Ishii) + + + + + + 「8.2. Pgpool-II + Watchdogの構築の例」のSSH公開鍵認証の説明を補足しました。(Bo Peng) + + + + + + + オンラインリカバリーの説明を改善しました。(Bo Peng) + + + 複数のpgpoolノードでwatchdogが有効になっていない場合、オンラインリカバリーのセカンドステージが適切に機能しないことについて言及しました。 + + + + + + + 回帰テスト修正 + + + + + 時折発生する069.memory_leak_extendedテストの失敗を修正しました。(Tatsuo Ishii) + + + 偶発するテストの失敗の原因は、pgbenchが終了した後にpsコマンドを実行する前にpgpoolの子プロセスが消えてしまうことにあると判明しました。 + これにより、「DISCARD ALL cannot be executed within a pipeline」というkind mismatchのFATALエラーが発生していました。 + これを修正するために、pgbenchをバックグラウンドで実行し、pgbenchが終了する前にプロセスのサイズを取得するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + リリース 4.1.16 + + リリース日 + 2023-05-18 + + + + 変更点 + + + + + マルチステートメントのクエリを判定するために、psqlscanのソースコードをPgpool-IIにインポートしました。(Tatsuo Ishii) + + + psqlscanは、PostgreSQLソースツリー内のモジュールです。 + これは本質的にPostgreSQL SQLスキャナのサブセットですが、各SQLステートメントの終わりの検出に特化しています。 + したがって、これを使用してクエリ文字列内のSQLステートメントの数をカウントできます。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + 複数のステートメントを幅広く使用できるようにしました。 (Tatsuo Ishii) + + + このコミットは、複数のステートメント (マルチステートメント) に関するPgpool-IIの長年の制限を排除しました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + 内部クエリでスキーマ修飾を使用するように変更しました。(Tatsuo Ishii) + + + 関数やキャストなどの一部のオブジェクトは、「pg_catalog.」スキーマ修飾を使用していませんでした。 + これによって直ちにセキュリティ上の懸念が生じるわけではありませんが、スキーマ修飾を使用することは常に良い習慣ですので、変更しました。 + + + + + + + 不具合修正 + + + + + 共有リレーションキャッシュで発生しうるデッドロックを修正しました。(Tatsuo Ishii) + + + ユーザー定義関数がテーブルロックを取得する場合、拡張クエリプロトコルを使用して関数を呼び出すとデッドロックが発生する可能性がありました。 + 以下にシナリオを示します。 + + + + (1) セッション中クライアントはparse、bind、executeリクエストをpgpoolに送信します。 + + + + + + + (2) セッションAのPgpool-IIはリクエストをPostgreSQLに転送します。 + + + + + + + (3) セッションAのPostgreSQLがexecuteを実行し、テーブルロックが発生します。 + + + + + + + (4) セッションBで、クライアントは関数のparse、bind、executeリクエストをpgpoolに送信します。 + + + + + + + (5) セッションBのPgpoolはリクエストをPostgreSQLに転送します。 + + + + + + + (6) セッションBのPostgreSQLはbindを実行しますが、テーブルはセッションAのPostgreSQLによってすでにロックされており、ロックの解放を待ちます。 + + + + + + + (7) セッションBのpgpoolはexecuteをPostgreSQLに転送した後、関数の揮発性をチェックするために共有リレーションキャッシュを検索するためのセマフォを取得します。 + 次に、do_queryを呼び出し、フラッシュメッセージをPostgreSQLに送信して、この時点までのPostgreSQLからの応答を取得します。 + ただし、#6ではPostgreSQLがテーブルロックを待機しているため、pgpoolはバインド完了後のメッセージを待つ必要があります。 + + + + + + + (8) セッションAのpgpoolがPostgreSQLにexecuteを転送した後、関数の揮発性をチェックするために共有リレーションキャッシュを検索しセマフォを取得しようとしましたが、セマフォはセッションBのpgpoolによってすでに取得されているため、セマフォの解放を待ちます。 + + + + + + + (9) セッションAとセッションBがお互いを待機するため、デッドロックが発生します。 + + + + + + これを修正するには、do_query()を呼び出す前にセマフォを解放するようにpool_search_relcache()を変更しました(ただし、セマフォはdo_query()の後に取得します)。 + これにより、上記#8のセッションAはセマフォを取得し、先に進むことができます。 + クライアントからsyncメッセージを受信し、PostgreSQLに転送します。 + syncを受信すると、ユーザ定義関数は実行を終了し、テーブルロックを解放します。 + これにより、セッションBのPostgreSQLがテーブルロックを取得できるようになります。 + + + + + + + musl libcを使用するシステムでのコンパイルエラーを修正しました。(bug 790) (Tatsuo Ishii) + + + パッチはleimaohuiによって提供されました。 + + + + + + + 複数のクエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + 特殊なケースでsrワーカーが間違ったクエリをスタンバイサーバに送信する不具合を修正しました。(Tatsuo Ishii) + + + ALWAYS_PRIMARYフラグが設定されている場合、PRIMARY_NODE_IDマクロは、プライマリがダウンしている場合でも、-1ではなくノードIDを返していました。 + この場合、ストリーミングレプリケーション遅延をチェックするワーカープロセスは、PostgreSQLのバージョンに応じてSELECT pg_current_wal_lsn()またはSELECT pg_current_xlog_location()をスタンバイに送信し、当然エラーが発生していました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + DEALLOCATEによる種類不一致エラーを修正しました。 + (bug 780) (Tatsuo Ishii) + + + 以下の条件がすべて満たされた場合、種類不一致エラーが発生していました。 + + + + ストリーミングレプリケーションモード + + + + + + + ロードバランスノードがプライマリ以外のノード + + + + + + + PREPAREがマルチステートメントクエリで使用されている + + + + + + + + + + ドキュメント修正 + + + + + の説明を追加しました。(Chen Ningwei) + + + + + + + PREPARE/EXECUTE/DEALLOCATEに関する制限を追加しました。(Tatsuo Ishii) + + + + + + + Pgpool-IIで-Dオプションを使用する場合の注意点を追加しました。(Tatsuo Ishii) + + + + + + + 「RPMからのインストール」セクションを強化しました。(Bo Peng) + + + + + + + 「Pgpool-II + Watchdogの構築の例」から「-D」起動オプションの設定を削除しました。(Bo Peng) + + + + + + + AES256をサポートするにはオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + .pcppassを使用するには、pcpコマンドの-wオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + を強化しました。(Tatsuo Ishii) + + + + + + + 回帰テスト修正 + + + + + 071.execute_and_deallocate/test.shをリファクタリングしました。(Tatsuo Ishii) + + + + + + + いくつかの回帰テストを強化しました。(Tatsuo Ishii) + + + + + + + 時折発生する005.jdbcテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.1.15 + + リリース日 + 2023-01-23 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + 以下の条件をすべて満たす場合、コマンドによりのパスワードが公開されます。このコマンドは、Pgpool-IIに接続できるすべてのユーザーが実行できます。(CVE-2023-22332) + + + + + + バージョン3.3以降 + + + + + + onに設定されている + + + + + + queryが設定されている + + + + + + にプレーンテキストのパスワードが設定されている + + + + + + 上記条件のすべてに該当するユーザは、このバージョンにアップグレードするか (show pool_statusコマンドでが表示されなくなる)、次の回避策のいずれかを使用することを強くお勧めします。 + + + + 4.0.x~4.4.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + には空文字を設定し、パスワードはpool_passwdファイルに設定する。 + + + + + + にAESで暗号化したパスワードを設定する。 + + + + + + いずれにせよ、PostgreSQLでを変更することをお勧めします。 + + + + 3.3.x~3.7.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + いずれにせよ、PostgreSQLを変更することをお勧めします。 + + + + Pgpool-II 3.7.xおよび以前のバージョンはサポートが終了しているため、これらのバージョンのマイナーアップデートはリリースされません。 + + + + + 変更点 + + + + + + およびコマンドでwd_lifecheck_passwordを表示しないように修正しました。(CVE-2023-22332) (Bo Peng) + + + + + + + ドキュメントに記載されているように、のデフォルト値を空の文字列に変更しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + pgpool-regclass.cのコンパイラ警告を修正しました。(Florian Weimer, Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + 共有メモリ使用時の設定の章のいくつかの誤りを修正し、説明を強化しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.1.14 + + リリース日 + 2022-12-22 + + + + 変更点 + + + + + + ログメッセージ"new IPC connection received"をDEBUG1にダウングレードしました。 + (bug 775) (Bo Peng) + + + これは通常のメッセージで、LOGとして記録されるべきではありません。 + パッチはpstefによって作成され、Bo Pengによってレビューされました。 + + + + + + + + 不具合修正 + + + + + + の問題を修正しました。(Muhammad Usama) + + + Watchdogクラスタ全体のヘルスチェックパラメータの最大値に基づいて、フェイルオーバコマンドのタイムアウトを動的に設定するように修正しました。 + + + Tatsuo Ishiiによってレビューおよびテストされました。 + 議論: [pgpool-hackers: 4227] + + + + + + + パーサ内でバックスラッシュを使った場合の警告を出力しないように修正しました。(Tatsuo Ishii) + + + standard_conforming_strings = offかつescape_string_warning = onの場合、PostgreSQLは文字列リテラル内でバックスラッシュを使った場合に警告を出力します。 + これは問題ありません。 + しかし、以前はPgpool-IIのパーサも同じメッセージを出力していました。 + これは冗長です。 + + + + + + + idle_session_timeoutに対応しました。(Tatsuo Ishii) + + + idle_session_timeout (PostgreSQL 14 で追加)が有効、かつ、タイムアウトが発生した場合、次のことが発生します: + + + + failover_on_backend_errorがon (デフォルト)の場合、Pgpool-IIはフェイルオーバを発生させます。 + + + + + + + PostgreSQL サーバが 1 台のみが idle_session_timeout を有効にしていると、Pgpool-II がハングする可能性があります。 + + + + + + idle_session_timeoutに対応するため、エラーコードを検出するdetect_idle_session_timeout_error()を追加しました。 + エラーを検出すると、Pgpool-II は致命的なエラーとしてフロントエンドにエラーコードを返し、セッションを切断します。 + これはidle_in_transaction_session_timeoutの実装と同じような修正です。 + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + 議論: [pgpool-hackers: 4208] + + + + + + + SSLエラーSSL_ERROR_ZERO_RETURNに対応しました。(Tatsuo Ishii) + + + 以前はこれによってフェイルオーバが発生しましたが、サーバは単に接続を閉じることを意味するため、実際には不要でした。 + + + 議論: [pgpool-general: 8366] + 議論: [pgpool-hackers: 4193] + + + + + + + メモリキャッシュサイズを2GBより多く設定した場合に発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + 問題は与えられたキャッシュブロックのメモリアドレスを返す block_address()関数にあり、 + 2GB上限まで有効な共有メモリ空間内のブロックのオフセットを計算するために32bit整数を使っていました。 + + + + + + + pcp_proc_infoSHOW pool_poolsおよびSHOW pool_processes内のまれなセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + セグメンテーション違反はget_pools()とget_processes()にありました。 + それらは、最初に共有メモリ上の特定のプロセス情報スロットのpidを抽出し、次にキーとして pid を使ってスロットを再び検索していました。 + これらのステップはロックによって保護されていなかったため、プロセス終了時に新しい子プロセスのフォークを担う親プロセスによって pid が上書きされた場合、 + pid を使った検索が失敗し、NULLを返す可能性がありました。 + その結果、それに続くNULLポインタの参照によってセグメンテーション違反が発生していました。 + + + 解決策は、最初にプロセス情報スロットへのポインタを取得し、次にポインタからpidメンバを抽出することです。 + この方法でも、親プロセスによる共有メモリ情報の同時更新は可能ですが(出力におかしな結果をもたらす可能性があります)、少なくともセグメンテーション違反は回避できます。 + + + + + + + 無効な長さのUnixドメインソケットパスを使えないように修正しました。(Masaya Kawamoto) + + + + + + + + ドキュメント修正 + + + + + + Doc: memqcache_methodの説明を拡充しました。(Tatsuo Ishii) + + + どの方式を使うべきかの説明を追加しました。 + + + + + + + Doc: ヘルスチェックプロセスでSSLが使えることに言及しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションのチェックでもSSLが使えることに言及しました。 + これは2010年以降に使えていたはずです。 + + + 議論: [pgpool-hackers: 4187] + + + + + + + + 回帰テスト修正 + + + + + + 環境変数を使ってPGPOOLDIRを定義できるようにしました。 + (bug 766) (Bo Peng) + + + + + + + + + リリース 4.1.13 + + リリース日 + 2022-08-18 + + + + 変更点 + + + + + + サンプルスクリプトで指定するrestore_commandにsshオプションを追加しました。(Bo Peng) + + + パッチはJon SCHEWEによって作成され、Bo Pengによって更新されました。 + + + + + + + CloseCompleteを受け取った時、バッファリングなしでフロントエンドに転送するようになりました。(Tatsuo Ishii) + + + 074.bug700_memqcache_segfaultで時折タイムアウトエラーが発生していました。 + + + + + + + + 不具合修正 + + + + + + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + + Pgpool-IIは"Select '2022-02-18 07:00:00.006547'::timestamp"のような問合せをキャッシュしていませんでした。 + TIMESTAMP、TIME、DATEを含むSELECT文はキャッシュされるようになりますが、TIMESTAMPZ、TIMEZを含むSELECT文は"SET TIME ZONE"コマンドなどで結果が変更されるためキャッシュされません。 + また、TIMESTAMPZやTIMEZ型を返す関数を含むSELECT文も同様の理由でキャッシュされません。 + Discussion: [pgpool-general: 8285] + + + + + + + + ドキュメント修正 + + + + + + Doc: 誤字を修正しました。(Tatsuo Ishii) + + + + + + + Doc: 特定のSELECT文がキャッシュされないことに言及しました。(Tatsuo Ishii) + + + 特定のSELECT文は以下です。 + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を使っているSELECT + + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEへのキャストを含むSELECT + + + + + SQLValueFunction (CURRENT_TIME, CURRENT_USERなど)を含むSELECT + + + + + + + + + + Doc: Unixドメインソケット接続するときのPCPパスワードファイルの使用についての説明を修正しました。(Masaya Kawamoto) + + + pcppassファイルのlocalhostエントリはデフォルトのPCPソケットディレクトリパスへの接続とのみマッチして、全てのUnixソケット接続には使用されません。 + この振る舞いはpgpassファイルと同じです。 + + + + + + + Doc: 必要メモリの説明を修正し、詳細にしました。(Tatsuo Ishii) + + + + + + + pgpoolの子プロセスが動作する間のメモリ使用についての説明を追加しました。 + + + + + + より正確な結果を計算できるように、必要共有メモリを計算する式を詳細にしました。 + + + + + + インメモリクエリキャッシュ用の共有メモリ量を修正しました。64MBは誤った値でした。 + + + + + + 必要プロセスメモリを修正しました。以前の式はRSSを基にしていましたが、RSSはライブラリに使用されるメモリなどの共有メモリも含むため、PSSを使用するべきです。 + これによって以前より要求メモリが大幅に減少します。 + + + + + + + + + + Doc: の誤った説明を修正しました。(Tatsuo Ishii) + + + これらのパラメータは設定ファイルの再読み込みでは変更できず、Pgpool-IIの再起動が必要です。 + + Discussion: [pgpool-general: 8195] + + + + + + + + テストツール修正 + + + + + + PostgreSQL 15でpgpool_setupを実行できるようになりました。(Tatsuo Ishii) + + + ticket 757を参照ください。 + + + + + + + + 回帰テスト修正 + + + + + + Test: 回帰テストでPgpool-IIのバージョンを表示するようになりました。(Tatsuo Ishii) + + + + + + + Test: 適切なinstall directoryでpgpool.confを探すように回帰テストスクリプトを修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 4.1.12 + + リリース日 + 2022-05-19 + + + + 変更点 + + + + + Pgpool-IIメインプロセスの停止を強化しました。(Tatsuo Ishii) + + + 「pgpool stop」が一定期間(現在5秒)以内にメインプロセスを終了できなかった場合は、信号を再送信するように修正しました。 + + + + + + + コマンドのPIDの長さを7文字に変更しました。(Bo Peng) + + + + + + + Parseメッセージ処理のエラーメッセージにメッセージの種類、バックエンドノードIDを含めるように改善しました。(Tatsuo Ishii) + + + + + + + ParameterStatusメッセージのログレベルをLOGからDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + のデフォルト値を「*」から「localhost」に変更しました。(Tatsuo Ishii) + + + + + + + のフィールド名を変更しました。(Muhammad Usama) + + + + + + + + 不具合修正 + + + + + lost状態のリモートPgpool-IIノードが再起動後にクラスタに再参加できない問題を修正しました。(Muhammad Usama) + + + 報告: [pgpool-general: 7896] + + + + + + + 無限待機の可能性を回避するために、Pgpool-IIメインプロセスのexit_handlerを修正しました。(Tatsuo Ishii) + + + + + + + プライマリ検索中にバックエンドが失敗またはシャットダウンした場合にPgpool-IIのメインプロセスが終了してしまう問題を修正しました。(Tatsuo Ishii) + + + + + + + Watchdogで発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + pg_isreadyを使用してPostgreSQLのステータスを確認するようにfollow_primary.sh.sampleを修正しました。(Bo Peng) + + + + + + + + ドキュメント修正 + + + + + Doc: 設定例を更新しました。(Masaya Kawamoto) + + + + + + + Doc: pcp_watchdog_infoの出力例を更新しました。(Bo Peng) + + + + + + + Doc: pg_encの引数として「$」文字を含むパスワードを指定する場合は、エスケープする必要があることを注意事項に追加しました。(Bo Peng) + + + + + + + + 回帰テスト修正 + + + + + タイムアウトエラーを回避するために、リグレッションテスト018.detach_primaryを強化しました。(Tatsuo Ishii) + + + + + + + タイムアウトエラーを回避するために、リグレッションテスト074.bug700_memqcache_segfaultを強化しました。(Tatsuo Ishii) + + + + + + + セグメンテーション違反を検出するようにテストスクリプトを改善しました。(Bo Peng) + + + + + + + + リリース 4.1.11 + + リリース日 + 2022-02-17 + + + + 変更点 + + + + + + in_hot_standbyによるメッセージ長の違いに関する不要なログを抑制しました。(Tatsuo Ishii) + + + PostgreSQL 14 は新しいパラメータを導入しました: in_hot_standby + + + この値はスタンバイサーバの場合は "on" で、プライマリサーバの場合は "off" になります。 + その結果 pgpool のログは以下のメッセージで溢れていました。 + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + これを防ぐために、パラメータ名がin_hot_standbyでない場合にのみログを出力するようになりました。 + + + また、メッセージにパラメータ名を表示するようになりました。例を示します。 + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + の形式の検査を追加しました。(Masaya Kawamoto) + + + wd_lifecheck_passwordrecovery_passwordはmd5ハッシュ形式を使用できませんが、pgpool は認証失敗を報告するだけでそれらのチェックをしていませんでした。 + + + + + + + パラメータステータスの取り扱いを変更しました。(Tatsuo Ishii) + + + バックエンドからパラメータステータスのメッセージが届いたときにただメモリー上に記憶するだけでなく、フロントエンドに転送するようになりました。 + + + + + + + + 不具合修正 + + + + + + pcp_node_infoの実行の際に長時間待機する不具合を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Coverityによって見つかったヘルスチェックプロセスの問題を修正しました。(Tatsuo Ishii) + + + + + + + Coverityによって見つかったメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + プライマリノードが存在しない場合の対処をするようにfailover()を修正しました。(Tatsuo Ishii) + + + プライマリノードが存在しない場合に pgpool が起動したときなどReq_info->primary_node_idが -1 である場合にfailover()find_primary_node_repeatedly()の呼び出しをスキップしていました。 + また、follow_master_commandも実行されませんでした。 + + + Discussion: [pgpool-hackers: 4113] + + + + + + + failover スクリプトのサンプルを修正しました。(Bo Peng) + + + old primary node id が"-1"の場合を考慮していませんでした。 + + + + + + + バックエンドに接続できないときにストリーミングレプリケーションチェックプロセスがリトライしないように修正しました。(bug 742)(Bo Peng) + + + このリトライによってフェイルオーバに時間がかかっていました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントの誤字を修正しました。(pengbo) + + + パッチはUmar Hayatによって提供されました。 + + + + + + + PostgreSQL YUM リポジトリからPgpool-IIがインストールされないように /etc/yum.repos.d/pgdg-redhat-all.repo を"exclude"する設定を追加しました。(Bo Peng) + + + + + + + ParameterStatusin_hot_standbyパラメータに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + set_configに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + + テストツール修正 + + + + + + pgpool_setupが作成するfailoverスクリプトを修正しました。(Tatsuo Ishii) + + + pgpool_setupfailover.shを作成するとき、プライマリサーバが存在しない場合を考慮していませんでした。 + + + + + + + + 回帰テスト修正 + + + + + + 再コンパイルしないで既存のインストールで回帰テストを実行できるようになりました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + テスト075を修正しました。(Tatsuo Ishii) + + + pgpool が起動していなくても成功していました。 + 報告とパッチはQiang Lingjieによって提供されました。 + Discussion: [pgpool-hackers: 4085] + + + + + + + noinstall モード時のpgpool_setupwatchdog_setupのバイナリパスを修正しました。(Bo Peng) + + + + + + + + + リリース 4.1.10 + + リリース日 + 2021-12-23 + + + + 変更点 + + + + + + yaccとの非互換性によって出力されるbisonの警告を抑制しました。(Tatsuo Ishii) + + + + + + + 冗長なコードを修正しました。(Tatsuo Ishii) + + + パッチはLu Chenyangによって提供されました。 + + + + + + + + ドキュメント修正 + + + + + + Doc: pcp_watchdog_infoマニュアルの誤字を修正しました。(Tatsuo Ishii) + + + + + + + Doc: 設定例の誤字を修正しました。(Bo Peng) + + + パッチはLu Chenyangによって提供されました。 + + + + + + + Doc: リリースノートの誤字を修正しました。(Bo Peng) + + + + + + + + + リリース 4.1.9 + + リリース日 + 2021-11-18 + + + + セキュリティリリース + + + + + SSL暗号化ハンドシェイク後の余計なデータを拒否するようにしました。(Tatsuo Ishii) + + + サーバサイドのSSLネゴシエーションの実装において、任意のSQLコマンドを実行できる中間者攻撃が可能でした。 + これはPgpool-IIがクライアント認証で証明書認証を使用しているか、hostssl + trust認証の場合に可能でした。 + PostgreSQLのCVE-2021-23214と似た脆弱性です。 + + + 同様に、クライアントサイドのSSLネゴシエーション実装において、任意の結果に改ざんする中間者攻撃が可能でした。 + これはPostgreSQLがクライアント認証でhostssl + trust認証を使用しているときに可能でした。 + 証明書認証の場合には、Pgpool-IIはPgpool-IIとPostgreSQL間で証明書認証を実装していないため問題ありません。 + PostgreSQLのCVE-2021-23222と似た脆弱性です。 + + + + + + + 変更点 + + + + + + pg_terminate_backend()の処理に関するPostgreSQL 14対応をしました。(Tatsuo Ishii) + + + + + + + Pgpool-IIメインプロセスのSIGCHLDハンドラを改良しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスがSIGKILLシグナルでkillされたとき、SIGCHLDハンドラは他のシグナルと同じようにLOGレベルメッセージを発していました。 + しかし、SIGKILLシグナルはOMM killerによるkillなど重要なイベントなので、WARNINGレベルのメッセージを発するようにしました。 + Michail Alexakisから提案されました。 + Discussion: [pgpool-general: 7750] + + + + + + + + 不具合修正 + + + + + + が0のときに起こるコネクションカウンタの不具合を修正しました。(Tatsuo Ishii) + + + reserved_connectionsが0のとき、コネクションカウンタを管理する必要はありませんでした。 + この修正によって不意のカウンタリークによる不必要な"Sorry, too many clients already"エラーを防ぐことができます。 + Discussion: [pgpool-general: 7750] + + + + + + + bug 732: フェイルオーバ中のセグメンテーション違反を修正しました。 (Muhammad Usama) + + + + + + + COPY FROM中のハングアップを修正しました。(Tatsuo Ishii) + + + COPY FROM中にエラーが発生したとき、Pgpool-IIはフロントエンドからCOPY終了マーカーが送信されたあと、バックエンドからの応答を永遠に待っている可能性がありました。 + Bo Pengによって発見されました。 + + + + + + + rawモードでの誤った負荷分散ノードの表示を修正しました。(Bo Peng) + + + rawモードでは、Pgpool-IIはすべてのクエリをメインノードに送信します。 + この不具合は表示上の問題だけで、クエリの転送処理に影響はないですが、ユーザを混乱させる可能性があるので、修正しました。 + + + + + + + PGPOOL SHOW ALLの実行結果にbackend_flag*が2回表示される不具合を修正しました。(Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + Doc: ドキュメントのtypoを修正しました。(Bo Peng) + + + + + + + ドキュメントとサンプルスクリプトのtypoを修正しました。(Bo Peng) + + + パッチはKazufumi Notoによって提供されました。 + + + + + + + Doc: PGPOOL SHOWコマンドを実行する際に、大文字を含むパラメータ名の場合には、 + パラメータ名をダブルクォートで囲んで実行する必要があることを追加しました。(Bo Peng) + + + + + + + + テストツール修正 + + + + + + 新しいメインノードが利用できない場合に何もしないようにpgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + + 回帰テスト修正 + + + + + + たまに発生する073.pg_terminate_backendの失敗を修正しました。(Tatsuo Ishii) + + + + + + + テスト074の名前を変更しました。(Bo Peng) + + + + + + + テストの失敗を防ぐためにpsqlコマンドのパスを修正しました。(Bo Peng) + + + + + + + + + リリース 4.1.8 + + リリース日 + 2021-08-05 + + + + 変更点 + + + + + + ドメイン名を含めたホスト名の長さの最大値を変更しました。(Tatsuo Ishii) + + + ホスト名の長さの最大値を128にしていましたが、正しくは254でした。 + Discussion: [pgpool-hackers: 3903] + + + + + + + + 不具合修正 + + + + + + クエリキャッシュでSQLValueFunctionsを含むクエリをキャッシュしないようにしました。(Tatsuo Ishii) + + + SQLValueFunctionsの一覧は以下になります。 + + + + CURRENT_DATE + + + + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + + + + + SESSION_USER + + + + + USER + + + + + CURRENT_CATALOG + + + + + CURRENT_SCHEMA + + + + + + + + + + describeメッセージのあとにNoDataで応答された場合のクライアント側のハングアップを修正しました。(Tatsuo Ishii) + + + 問題の報告、パッチはDaniel van de Giessenより提供されました。 + Discussion: [pgpool-hackers: 3950] + + + + + + + SIモードにおける不正なメッセージの送信を修正しました。(Tatsuo Ishii) + + + クエリがシリアル化エラーなどの特定の理由によってアボートしたとき、Pgpool-IIは + メインノード以外で実行されているトランザクションを中止するためにエラークエリを送信します。そのメッセージ長が + 正しくなかったためバックエンドで「invalid string in message」エラーが発生していました。 + + + + + + + Pgpool-IIが停止したときに孤児プロセスが残る不具合を修正しました。(Tatsuo Ishii) + + + follow_primary_commandの実行中にPgpool-IIが停止すると、 + follow_primary_commandによって開始されたいくつかのプロセスが残ったままになる可能性がありました。 + + + + + + + pcp_detach_nodeの実行後ダウンノードが残る不具合を修正しました。(Tatsuo Ishii) + + + プライマリノードをpcp_detach_nodeでデタッチしたとき、follow_primary_commandの + 実行後にもスタンバイノードがダウンのままになっていました。 + Discussion: [pgpool-hackers: 3915] + + + + + + + pgpool.confのリロードで変更できない + 不具合を修正しました。(Tatsuo Ishii) + + + + + + + watchdog通信の競合状態を修正しました。(Tatsuo Ishii) + + + メインプロセスがwatchdogプロセスから通知された処理を実行中に、watchdogプロセスが新しいメッセージを + メインプロセスに通知したとき、新しいメッセージが処理されるまでに大幅な遅延が発生していました。 + Discussion: [pgpool-hackers: 3900] + + + + + + + 再起動後にwatchdogノードステータスが更新されない問題を修正しました。 + (bug 684) (Muhammad Usama) + + + + + + + + ドキュメント修正 + + + + + + Doc: の説明を増やしました。(Tatsuo Ishii) + + + + + + + Doc: いくつかのドキュメントのtypoを修正しました。(Bo Peng) + + + + + + + Doc: インメモリクエリキャッシュのtypoを修正しました。(Tatsuo Ishii) + + + + + + + Doc: の説明を修正しました。(Masaya Kawamoto) + + + + + + + + テストツール修正 + + + + + + ポータブルなfollow_primary.shを生成するようにpgpool_setup + を修正しました。(Tatsuo Ishii) + + + + + + + pgpool_setupで使用されるrsyncのパラメータを修正しました。(Tatsuo Ishii) + + + + + + + pgpool_setup中のベースバックアップ処理を修正しました。(Tatsuo Ishii) + + + + + + + watchdog_setupのスクリプトを修正しました。(Tatsuo Ishii) + + + watchdog_setupによって生成されるshutdownallスクリプトは、全体シャットダウンでは + 不必要なフェイルオーバ処理を引き起こしていました。 + + + + + + + + 回帰テスト修正 + + + + + + 075.detach_primary_left_down_nodeの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 031.connection_life_timeの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 018.detach_primaryの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 028.watchdog_enable_consensus_with_half_votesの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 018.detach_primaryの不具合を修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 4.1.7 + + + リリース日 + 2021-05-20 + + + + + 不具合修正 + + + + + サンプルスクリプトの改善を行いました。 (Bo Peng) + + + + + + + リグレッションテスト018.detach_primaryの不具合を修正しました。 (Tatsuo Ishii) + + + + + + + の競合状態を修正しました。(Tatsuo Ishii) + + + が同時に実行されると、多くの問題が発生していました。 + 典型的な問題としては、プライマリノードが見つからないことです。 + + + + + + + Doc: の説明を修正しました。(Tatsuo Ishii) + + + パラメータは、Pgpool-IIがrootで起動する場合にのみ使用できます。 + + + + + + + Doc: の説明を改善しました。(Tatsuo Ishii) + + + + + + + + + Doc: に関する誤った説明を削除しました。(Tatsuo Ishii) + + + + + + + + + database/app_name_redirect_preference_listがステートメントレベル負荷分散モードで正しく動作しない不具合を修正しました。 + (bug 707) (Bo Peng) + + + + + + + pgpool0の配下のみにデータベースクラスタを作成するようにを修正しました。(Tatsuo Ishii) + + + + + + + クエリキャッシュが有効になっている場合のpgpoolのクラッシュを修正しました。 + (bug 700) (Tatsuo Ishii) + + + ストリーミングレプリケーションモードと論理レプリケーションモード以外でCloseCompleteを受信すると、Pgpool-IIがクラッシュしていました。 + + + + + + + follow_primary.shサンプルスクリプトを修正しました。 + (bug 694) (Bo Peng) + + + pg_rewindを実行した後に、スタンバイノードのpg_replslotディレクトリを空にするように修正しました。 + これは、古いPostgreSQLバージョンではpg_replslotディレクトリがプライマリノードからコピーされる可能性があるためです。 + + + + + + + クエリキャッシュがストリーミングレプリケーションモードと論理レプリケーションモード以外で作成されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + asyncpgを利用した場合のハングアップを修正しました。(Tatsuo Ishii) + + + + + + + Startupパケットを受信したときのデバッグメッセージを改善しました。 (Tatsuo Ishii) + + + + + + + Doc: 多数ドキュメントの改善を行いました。 (Tatsuo Ishii, Bo Peng) + + + + + + + + + リリース 4.1.6 + + + リリース日 + 2021-02-18 + + + + + 変更点 + + + + + Pgpool-II起動時に既存のwatchdogコマンドソケットファイルを削除するように修正しました。(Muhammad Usama) + + + パッチはMasaya Kawamotoによって提供されました。 + + + + + + + + 不具合修正 + + + + + の誤ったweightの表示を修正しました。 (Tatsuo Ishii) + + + + + + + follow_primary.sh.samplepg_rewind実行後にrecovery.confが削除されないように修正しました。(Bo Peng) + + + + + + + Watchdogリーダーによる同期処理後に、ヘルスチェックプロセスが起動されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + watchdog_setupの誤ったデータベースクラスタのパスを修正しました。(Tatsuo Ishii) + + + + + + + DBノードごとに個別のアーカイブディレクトリを作成するようにpgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + ヘルスチェックプロセス起動時のメッセージを修正しました。(Tatsuo Ishii) + + + + + + + Doc: サンプルスクリプトはテーブルスペースをサポートしていないことをドキュメント「Pgpool-II + Watchdogの構築の例」に追加しました。(Bo Peng) + + + + + + + Doc: 共有リレーションキャッシュに必要な共有メモリについての説明を追加しました。(Tatsuo Ishii) + + + + + + + 共有メモリの割り当て中のエラーを修正しました。(Tatsuo Ishii) + + + + + + + ERRORが発生した場合、が正しくカウンタされない不具合を修正しました。(Tatsuo Ishii) + + + + + + Doc: インストールのヒントのセクションでfirewall-cmdの使用法を修正しました。(Tatsuo Ishii) + + + この例では、firewall-cmdが不要なポートを開放しました。 + + + + + + + backend_flag0 = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER'またはfailover_command=''の場合に発生しうるセグメンテーション違反を修正しました。 + (bug 672) (Tatsuo Ishii) + + + + + + pool_passwdのファイルスワッピングの競合状態を修正しました。(Tatsuo Ishii) + + + パッチはMasaya Kawamotoによって提供されました。 + + + + + + Doc: のドキュメントを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.1.5 + + + リリース日 + 2020-11-19 + + + + + 変更点 + + + + + Doc: ドキュメントの「Auroraの設定例」を更新しました。(Bo Peng) + + + + + + + Doc: Pgpool-IIGSSAPIをサポートしないという注意事項を追加しました。(Tatsuo Ishii) + + + + + + + フロントエンドがGSSAPI暗号化接続を要求した場合、 + Pgpool-IIGSSAPIをサポートしていないため、 + これまでエラーを返していましたが、他の方式での接続を要求するように変更しました。(Tatsuo Ishii) + + + パッチはTatsuo Ishiiにより作成され、Umar Hayatによりレビュー・テストされました。 + + + + + + + Doc: ドキュメントの設定例「Pgpool-II + Watchdogの構築の例」を更新しました。(Bo Peng) + + + + + + + + + 不具合修正 + + + + + ネイティブレプリケーションモードで「INSERT ... ON CONFLICT」クエリ書換えの不具合を修正しました。 + (bug 654) (Bo Peng) + + + + + + + クエリがキャンセルされたときにコネクションカウントが減少しない不具合を修正しました。 + (bug 656) (Tatsuo Ishii) + + + + + + + Doc: PostgreSQLの使用可能なバージョンを7.4以降に修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.1.4 + + + リリース日 + 2020-09-17 + + + + + 変更点 + + + + + + PostgreSQL 12.4 のガイドラインに従ってPgpool-IIの拡張機能のスクリプトを修正しました。(Tatsuo Ishii) + + + + CREATE OR REPLACE FUNCTIONの使用を避けて、代わりにCREATE FUNCTIONを使用するように修正しました。 + + + + + + + + の"PGBIN"と"LPATH"を、PostgreSQLのbin pathとlib pathにしました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + Doc: オンラインリカバリが利用可能なPgpool-IIの動作モードに関する誤った説明を修正しました。(Bo Peng) + + + + + + + + いくつかの不要なチェックをソースコードから削除しました。(Tatsuo Ishii) + + + + パッチはby Hou, Zhijieにより提供されました。 + + + + + + + + relcacheクエリがプライマリ以外に送信される不具合を修正しました。(Tatsuo Ishii) + + + + ストリーミングレプリケーションモードでは、relcacheクエリはプライマリノードに送信されるようになっています。 + しかし、実際には、プライマリノードがマスターノードでない場合、relcacheクエリはプライマリノードに送信されませんでした。 + 通常、これはプライマリがノード0でない場合に発生する可能性があります。 + + + + + + + + が有効になっているときにが機能しない問題を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] + + + + + + + + 認証処理において有益なエラーメッセージを表示するように修正しました。(Tatsuo Ishii) + + + + + + + + の"PGBIN"と"LPATH"を、PostgreSQLのbin pathとlib pathにしました。(Bo Peng) + + + + + + + + Test: 時々に発生する073.pg_terminate_backendテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + 特定の場合に発生するpgpool子プロセスのセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + 以下の方法で再現できます。 + + + + + すべてのバックエンドを停止します。 + + + + + + 無効なクライアントでpgpoolに接続します。例えば、pcpのポートではなく、pgpoolのポート番号を使用してpcp_attach_nodeを実行します。 + + + + + + + + + + + + リリース 4.1.3 + + + リリース日 + 2020-08-20 + + + + + 変更点 + + + + + Doc: TLSバージョン1.2あるいはそれ以下のバージョンのみがの影響をうけるという説明を追加しました。(Tatsuo Ishii) + + + + + + + Doc: サンプルスクリプトへのリンクを「設定例」に追加しました。(Bo Peng) + + + + + + + Doc: に関する説明を改善しました。(Bo Peng) + + + パッチはKenichiro Tanakaにより提供されました。 + + + + + + + pool_hba.confサンプルファイルにhostssl/hostnosslに関する説明を追加しました。(Tatsuo Ishii) + + + + + + + Doc: 多数ドキュメントの改善を行いました。(Tatsuo Ishii) + + + + + + + Doc: に関する注意点を追加しました。(Takuma Hoshiai) + + + レプリケーションスロットを使用している場合、が動作しない可能性があります。 + スタンバイノードがダウンした際に、によりスタンバイのレプリケーションスロットが削除され、 + レプリケーションが停止している可能性があるためです。 + + + + + + + + 不具合修正 + + + + + pgpoolの起動時に、pidファイルが存在する場合、書き込む前にpidファイルを長さゼロに切り詰めるように修正しました。(Bo Peng) + + + パッチはmaliangzhuにより提供されました。 + + + + + + + Doc: のパラメータの説明の誤りを修正しました。(Bo Peng) + + + + + + + ストリーミングレプリケーションモードでプライマリノードが0以外の場合、が機能しない問題を修正しました。(Tatsuo Ishii) + + + + + + + -rオプション及びPostgreSQL 12でのpgpool_setupの問題を修正しました。(Tatsuo Ishii) + + + + + + + RPMパッケージのPCPコマンドのUNIX_DOMAIN_PATH/var/run/postgresqlに変更します。(Bo Peng) + + + + + + + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + クエリキャッシュが有効な場合、あるテーブルが更新された場合、Pgpool-IIは自動的にそのテーブルに関係する全てのキャッシュを削除するようになっています。 + しかし、EXPLAIN ANALYZEまたはCTEで更新クエリを実行した場合に、 + これらのクエリが誤って参照クエリとして扱われ、キャッシュが削除されませんでした。 + + + パッチはHou, Zhijieにより作成され、Tatsuo Ishiiにより修正されました。 + + + + + + + コーナーケースで発生するPgpool-IIのハングアップを修正しました。(Tatsuo Ishii) + + + + + + + user、database、application_name以外のパラメータが指定された場合、startupパケットの読み取りが失敗する不具合を修正しました。(Tatsuo Ishii) + + + + + + + pg_terminate_backendを実行した時にコネクションのカウントがずれる不具合を修正しました。(Takuma Hoshiai) + + + + + + + アプリケーション名がに含まれている場合に発生するセグメンテーション違反を修正しました。 (bug 615) (Tatsuo Ishii) + + + + + + + ネイティブレプリケーションモードでpg_terminate_backend()を実行すると、フェイルオーバを引き起こしてしまう不具合を修正しました。(Takuma Hoshiai) + + + + + + + IBM Zハードウェアでの004.watchdogテストのクラッシュを修正しました。 (bug 614) (Tatsuo Ishii) + + + パッチはgregn123により作成され、Tatsuo Ishiiにより修正されました。 + + + + + + + + + リリース 4.1.2 + + + リリース日 + 2020-05-21 + + + + + 不具合修正 + + + + + + 一部のシステム(Fedora 32)で発生するビルドエラーを修正しました。(Tatsuo Ishii) + + + + + + + + Doc: パラメータに関する注意事項を追加しました。(Bo Peng) + + + + + + + + Pgpool-IIがすべての暗号方式を受け付ける不具合を修正しました。(bug 608) (Muhammad Usama) + + + + + + + + 認証の詳細ログをダウングレードしました。(Tatsuo Ishii) + + + + + + + + 不要なチェックを削除しました。(Tatsuo Ishii) + + + + パッチはsherlockcppによって提供されました。Discussion: [pgpool-general: 7004] + + + + + + + + Doc: ドキュメントのタイポを修正しました。(Tatsuo Ishii) + + + + パッチはUmar Hayatによって提供されました。 + Discussion: [pgpool-hackers: 3587] + + + + + + + + PCP プロセスのセグメンテーション違反を修正しました。(bug 598) (Muhammad Usama) + + + + + + + + Watchdogで一部の警告メッセージが出力されない問題を修正しました。(Tatsuo Ishii) + + + + パッチはsherlockcppによって提供されました。 + Discussion: ([pgpool-general: 6956] + + + + + + + + Doc: タイポを修正しました。(Tatsuo Ishii, Bo Peng) + + + + パッチはsherlockcppによって提供されました。 + + + + + + + + Syncメッセージの直後にExecuteメッセージが発行され、クエリキャッシュがヒットすると、Pgpool-IIがハングアップする不具合を修正しました。(Tatsuo Ishii) + + + + + + + + Watchdogのソースコードの不適切なJSONデータの処理を修正しました。(bug 596) (Tatsuo Ishii) + + + + パッチはGreg Nancarrow (Fujitsu Australia)によって提供されました。 + + + + + + + + SCRAM認証処理の不具合を修正しました。(bug 595) (Tatsuo Ishii) + + + + パッチはGreg Nancarrow (Fujitsu Australia)によって提供されました。 + + + + + + + + ネイティブレプリケーションモードで起こりうるデータの不整合を修正しました。(Tatsuo Ishii) + + + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] + + + + + + + + ホスト名が長い場合、バッファサイズの制限によってWatchdogのpingが失敗する問題を修正しました。(bug 516) (Bo Peng) + + + + + + + + Doc: 多数のドキュメント改善を行いました。(Tatsuo Ishii) + + + + + + + + 「last status change」のタイムスタンプが正しく表示されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.1.1 + + + リリース日 + 2020-02-20 + + + + + 変更点 + + + + + + ネイティブレプリケーションモードの場合に、クォーラム合意によるフェールオーバ機能を無効にしました。(Muhammad Usama) + + + + ネイティブレプリケーションモードで、Pgpool-II + はすべてのバックエンドノードでデータをレプリケーションする役割を果たしています。 + ノードがquarantine(隔離)状態になると、Pgpool-II + はそのノードへの書き込みを停止するので、データの不整合を引き起こす可能性があります。 + + + + そのため、レプリケーションモードの場合に、バックエンドノードがquarantine(隔離)状態にならないように、 + 機能を無効にしました。 + + + + + + + 起動時のbind()エラーを回避するために、ソケットファイルが存在するかどうかを確認し、 + PIDファイルが存在しない場合、それらのソケットファイルを削除するように修正しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + レプリケーションモードの場合に、クエリのタイムスタンプがリライトされない不具合を修正しました。 + (bug 551) (Bo Peng) + + + + + + + + Doc: ドキュメントの更新、タイポの修正を行いました。(Takuma Hoshiai, Tatsuo Ishii, Bo Peng) + + + + + + + + pgpool-recovery関数の定義ファイルを更新します。(Tatsuo Ishii) + + + + + + + + が空の場合、リロード後に発生する子プロセスのセグメンテーション違反を修正しました。 + (bug 571) (Bo Peng) + + + + + + + + スタンバイサーバが存在しない場合、不要なエラーメッセージを出力させないように修正しました。(Tatsuo Ishii) + + + + + + + + PostgreSQL 12に対応するように修正しました。(Tatsuo Ishii) + + + + + + + Doc: follow_master_command サンプルスクリプトの%Mと%Hパラメータの順序を変更しました。(Bo Peng) + + + + + + + + 時々起こるリグレッションテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + 4.1 で正常に動作しない NotificationResponse メッセージの扱いを修正しました。 + (bug 573) (Tatsuo Ishii) + + + + + + + primary_conninfoのapplication_nameが空の場合に発生するレプリケーション遅延チェックワーカープロセスのセグメンテーション違反を修正しました。 + (bug 565) (Tatsuo Ishii) + + + + + + + = 'ALWAYS_MASTER'の場合に、コマンドの出力に ALWAYS_MASTERが表示されない不具合を修正しました。(Takuma Hoshiai) + + + + + + + syslogが出力されない不具合を修正しました。(Bo Peng) + + + + + + + + + リリース 4.1.0 + + + リリース日 + 2019-10-31 + + + + + 概要 + + + このバージョンでは、待望の機能を実装しています。 + また、パフォーマンスに関連する分野も強化しています。 + PostgreSQL12の新しいSQLパーサを取り込んでいます。 + + + + Pgpool-II4.1の主な改善点は以下のとおりです。 + + + + + + + + + ステートメントレベルの負荷分散に対応しました。 + 以前のPgpool-IIは、セッションレベルの負荷分散のみ可能でした。 + このバージョンでは、statement level load balancingを使用でき、フロントエンドがPgpool-IIに常時接続しているが、存在するスタンバイサーバのリソースを使用したい場合に便利です。 + + + + + + + 自動フェイルバックは、フェイルバックするために十分な安全を考慮しストリーミングレプリケーションのスタンバイサーバを自動的にアタッチできます。 + + + + + + + 多くの領域でのパフォーマンス向上が向上しました。 + + + + + 共有リレーションキャッシュは、セッション間でリレーションキャッシュを再利用でき、PostgreSQLシステムカタログに対する内部的なクエリを減らすことができます。 + + + + + + 不必要なパース処理を取り除くためにDML文用にSQLパーサを持ちます。 + + + + + + 特定クエリの負荷分散を制御します。 + + + + + + + + + + PostgreSQL12のSQLパーサを取り込みました。 + + + + + + + + バージョン4.1への移行 + + + バージョン4.1には、以前のバージョンとの互換性に影響するいくつかの変更点が含まれています。 + 以下の非互換性に注意してください。 + + + + + + + + および同様のコマンドにreplication_statereplication_sync_state列を追加しました。(Tatsuo Ishii) + + + + PostgreSQL 9.1 で利用可能なpg_stat_replication (replication_state_syncも使用します。しかし、9.2以降でのみ利用可能です。)から重要な情報を表示できます。 + この目的のために各バックエンドホストの設定パラメータに新しいパラメータが追加しました。 + pg_stat_replicationはストリーミングレプリケーションの遅延チェックプロセスから呼び出されます。 + そのため、が0の場合、これらの新しい列は利用できません。 + + + + および関数も変更されています。 + + + + + + + 多数決ルールを設定するパラメータを追加しました。 (Muhammad Usama, Tatsuo Ishii) + + + これは、偶数(すなわち、2, 4, 6...) watchdogクラスタにおけるクォーラムの存在および多数決の決定における振る舞いを変更します。 + 奇数のクラスタ(3, 5, 7...)は影響を受けません。 + このパラメータがオフ(デフォルトです)の場合、2ノードのwatchdogクラスタは、クォーラムを持つためには2ノードの両方が生存している必要があります。 + クォーラムが存在しないと、1) VIPが失われます 2) フェイルオーバスクリプトが実行されません 3) watchdogのマスターが存在しなくなります。 + 特に#2は、既存のPostgreSQLがダウンしても新しいプライマリが存在しなくなるので、困ったことになるでしょう。 + おそらく2ノードのwatchdogクラスタユーザはi、このパラメータをオンにして、今までと同様に振る舞まうようにしたいでしょう。 + 一方4ノード以上の偶数watchdogクラスタユーザはこのパラメータがオフであることにメリットがあります。 + なぜなら、半分のwatchdogノードがダウンしてsplit brainになる可能性を防ぐことができるからです。 + + + + + + + + RPMs からインストールする場合、デフォルトではpostgresユーザで + Pgpool-IIを起動するようになりました。(Bo Peng) + + + + セキュリティ上の理由で、Pgpool-IIのデフォルトの起動ユーザが + postgresユーザに変更されました。 + + + + RPMsからインストールする場合、postgresユーザがパスワードなしに + sudoを介してif_up/down_cmd及びarping_cmdを + 実行できるように設定されています。 + また、if_up/down_cmdarping_cmdに指定したコマンドが"/"で始まる場合、 + フルパスとみなしif_cmd_patharping_pathの設定を無視します。 + + + + + + + + sent messageモジュールのログをLOGからDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + + + + + + + + 主な改善点 + + + + + + + ステートメントレベルの負荷分散を使うことができます (Bo Peng) + + + + この機能ではステートメント単位の負荷分散ノードの選択を有効にします。 + 負荷分散の現在の機能では、負荷分散ノードはセッション開始時に決定され、セッションの終了まで変更されませんでした。 + = on に設定すると、負荷分散ノードは参照クエリごとに決定されます。 + 例えば、コネクションプーリングを使用するアプリケーションでは、セッションは長い時間保持される可能性があり負荷分散ノードはセッションの終了まで変更しないため、バックエンドサーバとのコネクションが開いたまま残ります。 + statement_level_load_balanceが有効の場合、セッション毎ではなくクエリ毎に負荷分散ノードを決定することができます。 + + + + + + + + を追加しました。(Takuma Hoshiai) + + + + 実際には正常に稼働しているがDOWN状態のバックエンドノードを自動で再アタッチできます。 + + + + この機能を使うためには、PostgreSQLが9.1以降、かつ新しい設定変数 auto_failbackが有効である必要があります。 + Pgpool-IIは、sr_checkとhealth_checkが有効なストリーミングレプリケーションモードで動作している必要もあります。 + Pgpool-IIは、問題のスタンバイノードが稼動しており、プライマリサーバからレプリケーションストリームを受け取れるか確認するためPostgreSQLプライマリサーバ上のpg_stat_replicationを呼び出します。 + + + + この機能は、一時的なネットワーク障害が原因でスタンバイサーバがフェイルオーバした場合に役立ちます。 + + + + + + + + 新しいを追加しました。(Takuma Hoshiai) + + + + リレーションキャッシュは、子プロセスのローカルキャッシュに蓄積されるため、すべての子プロセスはリレーションキャッシュを取得するために同じクエリを実行していました。 + がonの場合は、リレーションキャッシュがメモリキャッシュに蓄積され全ての子プロセスで共有します。 + 同じクエリが実行されることによる負荷の軽減が期待できます。 + + + + + + + + 一時テーブルを確認するための新しいパラメータを追加しました。(Tatsuo Ishii) + + + + 一時テーブルの確認はシステムカタログを参照する必要があるため遅いです。 + システムカタログの参照を除外するため、CREATE TEMP TABLE/DROP TABLEをトレースする新しい方式が追加されました。 + 新しい方式を使用するためには、traceに設定してください。 + + + + 関数やトリガ内で作られたテーブルをトレースすることができないことに注意してください。 + この場合、従来の方式を使用すべきです。 + + + + + + + + システムカタログに対する内部クエリを減らしました。(Tatsuo Ishii) + + + + 現在、リレーションキャッシュモジュールは、PostgreSQLから様々な情報を取得するために7つ以上のクエリを発行しています。 + これらのいくつかは、 Pgpool-IIPostgreSQLの複数のバージョンで動作するために必要となります。 + このような内部クエリを削減するためには、どんな種類のクエリが必要とされているかを知るためにPostgreSQLバージョンを取得します。 + 例えばpg_namespaceが存在するか知る必要がある場合、この目的のためにpg_classにクエリを送ります。 + しかし、pg_namespaceはPostgreSQL 7.3で導入されていることを知っていれば、pg_classを調べる必要はありません。 + + + + + + + + 大規模なINSERTとUPDATE文のパフォーマンスの強化。(Muhammad Usama) + + + + Pgpool-IIでは、特にINSERTとUPDATE文のクエリをどこに送る必要があるか決定するためにとても小さな情報だけを必要とします。 + 例えば、マスタースレーブモードでINSERT文の場合、Pgpool-IIは列の値と他のパラメータについては気にせずステートメント内で参照されるリレーション名だけを必要とします。 + しかし、Pgpool-IIで使うパーサーは、PostgreSQLのソースから取り込んだものなので、値のリストを含む完全なクエリを構文解析します。小さいステートメントでは無害と考えられますが、INSERTとUPDATEで多くの列値と値の中に巨大なデータがある場合、かなりの時間を消費します。 + + + + このアイデアは、必要な情報を確認したら直ちにINSERTやUPDATE文の構文解析を省くことです。 + この目的のため、マスタースレーブモード内で呼び出される二つ目の小さなパーサーを追加し、巨大なINSERTやUPDATE文に関するパフォーマンスを引き出そうとしています。 + + + + 二つ目のパーサの追加とは別に、パフォーマンスの強化に向けた変更も含まれています。 + 詳細は、commitを参照してください。 + + + + + + + + PostgreSQL 12 beta2の新しいパーサを取り込みました。(Bo Peng) + + + + PostgreSQL12のパーサの主な改善点は以下のとおりです。 + + + + + + 新しいVACUUMのオプション: SKIP_LOCKED、INDEX_CLEANUP、TRUNCATEの対応 + + + + + + COMMIT AND CHAINとROLLBACK AND CHAINコマンドの対応 + + + + + + WHERE句のCOPY FROMの対応 + + + + + + CREATE OR REPLACE AGGREGATEコマンドの対応 + + + + + + CREATE STATISTICSのMCV(most-common-value)対応 + + + + + + REINDEXのCONCURRENTLYオプションの対応 + + + + + + EXPLAINのSETTINGSオプションの対応 + + + + + + + + + + + リレーションキャッシュのクエリを負荷分散ノードに送ることができます。(Tatsuo Ishii) + + + + リレーションキャッシュ項目を作るためのクエリは、常にマスタ(プライマリ)ノードに送られていました。 + レプリケーションの遅延による悪い影響を取り除けるため、これは通常適しています。 + しかしながら、もしマスタノードの負荷を下げたい場合、マスタノード以外の他ノードにそのクエリを送ることができるので便利です。 + このパッチは、新しいパラメータを導入します。 + もしload_balance_nodeに設定した場合、リレーションキャッシュのクエリは負荷分散ノードに送られるでしょう。 + もしmasterに設定した場合、クエリは今迄と同様にマスタノードに送られます(これがデフォルトです)。 + + + + + + + + black function listで指定された、もしくはwhite function listで指定されていない関数を持つSELECT後の負荷分散を無効化します。(Bo Peng) + + + + Pgpool-II4.0以前では、 = transactionに設定することで明確なトランザクション内で更新を伴うクエリが発行されたとき、後続のクエリはレプリケーション遅延を避けるためにトランザクションが終了するまでプライマリのみに送られるべきです。 + しかしながら、で指定された、もしくはで指定されていない 更新を伴う関数は、white queryとは見なされず、後続の参照クエリはまだ負荷分散します。 + このcommitは、black function listで指定された、もしくはwhite function listで指定されていない関数を持つSELECT後の負荷分散を無効化します。 + + + + + + + + フロントエンドからの新しい接続を許可しないための新しい機能を実装しました。(Tatsuo Ishii) + + + + Pgpool-IIは、最大フロントエンドまでを許可し、子プロセスの1つが解放されるまで多くの接続要求をキューします。 + これはほとんどの場合うまく動作しますが、各セッションで長い時間が掛かるとキューが長くなり、システム全体が円滑に動作しなくなります。 + 問題は克服するため、フロントエンドからの多くの接続要求を処理する新しい方式を実装しました。 + を1以上に設定すると、クライアントからの現在の接続数が(num_init_children - reserved_connections)以上になった場合、ブロックするのではなくクライアントからの後続の接続は受理されずエラーメッセージ"Sorry, too many clients already"を返します。 + + + + + + + + 必要のないselect(2)システムコールを取り除くことによりパフォーマンスを向上しました。(Tatsuo Ishii, Jesper Pedersen) + + + + + + + + フロントエンドへメッセージを送信している間のパフォーマンスを向上しました。(Tatsuo Ishii) + + + + フロントエンドへメッセージを送信するSimpleForwardToFrontend()は、'D'もしくは'd'の場合のみバッファに書き込みます。 + その他のメッセージ種類は即座にソケットに書き込まれます。 + しかし、実際にはこれは必要ではありませんでした。 + そのため、致命的でないメッセージだけバッファに書き込むようにしました。 + これによって10~17%のパフォーマンス向上が見られます。 + + + + + + + + 必要のない警告もしくはエラーメッセージの解析を回避しました。(Tatsuo Ishii) + + + + バックエンドへクエリを送信後、Pgpool-IIはいつもper_node_error_log()によってpool_extract_error_message()を呼び出していました。 + エラーもしくは警告メッセージがバックエンドから返された場合も、関数内でメモリの割り当てが実行されていました。 + CPUサイクルの消費を避けるため、メッセージの種類を確認し、エラーもしくは警告メッセージでなければpool_extract_error_message()の呼び出しを避けます。 + + + + + + + + CopyDataメッセージ操作のパフォーマンスを向上しました + + + + COPY XX FROM STDINが実行されるとき(代表的なクライアントはpg_dump)、それぞれのコピー行データは、CopyDataメッセージを用いてPgpool-IIからフロントエンドに送られます。 + 以前は、一つのCopyDataメッセージに続いてフラッシュをしており、多大なコストがかかっていました。 + 代わりに、現在はコマンドの完了、警告メッセージもしくはエラーメッセージの後にフラッシュされます。 + 簡易テストでは、この変更により2.5倍速度が向上することが分かりました。 + + + + + + + + および内でMD5ハッシュパスワードが使用できます。(Tatsuo Ishii) + + + + + + + + SSLでのEDDHキー交換に対応しました。(Takuma Hoshiai) + + + + + + + + "pgpool show backend"グループにbackend_application_nameを追加しました。(Tatsuo Ishii) + + + + + + + + + + + PostgreSQL 12に対応しました。(Tatsuo Ishii) + + + + recovery.confは今後使用されません。 + スタンバイのリカバリ設定は現在postgresql.conf内となります。 + "standby.signal"ファイルもまた、スタンバイサーバとしてpostmasterを起動するためにPostgreSQLデータベースクラスタディレクトリ内で必要となります。 + + + + HeapTupleGetOid()はPostgreSQL12では今後使用できません。 + GETSTRUCT()を使用し、Form_pg_procのoid列を参照します。 + + + + pgpool_admエクステンションを変更します。 + 現在は、 oidが無くなったため、CreateTemplateTupleDesc()の定義が変更されました。 + + + + + + + + バックエンドが全てダウンしている際、フェイルオーバの速度が向上しました。(Tatsuo Ishii) + + + + すべてのバックエンドがダウン状態であっても、Pgpool-IIの期限までプライマリノードを探します。 + これは時間の浪費だけではなく、プライマリノードの検索中はフェイルオーバプロセスが一時中断され、Pgpool-IIの全ての子プロセスが機能していない状態になるため、Pgpool-IIはハングしているように見えます。従って、クライアントからの接続要求を受け入れるプロセスがありません。 + プライマリ検索のデフォルト値は300秒であるため、これは通常300秒間維持します。 + これはユーザにって快適ではありません。 + + + + この修正では、もしすべてのバックエンドがダウン状態であれば、に関係なくプライマリノードを探すことを即時に諦めフェイルオーバプロセスが即時に終了します + + + + + + + + プライマリバックエンドノードがquarantine状態になるのであれば、マスタwatchdogノードを辞退します。(Muhammad Usama) + + + + こうすることで、プライマリPostgreSQLサーバが存在しない状況を避けることができます。 + この実装のためには、隔離されたプライマリノードのフェイルオーバに関する合意の取得に失敗する場合、マスタ/コーディネータのwatchdogノードはその状態からFAILOVER_COMMAND_FINISH_TIMEOUT(15)秒以内に辞退します。 + + + + 隔離されたプライマリノードのためにwatchdogのマスタが辞退する場合、wd_priorityが-1に減少するため、マスタ/コーディネータノード選択のための次の選挙で最も低い優先度となるはずです。 + そして一度選挙で完了されると、ノードのwd_priorityは元の設定値に戻ります。 + + + + スタンバイノードのフェイルオーバの合意に失敗した場合、何もしません。 + + + + + + + 多数決ルールの計算方法を設定するパラメータを追加しました。(Muhammad Usama, Tatsuo Ishii) + + + Pgpool-IIはwatchdogクラスタが偶数のノードで構成されている場合、ちょうど50%の賛成を得られたときにクォーラムの存在とフェイルオーバの合意を決定します。 + パラメータにより、ユーザはPgpool-IIに対して、偶数ノードのクラスタにおける分散合意が(n/2)なのか、((n/2) +1)なのかを設定できます。 + 奇数ノードのクラスタ(3, 5, 7...)は、影響を受けません。 + 2ノードのクラスタでは特別な注意が必要です。 + 詳細はをご覧ください。 + + + + + + + + に絶対パスを指定できるようになりました。(Bo Peng) + + + + パッチはDanylo Hlynskyiにより提供されました。 + + + + + + + + フェイルオーバ、オンライリカバリで実行される各種サンプルスクリプトを追加しました。(Bo Peng) + + + + failover.sh.sample、follow_master.sh.sample、recovery_1st_stage.sample、recovery_2nd_stage.sample、 + pgpool_remote_start.sampleのサンプルスクリプトを配布別に含めるようにします。 + + + + + + + + ドキュメントを強化しました。 + + + + + パフォーマンスの章()を追加しました。(Tatsuo Ishii) + + + + + + + "チュートリアル"の"さあ始めましょう"と"Watchdog"、および"サーバ管理"のいくつかの節を強化しました。(takuma hoshiai) + + + + + + + 設定の例の"Pgpool-II + Watchdogの構築の例"を更新しました。(bo peng) + + + + + + + white/black_function_listでスキーマ修飾が使用出来ないことを記述しました。(tatsuo Ishii) + + + + + + + について説明を強化しました。(tatsuo Ishii) + + + + + + + detach_false_primary設定パラメータの注釈を追加しました。(tatsuo ishii) + + + + + + + follow_master_commandに説明を追加しました。(tatsuo ishii) + + + + + + + watchdog/pgpool-IIの例を強化しpg_monitorロールについて記述しました。(tatsuo ishii) + + + + + + + マルチステートメントクエリがプライマリノードにのみ送られることを記述しました。(tatsuo ishii) + + + + + + + 負荷分散の説明を追加しました。(tatsuo ishii) + + + + + + + pcpのリファレンスページにpcp.confの作成方法に役立つリンクを追加しました。(tatsuo ishii) + + + + + + + pcp_node_infoのマニュアルの説明を追加しました。(tatsuo ishii) + + + + + + + pg_md5のマニュアルページにpool_passwd文字列の表現の仕方の説明を追加しました。(tatsuo ishii) + + + + + + + クライアント認証のドキュメントを強化しました。(tatsuo ishii) + + + + + + + クォーラムによるフェイルオーバに関するドキュメントを強化しました。(tatsuo ishii) + + + + + + + + rawモードもしくはload_balance_mode = offの場合のリレーションキャッシュについて記述しました。(tatsuo ishii) + + + + + + + フェイルオーバについての一般的な説明を追加しました。(tatsuo ishii) + + + + + + + + + + + + + バグ修正 + + + + + このリリースではPgpool-II 4.0.7 と同様のバグ修正が既に適用されています。 + 修正の詳細はを参照してください。 + + + + + diff --git a/doc.ja/src/sgml/release-4.2.sgml b/doc.ja/src/sgml/release-4.2.sgml new file mode 100644 index 000000000..c60138355 --- /dev/null +++ b/doc.ja/src/sgml/release-4.2.sgml @@ -0,0 +1,6365 @@ + + + + + リリース 4.2.24 + + リリース日 + 2025-11-25 + + + + 変更点 + + + + + 不要なapplication_nameの処理を削除しました。(Tatsuo Ishii) + + + 以前のコミットで、既存接続を再利用する際にapplication_nameを設定する処理が追加されました。 + しかしこれは不要です。DISCARD ALLにより接続再利用時に自動的にapplication_nameがリセットされ、 + send_params()によってフロントエンドに必要なパラメータステータス(application_nameを含む)が送信されます。 + この冗長な処理を削除することで、特に地理的に離れたバックエンドノードでのパフォーマンスが向上します。 + + + ディスカッション: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + 不具合修正 + + + + + CopyOutでのセグメンテーションフォルトを修正しました。(Tatsuo Ishii) + + + 拡張プロトコルでCOPY relname TO STDOUTが実行された場合、Pgpool-IIがセグフォルトを起こしていました。 + + + この問題はhttps://github.com/teteshによって報告されました。 + + + ディスカッション: datanymizer and pg-pool segmentation fault + + + + + + Watchdogのスプリットブレイン回避するよう修正しました。(Tatsuo Ishii) + + + Watchdogはビーコンメッセージとハートビートで通信します。 + ハートビートが有効でない場合、ビーコンが30秒以上届かないとスプリットブレインが発生することがあります。 + 古いリーダーを無効化することで、同時に二人のリーダーが存在しないように修正しました。 + ノードがリーダーからのビーコンを2回以上見逃すと、リーダーはLOST状態となり、 + set_state(WD_JOINING) により新リーダー選出が開始されます。 + + + + + + + 存在しないプリペアドステートメント使用時のFATALエラー防止するよう修正しました。(Tatsuo Ishii) + + + 以前は Bind()が存在しないプリペアドステートメントでFATALエラーを出していました。 + はステートメントの存在を確認し、存在しない場合はフロントエンドにERRORメッセージを送信するようになりました。ログは残りません。 + + + + + + + -pと -P両方使用時に動作しない問題を修正しました。(Tatsuo Ishii) + + + 元の報告では、pg_enc -p -P実行時にパスワードと暗号キーを求められましたが、 + キーが提供されない場合に失敗していました。 + また、コメント /* prompt for postgres password */ が誤解を招くため、 + /* prompt for password to be encrypted */ に修正されました。 + + + ディスカッション: pg_enc + + + + + + + 32ビット環境でのコンパイルの問題を修正しました。(Tatsuo Ishii) + + + 32ビットシステムでsrc/parser/snprintf.cをコンパイルすると isnan()isinf()が未定義でエラーになりました。 + math.hをインクルードし、ヘッダーファイルの順序も整理しました。 + 元々 PostgreSQLから取り込まれたファイルで、math.hは既に含まれていました。 + 修正は fix compiling issues for 32-bit targets のプルリクエストに記載してあります。 + + + + + + + recovery_1st_stage.sampleでBashのディレクトリ削除を安全に行うよう修正しました。(Taiki Koshino) + + + rmコマンドの変数をクォートし、意図しない削除を防止しました: + rm -rf "${DEST_NODE_PGDATA}" + + + + + + + 指定なしでコンパイルする際のエラーを修正しました。(Tatsuo Ishii) + + + 指定なしでコンパイルするとエラーが発生していました。 + 対応として該当コードブロックを #ifdef USE_MEMCACHEDで囲みました。 + + + この問題はBo Pengによって報告されました。 + + + + + + + ドキュメント修正 + + + + + 8.2. Pgpool-II + Watchdog Setup Example の "PostgreSQLスタンバイ設定" ドキュメントを更新しました。(Taiki Koshino) + + + オンラインリカバリなしでスタンバイを設定する場合、postgresql.auto.confにprimary_conninfoを書き込まないよう注意を追加しました。 + + + ディスカッション: Follow primary command not fixing postgresql.auto.conf + + + + + + + watchdog_setupのマニュアルを修正しました。(Tatsuo Ishii) + + + heartbeartがwatchdog_setupに設定されていないと誤記されていた箇所を修正しました。 + + + + + + + 回帰テスト修正 + + + + + 023.ssl_connectionをPostgreSQL 18に対応するよう修正しました。(Tatsuo Ishii) + + + PostgreSQL 18でpsqlの \conninfo出力形式が大幅に変更されたため、 + このテストが失敗していました。 + PostgreSQLバージョンに応じてテストスクリプトを修正しました。 + + + + + + + 010.rewrite_timestampのRubyスクリプトを修正しました。(Tatsuo Ishii) + + + RubyのFile.existsは新しいバージョンで非推奨のため、File.existに置き換えました。 + + + + + + + 034と075のタイムアウトを調整しました。(Tatsuo Ishii) + + + 034.promote_nodeと075.detach_primary_left_down_nodeのスクリプト終了タイムアウトを60秒から120秒に変更し、 + 誤エラーが発生する可能性を減らしました。 + + + + + + + 023.ssl_connectionにssl_ecdh_curveのテストを追加しました。(Tatsuo Ishii) + + + 023.ssl_connectionはssl_ecdh_curveのテストをカバーしていなかったため、 + 不正なssl_ecdh_curveパラメータでフロントエンドとpgpoolの接続が失敗するか確認しました。 + + + + + + + + リリース 4.2.23 + + リリース日 + 2025-08-21 + + + + 不具合修正 + + + + + watchdog が不適切な NOTICE メッセージを出力する問題を修正しました。 (Tatsuo Ishii) + + + read_ipc_socket_and_process() は、IPCソケットへのコマンド書き込みのたびに、書き込みが成功した場合でも通知メッセージを出力していました。これを修正し、書き込みが失敗した場合にのみ通知メッセージを出力するようにしました。 + log_min_messagesが notice 以上に設定されている場合にのみメッセージが表示されるため、このバグが発見されていませんでした。 + + + ディスカッション: pgpool IPC socket connection issue + + + + + + + + スタートアップパケットを読んでいるときのメモリーリークを修正しました。(Tatsuo Ishii) + + + pool_push_pending_data でのリソースリークを修正しました。 + + + + + + + ビッグエンディアンマシン上の scram-sha-256 認証の不具合を修正しました。(Tatsuo Ishii) + + + scram-sha-256 認証を実行する際、ハッシュ関数 pg_sha_256_final が使用されます。 + これは PostgreSQL からインポートされたもので、プリプロセッサ定義 WORDS_BIGENDIAN を使用してホストマシンのエンディアンを判断します。 + WORDS_BIGENDIAN は configure 時に定義する必要がありますが、pg_sha_256_final(およびその他)が PostgreSQL からインポートされた際にこの部分が省略されていました。 + その結果、scram-sha-256 はリトルエンディアンマシンでのみ動作していました。 + configure.ac に AC_C_BIGENDIAN マクロを追加することでこの問題を修正しました。。 + + + この問題は Christoph Berg によって報告され、 pranavkaruvally によって分析されました。 + + + ディスカッション: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + ソースコードのタイプミスを修正しました。 (Bo Peng) + + + + + + + ハートビートデバイスの処理を修正しました。(Tatsuo Ishii) + + + pgpool.conf の処理中に、heartbeat_deviceが誤って処理され、最初のデバイスが無視されていました。 + + + この問題は Bo Peng によって分析されました。 + + + + + + + ドキュメント修正 + + + + + リロードによって反映されないパラメータのドキュメントを修正しました。 (Taiki Koshino) + + + authentication_timeoutmemqcache_oiddirはリロードしても反映されません。 + ドキュメントが「このパラメータはサーバー起動時にのみ設定できます。」に変更されました。 + + + + + + + + watchdog リーダーの用語を統一しました。(Tatsuo Ishii) + + + 以前は「leader」「active」「coordinater」という用語が、watchdog のリーダーノードを指すために使用されていました。このコミットではこれらを「leader」に統一しました。 + advanced.sgml も修正しました。 + + + + + + + + サンプルスクリプトを修正しました。(Taiki Koshino) + + + 「8.2. Pgpool-II + Watchdogの構築の例」のサンプルスクリプトを修正しました。 + + + + + + + ロードバランスの説明で論理レプリケーションモードと Slony モードが抜けている問題を修正しました(Tatsuo Ishii) + + + + + + + カーネルの資源に関するセクションを追加しました。 (Tatsuo Ishii) + + + Pgpool-II は System V の共有メモリとセマフォを使用します。 + 要件についてはドキュメントを参照することをお勧めします。 + + + + + + + configure の オプションの説明を追加しました。(Tatsuo Ishii) + + + これは LDAPサポートがv4.2で導入されたときに見落としていました。 + + + + + + + Pgpool-II でサポートされているプラットフォームを明確にしました。 (Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Tatsuo Ishii) + + + + + + + 回帰テスト修正 + + + + + 029.cert_passphrase 回帰テストを安定化しました。 (Tatsuo Ishii) + + + ssl_passphrase_commandが有効でない場合、エラーメッセージは通常「bad decrypt」ですが、「wrong tag」となる場合もありました。 + + + + + + + + リリース 4.2.22 + + リリース日 + 2025-05-15 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + Pgpool-IIのクライアント認証メカニズムには認証バイパスの脆弱性があります。 + 本来であれば認証が必要な場合でも、認証処理がスキップされてしまう可能性があります。 + この脆弱性を悪用することで、攻撃者が任意のユーザとしてログインし、データベース内の情報を参照・改ざんしたり、データベースを停止させたりすることができる可能性があります。(CVE-2025-46801) + + + なお、本脆弱性の影響を受けるのは、下記のパターン1から3いずれかの条件を満たす場合に限られます。 + + + + + パターン 1:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + pool_hba.confpassword認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードが設定されていない + + + + + pg_hba.confscram-sha-256またはmd5認証方式を使用している + + + + + + + + パターン 2:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + enable_pool_hba = off + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + + パターン 3:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + rawモードを使用している (backend_clustering_mode = 'raw') + + + + + pool_hba.confmd5認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードがテキストまたはAES形式で登録されている + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + この脆弱性の影響を受けるのは、Pgpool-II 4.0系および4.1系のすべてのバージョン、4.2.0-4.2.21、4.3.0-4.3.14、4.4.0-4.4.11、4.5.0-4.5.6、4.6.0です。 + Pgpool-II 4.6.1、4.5.7、4.4.12、4.3.15、4.2.22以降へのアップグレードを強くお勧めします。 + それができない場合は、発生条件パターンに当てはまらない設定の組み合わせに変更してください。 + + + + + 変更点 + + + + + 設定ファイルにメジャーバージョンを追加しました。 (Bo Peng) + + + + + + + 不具合修正 + + + + + クライアント認証が正しく実行されない場合があるのを修正しました。(Tatsuo Ishii) + + + enable_pool_hbaがonで、auth methodが"password"、pool_passwdにパスワードが登録されておらず、pg_hba.confの認証方式が"scram-sha-256"か"md5"の場合、クライアントが最初にpgpoolに接続したときには認証が期待通りに実行されます。 + しかし、クライアントがキャッシュされたコネクションに接続すると、任意のパスワードが通ってしまいます。 + + + また、enable_pool_hba = offのいくつかのケースでは、本来パスワードが聞かれるはずが、最初からパスワードが聞かれない、あるいはキャッシュされたコネクションに接続した時にはパスワードが聞かれないことがありました。 + + + 上記を修正するのに加え、以下の変更を行いました。 + + + + + 認証コードを単純化するために、PostgreSQLが1台の時のコードパスを削除しました。 + + + + + crypt認証のサポートをフロントエンドとバックエンドから削除しました。 + この機能はドキュメントに書かれておらず、テストもされていませんでした。 + また、crypt認証はPostgreSQLではだいぶ以前(8.4, 2009)に削除されています。 + + + + + 新しい回帰テストの"040.client_auth"を追加しました。 + このテストは、CSV形式のテスト設定ファイルを使って、包括的なクライアント認証のテストを実施します。 + + + + + + + + クエリキャッシュにおける、古くからあるバインド時のバグを修正しました。(Tatsuo Ishii) + + + 名前付きステートメントを準備すると、バインド後にパースメッセージなしで実行することが可能です。 + 問題は、実行時またはCOMMIT時にクエリキャッシュを無効化するために必要なテーブルOIDが、パースメッセージ処理(Parse())でのみ収集されていたことです。 + そのため、前回の実行後にパースなしでバインドを実行すると、テーブルOIDが収集されず、pgpoolはクエリキャッシュの無効化に失敗していました。 + バインド時にもテーブルOIDを収集するよう修正しました。 + 006.memqcacheに回帰テストを追加しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + クエリキャッシュの無効化に失敗する問題を修正しました。 (Tatsuo Ishii) + + + 実行メッセージを受信すると、pgpoolは最大行数パラメータをチェックします。この値が0でない場合、pgpoolはpool_handle_query_cache()にクエリキャッシュを作成しないよう指示するために、"partial_fetch"フラグを設定します。 + 問題は、コミット2a99aa5d1が、INSERT/UPDATE/DELETEであっても実行メッセージパラメータが0以外(ほとんどの場合1)に設定され、pgpoolがSELECT以外の場合でもこのフラグを設定することを見落としていることです。 + この結果、このフラグがtrueの場合、pool_handle_query_cache()内の後続のコードでキャッシュの無効化がスキップされるため、クエリキャッシュの無効化に失敗していました。 + フラグを設定する前にクエリが読み取り専用のSELECTであるかどうかを確認するようにExecute()を修正しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + OpenBSDへ移植する際の問題を修正しました。 (Tatsuo Ishii) + + + ディスカッション: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + このパッチはMartijn van Durenによって作成されました。 + + + + + + json_writerが特殊文字を正確にエンコードできない問題を修正しました。(Bo Peng) + + + が特殊文字を含んでいる状態でwatchdogを起動するとPgpool-IIがクラッシュしていました。 + + + このパッチはMartijn van Durenによって作成され、Bo Pengによって微修正されました。 + + + + + + リロード時にを開くようにストリーミングレプリケーションチェックとヘルスチェックプロセスを修正しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションチェックとヘルスチェックはリロード前にを開いていませんでした。 + もしが空文字列の時は、からパスワードを得ます。 + そのためこれらのプロセスはリロード時にの古いコンテンツを読み取ります。 + + + + + + ドキュメント修正 + + + + + の説明を改善しました。(Tatsuo Ishii) + + + が計算されるタイミングは、接続キャッシュを保持しているプロセスからクライアントが切断されたときであることを追記しました。 + + + ディスカッション: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + についての説明を改善しました。 (Tatsuo Ishii) + + + スーパーユーザーかpg_monitorグループであるべきです。 + + + + + + + + リリース 4.2.21 + + リリース日 + 2025-02-28 + + + + 変更点 + + + + + サンプルフォロープライマリスクリプトからpg_basebackupの処理を削除しました。(Bo Peng) + + + pg_rewindが失敗した場合、ユーザーにとって最も安全な方法は手動で復旧することです。 + + + + + + + 不具合修正 + + + + + per_node_error_log()のエラーメッセージでコロンが重複して出力される不具合を修正しました。(Bo Peng) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + pool_signalの不具合を修正しました。(Tatsuo Ishii) + + + 以前は、pool_signalSA_RESTARTフラグを設定していませんでした。 + そのため、シグナルによって中断されたシステムコールは再起動されません。 + 一部のコードは、システムコールがシグナルによって中断された場合に再起動するように準備されています。 + しかし、すべての箇所で対応できているかは不明なため、フラグを追加しました。 + なお、PostgreSQLでは常にこのフラグが使用されています。 + + + + + + + パラメータにデフォルト値以外のファイルが指定されている場合に、pg_md5pg_encがパスワードファイルを更新しない問題を修正しました。(Bo Peng) + + + この問題はSadhuprasad Patroによって報告されました。 + + + + + + + ストリーミングレプリケーションモードにおけるクエリキャッシュのいくつかの不具合を修正しました。(Tatsuo Ishii) + + + + + クエリキャッシュが有効で、フロントエンドから実行メッセージが送信された場合、クエリキャッシュデータが使用可能であれば、Pgpool-IIはそのデータをバックエンドメッセージバッファに挿入します。 + しかし、キャッシュされたメッセージが不適切な位置に挿入されることで、Pgpool-IIが誤って「kind mismatch」エラーを発生させることがありました。 + + + + + また、クエリキャッシュが有効で、クエリが拡張クエリモードで実行されている場合に、Pgpool-II がストリーミングレプリケーションモードで動作していると、実行メッセージが誤った結果を返す可能性がありました。 + + + + + さらに、複数の実行メッセージが連続して送信された場合、Pgpool-IIは各実行メッセージに対してクエリキャッシュから同じ結果を返していましたが、これは誤りです。 + 本来、2回目以降の実行では0行が返されるべきでした。 + + + ディスカッション: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + ドキュメント修正 + + + + + クライアント認証の章を強化しました。(Tatsuo Ishii) + + + pool_passwdに関する説明部分を追加しました。 + これまで、概要ページにはpool_hba.confの説明のみが記載されていましたが、今回pool_passwdの一般的なガイドを追加しました。 + これにより、ユーザーがこの章をより理解しやすくなりました。 + + + + + + + 回帰テスト修正 + + + + + 032.dml_adaptive_loadbalanceテストの安定性を向上させました。(Tatsuo Ishii) + + + + + + + + リリース 4.2.20 + + リリース日 + 2024-11-28 + + + + 不具合修正 + + + + + + バックエンドがエラーメッセージを送信した場合に、SSLネゴシエーションを中止するよう修正しました。(Tatsuo Ishii) + + + SSLネゴシエーションのクライアント側実装(pool_ssl_negotiate_clientserver())では、 + 中間者攻撃者がSSLネゴシエーションフェーズ中に長いエラーメッセージを送信することで、 + Pgpool-IIやクライアントを混乱させる可能性がありました。 + このコミットでは、ネゴシエーションを直ちに拒否(FATALエラーを発行)し、 + そのような攻撃を防ぐためにセッションを終了するよう修正しました。 + + + これは、PostgreSQLのCVE-2024-10977に似ています。 + + + + + + + リロード処理がWatchdogプロセスに反映されない問題を修正しました。(Bo Peng) + + + Pgpool-IIの + reload_config()関数は、 + WatchdogププロセスにSIGHUPシグナルを送信する必要がありました。 + + + + + + + do_query関数の不具合を修正しました。(Tatsuo Ishii) + + + htons/htonlの代わりにntohs/ntohlを使用するようにdo_queryを修正しました。 + + + + + + + pool_passwdを更新してリロードした後の認証失敗問題を修正しました。(Tatsuo Ishii) + + + pool_hba.confが無効になっている場合、Pgpool-IIのリロードが実行されても、Pgpool-IIの子プロセスはpool_passwdの更新を認識しませんでした。 + リロード処理関数check_config_reload()は、が有効な場合にのみpool_passwdを再オープンする必要があると誤って判断していたことが原因でした。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html + + + + + + + COPYがハングする問題を修正しました。(#79) (Tatsuo Ishii) + + + COPY IN状態(つまり、COPY FROM STDIN)中、フロントエンドはFlushまたはSyncメッセージを送信できます。 + F/Bプロトコル仕様によると、これらは無視されるはずですが、Pgpool-IIは無効なメッセージとして処理し、これがCOPYのハングの原因でした。 + + + リグレッションテストも追加しました。 + + + + + + + シャットダウン中にPgpool-IIの子プロセスがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + 実際のクラッシュはclose_all_backend_connections()内で発生していました。 + この関数は、on_system_exitchild_will_go_down()を登録するために呼び出されます。 + この時点では、Pgpool-II子プロセスが起動し、pool_init_cp()を実行した直後であるようです。 + 接続プールオブジェクトが完全に初期化されていなかったため、クラッシュが発生していました。 + + + この問題はEmond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + 認証失敗による散発的なヘルスチェックの失敗を修正しました。(Tatsuo Ishii) + + + が空文字列の場合、ヘルスチェックプロセスはpool_passwdファイルからパスワードを検索します。 + 問題は、このファイルのファイルディスクリプタが親pgpoolプロセスから継承されている点です。 + pgpoolメインプロセスとヘルスチェックプロセス(複数存在する可能性あり)が同じディスクリプタを共有するため、さまざまな問題が発生していました。 + この問題を解決するために、ヘルスチェックプロセスが開始される際にファイルを再度開き、 + それぞれのヘルスチェックプロセスが独自のファイルディスクリプタを持つようにしました。 + + + なお、pgpoolの子プロセス(フロントエンドセッションを担当)はすでにファイルディスクリプタを再度開く処理を行っており、これが今回の問題には関連していません。 + + + この問題は、Emond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + ALTER ROLEのクエリキャッシュ無効化を最適化しました。(Tatsuo Ishii) + + + コミット6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89は、ALTER ROLE/USERステートメントが使用される際にクエリキャッシュを無効にしています。 + しかし、実際にはこれが過剰です。 + 次のクエリはロールの権限に影響を与えないため、クエリキャッシュを無効にする必要はありません。 + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + したがって、これらのコマンドが使用される場合には、クエリキャッシュを無効にしないようにしました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Pgpool-IIの子プロセスが終了したときにPgpool-IIがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスが終了すると、close_all_backend_connections()が呼び出され、接続プール内のすべてのバックエンド接続が閉じられます。 + しかし、誤ってMAIN_CONNECTIONマクロが使用されていました。 + このマクロは現在アクティブな接続には適していますが、接続プールが作成された時点でのメインノードが異なる可能性があるため、プールされた接続には適していませでした。 + この問題を修正するために、代わりにin_use_backend()を使用するよう変更しました。 + + + Emond Papegaaijによって報告されました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードのバグを修正しました。(#69) (Tatsuo Ishii) + + + INSERTコマンドを受信すると、Pgpool-IIはターゲットテーブルに対して自動的にテーブルLOCKコマンドを発行しますが、メインノード以外のノードにコマンドを送信し忘れていました。 + この問題は拡張クエリモードの場合にのみ発生していました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードの別のバグを修正しました。(Tatsuo Ishii) + + + insert_lock()は、メインノード以外のノードに行ロックコマンド(lock_kind == 3 の場合)を送信するのを忘れていました。 + + + + + + + pool_memqcache.cのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はコミット6fdba5c33によって導入されました。 + + + + + + + + ドキュメント修正 + + + + + ドキュメントとサンプル設定ファイルのタイポを修正しました。(Bo Peng) + + + + + + + 回帰テスト修正 + + + + + テスト024.cert_authをOpenSSL 3.2に対応するよう修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.2.19 + + リリース日 + 2024-09-09 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + クエリキャッシュ機能()が有効な時に、データベースユーザがクエリキャッシュ経由で本来読み出せない行を読むことが可能でした。(CVE-2024-45624) + + + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22より古く、クエリキャッシュ機能を持つすべてのバージョン(クエリキャッシュ機能は3.2で実装されました)がこの脆弱性の影響を受けます。 + + + + + + あるユーザのクエリキャッシュがテーブルに対して作成されていると、そのテーブルへのアクセス権がREVOKEコマンドで剥奪されても、アクセス権を持たないそのユーザがクエリキャッシュを通じてテーブルにアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュがテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、アクセス権を持たないBがクエリキャッシュを通じてアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュが行セキュリティが有効なテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、本来Bが見えない行をクエリキャッシュを通じて取り出すことが可能でした。 + + + + + Pgpool-II 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22以降へのアップグレードを強くお勧めします。 + それができない場合は、クエリキャッシュ機能を無効にしてください。 + + + なお、この脆弱性を修正するために、いくつかのコマンド(ALTER DATABASE, ALTER ROLE, ALTER TABLE, REVOKE)を実行すると、クエリキャッシュのすべてのデータを削除するようになりました。 + これにより、クエリキャッシュの性能に影響があるかも知れません。 + + + + + 変更点 + + + + + をバックポートしました。 (Tatsuo Ishii) + + + これは主にテストのためです。v4.1までバックポートしました。 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + 不具合修正 + + + + + + レプリケーションモードとスナップショットアイソレーションモードで発生する複数の不具合を修正しました。(Tatsuo Ishii) + + + 次の不具合を修正しました。 + + + + + レプリケーションモードおよびスナップショットアイソレーションモードでコマンドを実行すると、Pgpool-IIはクエリ準備完了メッセージを待ちますが、一部のコマンド(SET ROLEなど)がパラメータステータスメッセージを生成することを忘れていました。 + その結果、Pgpool-IIはクエリ準備完了メッセージの前に他のメッセージが到着したことをエラーとして出力していました。 + + + + + + 前のクエリがパラメータステータスメッセージを生成した場合、後続のparse()はそれを読み取って処理する必要があります。 + これは、パラメータステータスメッセージの後に続くはずのクエリ準備完了メッセージを読み取る必要があるためです。 + + + ただし、ParameterStatus()が呼び出されると、クエリ進行中フラグが設定され、このparse()呼び出しで処理されるクエリが負荷分散されている場合、バックエンドからのパラメータステータスメッセージの1つだけが処理される可能性がありました。 + パラメータステータスメッセージはSETコマンドによって生成され、SETコマンドはレプリケーションモードおよびスナップショットアイソレーションモードのすべての生きているバックエンドに送信されるため、すべての生きているバックエンドから送信される可能性がありました。 + そのため、ParameterStatus()を呼び出す前に、クエリ進行中フラグを設定解除するように修正しました。 + + + + + + + + + + + リリース 4.2.18 + + リリース日 + 2024-08-15 + + + + 変更点 + + + + + + サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 (Bo Peng) + + + postgresqlxx-serverがインストールされていない可能性があるため、サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 + + + + + + + + 不具合修正 + + + + + + フラッシュメッセージを受信した後にハングする問題を修正しました。 (#59) (Tatsuo Ishii) + + + + + + + セグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Pgpool-IIの子プロセスがpool_do_authでセグメント違反になることがありました。 + 原因はMAIN_CONNECTION()がNULLを返すことでした。 + my_main_node_idが不正なノードID 0に設定されていたようですが、これは実際にはダウン状態でした。 + そのため、cp->slots[0]には接続がありませんでした。 + + + この問題はEmond Papegaaijによって報告されました。 + Discussion: [pgpool-general: 9175] + + + + + + + MAIN_NODEマクロを使用しないようにセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 一部の関数 (close_idle_connection()、new_connection()、pool_create_cp())では、MAIN*とVALID_BACKENDが不適切な場所で使用されていました。 + MAIN*とVALID_BACKENDは、バックエンドへの現在の接続に対してのみ有効であり、プールされた接続には有効ではありません。 + プールされた接続では、どのバックエンドがメインノードであるか、または稼働中であるかは、バックエンドへの現在の接続と必ず同じであるためです。 + これらのマクロを誤って使用すると、セグメンテーション違反が発生することがありました。 + + + この問題はEmond Papegaaij によって報告されました。 + Discussion: [pgpool-general: 9114] + + + + + + + MAIN_NODEマクロ(実際は pool_virtual_main_db_node_id())を修正しました。 (Tatsuo Ishii) + + + セッションコンテキストがない場合、マクロはREAL_MAIN_NODE_IDに使用されます。 + フェイルオーバー/フェイルバックが発生すると、いつでもREAL_MAIN_NODE_IDが変更される可能性があるため、これは誤りでした。 + + + REAL_MAIN_NODE_ID == my_main_node_id == 1と仮定します。 + その後、フェイルバックにより、REAL_MAIN_NODE_IDは0に変更されます。 + その後、MAIN_CONNECTION(cp)はNULLを返し、これへの参照はセグメンテーションエラーを引き起こします。 + この問題を回避するには、代わりにmy_main_node_idを返すように修正しました。 + + + + + + + show pool_processesで行の説明が2回表示されないように修正しました。(Tatsuo Ishii) + + + processes_reporting()が誤ってsend_row_description()とsend_row_description_and_data_rows()の両方を呼び出していました。 + + + Discussion: [pgpool-hackers: 4471] + + + + + + + 子プロセスでのセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + ネットワークが短時間中断されると、Watchdogが停止し、Pgpool-IIが強制終了する問題を修正しました。 (#823) (Muhammad Usama) + + + ネットワーク監視を有効にすると、Pgpool-IIノードはすべてのネットワークインターフェイスまたは割り当てられたIPアドレスを失った場合に直ちにシャットダウンし、通信できないノードをクラスタからすばやく削除することで追加の保護を提供します。 + + + 問題は、ネットワーク監視が無効になっている場合でも、Pgpool-IIがネットワークブラックアウトイベントに応答していたことです。 + この修正により、ネットワーク監視が有効になっていない場合にネットワーク監視ソケットがオープンされなくなり、不要なシャットダウンが防止されます。 + + + + + + + Watchdogが有効な場合にpgpool resetコマンドが動作しない問題を修正しました。 (Tatsuo Ishii) + + + バグはkeiseoによって報告・問題分析されました。 + Disscussion: [pgpool-hackers: 4465] + + + + + + + psql_scanのクラッシュを修正しました。 (#54) (Tatsuo Ishii) + + + 長いクエリ内の文字列がpsql変数(つまり「:」で始まる)であるかどうかを判別しているときに、psql_scanがクラッシュする問題がありました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントとプログラムソースコードの大量なタイポミスを修正しました。(Tatsuo Ishii) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + 仮想IP関連パラメータのデフォルト値をドキュメントに追加しました。(Bo Peng) + + + + + + + + + リリース 4.2.17 + + リリース日 + 2024-05-16 + + + + 不具合修正 + + + + + -Werror=implicit-function-declarationオプションで発生するコンパイルエラーを修正しました。(Bo Peng) + + + 非推奨のldap関数のプロトタイプを含めるためにLDAP_DEPRECATEDを追加しました。 + また、autoconfチェックで不足していたヘッダーファイルを追加しました。 + + + パッチはVladimir Petkoによって作成されました。 + + + + + + + セグメンテーション違反のさまざまな原因を修正しました。(Tatsuo Ishii) + + + フェイルオーバーが関与している特定のケースでは、Pgpool-IIとその子プロセスのセグメント違反が発生していました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + 初期化されていないメモリエラーを修正しました。(Tatsuo Ishii) + + + read_startup_packetの初期化されていないメモリエラーを含むいくつかのエラーがvalgrindによって報告されました。 + valgrindは、キャンセルまたはSSL要求の場合にpallocを使用してスタートアップパケット内のユーザー名にメモリを割り当て、その後、そのメモリがpstrdupによって使用されます。 + pallocによって割り当てられたメモリは未定義であったため、これをpalloc0に修正しました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + load_balance_modeがオフの場合に発生するエラー/ハングアップを修正しました。(Tatsuo Ishii) + + + load_balance_modeがオフで、プライマリノードIDが0でない場合には、BEGINなどクエリでエラー/ハングアップが発生していました。 + コミット 3f3c1656の修正によって導入された問題です。 + + + バグはEmond Papegaaijによって発見・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + 特定のCFLAGSによるコンパイルエラーを修正しました。(Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42によって報告されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + サンプルpgpool.conf内のコメントを修正しました。(Bo Peng) + + + sr_check_periodのデフォルト値は10秒であるため、修正しました。コメント内のいくつかのタイポも修正しました。 + + + パッチはhiroinによって作成され、Bo Pengによって修正されました。 + + + + + + + 拡張クエリが終了していない場合でもリセットクエリを実行できるようにしました。(Tatsuo Ishii) + + + コミット240c668dが原因で、拡張クエリメッセージが終了していない場合、リセットクエリが失敗していました。 + このコミットでは、SimpleQuery()でリセットクエリを実行しているかどうかをチェックすることで、この問題を修正しました。 + また、テストケースも追加しました。 + + + + + + + 不適切なプロトコルデータから保護するように修正しました。(Tatsuo Ishii) + + + 拡張クエリメッセージのシーケンスが終了する前にシンプルクエリメッセージが到着すると、Pgpool-IIがハングする可能性がありました。 + これは、シンプルクエリのセッションコンテキスト内のクエリコンテキストが、拡張クエリメッセージのクエリコンテキストによって上書きされたためです。 + + + このコミットでは、拡張クエリプロトコルメッセージが終了したかどうかをチェックするように実装しました。 + 終了していない場合は、FATALエラーを発生させます。このチェックによって検出された既知の例は、JDBCドライバーの「autosave=always」オプションです。 + つまり、このコミットの後、問題(拡張クエリメッセージプロトコルが終了する前にシンプルプロトコルメッセージを送信する)がJDBCドライバー側で修正されるまで、 + Pgpool-IIはこのオプションを受け入れません。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + ドキュメント修正 + + + + + + 「上位サーバへの接続」ドキュメントを改善します。(Bo Peng) + + + + + + + 日本語ドキュメントの言語クリーンアップしました。(Masaya Kawamoto) + + + + + + + + 回帰テスト修正 + + + + + + Java 21での非推奨警告を回避するために回帰テスト005.jdbcを修正しました。(Bo Peng) + + + Java 21での非推奨警告を回避するには、Runtime.exec(String)をRuntime.exec(String[])に置き換えました。 + + + パッチはVladimir Petkoによって作成され、Bo Pengによって修正されました。 + + + + + + + + + リリース 4.2.16 + + リリース日 + 2024-02-29 + + + + 変更点 + + + + + サンプルスクリプトからrestore_commandの設定を削除しました。 (Bo Peng) + + + レプリケーションスロットが有効になっているため、restore_commandは不要です。 + この設定により、フェールオーバーが失敗するケースがあるからです。 + + + + + + + 不具合修正 + + + + + のデフォルト値を修正しました。 (Bo Peng) + + + recovery_userデフォルト値はと同じである必要があるため、 + デフォルト値を''から'nobody'に変更しました。 + + + + + + + BEGINなどでのの不具合を修正しました。 (Tatsuo Ishii) + + + statement_level_load_balanceが有効な場合、 + が無効であっても、 + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE ALL/DISCARDがプライマリノードとすべてのスタンバイノードに送信されていました。 + これは明らかに間違っているだけでなく、スタンバイノードの1つがリモートネットワークにある場合、速度が低下する原因となります。 + + + load_balance_modeがオフの場合、 + Pgpool-IIはそのようなクエリをプライマリノードにのみ送信するように修正しました。 + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + ドキュメント修正 + + + + + 日本語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + Watchdog「リーダー」ではなく「マスター」を誤って使用していました。 + + + + + + + 英語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + PostgreSQL「プライマリ」ではなく「メイン」を誤って使用していました。 + + + + + + + + リリース 4.2.15 + + リリース日 + 2023-11-30 + + + + 変更点 + + + + + 大文字のホスト名をサポートするようにサンプルスクリプトのレプリケーションスロット名の変換処理を変更しました。(Bo Peng) + + + フェイルオーバやオンラインリカバリの時に実行されるスクリプトで、自動的にレプリケーションスロットを削除/作成しています。 + レプリケーションスロット名には大文字を使用できないため、ホスト名を小文字に変換するようにこれらのスクリプトを修正しました。 + + + パッチはSheikh Wasiu Al Hasibによって作成され、Bo Pengによって修正されました。 + + + + + + + パラメータ用のサンプルスクリプトescalation.sh.sampleでSSH接続時のタイムアウト時間を指定するようにしました。(Bo Peng) + + + + + + + 不具合修正 + + + + + 不要なログ行を削除しました。(Tatsuo Ishii) + + + デバッグメッセージ「unset_tx_started_by_multi_statement_query is called in CommandComplete」が誤って残っていました。 + + + + + + + DECLAREによって作成されたポータルでアボートしないようにDescribe()を修正しました。(Tatsuo Ishii) + + + DECLARE foo CURSOR FORを実行すると、PostgreSQLによって「foo」という名前のポータルが自動的に作成されます。 + このポータルはPgpool-IIによって管理されないため、Describe fooメッセージは「unable to execute Describe. unable to get the bind message」エラーで失敗していました。 + + + これを修正するため、Describe()でダミーの書き込みクエリコンテキストを作成し、Describeメッセージをプライマリ(ストリーミングレプリケーションモード)またはすべてのノード(レプリケーション/スナップショットアイソレーションモード)に送信するようにしました。 + + + 新たなテストケース080も追加しました。 + + + この問題はHeather Lapointeによって報告・分析されました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + NAMEDATALENの重複定義を削除しました。(Tatsuo Ishii) + + + src/include/pg_config_manual.hのみでNAMEDATALENを定義するようにしました。 + また、src/utils/pool_select_walker.c内のPOOL_NAMEDATALENNAMEDATALENに置き換えました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + ドキュメント修正 + + + + + PCPがすべてのアドレスをリッスンするにはpcp_listen_addresses = '*'の設定が必要である旨を「Pgpool-II + Watchdogの構築の例」に記載しました。 + + + + + + + のドキュメントの説明を強化しました。(Tatsuo Ishii) + + + を使用しない場合は、の実行が必要である旨を記載しました。 + + + + + + + 回帰テスト修正 + + + + + pgpool_setupを強化しました。(Tatsuo Ishii) + + + フェイルオーバスクリプトおよびフォロープライマリスクリプトでより適切なログを出力できるようにpgpool_setupを改善しました。 + + + + + + + + リリース 4.2.14 + + リリース日 + 2023-08-17 + + + + 変更点 + + + + + 共有メモリの初期化後にのみ、システム終了コールバックを呼び出すようにしました。(Muhammad Usama) + + + 共有メモリの取得に失敗して、終了時コールバックが呼び出された場合、クリーンアップ関数は、共有メモリに存在するprocess_infoにアクセスする際にセグメンテーション違反を引き起こす可能性がありました。 + process_infoがNULLのときに終了コールバックからの中断で修正することもできますが、共有メモリの初期化に成功した後に関数をインストールする方がより良いアプローチです。 + なぜなら、システムの残りの部分は常にprocess_infoがNULLになることはないと想定しており、また、子プロセスが生成される前にクリーンアップをする必要はないからです。 + + + + + + + 一部のシステムカタログ照会関数にスキーマ修飾を追加しました。(Tatsuo Ishii) + + + + + + + 不具合修正 + + + + + Coverityの警告を修正しました。(Tatsuo Ishii) + + + クエリキャッシュのモジュールで、time_tの値がint32変数に割り当てられる問題を修正しました。 + Coverityの指摘に従いまして、変数の型をint64に変更しました。 + また、time_tの差分を計算するためにdifftime()を使用しました。これは推奨される方法です。 + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + find_primary_node_repeatedlyが指定時間内で終了しない問題を修正しました。(Bo Peng) + + + + + + + v2プロトコルを利用する場合のクラッシュを修正しました。(bug 807)(Tatsuo Ishii) + + + read_kind_from_backend()で統計データを蓄積する際、v2プロトコルのケースには対応していませんでした。 + + + MCanivezからバグ報告とパッチを提供いただきました。 + + + + + + + マルチステートメントにおけるPREPAREの利用を修正しました。(Tatsuo Ishii) + + + マルチステートメントの二番目以降の位置にPREPAREが含まれている場合、その後のbindメッセージでプリペアドステートメントを利用すると、送信されたメッセージにプリペアドステートメントが保存されな +いため、「unable to bind」エラーが発生していました。 + + + この問題を修正するために、ステートメントを解析した後にそのようなケースが見つかった場合、名前付きステートメントのクエリコンテキストを作成し、送信メッセージのリストに追加するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + この修正のため、リグレッションテスト079..multi_prepareを追加しました。 + + + + + + + pgprotoをパラメータを使用するbindメッセージを処理できるようにしました。(Tatsuo Ishii) + + + 以前、pgprotoはパラメータを持たないbindメッセージしか処理できませんでした。 + + + + + + + サンプルスクリプトのログメッセージを修正しました。(Bo Peng) + + + + + + + ドキュメント修正 + + + + + loggerプロセスのアプリケーション名記載漏れを修正しました。(Bo Peng) + + + + + + + 停止モードの意味を明確にしました。(Tatsuo Ishii) + + + + + + + 4.2.10リリースノートにあった誤った情報を削除しました。(Bo Peng) + + + 「pgpool_recovery拡張のスクリプトを修正しました。 (Tatsuo Ishii)」の記載を削除しました。 + + + + + + + 「8.2. Pgpool-II + Watchdogの構築の例」のSSH公開鍵認証の説明を補足しました。(Bo Peng) + + + + + + + 負荷分散章の説明を修正しました。(Tatsuo Ishii) + + + 一部の文章で「ストリーミングレプリケーションモード」と記述されるべきの箇所が「ネイティブレプリケーションモード」となっていました。 + また、ストリーミングレプリケーションモードにおける負荷分散の追加要件に関する説明を改善しました。 + いくつかのインデックスを追加しました。 + + + + + + + オンラインリカバリーの説明を改善しました。(Bo Peng) + + + 複数のpgpoolノードでwatchdogが有効になっていない場合、オンラインリカバリーのセカンドステージが適切に機能しないことについて言及しました。 + + + + + + + 回帰テスト修正 + + + + + 時折発生する069.memory_leak_extendedテストの失敗を修正しました。(Tatsuo Ishii) + + + 偶発するテストの失敗の原因は、pgbenchが終了した後にpsコマンドを実行する前にpgpoolの子プロセスが消えてしまうことにあると判明しました。 + これにより、「DISCARD ALL cannot be executed within a pipeline」というkind mismatchのFATALエラーが発生していました。 + これを修正するために、pgbenchをバックグラウンドで実行し、pgbenchが終了する前にプロセスのサイズを取得するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + リリース 4.2.13 + + リリース日 + 2023-05-18 + + + + 変更点 + + + + + マルチステートメントのクエリを判定するために、psqlscanのソースコードをPgpool-IIにインポートしました。(Tatsuo Ishii) + + + psqlscanは、PostgreSQLソースツリー内のモジュールです。 + これは本質的にPostgreSQL SQLスキャナのサブセットですが、各SQLステートメントの終わりの検出に特化しています。 + したがって、これを使用してクエリ文字列内のSQLステートメントの数をカウントできます。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + 複数のステートメントを幅広く使用できるようにしました。 (Tatsuo Ishii) + + + このコミットは、複数のステートメント (マルチステートメント) に関するPgpool-IIの長年の制限を排除しました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + 内部クエリでスキーマ修飾を使用するように変更しました。(Tatsuo Ishii) + + + 関数やキャストなどの一部のオブジェクトは、「pg_catalog.」スキーマ修飾を使用していませんでした。 + これによって直ちにセキュリティ上の懸念が生じるわけではありませんが、スキーマ修飾を使用することは常に良い習慣ですので、変更しました。 + + + + + + + 不具合修正 + + + + + 共有リレーションキャッシュで発生しうるデッドロックを修正しました。(Tatsuo Ishii) + + + ユーザー定義関数がテーブルロックを取得する場合、拡張クエリプロトコルを使用して関数を呼び出すとデッドロックが発生する可能性がありました。 + 以下にシナリオを示します。 + + + + (1) セッション中クライアントはparse、bind、executeリクエストをpgpoolに送信します。 + + + + + + + (2) セッションAのPgpool-IIはリクエストをPostgreSQLに転送します。 + + + + + + + (3) セッションAのPostgreSQLがexecuteを実行し、テーブルロックが発生します。 + + + + + + + (4) セッションBで、クライアントは関数のparse、bind、executeリクエストをpgpoolに送信します。 + + + + + + + (5) セッションBのPgpoolはリクエストをPostgreSQLに転送します。 + + + + + + + (6) セッションBのPostgreSQLはbindを実行しますが、テーブルはセッションAのPostgreSQLによってすでにロックされており、ロックの解放を待ちます。 + + + + + + + (7) セッションBのpgpoolはexecuteをPostgreSQLに転送した後、関数の揮発性をチェックするために共有リレーションキャッシュを検索するためのセマフォを取得します。 + 次に、do_queryを呼び出し、フラッシュメッセージをPostgreSQLに送信して、この時点までのPostgreSQLからの応答を取得します。 + ただし、#6ではPostgreSQLがテーブルロックを待機しているため、pgpoolはバインド完了後のメッセージを待つ必要があります。 + + + + + + + (8) セッションAのpgpoolがPostgreSQLにexecuteを転送した後、関数の揮発性をチェックするために共有リレーションキャッシュを検索しセマフォを取得しようとしましたが、セマフォはセッションBのpgpoolによってすでに取得されているため、セマフォの解放を待ちます。 + + + + + + + (9) セッションAとセッションBがお互いを待機するため、デッドロックが発生します。 + + + + + + これを修正するには、do_query()を呼び出す前にセマフォを解放するようにpool_search_relcache()を変更しました(ただし、セマフォはdo_query()の後に取得します)。 + これにより、上記#8のセッションAはセマフォを取得し、先に進むことができます。 + クライアントからsyncメッセージを受信し、PostgreSQLに転送します。 + syncを受信すると、ユーザ定義関数は実行を終了し、テーブルロックを解放します。 + これにより、セッションBのPostgreSQLがテーブルロックを取得できるようになります。 + + + + + + + musl libcを使用するシステムでのコンパイルエラーを修正しました。(bug 790) (Tatsuo Ishii) + + + パッチはleimaohuiによって提供されました。 + + + + + + + 複数のクエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + 特殊なケースでsrワーカーが間違ったクエリをスタンバイサーバに送信する不具合を修正しました。(Tatsuo Ishii) + + + ALWAYS_PRIMARYフラグが設定されている場合、PRIMARY_NODE_IDマクロは、プライマリがダウンしている場合でも、-1ではなくノードIDを返していました。 + この場合、ストリーミングレプリケーション遅延をチェックするワーカープロセスは、PostgreSQLのバージョンに応じてSELECT pg_current_wal_lsn()またはSELECT pg_current_xlog_location()をスタンバイに送信し、当然エラーが発生していました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + DEALLOCATEによる種類不一致エラーを修正しました。 + (bug 780) (Tatsuo Ishii) + + + 以下の条件がすべて満たされた場合、種類不一致エラーが発生していました。 + + + + ストリーミングレプリケーションモード + + + + + + + ロードバランスノードがプライマリ以外のノード + + + + + + + PREPAREがマルチステートメントクエリで使用されている + + + + + + + + + + 回帰テストのコンパイルエラーを修正しました。(Takuma Hoshiai) + + + gcc10を使用したタイムスタンプテストでエラーが発生していました。 + + + + + + + show pool_versionで行の説明が2回表示される問題を修正しました。(Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + の説明を追加しました。(Chen Ningwei) + + + + + + + PREPARE/EXECUTE/DEALLOCATEに関する制限を追加しました。(Tatsuo Ishii) + + + + + + + Pgpool-IIで-Dオプションを使用する場合の注意点を追加しました。(Tatsuo Ishii) + + + + + + + 「RPMからのインストール」セクションを強化しました。(Bo Peng) + + + + + + + 「サーバの準備と運用」の章に「PostgreSQLデータベースのバックアップ」セクションを追加しました。(Tatsuo Ishii) + + + + + + + 「Pgpool-II + Watchdogの構築の例」から「-D」起動オプションの設定を削除しました。(Bo Peng) + + + + + + + 「制限事項」セクションを修正しました。(Tatsuo Ishii) + + + + + + SCRAM-SHA-256認証に関する記述を追加 + + + + + + + スナップショットアイソレーションモードに関する記述を追加 + + + + + + + + + + AES256をサポートするにはオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + .pcppassを使用するには、pcpコマンドの-wオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + を強化しました。(Tatsuo Ishii) + + + + + + + 回帰テスト修正 + + + + + 071.execute_and_deallocate/test.shをリファクタリングしました。(Tatsuo Ishii) + + + + + + + いくつかの回帰テストを強化しました。(Tatsuo Ishii) + + + + + + + 時折発生する005.jdbcテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.2.12 + + リリース日 + 2023-01-23 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + 以下の条件をすべて満たす場合、コマンドによりのパスワードが公開されます。このコマンドは、Pgpool-IIに接続できるすべてのユーザーが実行できます。(CVE-2023-22332) + + + + + + バージョン3.3以降 + + + + + + onに設定されている + + + + + + queryが設定されている + + + + + + にプレーンテキストのパスワードが設定されている + + + + + + 上記条件のすべてに該当するユーザは、このバージョンにアップグレードするか (show pool_statusコマンドでが表示されなくなる)、次の回避策のいずれかを使用することを強くお勧めします。 + + + + 4.0.x~4.4.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + には空文字を設定し、パスワードはpool_passwdファイルに設定する。 + + + + + + にAESで暗号化したパスワードを設定する。 + + + + + + いずれにせよ、PostgreSQLでを変更することをお勧めします。 + + + + 3.3.x~3.7.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + いずれにせよ、PostgreSQLを変更することをお勧めします。 + + + + Pgpool-II 3.7.xおよび以前のバージョンはサポートが終了しているため、これらのバージョンのマイナーアップデートはリリースされません。 + + + + + 変更点 + + + + + + およびコマンドでwd_lifecheck_passwordを表示しないように修正しました。(CVE-2023-22332) (Bo Peng) + + + + + + + ドキュメントに記載されているように、のデフォルト値を空の文字列に変更しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + pgpool-regclass.cのコンパイラ警告を修正しました。(Florian Weimer, Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + 共有メモリ使用時の設定の章のいくつかの誤りを修正し、説明を強化しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.2.11 + + リリース日 + 2022-12-22 + + + + 変更点 + + + + + + ログメッセージ"new IPC connection received"をDEBUG1にダウングレードしました。 + (bug 775) (Bo Peng) + + + これは通常のメッセージで、LOGとして記録されるべきではありません。 + パッチはpstefによって作成され、Bo Pengによってレビューされました。 + + + + + + + + 不具合修正 + + + + + + の問題を修正しました。(Muhammad Usama) + + + Watchdogクラスタ全体のヘルスチェックパラメータの最大値に基づいて、フェイルオーバコマンドのタイムアウトを動的に設定するように修正しました。 + + + Tatsuo Ishiiによってレビューおよびテストされました。 + 議論: [pgpool-hackers: 4227] + + + + + + + パーサ内でバックスラッシュを使った場合の警告を出力しないように修正しました。(Tatsuo Ishii) + + + standard_conforming_strings = offかつescape_string_warning = onの場合、PostgreSQLは文字列リテラル内でバックスラッシュを使った場合に警告を出力します。 + これは問題ありません。 + しかし、以前はPgpool-IIのパーサも同じメッセージを出力していました。 + これは冗長です。 + + + + + + + idle_session_timeoutに対応しました。(Tatsuo Ishii) + + + idle_session_timeout (PostgreSQL 14 で追加)が有効、かつ、タイムアウトが発生した場合、次のことが発生します: + + + + failover_on_backend_errorがon (デフォルト)の場合、Pgpool-IIはフェイルオーバを発生させます。 + + + + + + + PostgreSQL サーバが 1 台のみが idle_session_timeout を有効にしていると、Pgpool-II がハングする可能性があります。 + + + + + + idle_session_timeoutに対応するため、エラーコードを検出するdetect_idle_session_timeout_error()を追加しました。 + エラーを検出すると、Pgpool-II は致命的なエラーとしてフロントエンドにエラーコードを返し、セッションを切断します。 + これはidle_in_transaction_session_timeoutの実装と同じような修正です。 + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + 議論: [pgpool-hackers: 4208] + + + + + + + SSLエラーSSL_ERROR_ZERO_RETURNに対応しました。(Tatsuo Ishii) + + + 以前はこれによってフェイルオーバが発生しましたが、サーバは単に接続を閉じることを意味するため、実際には不要でした。 + + + 議論: [pgpool-general: 8366] + 議論: [pgpool-hackers: 4193] + + + + + + + メモリキャッシュサイズを2GBより多く設定した場合に発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + 問題は与えられたキャッシュブロックのメモリアドレスを返す block_address()関数にあり、 + 2GB上限まで有効な共有メモリ空間内のブロックのオフセットを計算するために32bit整数を使っていました。 + + + + + + + pcp_proc_infoSHOW pool_poolsおよびSHOW pool_processes内のまれなセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + セグメンテーション違反はget_pools()とget_processes()にありました。 + それらは、最初に共有メモリ上の特定のプロセス情報スロットのpidを抽出し、次にキーとして pid を使ってスロットを再び検索していました。 + これらのステップはロックによって保護されていなかったため、プロセス終了時に新しい子プロセスのフォークを担う親プロセスによって pid が上書きされた場合、 + pid を使った検索が失敗し、NULLを返す可能性がありました。 + その結果、それに続くNULLポインタの参照によってセグメンテーション違反が発生していました。 + + + 解決策は、最初にプロセス情報スロットへのポインタを取得し、次にポインタからpidメンバを抽出することです。 + この方法でも、親プロセスによる共有メモリ情報の同時更新は可能ですが(出力におかしな結果をもたらす可能性があります)、少なくともセグメンテーション違反は回避できます。 + + + + + + + 無効な長さのUnixドメインソケットパスを使えないように修正しました。(Masaya Kawamoto) + + + + + + + + ドキュメント修正 + + + + + + Doc: Aurora設定例内のタイポを修正しました。(Tatsuo Ishii) + + + + + + + Doc: memqcache_methodの説明を拡充しました。(Tatsuo Ishii) + + + どの方式を使うべきかの説明を追加しました。 + + + + + + + Doc: ヘルスチェックプロセスでSSLが使えることに言及しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションのチェックでもSSLが使えることに言及しました。 + これは2010年以降に使えていたはずです。 + + + 議論: [pgpool-hackers: 4187] + + + + + + + + 回帰テスト修正 + + + + + + 環境変数を使ってPGPOOLDIRを定義できるようにしました。 + (bug 766) (Bo Peng) + + + + + + + + + リリース 4.2.10 + + リリース日 + 2022-08-18 + + + + 変更点 + + + + + + サンプルスクリプトで指定するrestore_commandにsshオプションを追加しました。(Bo Peng) + + + パッチはJon SCHEWEによって作成され、Bo Pengによって更新されました。 + + + + + + + サンプルスクリプトを更新しました。(Bo Peng) + + + + レプリケーションスロットを作成/削除するときの接続データベース名をpostgresにしました。 + + + + + + + sshログインユーザとssh鍵ファイルを変数で指定するようになりました。 + + + + + + + + + + CloseCompleteを受け取った時、バッファリングなしでフロントエンドに転送するようになりました。(Tatsuo Ishii) + + + 074.bug700_memqcache_segfaultで時折タイムアウトエラーが発生していました。 + + + + + + + 不具合修正 + + + + + + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + + Pgpool-IIは"Select '2022-02-18 07:00:00.006547'::timestamp"のような問合せをキャッシュしていませんでした。 + TIMESTAMP、TIME、DATEを含むSELECT文はキャッシュされるようになりますが、TIMESTAMPZ、TIMEZを含むSELECT文は"SET TIME ZONE"コマンドなどで結果が変更されるためキャッシュされません。 + また、TIMESTAMPZやTIMEZ型を返す関数を含むSELECT文も同様の理由でキャッシュされません。 + Discussion: [pgpool-general: 8285] + + + + + + + + スナップショットアイソレーションモードで、internal transactionの取り回しにおける不具合を修正しました。(Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + Doc: 特定のSELECT文がキャッシュされないことに言及しました。(Tatsuo Ishii) + + + 特定のSELECT文は以下です。 + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を使っているSELECT + + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEへのキャストを含むSELECT + + + + + SQLValueFunction (CURRENT_TIME, CURRENT_USERなど)を含むSELECT + + + + + + + + + + Doc: Unixドメインソケット接続するときのPCPパスワードファイルの使用についての説明を修正しました。(Masaya Kawamoto) + + + pcppassファイルのlocalhostエントリはデフォルトのPCPソケットディレクトリパスへの接続とのみマッチして、全てのUnixソケット接続には使用されません。 + この振る舞いはpgpassファイルと同じです。 + + + + + + + Doc: 必要メモリの説明を修正し、詳細にしました。(Tatsuo Ishii) + + + + + + + pgpoolの子プロセスが動作する間のメモリ使用についての説明を追加しました。 + + + + + + より正確な結果を計算できるように、必要共有メモリを計算する式を詳細にしました。 + + + + + + インメモリクエリキャッシュ用の共有メモリ量を修正しました。64MBは誤った値でした。 + + + + + + 必要プロセスメモリを修正しました。以前の式はRSSを基にしていましたが、RSSはライブラリに使用されるメモリなどの共有メモリも含むため、PSSを使用するべきです。 + これによって以前より要求メモリが大幅に減少します。 + + + + + + + + + + Doc: の誤った説明を修正しました。(Tatsuo Ishii) + + + これらのパラメータは設定ファイルの再読み込みでは変更できず、Pgpool-IIの再起動が必要です。 + + Discussion: [pgpool-general: 8195] + + + + + + + + テストツール修正 + + + + + + PostgreSQL 15でpgpool_setupを実行できるようになりました。(Tatsuo Ishii) + + + ticket 757を参照ください。 + + + + + + + pgpool_setupはRPMに含まれるサンプルスクリプトとサンプルの設定ファイルをテストできるようになりました。(Bo Peng) + + + + + + + + 回帰テスト修正 + + + + + + Test: 回帰テストでPgpool-IIのバージョンを表示するようになりました。(Tatsuo Ishii) + + + + + + + Test: 適切なinstall directoryでpgpool.confを探すように回帰テストスクリプトを修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.2.9 + + リリース日 + 2022-05-19 + + + + 変更点 + + + + + Pgpool-IIメインプロセスの停止を強化しました。(Tatsuo Ishii) + + + 「pgpool stop」が一定期間(現在5秒)以内にメインプロセスを終了できなかった場合は、信号を再送信するように修正しました。 + + + + + + + コマンドのPIDの長さを7文字に変更しました。(Bo Peng) + + + + + + + Parseメッセージ処理のエラーメッセージにメッセージの種類、バックエンドノードIDを含めるように改善しました。(Tatsuo Ishii) + + + + + + + ParameterStatusメッセージのログレベルをLOGからDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + のデフォルト値を「*」から「localhost」に変更しました。(Tatsuo Ishii) + + + + + + + のフィールド名を変更しました。(Muhammad Usama) + + + + + + + RPMパッケージでデフォルトでに関連するパラメータを有効にしました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + lost状態のリモートPgpool-IIノードが再起動後にクラスタに再参加できない問題を修正しました。(Muhammad Usama) + + + 報告: [pgpool-general: 7896] + + + + + + + 無限待機の可能性を回避するために、Pgpool-IIメインプロセスのexit_handlerを修正しました。(Tatsuo Ishii) + + + + + + + 共有メモリの割り当て関数の潜在的な不具合を修正しました。(Tatsuo Ishii) + + + + + + + 「-i」オプションを使用する場合のおよびの不具合を修正しました。(bug 747)(Tatsuo Ishii) + + + + + + + プライマリ検索中にバックエンドが失敗またはシャットダウンした場合にPgpool-IIのメインプロセスが終了してしまう問題を修正しました。(Tatsuo Ishii) + + + + + + + Watchdogで発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + pg_isreadyを使用してPostgreSQLのステータスを確認するようにfollow_primary.sh.sampleを修正しました。(Bo Peng) + + + + + + + + ドキュメント修正 + + + + + Doc: Kubernetesの設定例をgithubのリポジトリに移動しました。(Bo Peng) + + + + + + + Doc: 設定例を更新しました。(Masaya Kawamoto) + + + + + + + Doc: pcp_watchdog_infoの出力例を更新しました。(Bo Peng) + + + + + + + Doc: pg_encの引数として「$」文字を含むパスワードを指定する場合は、エスケープする必要があることを注意事項に追加しました。(Bo Peng) + + + + + + + + 回帰テスト修正 + + + + + タイムアウトエラーを回避するために、リグレッションテスト018.detach_primaryを強化しました。(Tatsuo Ishii) + + + + + + + タイムアウトエラーを回避するために、リグレッションテスト074.bug700_memqcache_segfaultを強化しました。(Tatsuo Ishii) + + + + + + + セグメンテーション違反を検出するようにテストスクリプトを改善しました。(Bo Peng) + + + + + + + + + リリース 4.2.8 + + リリース日 + 2022-02-17 + + + + 変更点 + + + + + + in_hot_standbyによるメッセージ長の違いに関する不要なログを抑制しました。。(Tatsuo Ishii) + + + PostgreSQL 14 は新しいパラメータを導入しました: in_hot_standby + + + この値はスタンバイサーバの場合は "on" で、プライマリサーバの場合は "off" になります。 + その結果 pgpool のログは以下のメッセージで溢れていました。 + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + これを防ぐために、パラメータ名がin_hot_standbyでない場合にのみログを出力するようになりました。 + + + また、メッセージにパラメータ名を表示するようになりました。例を示します。 + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + の形式の検査を追加しました。(Masaya Kawamoto) + + + wd_lifecheck_passwordrecovery_passwordはmd5ハッシュ形式を使用できませんが、pgpool は認証失敗を報告するだけでそれらのチェックをしていませんでした。 + + + + + + + パラメータステータスの取り扱いを変更しました。(Tatsuo Ishii) + + + バックエンドからパラメータステータスのメッセージが届いたときにただメモリー上に記憶するだけでなく、フロントエンドに転送するようになりました。 + + + + + + + + 不具合修正 + + + + + + pcp_node_infoの実行の際に長時間待機する不具合を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Coverityによって見つかったヘルスチェックプロセスの問題を修正しました。(Tatsuo Ishii) + + + + + + + Coverityによって見つかったメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + プライマリノードが存在しない場合の対処をするようにfailover()を修正しました。(Tatsuo Ishii) + + + プライマリノードが存在しない場合に pgpool が起動したときなどReq_info->primary_node_idが -1 である場合にfailover()find_primary_node_repeatedly()の呼び出しをスキップしていました。 + また、follow_master_commandも実行されませんでした。 + + + Discussion: [pgpool-hackers: 4113] + + + + + + + failover スクリプトのサンプルを修正しました。(Bo Peng) + + + old primary node id が"-1"の場合を考慮していませんでした。 + + + + + + + バックエンドに接続できないときにストリーミングレプリケーションチェックプロセスがリトライしないように修正しました。(bug 742)(Bo Peng) + + + このリトライによってフェイルオーバに時間がかかっていました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントの誤字を修正しました。(pengbo) + + + パッチはUmar Hayatによって提供されました。 + + + + + + + PostgreSQL YUM リポジトリからPgpool-IIがインストールされないように /etc/yum.repos.d/pgdg-redhat-all.repo を"exclude"する設定を追加しました。(Bo Peng) + + + + + + + ParameterStatusin_hot_standbyパラメータに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + set_configに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + + テストツール修正 + + + + + + pgpool_setupが作成するfailoverスクリプトを修正しました。(Tatsuo Ishii) + + + pgpool_setupfailover.shを作成するとき、プライマリサーバが存在しない場合を考慮していませんでした。 + + + + + + + + 回帰テスト修正 + + + + + + 再コンパイルしないで既存のインストールで回帰テストを実行できるようになりました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + テスト075を修正しました。(Tatsuo Ishii) + + + pgpool が起動していなくても成功していました。 + 報告とパッチはQiang Lingjieによって提供されました。 + Discussion: [pgpool-hackers: 4085] + + + + + + + noinstall モード時のpgpool_setupwatchdog_setupのバイナリパスを修正しました。(Bo Peng) + + + + + + + + + リリース 4.2.7 + + リリース日 + 2021-12-23 + + + + 変更点 + + + + + + yaccとの非互換性によって出力されるbisonの警告を抑制しました。(Tatsuo Ishii) + + + + + + + 冗長なコードを修正しました。(Tatsuo Ishii) + + + パッチはLu Chenyangによって提供されました。 + + + + + + + + ドキュメント修正 + + + + + + Doc: pcp_watchdog_infoマニュアルの誤字を修正しました。(Tatsuo Ishii) + + + + + + + Doc: 設定例の誤字を修正しました。(Bo Peng) + + + パッチはLu Chenyangによって提供されました。 + + + + + + + Doc: リリースノートの誤字を修正しました。(Bo Peng) + + + + + + + + + リリース 4.2.6 + + リリース日 + 2021-11-18 + + + + セキュリティリリース + + + + + SSL暗号化ハンドシェイク後の余計なデータを拒否するようにしました。(Tatsuo Ishii) + + + サーバサイドのSSLネゴシエーションの実装において、任意のSQLコマンドを実行できる中間者攻撃が可能でした。 + これはPgpool-IIがクライアント認証で証明書認証を使用しているか、hostssl + trust認証の場合に可能でした。 + PostgreSQLのCVE-2021-23214と似た脆弱性です。 + + + 同様に、クライアントサイドのSSLネゴシエーション実装において、任意の結果に改ざんする中間者攻撃が可能でした。 + これはPostgreSQLがクライアント認証でhostssl + trust認証を使用しているときに可能でした。 + 証明書認証の場合には、Pgpool-IIはPgpool-IIとPostgreSQL間で証明書認証を実装していないため問題ありません。 + PostgreSQLのCVE-2021-23222と似た脆弱性です。 + + + + + + + 変更点 + + + + + + pg_terminate_backend()の処理に関するPostgreSQL 14対応をしました。(Tatsuo Ishii) + + + + + + + Pgpool-IIメインプロセスのSIGCHLDハンドラを改良しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスがSIGKILLシグナルでkillされたとき、SIGCHLDハンドラは他のシグナルと同じようにLOGレベルメッセージを発していました。 + しかし、SIGKILLシグナルはOMM killerによるkillなど重要なイベントなので、WARNINGレベルのメッセージを発するようにしました。 + Michail Alexakisから提案されました。 + Discussion: [pgpool-general: 7750] + + + + + + + + 不具合修正 + + + + + + application_nameにloggerプロセスがなかったのを修正しました。(Tatsuo Ishii) + + + + + + + が0のときに起こるコネクションカウンタの不具合を修正しました。(Tatsuo Ishii) + + + reserved_connectionsが0のとき、コネクションカウンタを管理する必要はありませんでした。 + この修正によって不意のカウンタリークによる不必要な"Sorry, too many clients already"エラーを防ぐことができます。 + Discussion: [pgpool-general: 7750] + + + + + + + bug 732: フェイルオーバ中のセグメンテーション違反を修正しました。 (Muhammad Usama) + + + + + + + COPY FROM中のハングアップを修正しました。(Tatsuo Ishii) + + + COPY FROM中にエラーが発生したとき、Pgpool-IIはフロントエンドからCOPY終了マーカーが送信されたあと、バックエンドからの応答を永遠に待っている可能性がありました。 + Bo Pengによって発見されました。 + + + + + + + + ドキュメント修正 + + + + + + Doc: ドキュメントのtypoを修正しました。(Bo Peng) + + + + + + + ドキュメントとサンプルスクリプトのtypoを修正しました。(Bo Peng) + + + パッチはKazufumi Notoによって提供されました。 + + + + + + + Doc: 設定例のyum installコマンドのtypoを修正しました。(Bo Peng) + + + + + + + + 回帰テスト修正 + + + + + + たまに発生する073.pg_terminate_backendの失敗を修正しました。(Tatsuo Ishii) + + + + + + + テスト074の名前を変更しました。(Bo Peng) + + + + + + + テストの失敗を防ぐためにpg_configコマンドのパスを修正しました。(Bo Peng) + + + + + + + テストの失敗を防ぐためにpsqlコマンドのパスを修正しました。(Bo Peng) + + + + + + + + + リリース 4.2.5 + + リリース日 + 2021-09-14 + + + + 変更点 + + + + + PGPOOL SHOWコマンドのother_pgpoolオプションをwatchdogに変更しました。(Bo Peng) + + + 4.2からother_pgpoolパラメータが削除されたため、 + other_pgpoolオプションをwatchdogに変更すべきでした。 + + + + + + + 不具合修正 + + + + + Watchdogを利用する場合に、follow_primary_commandの実行に失敗する不具合を修正しました。 + (bug 731) (Muhammad Usama) + + + parse_wd_exec_cluster_command_json()関数のコーディングミスによるセグメンテーションが原因でした。 + この不具合は4.2.4で導入され、4.2.3以前のバージョンには影響しません。 + + + + + + + PGPOOL SHOW heartbeatおよびPGPOOL SHOW ALLコマンドの不具合を修正しました。(Bo Peng) + + + + + + + を0に設定できない不具合を修正しました。(Tatsuo Ishii) + + + ドキュメントによると、log_rotation_ageを0に設定することで、 + ログローテーション機能を無効にすることが可能です。 + ただし、許可される最小値が誤って10に設定されていたため、log_rotation_ageを0に設定できませんでした。 + + + + + + + rawモードでの誤った負荷分散ノードの表示を修正しました。(Bo Peng) + + + rawモードでは、Pgpool-IIはすべてのクエリをメインノードに送信します。 + この不具合は表示上の問題だけで、クエリの転送処理に影響はないですが、 + ユーザを混乱させる可能性があるので、修正しました。 + + + + + + + Pgpool-IIのloggerプロセスがCPUの100%を消費する問題を修正しました。(Tatsuo Ishii) + + + 問題の報告、パッチはFang Junより提供されました。 + Discussion: [pgpool-hackers: 3992] + + + + + + + SIモードにおいて、内部トランザクションがスナップショットを取得しない不具合を修正しました。(Tatsuo Ishii) + + + + + + + PGPOOL SHOW ALLの実行結果にbackend_flag*が2回表示される不具合を修正しました。(Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + Doc: PGPOOL SHOWコマンドを実行する際に、大文字を含むパラメータ名の場合には、 + パラメータ名をダブルクォートで囲んで実行する必要があることを追加しました。(Bo Peng) + + + + + + + テストツール修正 + + + + + 新しいメインノードが利用できない場合に何もしないようにpgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.2.4 + + リリース日 + 2021-08-05 + + + + 変更点 + + + + + + ドメイン名を含めたホスト名の長さの最大値を変更しました。(Tatsuo Ishii) + + + ホスト名の長さの最大値を128にしていましたが、正しくは254でした。 + Discussion: [pgpool-hackers: 3903] + + + + + + + + 不具合修正 + + + + + + クエリキャッシュでSQLValueFunctionsを含むクエリをキャッシュしないようにしました。(Tatsuo Ishii) + + + SQLValueFunctionsの一覧は以下になります。 + + + + CURRENT_DATE + + + + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + + + + + SESSION_USER + + + + + USER + + + + + CURRENT_CATALOG + + + + + CURRENT_SCHEMA + + + + + + + + + + watchdogからfollow_primaryコマンドをロックする機能を実装しました。(Muhammad Usama) + + + これは"detach_false_primaryとfollow_primary_commandの競合状態を修正しました。"の補足修正です。 + 以前の修正はほとんどのケースで正しかったのですが、いくつかのケースで失敗する可能性がありました。 + + + + + + + describeメッセージのあとにNoDataで応答された場合のクライアント側のハングアップを修正しました。(Tatsuo Ishii) + + + 問題の報告、パッチはDaniel van de Giessenより提供されました。 + Discussion: [pgpool-hackers: 3950] + + + + + + + pgpool.confサンプルの誤字が修正されました。(Tatsuo Ishii) + + + + + + + SIモードにおける不正なメッセージの送信を修正しました。(Tatsuo Ishii) + + + クエリがシリアル化エラーなどの特定の理由によってアボートしたとき、Pgpool-IIは + メインノード以外で実行されているトランザクションを中止するためにエラークエリを送信します。そのメッセージ長が + 正しくなかったためバックエンドで「invalid string in message」エラーが発生していました。 + + + + + + + Pgpool-IIが停止したときに孤児プロセスが残る不具合を修正しました。(Tatsuo Ishii) + + + follow_primary_commandの実行中にPgpool-IIが停止すると、 + follow_primary_commandによって開始されたいくつかのプロセスが残ったままになる可能性がありました。 + + + + + + + pcp_detach_nodeの実行後ダウンノードが残る不具合を修正しました。(Tatsuo Ishii) + + + プライマリノードをpcp_detach_nodeでデタッチしたとき、follow_primary_commandの + 実行後にもスタンバイノードがダウンのままになっていました。 + Discussion: [pgpool-hackers: 3915] + + + + + + + pgpool.confのリロードで変更できない + 不具合を修正しました。(Tatsuo Ishii) + + + + + + + watchdog通信の競合状態を修正しました。(Tatsuo Ishii) + + + メインプロセスがwatchdogプロセスから通知された処理を実行中に、watchdogプロセスが新しいメッセージを + メインプロセスに通知したとき、新しいメッセージが処理されるまでに大幅な遅延が発生していました。 + Discussion: [pgpool-hackers: 3900] + + + + + + + 再起動後にwatchdogノードステータスが更新されない問題を修正しました。 + (bug 684) (Muhammad Usama) + + + + + + + + ドキュメント修正 + + + + + + Doc: "Pgpool-II on Kubernetes"の設定例を更新しました。(Bo Peng) + + + + + + + Doc: の説明を増やしました。(Tatsuo Ishii) + + + + + + + Doc: いくつかのドキュメントのtypoを修正しました。(Bo Peng) + + + + + + + Doc: インメモリクエリキャッシュのtypoを修正しました。(Tatsuo Ishii) + + + + + + + Doc: ldap オプションのパラメータ名を修正しました。(Takuma Hoshiai) + + + + + + + Doc: の説明を修正しました。(Masaya Kawamoto) + + + + + + + + テストツール修正 + + + + + + ポータブルなfollow_primary.shを生成するようにpgpool_setup + を修正しました。(Tatsuo Ishii) + + + + + + + pgpool_setupで使用されるrsyncのパラメータを修正しました。(Tatsuo Ishii) + + + + + + + pgpool_setupで作成されるfollow_primary_commandのスクリプトを修正しました。(Tatsuo Ishii) + + + + + + + pgpool_setup中のベースバックアップ処理を修正しました。(Tatsuo Ishii) + + + + + + + watchdog_setupのスクリプトを修正しました。(Tatsuo Ishii) + + + watchdog_setupによって生成されるshutdownallスクリプトは、全体シャットダウンでは + 不必要なフェイルオーバ処理を引き起こしていました。 + + + + + + + + 回帰テスト修正 + + + + + + 075.detach_primary_left_down_nodeの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 031.connection_life_timeの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 018.detach_primaryの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 028.watchdog_enable_consensus_with_half_votesの不具合を修正しました。(Tatsuo Ishii) + + + + + + + 018.detach_primaryの不具合を修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 4.2.3 + + + リリース日 + 2021-05-20 + + + + + 不具合修正 + + + + + サンプルスクリプトの改善を行いました。 (Bo Peng) + + + + + + + リグレッションテスト018.detach_primaryの不具合を修正しました。 (Tatsuo Ishii) + + + + + + + の競合状態を修正しました。(Tatsuo Ishii) + + + が同時に実行されると、多くの問題が発生していました。 + 典型的な問題としては、プライマリノードが見つからないことです。 + + + + + + + Doc: の説明を修正しました。(Tatsuo Ishii) + + + heartbeat_deviceパラメータは、Pgpool-IIがrootで起動する場合にのみ使用できます。 + + + + + + + Doc: の説明を改善しました。(Tatsuo Ishii) + + + + + + + + + Doc: に関する誤った説明を削除しました。(Tatsuo Ishii) + + + + + + + + + database/app_name_redirect_preference_listがステートメントレベル負荷分散モードで正しく動作しない不具合を修正しました。 + (bug 707) (Bo Peng) + + + + + + + pgpool0の配下のみにデータベースクラスタを作成するようにを修正しました。(Tatsuo Ishii) + + + + + + + のデフォルト値を修正しました。(Tatsuo Ishii) + + + パッチはKAWAMOTO Masayaはによって作成されました。 + + + + + + + "pgproto"のアプリケーション名をpgprotoに設定しました。(Tatsuo Ishii) + + + + + + + クエリキャッシュが有効になっている場合のpgpoolのクラッシュを修正しました。 + (bug 700) (Tatsuo Ishii) + + + ストリーミングレプリケーションモードと論理レプリケーションモード以外でCloseCompleteを受信すると、Pgpool-IIがクラッシュしていました。 + + + + + + + follow_primary.shサンプルスクリプトを修正しました。 + (bug 694) (Bo Peng) + + + pg_rewindを実行した後に、スタンバイノードのpg_replslotディレクトリを空にするように修正しました。 + これは、古いPostgreSQLバージョンではpg_replslotディレクトリがプライマリノードからコピーされる可能性があるためです。 + + + + + + + クエリキャッシュがストリーミングレプリケーションモードと論理レプリケーションモード以外で作成されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + において、再起動に失敗した場合にフルリストアを実行するようにを修正しました。(Tatsuo Ishii) + + + + + + + asyncpgを利用した場合のハングアップを修正しました。(Tatsuo Ishii) + + + + + + + Startupパケットを受信したときのデバッグメッセージを改善しました。 (Tatsuo Ishii) + + + + + + + Doc: 多数ドキュメントの改善を行いました。 (Tatsuo Ishii, Bo Peng) + + + + + + + + + リリース 4.2.2 + + + リリース日 + 2021-02-18 + + + + + 不具合修正 + + + + + の誤ったweightの表示を修正しました。 (Tatsuo Ishii) + + + + + + + follow_primary.sh.samplepg_rewind実行後にrecovery.confが削除されないように修正しました。(Bo Peng) + + + + + + + Watchdogリーダーによる同期処理後に、ヘルスチェックプロセスが起動されない不具合を修正しました。(Tatsuo Ishii) + + + + + + + Doc: マニュアルに不足しているスナップショットアイソレーションモードの説明を修正しました。(Tatsuo Ishii) + + + + + + + watchdog_setupがスナップショットアイソレーションモードをサポートするように修正しました。(Tatsuo Ishii) + + + + + + + watchdog_setupの誤ったデータベースクラスタのパスを修正しました。(Tatsuo Ishii) + + + + + + + pgpool_setupによって作成されるfollow_primary.shの不具合を修正しました。 (Tatsuo Ishii) + + + + + + + pgpool_setupで使用されるshutdownallスクリプトを改善しました。(Tatsuo Ishii) + + + + + + + DBノードごとに個別のアーカイブディレクトリを作成するようにpgpool_setupを修正しました。(Tatsuo Ishii) + + + + + + + コマンドの結果に欠落しているの表示を修正しました。(Bo Peng) + + + + + + + ヘルスチェックプロセス起動時のメッセージを修正しました。(Tatsuo Ishii) + + + + + + + Doc: サンプルスクリプトはテーブルスペースをサポートしていないことをドキュメント「Pgpool-II + Watchdogの構築の例」に追加しました。(Bo Peng) + + + + + + + スナップショットアイソレーションモードで発生するセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + + + + + Doc: オンラインリカバリドキュメントで1st stageと2nd stageに関する説明を改善しました。(Tatsuo Ishii) + + + + + + + Doc: 共有リレーションキャッシュに必要な共有メモリについての説明を追加しました。(Tatsuo Ishii) + + + + + + + の許容範囲とデフォルト値を修正しました。 (Muhammad Usama) + + + + + + + 共有メモリの割り当て中のエラーを修正しました。(Tatsuo Ishii) + + + + + + + ERRORが発生した場合、が正しくカウントされない不具合を修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.2.1 + + + リリース日 + 2020-12-23 + + + + + 変更点 + + + + + すべてのpgpool.confサンプルファイルのソケットファイルのパスを/var/run/postgresqlに変更しました。(Bo Peng) + + + + + + + Pgpool-II親プロセスのすべての共有変数に単一の共有メモリセグメントを使用するように修正しました。(Muhammad Usama) + + + 共有メモリセグメントは限られたリソースであるため、多くのセグメントを開くことは避けるべきです。 + + + + + + Pgpool-II起動時に既存のwatchdogコマンドソケットファイルを削除するように修正しました。(Muhammad Usama) + + + パッチはMasaya Kawamotoによって提供されました。 + + + + + + + + + 不具合修正 + + + + + Doc: 欠落していたrawモードの説明を「5.3 クラスタリングモード」に追加しました。タイポを修正しました。(Bo Peng) + + + + + + + pcp_pool_statusおよびSHOW POOL_STATUSコマンドのハートビート関連パラメータの誤った結果を修正しました。(Bo Peng) + + + + + + + Doc: インストールのヒントのセクションでfirewall-cmdの使用法を修正しました。(Tatsuo Ishii) + + + この例では、firewall-cmdが不要なポートを開放しました。 + + + + + + + backend_flag0 = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER'またはfailover_command=''の場合に発生しうるセグメンテーション違反を修正しました。 + (bug 672) (Tatsuo Ishii) + + + + + + + およびwatchdogライフチェックメカニズムの一貫性のないpgpool node_idの問題を修正しました。(Muhammad Usama) + + + pgpoolノード0(リーダーwatchdog)がシャットダウンされると、すべてのpgpoolノードが異常終了する問題を修正しました。 + + + + + + + Watchdog機能が無効で、wd_portが定義されていない場合に発生するエラーを修正しました。(Tatsuo Ishii) + + + + + + + コンパイルエラーを修正しました。 + (bug 670) (Tatsuo Ishii) + + + パッチはajsによって提供されました。 + + + + + + + pool_passwdのファイルスワッピングの競合状態を修正しました。(Tatsuo Ishii) + + + パッチはMasaya Kawamotoによって提供されました。 + + + + + + + + + リリース 4.2.0 + + + リリース日 + 2020-11-26 + + + + + 概要 + + + このバージョンでは、設定と管理作業を容易にするために多くの改良が行われています。 + 更に複数PostgreSQLの間で更新の一貫性だけでなく、読み取り一貫性を保証する新しいクラスタリングモードが追加されました。 + また、SSLの機能が改善され、よりセキュアな運用ができるようになりました。 + さらに、PostgreSQL13の新しいSQLパーサを取り込んでいます。 + + + + + このバージョンでは、より適切な用語を使うために設定パラメータ名が変更されていることに注意してください。 + また、レポートでも用語が変更されています。詳細は、「移行」の章を見てください。 + + + + 主な改善項目は以下です。 + + + + + + 設定ファイルpgpool.confの項目が大幅に改善され、設定と管理が容易になりました。 + + + + + + が実装され、ログ管理が容易になりました。 + + + + + + が実装され、接続終了のログが取得できるようになりました。 + + + + + + コマンドとコマンドでパスワード登録をファイルから一括して行えるようになりました。 + + + + + + ヘルスチェックの統計情報をコマンドで、発行SQLの統計情報をコマンド取得できるようになりました。 + + + + + + 新しいPCPコマンドが追加されました。 + + + + + + システムカタログの情報を参照することにより、の記述を省略できるようになりました。 + + + + + + 複数PostgreSQLの間で更新の一貫性だけでなく、読み取り一貫性を保証する新しいクラスタリングモードが追加されました。 + + + + + + クライアントとPgpool-IIの間でLDAP認証がサポートされました。 + + + + + + SSLの設定にが追加されました。 + + + + + + PostgreSQL 13のSQLパーサを取り込みました。 + + + + + + + + + + バージョン4.2への移行 + + + + + + + master_slave_mode、master_slave_sub_mode、replication_modeは廃止され、になりました。 + 以下のように書き換えてください。 + + + + + + master_slave_mode = 'on'、master_slave_sub_mode = 'stream' → backend_clustering_mode = 'streaming_replication' + + + + + + master_slave_mode = 'on'、master_slave_sub_mode = 'logical' → backend_clustering_mode = 'logical_replication' + + + + + + master_slave_mode = 'on'、master_slave_sub_mode = 'slony' → backend_clustering_mode = 'slony' + + + + + + replication_mode = 'on' → backend_clustering_mode = 'native_replication' + + + + + + replication_mode = 'off'、master_slave_mode = 'off' → backend_clustering_mode = 'raw' + + + + + + + + + + + + 適切な用語に変更しました。(Umar Hayat) + + + + pgpool.confに以下の変更が行われました。 + + + + + black_function_list → write_function_list + + + + + + white_function_list → read_only_function_list + + + + + + black_query_pattern → primary_routing_query_pattern + + + + + + black_memcache_table_list → cache_unsafe_table_list + + + + + + white_memcache_table_list → cache_safe_table_list + + + + + + ALWAYS_MASTER flag → ALWAYS_PRIMARY flag + + + + + + follow_master_command → follow_primary_command + + + + + + + relcache_query_targetのオプション値'master'を'primary'に変更しました。 + + + + + + + + + レポートで使われている用語を変更しました。 + + + + + master → main + + + slave → replica + + + + + + + + スクリプトの引数で使われている用語を変更しました。 + + + + + master → main + + + + + + + + watchdogで使われている用語を変更しました。 + + + + + master → leader + + + + + + + + + + + 以下のwatchdogパラメータは使えなくなりました。 + + - wd_hostname + - wd_port + - wd_heartbeat_port + - heartbeat_device + - heartbeat_destination0 + - heartbeat_destination_port0 + - heartbeat_destination1 + - heartbeat_destination_port1 + - other_pgpool_hostname0 + - other_pgpool_port0 + - other_wd_port0 + - other_pgpool_hostname1 + - other_pgpool_port1 + - other_wd_port1 + + その代わりに以下のパラメータを使ってください。 + 詳細は、を参照してください。 + + hostname0 = 'server1' + wd_port0 = 9000 + pgpool_port0 = 9999 + + hostname1 = 'server2' + wd_port1 = 9000 + pgpool_port1 = 9999 + + hostname2 = 'server3' + wd_port2 = 9000 + pgpool_port2 = 9999 + + heartbeat_hostname0 = 'server1' + heartbeat_port0 = 9694 + heartbeat_device0 = '' + + heartbeat_hostname1 = 'server2' + heartbeat_port1 = 9694 + heartbeat_device1 = '' + + heartbeat_hostname2 = 'server3' + heartbeat_port2 = 9694 + heartbeat_device2 = '' + + 4.1までとは違って、watchdogのパラメータはすべてのホストで同じです。 + どのホストであるかを区別するために、pgpool_node_idというファイルを作り、その中に0, 1, 2などのホストの識別を表す数字を入れてください。 + + + + + + + の値は空となりました。 + + + + + + + + + バグ修正 + + + + + このリリースではPgpool-II 4.1.4 と同様のバグ修正が既に適用されています。 + 修正の詳細はを参照してください。 + + + + + + + + 主な改善点 + + + + + + ereportsからstrerror()呼び出しを削除しました。(Muhammad Usama) + + + ereport()を呼び出すと、errno値がリセットされ、「strerror(errno)」を使用すると、誤ったエラーメッセージが出力されます。 + 正しい方法は、代わりに%mを使用することです。 + + + + + + + + master_slave_mode、master_slave_sub_mode、replication_modeをに統合しました。(Tatsuo Ishii) + + + + + + + + Watchdog関連の設定パラメータをシンプルにしました。(Bo Peng) + + + + + + + + 設定パラメータで単位を指定できるようになりました。(Muhammad Usama) + + + + + + + + を追加しました。(Muhammad Usama, Japanese doc by Tatsuo Ishii) + + + + これはPostgreSQLのログ収集プロセスを取り込んだものです。 + + + + + + + + で接続切断ログが取れるようになりました。(Takuma Hoshiai) + + + + + + + + のアプリケーション名設定パラメータが多くの場所で有効になるようにしました。(Tatsuo Ishii) + + + + 前はの%aはスタートアップメッセージでだけ設定できました。 + これを、接続パラメータあるいはSETコマンドでapplication_nameを設定したときにも有効になるようにしました。 + + + + また、固定のアプリケーション名を内部プロセスに設定し、ログファイル中のどの行がどのプロセスに所属するのか管理者が容易に判断できるようにました。 + + + + + + + + を変更し、にアプリケーション名が含まれるようにしました。(Tatsuo Ishii) + + + + + + + + がユーザ名/パスワードペアの入力ファイルを受け付けるようになりました。(Umar Hayat, Japanese doc by Tatsuo Ishii) + + + + + + + + がユーザ名/パスワードペアの入力ファイルを受け付けるようになりました。(Umar Hayat, Japanese doc by Tatsuo Ishii) + + + + + + + + を追加しました。(Tatsuo Ishii) + + + + この新しいコマンドは、Pgpool-IIが起動してから実行されたSQLコマンドと、バックエンドからエラーが返された回数を表示します。 + + + + + + + + ヘルスチェックの統計情報を表示するを追加しました。(Tatsuo Ishii) + + + + + + + + 新しいPCPコマンドを追加しました。(Tatsuo Ishii) + + + + + + + + 新しいpgpool_adm関数を追加しました。(Tatsuo Ishii) + + + + + + + + pgpool設定ファイルを再ロードする新しいPCPコマンドを追加しました。(Jianshen Zhou, Muhammad Usama, Japanese + doc by Tatsuo Ishii) + + + + + + + + を使ってpgpoolクラスタ全体を停止することができるようになりました。(Muhammad Usama, Japanese doc by Tatsuo Ishii) + + + + + + + + wd_cliユーティリティを追加しました。(Muhammad Usama, Japanese doc by Tatsuo Ishii) + + + + Pgpool-IIと外部ヘルスチェックシステとの連携を容易にします。 + + + + + + + + 関数の揮発性をチェックすることによって書き込み関数を自動的に検出する機能を実装しました。(Tatsuo Ishii, Hou, Zhijie) + + + + システムカタログをチェックした結果、SELECT/WITHに含まれる関数が揮発性の性質を持っているなら、書き込みを行う関数であると見なします。 + この機能はが空である場合にのみ有効になります。 + この機能がデフォルトで有効になるように、black_function_listとwhite_function_listのデフォルトは空となりました。 + + + + + + + + 関数名を取得する方法を複数ヶ所で改善しました。(Hou, Zhijie) + + + + クエリキャッシュが有効である場合、Pgpool-IIはSELECT中の関数呼び出しを精査しました。 + 今までは関数がスキーマ修飾付きで呼び出されていると認識されませんでしたが、これを認識するように改善しました。 + + + + また、でスキーマ修飾付きの関数名が認識されなかったのも修正されました。 + なお、スキーマ修飾付きの関数名を登録する際は、スキーマ修飾なし関数名も登録するようにしてください。 + + + + + + + + dmlオブジェクトレベルの負荷分散をでサポートしました。(Subiao, Muhammad Usama) + + + + + + + + pgpool_adm関数で引数名が使えるようになりました。(Hou, Zhijie) + + + + 例を示します。 + + SELECT * FROM pcp_node_count(host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + + + + + + + + + テーブル、データベースOIDによるクエリキャッシュを削除する公開APIを追加しました。(Tatsuo Ishii) + + + + + + + + クライアントとpgpoolの間でのLDAP認証をサポートしました。(Takuma Hoshiai) + 詳細はをご覧ください。 + + + + + + + + scram/md5認証のリグレッションテストでAES256パスワード暗号化を使うように改善しました。(Tatsuo Ishii) + + + + + + + + で新しい"snapshot isolation mode"を追加しました。(Tatsuo Ishii) + + + + このモードは既存のnative replication modeと似ていますが、バックエンドの間でより厳密な読み取り一貫性を提供します。 + (いわゆる原子的読み取り一貫性) + これにより、あたかも複数のバックエンドから構成されるクラスタが単一のPostgreSQLサーバに見えるようになります。 + + + + + + + + hostssl/hostnosslについての記述をpool_hba.confサンプルファイルに追加しました。 + + + + hostssl/hostnosslはサポートされていましたが、pool_hba.confのコメントはそのことに言及していませんでした。 + + + + + + + のサポートを追加しました。(Umar Hayat, Japanese doc by Tatsuo Ishii) + + + + + + + + のサポートを追加しました。(Umar Hayat, Japanese doc by Tatsuo Ishii) + + + + + + + + SSL関連ファイルの相対パスを設定ファイルのあるディレクトリを基準にするようにしました。(Umar Hayat, Japanese doc by Bo Peng) + + + + + + + + 拡張問い合わせを実行中に適切なプロセス状態をpsコマンドで表示できるようにしました。(Takuma Hoshiai) + + + + + + + + 冗長過ぎる認証処理のログをダウングレードしました。(Tatsuo Ishii) + + + + + + + + 認証処理でより情報量の多いメッセージを表示するようにしました。(Tatsuo Ishii) + + + + + + + + スタンバイサーバが存在しない時に不必要なエラーメッセージが出ないようしました。(Tatsuo Ishii) + + + + + + + + 起動時にPIDファイルが存在しなかったらソケットファイルを削除するようにしました。(Bo Peng) + + + + + + + + pgprotoがNOTIFICATIONメッセージを理解できるようにしました。(Tatsuo Ishii) + + + + + + + + PostgreSQL 13 beta3の新しいパーサを取り込みました。 + 主なPostgreSQL 13パーサの変更点は以下です。 + + + + Remove an object's dependency on an extension + + ALTER TRIGGER ... NO DEPENDS ON EXTENSION ... + ALTER FUNCTION ... NO DEPENDS ON EXTENSION ... + + + + + + + Allow FETCH FIRST to use WITH TIES. + + FETCH FIRST ... WITH TIES + + + + + + + Allow ALTER VIEW to rename view columns + + ALTER VIEW ... RENAME COLUMN ... TO ... + + + + + + + Add VACUUM clause PARALLEL option + + VACUUM (PARALLEL 1) ... + + + + + + + + + + + + pgpool_setupwatchdog_setupの"PGBIN"と"LPATH"を、PostgreSQLのbin pathとlib pathにしました。(Bo Peng) + + + + + + + + PostgreSQLのlib pathをpg_configを使って取得し、regress.shのLD_LIBRARY_PATH環境変数に追加するようにしました。(Bo Peng) + + + + + + + + + + + RPMにpcp.confpool_hba.confのサンプルファイルが含まれるようにしました。(Bo Peng) + + + + + + + + RPM内のPCPのUNIX_DOMAIN_PATHを"/var/run/postgresql"にしました。 (Bo Peng) + + + + + + + + RHEL8/CentOS8で利用できるようにsrc/redhat/pgpool_rhel7.sysconfigをsrc/redhat/pgpool_rhel.sysconfigにファイル名を変えました。(Bo Peng) + + + + + + + + + 主なドキュメントの改善点 + + + + + + 新しいドキュメント「Kubernetesの設定例」を追加しました。(Bo Peng) + + + + + + + によって実行されるサンプルスクリプトescalation.shを追加しました。(Masaya Kawamoto) + + + + + + + 「8.2. Watchdogの設定例」を削除しました。(Bo Peng) + + + Watchdogの設定方法については、「Pgpool-II + Watchdogの構築の例」のを参照ください。 + + + + + + + + Pgpool-II/PostgreSQLの起動/停止などに関するドキュメントを追加しました。(Tatsuo Ishii) + + + + 詳細はなどを見てください。(Tatsuo Ishii) + + + + + + + + でsshでlocalhostにパスワード無しでログインできるようにしなければならないことを述べました。(Tatsuo Ishii) + + + + + + + + 設定例で使用しているサンプルスクリプトのURLとyumリポジトリのURLを変更しました。(Bo Peng) + + + + + + + + が実際には何をやっているのかを記述しました。(Tatsuo Ishii) + + + + + + + + 「RPMからのインストール」の章を更新しました。(Bo Peng) + + + + + + + + に注意書きを追加しました。(Takuma Hoshiai) + + + + + + + + .pgpoolkeyの説明を追加しました。(Tatsuo Ishii) + + + + + + + + の記述を改善しました。(Kenichiro Tanaka) + + + + + + + + コマンドとコマンドに関する注意書きを追加しました。(Bo Peng) + + + + + + + + インストールドキュメントを改善しました。(Tatsuo Ishii) + + + + 「プランニング」の章(参照)を追加し、ユーザがインストールの概要を把握できるようにしました。 + + + + + + + + スプリットブレインを避けるためには、Pgpool-IIは3ノード必要であることを明記しました。(Tatsuo Ishii) + + + + 詳細はをご覧ください。 + + + + + + + + フェイルオーバに関する記述を改善しました。(Tatsuo Ishii) + + + + 詳細はをご覧ください。 + + + + + + + + フェイルオーバ中にセッションが切断される条件を明示しました。(Tatsuo Ishii) + + + + 詳細はをご覧ください。 + + + + + + + + パラメータの記述を改善しました。 + + + + + + + + 設定例の章でスクリプトへのリンクを設定しました。(Bo Peng) + + + + 詳細はをご覧ください。 + + + + + + + + 中に環境変数PGPOOLKEYFILEについて記述しました。(Tatsuo Ishii) + + + + pg_encコマンドは実際にはその環境変数を認識します。 + + + + + + diff --git a/doc.ja/src/sgml/release-4.3.sgml b/doc.ja/src/sgml/release-4.3.sgml new file mode 100644 index 000000000..6aee29854 --- /dev/null +++ b/doc.ja/src/sgml/release-4.3.sgml @@ -0,0 +1,5050 @@ + + + + + リリース 4.3.20 + + リリース日 + 2026-06-04 + + + + 不具合修正 + + + + + pgprotoで改行データを扱えるようにしました。(Tatsuo Ishii) + + + 現在は\nが改行として認識されます。 + これはCOPYに必要な修正です。 + + + + + + + アボート状態のトランザクションでの空クエリ処理を修正しました。(Tatsuo Ishii) + + + アボート状態のトランザクションで空クエリが誤ってエラーになる問題を修正しました。 + 空クエリはアボート状態のトランザクションでも許可されるべきですが、以前のコミットによりcheck_transaction_state_and_abort()が空クエリを拒否していました。 + この修正により、SimpleQuery()で空クエリを検出し、チェックを通さないようにしました。 + + + この問題はRonaldo Raivilによって報告されました。 + + + ディスカッション: pgpool ≥ 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + ssl_dh_params_fileの説明を修正しました。(Tatsuo Ishii) + + + パラメータが空の場合だけでなく、不正なパラメータが指定された場合も、組み込みのデフォルト値にフォールバックするようになっていました。 + + + + + + + PCPのメインプロセスが再起動時に子プロセスのPIDを保持するように修正しました。(Tatsuo Ishii) + + + フェイルオーバー/フェイルバック時にPCPのメインプロセスが再起動すると、子PCPワーカープロセスのPID一覧を失ってしまう問題を修正しました。 + + その結果、pcp_promote_nodeなどのコマンドが無限にハングする可能性がありました。 + この修正により、PCPワーカープロセスのPIDを共有メモリに保持し、PCPのメインプロセス再起動後も利用できるようにしました。 + + + この問題はTaiki Koshinoによって報告されました。 + + + ディスカッション: Problem with pcp process + + + + + + + バージョンの不一致があったため 4.3.19 用にコンフィギュアファイルを再作成しました。(Bo Peng) + + + + + + + SSLモジュールでのメモリリークを修正しました。(Tatsuo Ishii) + + + 不正なDHパラメータが指定された場合に、load_dh_file()でメモリリークが発生する問題を修正しました。 + この関数はPEM_read_DHparams()が返したメモリを解放していませんでした。 + + また同じファイル内のコピーライト表示を修正し、元のPostgreSQLのコピーライトを保持するようにしました。 + + + ディスカッション: Memory leak in SSL module + + + + + + + SET transaction_read_only = 0の誤ったルーティングを修正しました。(Bo Peng) + + + SET transaction_read_only = 0がstandbyノードに誤って送られ、クエリエラーが発生する問題を修正しました。 + また、不適切なbool型のret = POOL_BOTHを適切なenum型に修正しました。 + + + この問題はliujinyang-highgoによって報告されました。 + + + ディスカッション: set command ‘set transaction_read_only = 0;‘ routed to standby node and execute failed. + + + + + + + ドキュメント修正 + + + + + ignore_leading_white_spaceおよびallow_sql_commentsのドキュメントを修正しました。(Tatsuo Ishii) + + + デフォルト値の説明が不足していました。 + + + + + + + + リリース 4.3.19 + + リリース日 + 2026-02-26 + + + + 変更点 + + + + + 並列でmakeを実行できるようになりました。(Tatsuo Ishii) + + + 以前、makeの並列実行は以下のように失敗していました。 + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + anthonyrousselによってパッチが作成され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Fix parallel build + + + + + + + primary_conninfoのホストが不一致であることを詳細にログに出力するようになりました。(Taiki Koshino) + + + pgpool.confに設定されているPostgreSQLprimary_conninfoのホスト設定が一致しない場合以下のようなログが出力されます。 + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + + サポートされている最小のOpenSSLバージョンを明記しました。(Tatsuo Ishii) + + + こちらは以下を使用したconfigure.acによって実現しています。 + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + サポートされている最小バージョンは1.0.2で、これは現時点ではPostgreSQLと同じです(実際にはAC_DEFINEはPostgreSQLから導入されています)。 + また、インストールされているOpenSSLが3.0などの新しいバージョンである場合、OpenSSLの非推奨警告を回避できる可能性があります。 + さらに、インストールドキュメントに、必要なOpenSSLの最小バージョンは1.0.2であることを記載しました。 + + + + + + + 不具合修正 + + + + + check_transaction_state_and_abort()の考慮不足を修正しました。(Tatsuo Ishii) + + + この関数はフロントエンドがNULLアカウントであるケースを考慮していませんでした。 + + + この問題はCoverityによって発見されました。 + + + + + + + walker()が早めに結果を返すように修正しました。(Tatsuo Ishii) + + + 以前、walker()は対象オブジェクトを見つけたときにfalseを返していましたが、 + trueを返すようにし処理をショートカットするようにしました。 + + またwaker()の設計意図が分かりやすいようにPostgreSQLのコメントを移植しました。 + + + この問題はliujinyang-highgoによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Improper handling in the function view_walker(). + + + + + + + scram-sha-256認証でのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はCoverityによって発見されました。 + + + + + + + malloc()の返り値チェックを修正しました。(Tatsuo Ishii) + + + create_inet_domain_sockets()はソケットのファイルディスクリプタ用メモリを割り当てている間にmalloc()が返す値のチェックをしていませんでした。 + + + + + + + integer型のオーバーフローが起きる可能性がある問題を修正しました。(Tatsuo Ishii) + + + pool_write_flush()pool_flus_it()ではwrite(2)が使用されています。 + write(2)はssize_tを返しますが、コード内には戻り値がint変数に代入されている箇所がいくつかありました。 + その結果、戻り値が負の値として評価され、エラーが発生する可能性がありました。 + + + + + + + + リリース 4.3.18 + + リリース日 + 2025-12-15 + + + + 変更点 + + + + + pgpool_setupで非推奨の「egrep」の代わりに「grep -E」を使用するようにしました。(Bo Peng) + + + 新しいGNUのgrepバージョンでの廃止警告を回避するために、「egrep」を「grep -E」に置き換えました。 + + + + + + + 不具合修正 + + + + + show pool_statusのバッファオーバーフローエラーを修正しました。(Tatsuo Ishii) + + + SHOW POOL_STATUS、pgpool show、および pcp_pool_statusコマンドでバッファオーバーフローが発生する問題を修正しました。 + 問題の原因は、backend_flagがALWAYS_PRIMARYに設定されている場合に、pool_flag_to_str()関数がbackend_flagを文字列化する際に静的バッファの末尾を越えて書き込んでしまうことでした。 + + + この問題はzam bakによって報告され、Bo Pengによってよって分析されました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + 「show pool_status」に表示されるmemqcache_stats_start_timeの出力を修正しました。(Tatsuo Ishii) + + + get_config()がctime()を使って時刻を文字列化していましたが、ctime()の戻り値の末尾には改行が含まれることを考慮していませんでした。 + その結果、memqcache_stats_start_timeの行に余計な改行が入り、さらに次の行が空欄として表示されてしまう問題が発生していました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + + リリース 4.3.17 + + リリース日 + 2025-11-25 + + + + 変更点 + + + + + 不要なapplication_nameの処理を削除しました。(Tatsuo Ishii) + + + 以前のコミットで、既存接続を再利用する際にapplication_nameを設定する処理が追加されました。 + しかしこれは不要です。DISCARD ALLにより接続再利用時に自動的にapplication_nameがリセットされ、 + send_params()によってフロントエンドに必要なパラメータステータス(application_nameを含む)が送信されます。 + この冗長な処理を削除することで、特に地理的に離れたバックエンドノードでのパフォーマンスが向上します。 + + + ディスカッション: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + 不具合修正 + + + + + CopyOutでのセグメンテーションフォルトを修正しました。(Tatsuo Ishii) + + + 拡張プロトコルでCOPY relname TO STDOUTが実行された場合、Pgpool-IIがセグフォルトを起こしていました。 + + + この問題はhttps://github.com/teteshによって報告されました。 + + + ディスカッション: datanymizer and pg-pool segmentation fault + + + + + + Watchdogのスプリットブレイン回避するよう修正しました。(Tatsuo Ishii) + + + Watchdogはビーコンメッセージとハートビートで通信します。 + ハートビートが有効でない場合、ビーコンが30秒以上届かないとスプリットブレインが発生することがあります。 + 古いリーダーを無効化することで、同時に二人のリーダーが存在しないように修正しました。 + ノードがリーダーからのビーコンを2回以上見逃すと、リーダーはLOST状態となり、 + set_state(WD_JOINING) により新リーダー選出が開始されます。 + + + + + + + 存在しないプリペアドステートメント使用時のFATALエラー防止するよう修正しました。(Tatsuo Ishii) + + + 以前はBind()が存在しないプリペアドステートメントでFATALエラーを出していました。 + はステートメントの存在を確認し、存在しない場合はフロントエンドにERRORメッセージを送信するようになりました。ログは残りません。 + + + + + + + -pと -P両方使用時に動作しない問題を修正しました。(Tatsuo Ishii) + + + 元の報告では、pg_enc -p -P実行時にパスワードと暗号キーを求められましたが、 + キーが提供されない場合に失敗していました。 + また、コメント /* prompt for postgres password */ が誤解を招くため、 + /* prompt for password to be encrypted */ に修正されました。 + + + ディスカッション: pg_enc + + + + + + + 32ビット環境でのコンパイルの問題を修正しました。(Tatsuo Ishii) + + + 32ビットシステムでsrc/parser/snprintf.cをコンパイルするとisnan()isinf()が未定義でエラーになりました。 + math.hをインクルードし、ヘッダーファイルの順序も整理しました。 + 元々 PostgreSQLから取り込まれたファイルで、math.hは既に含まれていました。 + 修正は fix compiling issues for 32-bit targets のプルリクエストに記載してあります。 + + + + + + + recovery_1st_stage.sampleでBashのディレクトリ削除を安全に行うよう修正しました。(Taiki Koshino) + + + rmコマンドの変数をクォートし、意図しない削除を防止しました: + rm -rf "${DEST_NODE_PGDATA}" + + + + + + + 指定なしでコンパイルする際のエラーを修正しました。(Tatsuo Ishii) + + + 指定なしでコンパイルするとエラーが発生していました。 + 対応として該当コードブロックを #ifdef USE_MEMCACHEDで囲みました。 + + + この問題はBo Pengによって報告されました。 + + + + + + + ドキュメント修正 + + + + + 8.2. Pgpool-II + Watchdog Setup Example の "PostgreSQLスタンバイ設定" ドキュメントを更新しました。(Taiki Koshino) + + + オンラインリカバリなしでスタンバイを設定する場合、postgresql.auto.confにprimary_conninfoを書き込まないよう注意を追加しました。 + + + ディスカッション: Follow primary command not fixing postgresql.auto.conf + + + + + + + watchdog_setupのマニュアルを修正しました。(Tatsuo Ishii) + + + heartbeartがwatchdog_setupに設定されていないと誤記されていた箇所を修正しました。 + + + + + + + 回帰テスト修正 + + + + + 023.ssl_connectionをPostgreSQL 18に対応するよう修正しました。(Tatsuo Ishii) + + + PostgreSQL 18でpsqlの\conninfo出力形式が大幅に変更されたため、 + このテストが失敗していました。 + PostgreSQLバージョンに応じてテストスクリプトを修正しました。 + + + + + + + 010.rewrite_timestampのRubyスクリプトを修正しました。(Tatsuo Ishii) + + + RubyのFile.existsは新しいバージョンで非推奨のため、File.existに置き換えました。 + + + + + + + 034と075のタイムアウトを調整しました。(Tatsuo Ishii) + + + 034.promote_nodeと075.detach_primary_left_down_nodeのスクリプト終了タイムアウトを60秒から120秒に変更し、 + 誤エラーが発生する可能性を減らしました。 + + + + + + + 023.ssl_connectionにssl_ecdh_curveのテストを追加しました。(Tatsuo Ishii) + + + 023.ssl_connectionはssl_ecdh_curveのテストをカバーしていなかったため、 + 不正なssl_ecdh_curveパラメータでフロントエンドとpgpoolの接続が失敗するか確認しました。 + + + + + + + + リリース 4.3.16 + + リリース日 + 2025-08-21 + + + + 不具合修正 + + + + + watchdog が不適切な NOTICE メッセージを出力する問題を修正しました。 (Tatsuo Ishii) + + + read_ipc_socket_and_process() は、IPCソケットへのコマンド書き込みのたびに、書き込みが成功した場合でも通知メッセージを出力していました。これを修正し、書き込みが失敗した場合にのみ通知メッセージを出力するようにしました。 + log_min_messages が notice 以上に設定されている場合にのみメッセージが表示されるため、このバグが発見されていませんでした。 + + + ディスカッション: pgpool IPC socket connection issue + + + + + + + + スタートアップパケットを読んでいるときのメモリーリークを修正しました。(Tatsuo Ishii) + + + pool_push_pending_data でのリソースリークを修正しました。 + + + + + + + ビッグエンディアンマシン上の scram-sha-256 認証の不具合を修正しました。(Tatsuo Ishii) + + + scram-sha-256 認証を実行する際、ハッシュ関数 pg_sha_256_final が使用されます。 + これは PostgreSQL からインポートされたもので、プリプロセッサ定義 WORDS_BIGENDIAN を使用してホストマシンのエンディアンを判断します。 + WORDS_BIGENDIAN は configure 時に定義する必要がありますが、pg_sha_256_final(およびその他)が PostgreSQL からインポートされた際にこの部分が省略されていました。 + その結果、scram-sha-256 はリトルエンディアンマシンでのみ動作していました。 + configure.ac に AC_C_BIGENDIAN マクロを追加することでこの問題を修正しました。。 + + + この問題は Christoph Berg によって報告され、 pranavkaruvally によって分析されました。 + + + ディスカッション: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + ソースコードのタイプミスを修正しました。 (Bo Peng) + + + + + + + ハートビートデバイスの処理を修正しました。(Tatsuo Ishii) + + + pgpool.conf の処理中に、heartbeat_device が誤って処理され、最初のデバイスが無視されていました。 + + + この問題は Bo Peng によって分析されました。 + + + + + + + pgpool.confのコメントのタイプミスを修正しました。 (Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + 「8.3. ネイティブレプリケーション/スナップショットアイソレーションモードの構築の例」のドキュメントを改善しました。(Taiki Koshino) + + + サンプルスクリプトのリンクと「事前設定」の説明を改善しました。 + + + + + + + リロードによって反映されないパラメータのドキュメントを修正しました。 (Taiki Koshino) + + + authentication_timeoutmemqcache_oiddir はリロードしても反映されません。 + ドキュメントが「このパラメータはサーバー起動時にのみ設定できます。」に変更されました。 + + + + + + + + watchdog リーダーの用語を統一しました。(Tatsuo Ishii) + + + 以前は「leader」「active」「coordinater」という用語が、watchdog のリーダーノードを指すために使用されていました。このコミットではこれらを「leader」に統一しました。 + advanced.sgml も修正しました。 + + + + + + + + サンプルスクリプトを修正しました。(Taiki Koshino) + + + 「8.2. Pgpool-II + Watchdogの構築の例」のサンプルスクリプトを修正しました。 + + + + + + + ロードバランスの説明で論理レプリケーションモードと Slony モードが抜けている問題を修正しました(Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Bo Peng) + + + 「replication_state」と「replication_sync_state」を正しく表示するには、各 backend_application_nameXprimary_conninfoapplication_name に指定された値と一致する必要があることを明確にしました。 + + + + + + + カーネルの資源に関するセクションを追加しました。 (Tatsuo Ishii) + + + Pgpool-II は System V の共有メモリとセマフォを使用します。 + 要件についてはドキュメントを参照することをお勧めします。 + + + + + + + configure の オプションの説明を追加しました。(Tatsuo Ishii) + + + これは LDAPサポートがv4.2で導入されたときに見落としていました。 + + + + + + + Pgpool-II でサポートされているプラットフォームを明確にしました。 (Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Tatsuo Ishii) + + + + + + + 回帰テスト修正 + + + + + 029.cert_passphrase 回帰テストを安定化しました。 (Tatsuo Ishii) + + + ssl_passphrase_command が有効でない場合、エラーメッセージは通常「bad decrypt」ですが、「wrong tag」となる場合もありました。 + + + + + + + + リリース 4.3.15 + + リリース日 + 2025-05-15 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + Pgpool-IIのクライアント認証メカニズムには認証バイパスの脆弱性があります。 + 本来であれば認証が必要な場合でも、認証処理がスキップされてしまう可能性があります。 + この脆弱性を悪用することで、攻撃者が任意のユーザとしてログインし、データベース内の情報を参照・改ざんしたり、データベースを停止させたりすることができる可能性があります。(CVE-2025-46801) + + + なお、本脆弱性の影響を受けるのは、下記のパターン1から3いずれかの条件を満たす場合に限られます。 + + + + + パターン 1:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + pool_hba.confpassword認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードが設定されていない + + + + + pg_hba.confscram-sha-256またはmd5認証方式を使用している + + + + + + + + パターン 2:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + enable_pool_hba = off + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + + パターン 3:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + rawモードを使用している (backend_clustering_mode = 'raw') + + + + + pool_hba.confmd5認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードがテキストまたはAES形式で登録されている + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + この脆弱性の影響を受けるのは、Pgpool-II 4.0系および4.1系のすべてのバージョン、4.2.0-4.2.21、4.3.0-4.3.14、4.4.0-4.4.11、4.5.0-4.5.6、4.6.0です。 + Pgpool-II 4.6.1、4.5.7、4.4.12、4.3.15、4.2.22以降へのアップグレードを強くお勧めします。 + それができない場合は、発生条件パターンに当てはまらない設定の組み合わせに変更してください。 + + + + + 変更点 + + + + + 設定ファイルにメジャーバージョンを追加しました。 (Bo Peng) + + + + + + + 不具合修正 + + + + + クライアント認証が正しく実行されない場合があるのを修正しました。(Tatsuo Ishii) + + + enable_pool_hbaがonで、auth methodが"password"、pool_passwdにパスワードが登録されておらず、pg_hba.confの認証方式が"scram-sha-256"か"md5"の場合、クライアントが最初にpgpoolに接続したときには認証が期待通りに実行されます。 + しかし、クライアントがキャッシュされたコネクションに接続すると、任意のパスワードが通ってしまいます。 + + + また、enable_pool_hba = offのいくつかのケースでは、本来パスワードが聞かれるはずが、最初からパスワードが聞かれない、あるいはキャッシュされたコネクションに接続した時にはパスワードが聞かれないことがありました。 + + + 上記を修正するのに加え、以下の変更を行いました。 + + + + + 認証コードを単純化するために、PostgreSQLが1台の時のコードパスを削除しました。 + + + + + crypt認証のサポートをフロントエンドとバックエンドから削除しました。 + この機能はドキュメントに書かれておらず、テストもされていませんでした。 + また、crypt認証はPostgreSQLではだいぶ以前(8.4, 2009)に削除されています。 + + + + + 新しい回帰テストの"040.client_auth"を追加しました。 + このテストは、CSV形式のテスト設定ファイルを使って、包括的なクライアント認証のテストを実施します。 + + + + + + + + クエリキャッシュにおける、古くからあるバインド時のバグを修正しました。(Tatsuo Ishii) + + + 名前付きステートメントを準備すると、バインド後にパースメッセージなしで実行することが可能です。 + 問題は、実行時またはCOMMIT時にクエリキャッシュを無効化するために必要なテーブルOIDが、パースメッセージ処理(Parse())でのみ収集されていたことです。 + そのため、前回の実行後にパースなしでバインドを実行すると、テーブルOIDが収集されず、pgpoolはクエリキャッシュの無効化に失敗していました。 + バインド時にもテーブルOIDを収集するよう修正しました。 + 006.memqcacheに回帰テストを追加しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + クエリキャッシュの無効化に失敗する問題を修正しました。 (Tatsuo Ishii) + + + 実行メッセージを受信すると、pgpoolは最大行数パラメータをチェックします。この値が0でない場合、pgpoolはpool_handle_query_cache()にクエリキャッシュを作成しないよう指示するために、"partial_fetch"フラグを設定します。 + 問題は、コミット2a99aa5d1が、INSERT/UPDATE/DELETEであっても実行メッセージパラメータが0以外(ほとんどの場合1)に設定され、pgpoolがSELECT以外の場合でもこのフラグを設定することを見落としていることです。 + この結果、このフラグがtrueの場合、pool_handle_query_cache()内の後続のコードでキャッシュの無効化がスキップされるため、クエリキャッシュの無効化に失敗していました。 + フラグを設定する前にクエリが読み取り専用のSELECTであるかどうかを確認するようにExecute()を修正しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + OpenBSDへ移植する際の問題を修正しました。 (Tatsuo Ishii) + + + ディスカッション: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + このパッチはMartijn van Durenによって作成されました。 + + + + + + json_writerが特殊文字を正確にエンコードできない問題を修正しました。(Bo Peng) + + + が特殊文字を含んでいる状態でwatchdogを起動するとPgpool-IIがクラッシュしていました。 + + + このパッチはMartijn van Durenによって作成され、Bo Pengによって微修正されました。 + + + + + + リロード時にを開くようにストリーミングレプリケーションチェックとヘルスチェックプロセスを修正しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションチェックとヘルスチェックはリロード前にを開いていませんでした。 + もしが空文字列の時は、からパスワードを得ます。 + そのためこれらのプロセスはリロード時にの古いコンテンツを読み取ります。 + + + + + + ドキュメント修正 + + + + + の説明を改善しました。(Tatsuo Ishii) + + + が計算されるタイミングは、接続キャッシュを保持しているプロセスからクライアントが切断されたときであることを追記しました。 + + + ディスカッション: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + についての説明を改善しました。 (Tatsuo Ishii) + + + スーパーユーザーかpg_monitorグループであるべきです。 + + + + + + + + リリース 4.3.14 + + リリース日 + 2025-02-28 + + + + 変更点 + + + + + サンプルフォロープライマリスクリプトからpg_basebackupの処理を削除しました。(Bo Peng) + + + pg_rewindが失敗した場合、ユーザーにとって最も安全な方法は手動で復旧することです。 + + + + + + + 不具合修正 + + + + + per_node_error_log()のエラーメッセージでコロンが重複して出力される不具合を修正しました。(Bo Peng) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + pool_signalの不具合を修正しました。(Tatsuo Ishii) + + + 以前は、pool_signalSA_RESTARTフラグを設定していませんでした。 + そのため、シグナルによって中断されたシステムコールは再起動されません。 + 一部のコードは、システムコールがシグナルによって中断された場合に再起動するように準備されています。 + しかし、すべての箇所で対応できているかは不明なため、フラグを追加しました。 + なお、PostgreSQLでは常にこのフラグが使用されています。 + + + + + + + パラメータにデフォルト値以外のファイルが指定されている場合に、pg_md5pg_encがパスワードファイルを更新しない問題を修正しました。(Bo Peng) + + + この問題はSadhuprasad Patroによって報告されました。 + + + + + + + ストリーミングレプリケーションモードにおけるクエリキャッシュのいくつかの不具合を修正しました。(Tatsuo Ishii) + + + + + クエリキャッシュが有効で、フロントエンドから実行メッセージが送信された場合、クエリキャッシュデータが使用可能であれば、Pgpool-IIはそのデータをバックエンドメッセージバッファに挿入します。 + しかし、キャッシュされたメッセージが不適切な位置に挿入されることで、Pgpool-IIが誤って「kind mismatch」エラーを発生させることがありました。 + + + + + また、クエリキャッシュが有効で、クエリが拡張クエリモードで実行されている場合に、Pgpool-II がストリーミングレプリケーションモードで動作していると、実行メッセージが誤った結果を返す可能性がありました。 + + + + + さらに、複数の実行メッセージが連続して送信された場合、Pgpool-IIは各実行メッセージに対してクエリキャッシュから同じ結果を返していましたが、これは誤りです。 + 本来、2回目以降の実行では0行が返されるべきでした。 + + + ディスカッション: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + ドキュメント修正 + + + + + クライアント認証の章を強化しました。(Tatsuo Ishii) + + + pool_passwdに関する説明部分を追加しました。 + これまで、概要ページにはpool_hba.confの説明のみが記載されていましたが、今回pool_passwdの一般的なガイドを追加しました。 + これにより、ユーザーがこの章をより理解しやすくなりました。 + + + + + + + 回帰テスト修正 + + + + + 032.dml_adaptive_loadbalanceテストの安定性を向上させました。(Tatsuo Ishii) + + + + + + + + リリース 4.3.13 + + リリース日 + 2024-11-28 + + + + 不具合修正 + + + + + + バックエンドがエラーメッセージを送信した場合に、SSLネゴシエーションを中止するよう修正しました。(Tatsuo Ishii) + + + SSLネゴシエーションのクライアント側実装(pool_ssl_negotiate_clientserver())では、 + 中間者攻撃者がSSLネゴシエーションフェーズ中に長いエラーメッセージを送信することで、 + Pgpool-IIやクライアントを混乱させる可能性がありました。 + このコミットでは、ネゴシエーションを直ちに拒否(FATALエラーを発行)し、 + そのような攻撃を防ぐためにセッションを終了するよう修正しました。 + + + これは、PostgreSQLのCVE-2024-10977に似ています。 + + + + + + + リロード処理がWatchdogプロセスに反映されない問題を修正しました。(Bo Peng) + + + Pgpool-IIの + reload_config()関数は、 + WatchdogププロセスにSIGHUPシグナルを送信する必要がありました。 + + + + + + + do_query関数の不具合を修正しました。(Tatsuo Ishii) + + + htons/htonlの代わりにntohs/ntohlを使用するようにdo_queryを修正しました。 + + + + + + + pool_passwdを更新してリロードした後の認証失敗問題を修正しました。(Tatsuo Ishii) + + + pool_hba.confが無効になっている場合、Pgpool-IIのリロードが実行されても、Pgpool-IIの子プロセスはpool_passwdの更新を認識しませんでした。 + リロード処理関数check_config_reload()は、が有効な場合にのみpool_passwdを再オープンする必要があると誤って判断していたことが原因でした。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html + + + + + + + COPYがハングする問題を修正しました。(#79) (Tatsuo Ishii) + + + COPY IN状態(つまり、COPY FROM STDIN)中、フロントエンドはFlushまたはSyncメッセージを送信できます。 + F/Bプロトコル仕様によると、これらは無視されるはずですが、Pgpool-IIは無効なメッセージとして処理し、これがCOPYのハングの原因でした。 + + + リグレッションテストも追加しました。 + + + + + + + シャットダウン中にPgpool-IIの子プロセスがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + 実際のクラッシュはclose_all_backend_connections()内で発生していました。 + この関数は、on_system_exitchild_will_go_down()を登録するために呼び出されます。 + この時点では、Pgpool-II子プロセスが起動し、pool_init_cp()を実行した直後であるようです。 + 接続プールオブジェクトが完全に初期化されていなかったため、クラッシュが発生していました。 + + + この問題はEmond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + 認証失敗による散発的なヘルスチェックの失敗を修正しました。(Tatsuo Ishii) + + + が空文字列の場合、ヘルスチェックプロセスはpool_passwdファイルからパスワードを検索します。 + 問題は、このファイルのファイルディスクリプタが親pgpoolプロセスから継承されている点です。 + pgpoolメインプロセスとヘルスチェックプロセス(複数存在する可能性あり)が同じディスクリプタを共有するため、さまざまな問題が発生していました。 + この問題を解決するために、ヘルスチェックプロセスが開始される際にファイルを再度開き、 + それぞれのヘルスチェックプロセスが独自のファイルディスクリプタを持つようにしました。 + + + なお、pgpoolの子プロセス(フロントエンドセッションを担当)はすでにファイルディスクリプタを再度開く処理を行っており、これが今回の問題には関連していません。 + + + この問題は、Emond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + ALTER ROLEのクエリキャッシュ無効化を最適化しました。(Tatsuo Ishii) + + + コミット6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89は、ALTER ROLE/USERステートメントが使用される際にクエリキャッシュを無効にしています。 + しかし、実際にはこれが過剰です。 + 次のクエリはロールの権限に影響を与えないため、クエリキャッシュを無効にする必要はありません。 + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + したがって、これらのコマンドが使用される場合には、クエリキャッシュを無効にしないようにしました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Pgpool-IIの子プロセスが終了したときにPgpool-IIがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスが終了すると、close_all_backend_connections()が呼び出され、接続プール内のすべてのバックエンド接続が閉じられます。 + しかし、誤ってMAIN_CONNECTIONマクロが使用されていました。 + このマクロは現在アクティブな接続には適していますが、接続プールが作成された時点でのメインノードが異なる可能性があるため、プールされた接続には適していませでした。 + この問題を修正するために、代わりにin_use_backend()を使用するよう変更しました。 + + + Emond Papegaaijによって報告されました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードのバグを修正しました。(#69) (Tatsuo Ishii) + + + INSERTコマンドを受信すると、Pgpool-IIはターゲットテーブルに対して自動的にテーブルLOCKコマンドを発行しますが、メインノード以外のノードにコマンドを送信し忘れていました。 + この問題は拡張クエリモードの場合にのみ発生していました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードの別のバグを修正しました。(Tatsuo Ishii) + + + insert_lock()は、メインノード以外のノードに行ロックコマンド(lock_kind == 3 の場合)を送信するのを忘れていました。 + + + + + + + pool_memqcache.cのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はコミット6fdba5c33によって導入されました。 + + + + + + + + ドキュメント修正 + + + + + ドキュメントとサンプル設定ファイルのタイポを修正しました。(Bo Peng) + + + + + + + 回帰テスト修正 + + + + + テスト024.cert_authをOpenSSL 3.2に対応するよう修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.3.12 + + リリース日 + 2024-09-09 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + クエリキャッシュ機能()が有効な時に、データベースユーザがクエリキャッシュ経由で本来読み出せない行を読むことが可能でした。(CVE-2024-45624) + + + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22より古く、クエリキャッシュ機能を持つすべてのバージョン(クエリキャッシュ機能は3.2で実装されました)がこの脆弱性の影響を受けます。 + + + + + + あるユーザのクエリキャッシュがテーブルに対して作成されていると、そのテーブルへのアクセス権がREVOKEコマンドで剥奪されても、アクセス権を持たないそのユーザがクエリキャッシュを通じてテーブルにアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュがテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、アクセス権を持たないBがクエリキャッシュを通じてアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュが行セキュリティが有効なテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、本来Bが見えない行をクエリキャッシュを通じて取り出すことが可能でした。 + + + + + Pgpool-II 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22以降へのアップグレードを強くお勧めします。 + それができない場合は、クエリキャッシュ機能を無効にしてください。 + + + なお、この脆弱性を修正するために、いくつかのコマンド(ALTER DATABASE, ALTER ROLE, ALTER TABLE, REVOKE)を実行すると、クエリキャッシュのすべてのデータを削除するようになりました。 + これにより、クエリキャッシュの性能に影響があるかも知れません。 + + + + + 変更点 + + + + + をバックポートしました。 (Tatsuo Ishii) + + + これは主にテストのためです。v4.1までバックポートしました。 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + 不具合修正 + + + + + + レプリケーションモードとスナップショットアイソレーションモードで発生する複数の不具合を修正しました。(Tatsuo Ishii) + + + 次の不具合を修正しました。 + + + + + レプリケーションモードおよびスナップショットアイソレーションモードでコマンドを実行すると、Pgpool-IIはクエリ準備完了メッセージを待ちますが、一部のコマンド(SET ROLEなど)がパラメータステータスメッセージを生成することを忘れていました。 + その結果、Pgpool-IIはクエリ準備完了メッセージの前に他のメッセージが到着したことをエラーとして出力していました。 + + + + + + 前のクエリがパラメータステータスメッセージを生成した場合、後続のparse()はそれを読み取って処理する必要があります。 + これは、パラメータステータスメッセージの後に続くはずのクエリ準備完了メッセージを読み取る必要があるためです。 + + + ただし、ParameterStatus()が呼び出されると、クエリ進行中フラグが設定され、このparse()呼び出しで処理されるクエリが負荷分散されている場合、バックエンドからのパラメータステータスメッセージの1つだけが処理される可能性がありました。 + パラメータステータスメッセージはSETコマンドによって生成され、SETコマンドはレプリケーションモードおよびスナップショットアイソレーションモードのすべての生きているバックエンドに送信されるため、すべての生きているバックエンドから送信される可能性がありました。 + そのため、ParameterStatus()を呼び出す前に、クエリ進行中フラグを設定解除するように修正しました。 + + + + + + + + + + + リリース 4.3.11 + + リリース日 + 2024-08-15 + + + + 変更点 + + + + + + サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 (Bo Peng) + + + postgresqlxx-serverがインストールされていない可能性があるため、サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 + + + + + + + + 不具合修正 + + + + + + フラッシュメッセージを受信した後にハングする問題を修正しました。 (#59) (Tatsuo Ishii) + + + + + + + セグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Pgpool-IIの子プロセスがpool_do_authでセグメント違反になることがありました。 + 原因はMAIN_CONNECTION()がNULLを返すことでした。 + my_main_node_idが不正なノードID 0に設定されていたようですが、これは実際にはダウン状態でした。 + そのため、cp->slots[0]には接続がありませんでした。 + + + この問題はEmond Papegaaijによって報告されました。 + Discussion: [pgpool-general: 9175] + + + + + + + 設定ファイルの解析時に発生するセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 設定値が一重引用符で囲まれていない場合にpgpool.confを解析するときにセグメンテーション違反が発生していました。 + + + このパッチはCarlos Chapiによって作成され、Tatsuo Ishiiによってレビューおよび修正されました。 + + + + + + + MAIN_NODEマクロを使用しないようにセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 一部の関数 (close_idle_connection()、new_connection()、pool_create_cp())では、MAIN*とVALID_BACKENDが不適切な場所で使用されていました。 + MAIN*とVALID_BACKENDは、バックエンドへの現在の接続に対してのみ有効であり、プールされた接続には有効ではありません。 + プールされた接続では、どのバックエンドがメインノードであるか、または稼働中であるかは、バックエンドへの現在の接続と必ず同じであるためです。 + これらのマクロを誤って使用すると、セグメンテーション違反が発生することがありました。 + + + この問題はEmond Papegaaij によって報告されました。 + Discussion: [pgpool-general: 9114] + + + + + + + MAIN_NODEマクロ(実際は pool_virtual_main_db_node_id())を修正しました。 (Tatsuo Ishii) + + + セッションコンテキストがない場合、マクロはREAL_MAIN_NODE_IDに使用されます。 + フェイルオーバー/フェイルバックが発生すると、いつでもREAL_MAIN_NODE_IDが変更される可能性があるため、これは誤りでした。 + + + REAL_MAIN_NODE_ID == my_main_node_id == 1と仮定します。 + その後、フェイルバックにより、REAL_MAIN_NODE_IDは0に変更されます。 + その後、MAIN_CONNECTION(cp)はNULLを返し、これへの参照はセグメンテーションエラーを引き起こします。 + この問題を回避するには、代わりにmy_main_node_idを返すように修正しました。 + + + + + + + show pool_processesで行の説明が2回表示されないように修正しました。(Tatsuo Ishii) + + + processes_reporting()が誤ってsend_row_description()とsend_row_description_and_data_rows()の両方を呼び出していました。 + + + Discussion: [pgpool-hackers: 4471] + + + + + + + 子プロセスでのセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + ネットワークが短時間中断されると、Watchdogが停止し、Pgpool-IIが強制終了する問題を修正しました。 (#823) (Muhammad Usama) + + + ネットワーク監視を有効にすると、Pgpool-IIノードはすべてのネットワークインターフェイスまたは割り当てられたIPアドレスを失った場合に直ちにシャットダウンし、通信できないノードをクラスタからすばやく削除することで追加の保護を提供します。 + + + 問題は、ネットワーク監視が無効になっている場合でも、Pgpool-IIがネットワークブラックアウトイベントに応答していたことです。 + この修正により、ネットワーク監視が有効になっていない場合にネットワーク監視ソケットがオープンされなくなり、不要なシャットダウンが防止されます。 + + + + + + + Watchdogが有効な場合にpgpool resetコマンドが動作しない問題を修正しました。 (Tatsuo Ishii) + + + バグはkeiseoによって報告・問題分析されました。 + Disscussion: [pgpool-hackers: 4465] + + + + + + + psql_scanのクラッシュを修正しました。 (#54) (Tatsuo Ishii) + + + 長いクエリ内の文字列がpsql変数(つまり「:」で始まる)であるかどうかを判別しているときに、psql_scanがクラッシュする問題がありました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントとプログラムソースコードの大量なタイポミスを修正しました。(Tatsuo Ishii) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + フェイルオーバーのドキュメントを改良しました。(Tatsuo Ishii) + + + が有効な場合のフェイルオーバーの条件を明確にしました。 + + + + + + + 仮想IP関連パラメータのデフォルト値をドキュメントに追加しました。(Bo Peng) + + + + + + + + + リリース 4.3.10 + + リリース日 + 2024-05-16 + + + + 不具合修正 + + + + + -Werror=implicit-function-declarationオプションで発生するコンパイルエラーを修正しました。(Bo Peng) + + + 非推奨のldap関数のプロトタイプを含めるためにLDAP_DEPRECATEDを追加しました。 + また、autoconfチェックで不足していたヘッダーファイルを追加しました。 + + + パッチはVladimir Petkoによって作成されました。 + + + + + + + セグメンテーション違反のさまざまな原因を修正しました。(Tatsuo Ishii) + + + フェイルオーバーが関与している特定のケースでは、Pgpool-IIとその子プロセスのセグメント違反が発生していました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + 初期化されていないメモリエラーを修正しました。(Tatsuo Ishii) + + + read_startup_packetの初期化されていないメモリエラーを含むいくつかのエラーがvalgrindによって報告されました。 + valgrindは、キャンセルまたはSSL要求の場合にpallocを使用してスタートアップパケット内のユーザー名にメモリを割り当て、その後、そのメモリがpstrdupによって使用されます。 + pallocによって割り当てられたメモリは未定義であったため、これをpalloc0に修正しました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + load_balance_modeがオフの場合に発生するエラー/ハングアップを修正しました。(Tatsuo Ishii) + + + load_balance_modeがオフで、プライマリノードIDが0でない場合には、BEGINなどクエリでエラー/ハングアップが発生していました。 + コミット 3f3c1656の修正によって導入された問題です。 + + + バグはEmond Papegaaijによって発見・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + 特定のCFLAGSによるコンパイルエラーを修正しました。(Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42によって報告されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + サンプルpgpool.conf内のコメントを修正しました。(Bo Peng) + + + sr_check_periodのデフォルト値は10秒であるため、修正しました。コメント内のいくつかのタイポも修正しました。 + + + パッチはhiroinによって作成され、Bo Pengによって修正されました。 + + + + + + + 拡張クエリが終了していない場合でもリセットクエリを実行できるようにしました。(Tatsuo Ishii) + + + コミット240c668dが原因で、拡張クエリメッセージが終了していない場合、リセットクエリが失敗していました。 + このコミットでは、SimpleQuery()でリセットクエリを実行しているかどうかをチェックすることで、この問題を修正しました。 + また、テストケースも追加しました。 + + + + + + + Coverityによって指摘されたメモリリークを修正しました。(Takuma Hoshiai) + + + + + + + 不適切なプロトコルデータから保護するように修正しました。(Tatsuo Ishii) + + + 拡張クエリメッセージのシーケンスが終了する前にシンプルクエリメッセージが到着すると、Pgpool-IIがハングする可能性がありました。 + これは、シンプルクエリのセッションコンテキスト内のクエリコンテキストが、拡張クエリメッセージのクエリコンテキストによって上書きされたためです。 + + + このコミットでは、拡張クエリプロトコルメッセージが終了したかどうかをチェックするように実装しました。 + 終了していない場合は、FATALエラーを発生させます。このチェックによって検出された既知の例は、JDBCドライバーの「autosave=always」オプションです。 + つまり、このコミットの後、問題(拡張クエリメッセージプロトコルが終了する前にシンプルプロトコルメッセージを送信する)がJDBCドライバー側で修正されるまで、 + Pgpool-IIはこのオプションを受け入れません。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + ドキュメント修正 + + + + + + 「上位サーバへの接続」ドキュメントを改善します。(Bo Peng) + + + + + + + 日本語ドキュメントの言語クリーンアップしました。(Masaya Kawamoto) + + + + + + + PostgreSQLノードが2台の場合にpcp_promote_nodeを使用する際の注意点を追加しました。(Masaya Kawamoto) + + + PostgreSQLノードが2台であっても、follow_primary_commandを設定する必要があるケースがあります。 + + + + + + + + 回帰テスト修正 + + + + + + Java 21での非推奨警告を回避するために回帰テスト005.jdbcを修正しました。(Bo Peng) + + + Java 21での非推奨警告を回避するには、Runtime.exec(String)をRuntime.exec(String[])に置き換えました。 + + + パッチはVladimir Petkoによって作成され、Bo Pengによって修正されました。 + + + + + + + + + リリース 4.3.9 + + リリース日 + 2024-02-29 + + + + 変更点 + + + + + サンプルスクリプトからrestore_commandの設定を削除しました。 (Bo Peng) + + + レプリケーションスロットが有効になっているため、restore_commandは不要です。 + この設定により、フェールオーバーが失敗するケースがあるからです。 + + + + + + + 不具合修正 + + + + + , + および + のデフォルト値を修正しました。 (Bo Peng) + + + recovery_userデフォルト値はと同じである必要があるため、 + デフォルト値を''から'nobody'に変更しました。 + + + failover_on_backend_shutdownの正しいデフォルト値は「false」、 + insert_lockの正しいデフォルト値は「on」であるため、修正しました。 + + + + + + + BEGINなどでのの不具合を修正しました。 (Tatsuo Ishii) + + + statement_level_load_balanceが有効な場合、 + が無効であっても、 + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE ALL/DISCARDがプライマリノードとすべてのスタンバイノードに送信されていました。 + これは明らかに間違っているだけでなく、スタンバイノードの1つがリモートネットワークにある場合、速度が低下する原因となります。 + + + load_balance_modeがオフの場合、 + Pgpool-IIはそのようなクエリをプライマリノードにのみ送信するように修正しました。 + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + ドキュメント修正 + + + + + 日本語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + Watchdog「リーダー」ではなく「マスター」を誤って使用していました。 + + + + + + + 英語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + PostgreSQL「プライマリ」ではなく「メイン」を誤って使用していました。 + + + + + + + + リリース 4.3.8 + + リリース日 + 2023-11-30 + + + + 変更点 + + + + + 大文字のホスト名をサポートするようにサンプルスクリプトのレプリケーションスロット名の変換処理を変更しました。(Bo Peng) + + + フェイルオーバやオンラインリカバリの時に実行されるスクリプトで、自動的にレプリケーションスロットを削除/作成しています。 + レプリケーションスロット名には大文字を使用できないため、ホスト名を小文字に変換するようにこれらのスクリプトを修正しました。 + + + パッチはSheikh Wasiu Al Hasibによって作成され、Bo Pengによって修正されました。 + + + + + + + パラメータ用のサンプルスクリプトescalation.sh.sampleでSSH接続時のタイムアウト時間を指定するようにしました。(Bo Peng) + + + + + + + 不具合修正 + + + + + 不要なログ行を削除しました。(Tatsuo Ishii) + + + デバッグメッセージ「unset_tx_started_by_multi_statement_query is called in CommandComplete」が誤って残っていました。 + + + + + + + DECLAREによって作成されたポータルでアボートしないようにDescribe()を修正しました。(Tatsuo Ishii) + + + DECLARE foo CURSOR FORを実行すると、PostgreSQLによって「foo」という名前のポータルが自動的に作成されます。 + このポータルはPgpool-IIによって管理されないため、Describe fooメッセージは「unable to execute Describe. unable to get the bind message」エラーで失敗していました。 + + + これを修正するため、Describe()でダミーの書き込みクエリコンテキストを作成し、Describeメッセージをプライマリ(ストリーミングレプリケーションモード)またはすべてのノード(レプリケーション/スナップショットアイソレーションモード)に送信するようにしました。 + + + 新たなテストケース080も追加しました。 + + + この問題はHeather Lapointeによって報告・分析されました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + NAMEDATALENの重複定義を削除しました。(Tatsuo Ishii) + + + src/include/pg_config_manual.hのみでNAMEDATALENを定義するようにしました。 + また、src/utils/pool_select_walker.c内のPOOL_NAMEDATALENNAMEDATALENに置き換えました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + ドキュメント修正 + + + + + PCPがすべてのアドレスをリッスンするにはpcp_listen_addresses = '*'の設定が必要である旨を「Pgpool-II + Watchdogの構築の例」に記載しました。 + + + + + + + のドキュメントを修正しました。(Tatsuo Ishii) + + + 実際のバックエンドのステータスは、pg_isreadyではなくPQpingParamsを使用して取得しています。 + + + + + + + のドキュメントの説明を強化しました。(Tatsuo Ishii) + + + を使用しない場合は、の実行が必要である旨を記載しました。 + + + + + + + 回帰テスト修正 + + + + + pgpool_setupを強化しました。(Tatsuo Ishii) + + + フェイルオーバスクリプトおよびフォロープライマリスクリプトでより適切なログを出力できるようにpgpool_setupを改善しました。 + + + + + + + + リリース 4.3.7 + + リリース日 + 2023-08-17 + + + + 変更点 + + + + + 共有メモリの初期化後にのみ、システム終了コールバックを呼び出すようにしました。(Muhammad Usama) + + + 共有メモリの取得に失敗して、終了時コールバックが呼び出された場合、クリーンアップ関数は、共有メモリに存在するprocess_infoにアクセスする際にセグメンテーション違反を引き起こす可能性がありました。 + process_infoがNULLのときに終了コールバックからの中断で修正することもできますが、共有メモリの初期化に成功した後に関数をインストールする方がより良いアプローチです。 + なぜなら、システムの残りの部分は常にprocess_infoがNULLになることはないと想定しており、また、子プロセスが生成される前にクリーンアップをする必要はないからです。 + + + + + + + 一部のシステムカタログ照会関数にスキーマ修飾を追加しました。(Tatsuo Ishii) + + + + + + + 不具合修正 + + + + + Coverityの警告を修正しました。(Tatsuo Ishii) + + + クエリキャッシュのモジュールで、time_tの値がint32変数に割り当てられる問題を修正しました。 + Coverityの指摘に従いまして、変数の型をint64に変更しました。 + また、time_tの差分を計算するためにdifftime()を使用しました。これは推奨される方法です。 + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + find_primary_node_repeatedlyが指定時間内で終了しない問題を修正しました。(Bo Peng) + + + + + + + v2プロトコルを利用する場合のクラッシュを修正しました。(bug 807)(Tatsuo Ishii) + + + read_kind_from_backend()で統計データを蓄積する際、v2プロトコルのケースには対応していませんでした。 + + + MCanivezからバグ報告とパッチを提供いただきました。 + + + + + + + マルチステートメントにおけるPREPAREの利用を修正しました。(Tatsuo Ishii) + + + マルチステートメントの二番目以降の位置にPREPAREが含まれている場合、その後のbindメッセージでプリペアドステートメントを利用すると、送信されたメッセージにプリペアドステートメントが保存されな +いため、「unable to bind」エラーが発生していました。 + + + この問題を修正するために、ステートメントを解析した後にそのようなケースが見つかった場合、名前付きステートメントのクエリコンテキストを作成し、送信メッセージのリストに追加するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + この修正のため、リグレッションテスト079..multi_prepareを追加しました。 + + + + + + + pgprotoをパラメータを使用するbindメッセージを処理できるようにしました。(Tatsuo Ishii) + + + 以前、pgprotoはパラメータを持たないbindメッセージしか処理できませんでした。 + + + + + + + サンプルスクリプトreplication_mode_recovery_2nd_stage.sample内の変数名が間違っていたため修正しました。(Bo Peng) + + + + + + + ドキュメント修正 + + + + + loggerプロセスのアプリケーション名記載漏れを修正しました。(Bo Peng) + + + + + + + 停止モードの意味を明確にしました。(Tatsuo Ishii) + + + + + + + 4.2.10リリースノートにあった誤った情報を削除しました。(Bo Peng) + + + 「pgpool_recovery拡張のスクリプトを修正しました。 (Tatsuo Ishii)」の記載を削除しました。 + + + + + + + 「8.2. Pgpool-II + Watchdogの構築の例」のSSH公開鍵認証の説明を補足しました。(Bo Peng) + + + + + + + 負荷分散章の説明を修正しました。(Tatsuo Ishii) + + + 一部の文章で「ストリーミングレプリケーションモード」と記述されるべきの箇所が「ネイティブレプリケーションモード」となっていました。 + また、ストリーミングレプリケーションモードにおける負荷分散の追加要件に関する説明を改善しました。 + いくつかのインデックスを追加しました。 + + + + + + + オンラインリカバリーの説明を改善しました。(Bo Peng) + + + 複数のpgpoolノードでwatchdogが有効になっていない場合、オンラインリカバリーのセカンドステージが適切に機能しないことについて言及しました。 + + + + + + + 回帰テスト修正 + + + + + 時折発生する069.memory_leak_extendedテストの失敗を修正しました。(Tatsuo Ishii) + + + 偶発するテストの失敗の原因は、pgbenchが終了した後にpsコマンドを実行する前にpgpoolの子プロセスが消えてしまうことにあると判明しました。 + これにより、「DISCARD ALL cannot be executed within a pipeline」というkind mismatchのFATALエラーが発生していました。 + これを修正するために、pgbenchをバックグラウンドで実行し、pgbenchが終了する前にプロセスのサイズを取得するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + リリース 4.3.6 + + リリース日 + 2023-05-18 + + + + 変更点 + + + + + マルチステートメントのクエリを判定するために、psqlscanのソースコードをPgpool-IIにインポートしました。(Tatsuo Ishii) + + + psqlscanは、PostgreSQLソースツリー内のモジュールです。 + これは本質的にPostgreSQL SQLスキャナのサブセットですが、各SQLステートメントの終わりの検出に特化しています。 + したがって、これを使用してクエリ文字列内のSQLステートメントの数をカウントできます。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + 複数のステートメントを幅広く使用できるようにしました。 (Tatsuo Ishii) + + + このコミットは、複数のステートメント (マルチステートメント) に関するPgpool-IIの長年の制限を排除しました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + 内部クエリでスキーマ修飾を使用するように変更しました。(Tatsuo Ishii) + + + 関数やキャストなどの一部のオブジェクトは、「pg_catalog.」スキーマ修飾を使用していませんでした。 + これによって直ちにセキュリティ上の懸念が生じるわけではありませんが、スキーマ修飾を使用することは常に良い習慣ですので、変更しました。 + + + + + + + 不具合修正 + + + + + 共有リレーションキャッシュで発生しうるデッドロックを修正しました。(Tatsuo Ishii) + + + ユーザー定義関数がテーブルロックを取得する場合、拡張クエリプロトコルを使用して関数を呼び出すとデッドロックが発生する可能性がありました。 + 以下にシナリオを示します。 + + + + (1) セッション中クライアントはparse、bind、executeリクエストをpgpoolに送信します。 + + + + + + + (2) セッションAのPgpool-IIはリクエストをPostgreSQLに転送します。 + + + + + + + (3) セッションAのPostgreSQLがexecuteを実行し、テーブルロックが発生します。 + + + + + + + (4) セッションBで、クライアントは関数のparse、bind、executeリクエストをpgpoolに送信します。 + + + + + + + (5) セッションBのPgpoolはリクエストをPostgreSQLに転送します。 + + + + + + + (6) セッションBのPostgreSQLはbindを実行しますが、テーブルはセッションAのPostgreSQLによってすでにロックされており、ロックの解放を待ちます。 + + + + + + + (7) セッションBのpgpoolはexecuteをPostgreSQLに転送した後、関数の揮発性をチェックするために共有リレーションキャッシュを検索するためのセマフォを取得します。 + 次に、do_queryを呼び出し、フラッシュメッセージをPostgreSQLに送信して、この時点までのPostgreSQLからの応答を取得します。 + ただし、#6ではPostgreSQLがテーブルロックを待機しているため、pgpoolはバインド完了後のメッセージを待つ必要があります。 + + + + + + + (8) セッションAのpgpoolがPostgreSQLにexecuteを転送した後、関数の揮発性をチェックするために共有リレーションキャッシュを検索しセマフォを取得しようとしましたが、セマフォはセッションBのpgpoolによってすでに取得されているため、セマフォの解放を待ちます。 + + + + + + + (9) セッションAとセッションBがお互いを待機するため、デッドロックが発生します。 + + + + + + これを修正するには、do_query()を呼び出す前にセマフォを解放するようにpool_search_relcache()を変更しました(ただし、セマフォはdo_query()の後に取得します)。 + これにより、上記#8のセッションAはセマフォを取得し、先に進むことができます。 + クライアントからsyncメッセージを受信し、PostgreSQLに転送します。 + syncを受信すると、ユーザ定義関数は実行を終了し、テーブルロックを解放します。 + これにより、セッションBのPostgreSQLがテーブルロックを取得できるようになります。 + + + + + + + の不具合を修正しました。(bug 798) (Tatsuo Ishii) + + + クライアントがPgpool-IIに接続すると、スタンバイの1つがロードバランシングノードとして選択されます。 + セッションの継続中にスタンバイ遅延がdelay_thresholdを超えた場合、prefer_lower_delay_standbyは遅延が最小のスタンバイノードを新しいロードバランシングノードとして選択し、ターゲットバックエンドをそのノードに設定します。 + 残念ながら、SELECTクエリに書き込み機能などが含まれているかどうかを確認する前に決定が下されたため、Pgpool-IIはスタンバイで実行できないSELECTを送信していました。 + これを修正するために、prefer_lower_delay_standbyの処理を書き込み関数等のチェック後に移動しました。 + + + また、上記のケースを含めるように033.prefer_lower_standby_delay回帰テストも修正しました。 + + + + + + + musl libcを使用するシステムでのコンパイルエラーを修正しました。(bug 790) (Tatsuo Ishii) + + + パッチはleimaohuiによって提供されました。 + + + + + + + 複数のクエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + 特殊なケースでsrワーカーが間違ったクエリをスタンバイサーバに送信する不具合を修正しました。(Tatsuo Ishii) + + + ALWAYS_PRIMARYフラグが設定されている場合、PRIMARY_NODE_IDマクロは、プライマリがダウンしている場合でも、-1ではなくノードIDを返していました。 + この場合、ストリーミングレプリケーション遅延をチェックするワーカープロセスは、PostgreSQLのバージョンに応じてSELECT pg_current_wal_lsn()またはSELECT pg_current_xlog_location()をスタンバイに送信し、当然エラーが発生していました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + DEALLOCATEによる種類不一致エラーを修正しました。 + (bug 780) (Tatsuo Ishii) + + + 以下の条件がすべて満たされた場合、種類不一致エラーが発生していました。 + + + + ストリーミングレプリケーションモード + + + + + + + ロードバランスノードがプライマリ以外のノード + + + + + + + PREPAREがマルチステートメントクエリで使用されている + + + + + + + + + + 回帰テストのコンパイルエラーを修正しました。(Takuma Hoshiai) + + + gcc10を使用したタイムスタンプテストでエラーが発生していました。 + + + + + + + show pool_versionで行の説明が2回表示される問題を修正しました。(Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + の説明を追加しました。(Chen Ningwei) + + + + + + + PREPARE/EXECUTE/DEALLOCATEに関する制限を追加しました。(Tatsuo Ishii) + + + + + + + Pgpool-IIで-Dオプションを使用する場合の注意点を追加しました。(Tatsuo Ishii) + + + + + + + 「RPMからのインストール」セクションを強化しました。(Bo Peng) + + + + + + + 「サーバの準備と運用」の章に「PostgreSQLデータベースのバックアップ」セクションを追加しました。(Tatsuo Ishii) + + + + + + + 「Pgpool-II + Watchdogの構築の例」から「-D」起動オプションの設定を削除しました。(Bo Peng) + + + + + + + 「制限事項」セクションを修正しました。(Tatsuo Ishii) + + + + + + SCRAM-SHA-256認証に関する記述を追加 + + + + + + + スナップショットアイソレーションモードに関する記述を追加 + + + + + + + + + + PostgreSQLノードのステータスが「unknown」と表示される場合の説明を追加しました。(Tatsuo Ishii) + + + + + + + 実行時に、プロモートするターゲットノードが稼働中の必要であることを記載しました。(Tatsuo Ishii) + + + + + + + AES256をサポートするにはオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + .pcppassを使用するには、pcpコマンドの-wオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + 「2.8 insert_lockテーブルの作成」セクションを修正しました。(Tatsuo Ishii) + + + スナップショットアイソレーションモードについても言及する必要があったのに、ネイティブレプリケーションモードについてのみ言及していました。 + + + + + + + を強化しました。(Tatsuo Ishii) + + + + + + + Test Tools + + + + + 設定ファイルの末尾にいくつかのパラメータを追加するようにpgpool_setupを修正しました。(Bo Peng) + + + + + + + 回帰テスト修正 + + + + + 071.execute_and_deallocate/test.shをリファクタリングしました。(Tatsuo Ishii) + + + + + + + いくつかの回帰テストを強化しました。(Tatsuo Ishii) + + + + + + + 時折発生する005.jdbcテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.3.5 + + リリース日 + 2023-01-23 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + 以下の条件をすべて満たす場合、コマンドによりのパスワードが公開されます。このコマンドは、Pgpool-IIに接続できるすべてのユーザーが実行できます。(CVE-2023-22332) + + + + + + バージョン3.3以降 + + + + + + onに設定されている + + + + + + queryが設定されている + + + + + + にプレーンテキストのパスワードが設定されている + + + + + + 上記条件のすべてに該当するユーザは、このバージョンにアップグレードするか (show pool_statusコマンドでが表示されなくなる)、次の回避策のいずれかを使用することを強くお勧めします。 + + + + 4.0.x~4.4.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + には空文字を設定し、パスワードはpool_passwdファイルに設定する。 + + + + + + にAESで暗号化したパスワードを設定する。 + + + + + + いずれにせよ、PostgreSQLでを変更することをお勧めします。 + + + + 3.3.x~3.7.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + いずれにせよ、PostgreSQLを変更することをお勧めします。 + + + + Pgpool-II 3.7.xおよび以前のバージョンはサポートが終了しているため、これらのバージョンのマイナーアップデートはリリースされません。 + + + + + 変更点 + + + + + + およびコマンドでwd_lifecheck_passwordを表示しないように修正しました。(CVE-2023-22332) (Bo Peng) + + + + + + + ドキュメントに記載されているように、のデフォルト値を空の文字列に変更しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + pgpool-regclass.cのコンパイラ警告を修正しました。(Florian Weimer, Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + 共有メモリ使用時の設定の章のいくつかの誤りを修正し、説明を強化しました。(Tatsuo Ishii) + + + + + + + + + リリース 4.3.4 + + リリース日 + 2022-12-22 + + + + 変更点 + + + + + + ログメッセージ"new IPC connection received"をDEBUG1にダウングレードしました。 + (bug 775) (Bo Peng) + + + これは通常のメッセージで、LOGとして記録されるべきではありません。 + パッチはpstefによって作成され、Bo Pengによってレビューされました。 + + + + + + + + 不具合修正 + + + + + + の問題を修正しました。(Muhammad Usama) + + + Watchdogクラスタ全体のヘルスチェックパラメータの最大値に基づいて、フェイルオーバコマンドのタイムアウトを動的に設定するように修正しました。 + + + Tatsuo Ishiiによってレビューおよびテストされました。 + 議論: [pgpool-hackers: 4227] + + + + + + + アボートされたトランザクション内でROLLBACK TOコマンドが動作するように修正しました。(Tatsuo Ishii) + + + コミット: eea522ebfcf791a623e865deaa1aa6fb59e3c50b + によってアボートされたトランザクション内の問題が修正され、COMMIT/ROLLBACK以外のSQLコマンドがバックエンドに転送されないようにしました。 + しかし、ROLLBACK TOコマンドが漏れていました。 + その結果、ROLLBACK TOコマンドが発行されても、コマンドはバックエンドに転送されず、 + トランザクションはアボートされた状態のままになります。 + このコミットが入った4.3までさかのぼってパッチを適用しました。 + + + 議論: [pgpool-general-jp: 1716] + + + + + + + パーサ内でバックスラッシュを使った場合の警告を出力しないように修正しました。(Tatsuo Ishii) + + + standard_conforming_strings = offかつescape_string_warning = onの場合、PostgreSQLは文字列リテラル内でバックスラッシュを使った場合に警告を出力します。 + これは問題ありません。 + しかし、以前はPgpool-IIのパーサも同じメッセージを出力していました。 + これは冗長です。 + + + + + + + idle_session_timeoutに対応しました。(Tatsuo Ishii) + + + idle_session_timeout (PostgreSQL 14 で追加)が有効、かつ、タイムアウトが発生した場合、次のことが発生します: + + + + failover_on_backend_errorがon (デフォルト)の場合、Pgpool-IIはフェイルオーバを発生させます。 + + + + + + + PostgreSQL サーバが 1 台のみが idle_session_timeout を有効にしていると、Pgpool-II がハングする可能性があります。 + + + + + + idle_session_timeoutに対応するため、エラーコードを検出するdetect_idle_session_timeout_error()を追加しました。 + エラーを検出すると、Pgpool-II は致命的なエラーとしてフロントエンドにエラーコードを返し、セッションを切断します。 + これはidle_in_transaction_session_timeoutの実装と同じような修正です。 + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + 議論: [pgpool-hackers: 4208] + + + + + + + SSLエラーSSL_ERROR_ZERO_RETURNに対応しました。(Tatsuo Ishii) + + + 以前はこれによってフェイルオーバが発生しましたが、サーバは単に接続を閉じることを意味するため、実際には不要でした。 + + + 議論: [pgpool-general: 8366] + 議論: [pgpool-hackers: 4193] + + + + + + + メモリキャッシュサイズを2GBより多く設定した場合に発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + 問題は与えられたキャッシュブロックのメモリアドレスを返す block_address()関数にあり、 + 2GB上限まで有効な共有メモリ空間内のブロックのオフセットを計算するために32bit整数を使っていました。 + + + + + + + pcp_proc_infoSHOW pool_poolsおよびSHOW pool_processes内のまれなセグメンテーション違反を修正しました。(Tatsuo Ishii) + + + セグメンテーション違反はget_pools()とget_processes()にありました。 + それらは、最初に共有メモリ上の特定のプロセス情報スロットのpidを抽出し、次にキーとして pid を使ってスロットを再び検索していました。 + これらのステップはロックによって保護されていなかったため、プロセス終了時に新しい子プロセスのフォークを担う親プロセスによって pid が上書きされた場合、 + pid を使った検索が失敗し、NULLを返す可能性がありました。 + その結果、それに続くNULLポインタの参照によってセグメンテーション違反が発生していました。 + + + 解決策は、最初にプロセス情報スロットへのポインタを取得し、次にポインタからpidメンバを抽出することです。 + この方法でも、親プロセスによる共有メモリ情報の同時更新は可能ですが(出力におかしな結果をもたらす可能性があります)、少なくともセグメンテーション違反は回避できます。 + + + + + + + 無効な長さのUnixドメインソケットパスを使えないように修正しました。(Masaya Kawamoto) + + + + + + + + ドキュメント修正 + + + + + + Doc: Aurora設定例内のタイポを修正しました。(Tatsuo Ishii) + + + + + + + Doc: 制限事項のセクションを拡充しました。(Tatsuo Ishii) + + + pg_terminate_backendによって発生する不要なフェイルオーバを回避するため、 + failover_on_backend_shutdownが使えることに言及しました。 + + + + + + + Doc: memqcache_methodの説明を拡充しました。(Tatsuo Ishii) + + + どの方式を使うべきかの説明を追加しました。 + + + + + + + Doc: ヘルスチェックプロセスでSSLが使えることに言及しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションのチェックでもSSLが使えることに言及しました。 + これは2010年以降に使えていたはずです。 + + + 議論: [pgpool-hackers: 4187] + + + + + + + + 回帰テスト修正 + + + + + + 環境変数を使ってPGPOOLDIRを定義できるようにしました。 + (bug 766) (Bo Peng) + + + + + + + + + リリース 4.3.3 + + リリース日 + 2022-08-18 + + + + 変更点 + + + + + + サンプルスクリプトで指定するrestore_commandにsshオプションを追加しました。(Bo Peng) + + + パッチはJon SCHEWEによって作成され、Bo Pengによって更新されました。 + + + + + + + サンプルスクリプトを更新しました。(Bo Peng) + + + + レプリケーションスロットを作成/削除するときの接続データベース名をpostgresにしました。 + + + + + + + sshログインユーザとssh鍵ファイルを変数で指定するようになりました。 + + + + + + + + + + CloseCompleteを受け取った時、バッファリングなしでフロントエンドに転送するようになりました。(Tatsuo Ishii) + + + 074.bug700_memqcache_segfaultで時折タイムアウトエラーが発生していました。 + + + + + + + 不具合修正 + + + + + + pgpool_recovery拡張のスクリプトを修正しました。(Tatsuo Ishii) + + + + + + + クエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + + Pgpool-IIは"Select '2022-02-18 07:00:00.006547'::timestamp"のような問合せをキャッシュしていませんでした。 + TIMESTAMP、TIME、DATEを含むSELECT文はキャッシュされるようになりますが、TIMESTAMPZ、TIMEZを含むSELECT文は"SET TIME ZONE"コマンドなどで結果が変更されるためキャッシュされません。 + また、TIMESTAMPZやTIMEZ型を返す関数を含むSELECT文も同様の理由でキャッシュされません。 + Discussion: [pgpool-general: 8285] + + + + + + + + スナップショットアイソレーションモードで、internal transactionの取り回しにおける不具合を修正しました。(Tatsuo Ishii) + + + + + + + + ドキュメント修正 + + + + + + Doc: 特定のSELECT文がキャッシュされないことに言及しました。(Tatsuo Ishii) + + + 特定のSELECT文は以下です。 + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を使っているSELECT + + + + + TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEへのキャストを含むSELECT + + + + + SQLValueFunction (CURRENT_TIME, CURRENT_USERなど)を含むSELECT + + + + + + + + + + Doc: Unixドメインソケット接続するときのPCPパスワードファイルの使用についての説明を修正しました。(Masaya Kawamoto) + + + pcppassファイルのlocalhostエントリはデフォルトのPCPソケットディレクトリパスへの接続とのみマッチして、全てのUnixソケット接続には使用されません。 + この振る舞いはpgpassファイルと同じです。 + + + + + + + Doc: 必要メモリの説明を修正し、詳細にしました。(Tatsuo Ishii) + + + + + + + pgpoolの子プロセスが動作する間のメモリ使用についての説明を追加しました。 + + + + + + より正確な結果を計算できるように、必要共有メモリを計算する式を詳細にしました。 + + + + + + インメモリクエリキャッシュ用の共有メモリ量を修正しました。64MBは誤った値でした。 + + + + + + 必要プロセスメモリを修正しました。以前の式はRSSを基にしていましたが、RSSはライブラリに使用されるメモリなどの共有メモリも含むため、PSSを使用するべきです。 + これによって以前より要求メモリが大幅に減少します。 + + + + + + + + + + Doc: の誤った説明を修正しました。(Tatsuo Ishii) + + + これらのパラメータは設定ファイルの再読み込みでは変更できず、Pgpool-IIの再起動が必要です。 + + Discussion: [pgpool-general: 8195] + + + + + + + + テストツール修正 + + + + + + PostgreSQL 15でpgpool_setupを実行できるようになりました。(Tatsuo Ishii) + + + ticket 757を参照ください。 + + + + + + + pgpool_setupはRPMに含まれるサンプルスクリプトとサンプルの設定ファイルをテストできるようになりました。(Bo Peng) + + + + + + + + 回帰テスト修正 + + + + + + Test: 回帰テストでPgpool-IIのバージョンを表示するようになりました。(Tatsuo Ishii) + + + + + + + Test: 適切なinstall directoryでpgpool.confを探すように回帰テストスクリプトを修正しました。(Tatsuo Ishii) + + + + + + + + + + リリース 4.3.2 + + リリース日 + 2022-05-19 + + + + 変更点 + + + + + Pgpool-IIメインプロセスの停止を強化しました。(Tatsuo Ishii) + + + 「pgpool stop」が一定期間(現在5秒)以内にメインプロセスを終了できなかった場合は、信号を再送信するように修正しました。 + + + + + + + 失敗したトランザクション中にセッションを中止しないように修正しました。(Tatsuo Ishii) + + + 明示的なトランザクションが失敗した場合、commitまたはrollbackコマンドが実行されるまで、 + 後続のコマンドは無視する必要があります。 + ただし、relcache検索が発生した場合、Pgpool-IIはセッションを中止することがありました。 + + + Discussion: [pgpool-general: 8096] + + + + + + + コマンドのPIDの長さを7文字に変更しました。(Bo Peng) + + + + + + + Parseメッセージ処理のエラーメッセージにメッセージの種類、バックエンドノードIDを含めるように改善しました。(Tatsuo Ishii) + + + + + + + ParameterStatusメッセージのログレベルをLOGからDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + のデフォルト値を「*」から「localhost」に変更しました。(Tatsuo Ishii) + + + + + + + のフィールド名を変更しました。(Muhammad Usama) + + + + + + + RPMパッケージでデフォルトでに関連するパラメータを有効にしました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + lost状態のリモートPgpool-IIノードが再起動後にクラスタに再参加できない問題を修正しました。(Muhammad Usama) + + + 報告: [pgpool-general: 7896] + + + + + + + 無限待機の可能性を回避するために、Pgpool-IIメインプロセスのexit_handlerを修正しました。(Tatsuo Ishii) + + + + + + + Pgpool-IIのプロセス情報を取得する処理の不具合を修正しました。(Tatsuo Ishii) + + + + + + + 共有メモリの割り当て関数の潜在的な不具合を修正しました。(Tatsuo Ishii) + + + + + + + 「-i」オプションを使用する場合のおよびの不具合を修正しました。(bug 747)(Tatsuo Ishii) + + + + + + + %mに不要な情報が含まれないように修正しました。(Tatsuo Ishii) + + + + + + + プライマリ検索中にバックエンドが失敗またはシャットダウンした場合にPgpool-IIのメインプロセスが終了してしまう問題を修正しました。(Tatsuo Ishii) + + + + + + + Watchdogで発生するセグメンテーション違反を修正しました。(Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + private_backend_statusで管理されているバックエンドノードのステータスと共有メモリのバックエンドノードのステータスが一致しない場合にフェイルオーバ要求が拒否される問題を修正しました。 (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4127] + + + + + + + pg_isreadyを使用してPostgreSQLのステータスを確認するようにfollow_primary.sh.sampleを修正しました。(Bo Peng) + + + + + + + + ドキュメント修正 + + + + + Doc: Kubernetesの設定例をgithubのリポジトリに移動しました。(Bo Peng) + + + + + + + Doc: 設定例を更新しました。(Masaya Kawamoto) + + + + + + + Doc: pcp_watchdog_infoの出力例を更新しました。(Bo Peng) + + + + + + + Doc: pg_encの引数として「$」文字を含むパスワードを指定する場合は、エスケープする必要があることを注意事項に追加しました。(Bo Peng) + + + + + + + + 回帰テスト修正 + + + + + タイムアウトエラーを回避するために、リグレッションテスト018.detach_primaryを強化しました。(Tatsuo Ishii) + + + + + + + タイムアウトエラーを回避するために、リグレッションテスト074.bug700_memqcache_segfaultを強化しました。(Tatsuo Ishii) + + + + + + + セグメンテーション違反を検出するようにテストスクリプトを改善しました。(Bo Peng) + + + + + + + リグレッションテスト077.invalid_failover_nodeのタイムアウトを増やしました。(Tatsuo Ishii) + + + + + + + + + リリース 4.3.1 + + リリース日 + 2022-02-17 + + + + 変更点 + + + + + + in_hot_standbyによるメッセージ長の違いに関する不要なログを抑制しました。(Tatsuo Ishii) + + + PostgreSQL 14 は新しいパラメータを導入しました: in_hot_standby + + + この値はスタンバイサーバの場合は "on" で、プライマリサーバの場合は "off" になります。 + その結果 pgpool のログは以下のメッセージで溢れていました。 + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + これを防ぐために、パラメータ名がin_hot_standbyでない場合にのみログを出力するようになりました。 + + + また、メッセージにパラメータ名を表示するようになりました。例を示します。 + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + のデフォルト値を変更しました。(Tatsuo Ishii) + + + log_line_prefixのデフォルト値を "%t pid: %p" から "%m %a pid: %p" にしました。 + Discussion: [pgpool-hackers: 4097] + + + + + + + の形式の検査を追加しました。(Masaya Kawamoto) + + + wd_lifecheck_passwordrecovery_passwordはmd5ハッシュ形式を使用できませんが、pgpool は認証失敗を報告するだけでそれらのチェックをしていませんでした。 + + + + + + + パラメータステータスの取り扱いを変更しました。(Tatsuo Ishii) + + + バックエンドからパラメータステータスのメッセージが届いたときにただメモリー上に記憶するだけでなく、フロントエンドに転送するようになりました。 + + + + + + + + 不具合修正 + + + + + + pgpool_remote_start.sampleスクリプトを修正しました。(Bo Peng) + + + + + + + パラメータ名wd_initial_node_showup_timeに修正しました。(Bo Peng) + + + ドキュメントとは異なり、ソースコードではwd_initial_node_showup_timeとして記述されていました。 + + + + + + + pgpool-recovery SQLスクリプトの小さなミスを修正しました。(Muhammad Usama) + + + + + + + バックエンドに接続できないときにpcp_node_infoがハングアップする不具合を修正しました。(Tatsuo Ishii) + + + 報告とパッチレビューはEmond Papegaaijによって提供されました。 + Discussion: [pgpool-general: 7983] + + + + + + + pcp_node_infoの実行の際に長時間待機する不具合を修正しました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Coverityによって見つかったヘルスチェックプロセスの問題を修正しました。(Tatsuo Ishii) + + + + + + + Coverityによって見つかったメモリリークを修正しました。(Tatsuo Ishii) + + + + + + + プライマリノードが存在しない場合の対処をするようにfailover()を修正しました。(Tatsuo Ishii) + + + プライマリノードが存在しない場合に pgpool が起動したときなどReq_info->primary_node_idが -1 である場合にfailover()find_primary_node_repeatedly()の呼び出しをスキップしていました。 + また、follow_master_commandも実行されませんでした。 + + + Discussion: [pgpool-hackers: 4113] + + + + + + + failover スクリプトのサンプルを修正しました。(Bo Peng) + + + old primary node id が"-1"の場合を考慮していませんでした。 + + + + + + + バックエンドに接続できないときにストリーミングレプリケーションチェックプロセスがリトライしないように修正しました。(bug 742)(Bo Peng) + + + このリトライによってフェイルオーバに時間がかかっていました。 + + + + + + + + ドキュメント修正 + + + + + + 英語マニュアルと記述を同期しました。(Tatsuo Ishii) + + + + + + + pcp_watchdog_infoマニュアルの誤字を修正しました。(Tatsuo Ishii) + + + + + + + ドキュメントの誤字を修正しました。(pengbo) + + + パッチはUmar Hayatによって提供されました。 + + + + + + + PostgreSQL YUM リポジトリからPgpool-IIがインストールされないように /etc/yum.repos.d/pgdg-redhat-all.repo を"exclude"する設定を追加しました。(Bo Peng) + + + + + + + ParameterStatusin_hot_standbyパラメータに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + set_configに関する制約を追加しました。(Tatsuo Ishii) + + + + + + + + テストツール修正 + + + + + + pgpool_setupが作成するfailoverスクリプトを修正しました。(Tatsuo Ishii) + + + pgpool_setupfailover.shを作成するとき、プライマリサーバが存在しない場合を考慮していませんでした。 + + + + + + + + 回帰テスト修正 + + + + + + 再コンパイルしないで既存のインストールで回帰テストを実行できるようになりました。(Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + テスト075を修正しました。(Tatsuo Ishii) + + + pgpool が起動していなくても成功していました。 + 報告とパッチはQiang Lingjieによって提供されました。 + Discussion: [pgpool-hackers: 4085] + + + + + + + noinstall モード時のpgpool_setupwatchdog_setupのバイナリパスを修正しました。(Bo Peng) + + + + + + + + + + リリース 4.3.0 + + + リリース日 + 2021-12-07 + + + + + 概要 + + + このバージョンには、設定と管理を容易にするために多くの機能拡張が追加されています。 + 動的にwatchdogクラスタのサイズを調整するために、新しくwatchdogにクラスタメンバーシップ機構が導入されました。 + これにより、watchdogノードが停止されたり、接続が切断されたときにもリーダwatchdogノードがquorum/VIPを維持できます。 + 新しいPostgreSQL 14のSQL パーサが取り込まれています。 + また、スナップショットアイソレーションモード を本番環境で使用できるようにしました。 + このモードのための新しい設定例が設定例の章に提供されています + + + + + このバージョンでは、一部の設定パラメータのデフォルト値がより一貫性があり、便利になるように変更されていることに注意してください。 + 詳細については、移行セクションを参照してください。 + + + + + 以下は主な機能拡張です。 + + + + + + + + watchdogノードが削除されたときにもquorum/VIPを維持するために、新しくwatchdogにメンバーシップ機構が導入されました。 + + + + + + + 負荷分散ノードの選択時にレプリケーション遅延が最小のスタンバイノードを選択できるようにしました。 + この目的のために、新しいパラメータが追加されました。 + + + + + + + で昇格するノードIDを指定できるようにしました。 + この目的のために、新しいスイッチ--switchoverが追加されました。 + スイッチが指定されている場合、は現在のプライマリノードを切り離し、実際に指定されたノードを昇格します。 + + + + + + + PostgreSQLが管理者によってシャットダウンされたとき、またはpg_terminate_backendによって強制終了されたときに、フェイルオーバを発生させないように設定できるようにしました。 + この目的のために、新しいパラメータが追加されました。 + + + + + + + 、およびコマンドにより有用な情報を表示するために、新しいフィールドを追加しました。 + + + + + + + がすべてのバックエンドノード情報を一覧表示できるようにしました。 + + + + + + + 実際のPostgreSQLの状態を示す新しいフィールドをとその同種のコマンドに追加しました。 + + + + + + + リカバリ元のホスト名を表す新しいパラメータをおよびに追加しました。 + これは、hostnameコマンドが予期しないホスト名を返す一部のシステムで役立ちます。 + + + + + + + ミリ秒単位でログにタイムスタンプを出力できるようにしました。 + + + + + + + PostgreSQL 14 の SQL パーサを取り込みました。 + + + + PostgreSQL 14 パーサのおもな変更点は次のとおりです: + + + + + + + エイリアスをJOIN ... USINGに使用できるようにしました。 + + + + + + DISTINCTをGROUP BYに追加できるようにしました。 + + + + + + 共通テーブル式に新しいSEARCHとCYCLE句を追加しました。 + + + + + + + + + pgpool.confファイルでincludeディレクティブに対応しました。 + pgpool.confに取り込む分割した小さな設定ファイルを作成することができます。 + + + + + + + pgpool.confのサンプルファイルは、設定を容易にするために単一のサンプルファイルに統合されました。 + + + + + + + pgpool.confサンプルファイルのすべての構成パラメータは、どのパラメータを変更する必要があるかを明確にするためにコメント化されました。 + 一部の設定パラメータのデフォルト値が変更されていることに注意してください。 + 詳細については、移行のセクションを参照してください。 + + + + + + + + バージョン 4.3 への移行 + + + + + + + + pgpool.confのすべてのパラメータをコメント化しました。(Tatsuo Ishii) + + + + これにより、pgpool.confの混乱が少なくなり、PostgreSQL の方法に従うため、PostgreSQLユーザはpgpool.confを理解しやすくなります。 + + + + + + + + すべてのpgpool.conf.sampleファイルを単一のpgpool.conf.sampleに統合しました。(Tatsuo Ishii) + + + + pgpool.confのすべての設定パラメータがコメント化されたので、個別の設定サンプルファイルを用意する意味がなくなりました。 + パラメータを指定するだけで十分です。 + + + + + + + + のコンパイル時のデフォルト値を on に変更しました。(Tatsuo Ishii) + + + + insert_lockはpgpool.conf.sampleですでにonになっています。 + よってそれと同期しました。 + + + + + + + + のコンパイル時のデフォルト値をonに変更しました。(Tatsuo Ishii) + + + + は、ドキュメントとpgpool.confですでに on になっています。 + よってそれらと同期しました。 + + + + + + + + のコンパイル時のデフォルト値をonに変更しました。(Tatsuo Ishii) + + + + は、ドキュメントとpgpool.confですでに on になっています。 + よってそれらと同期しました。 + + + + + + + + のコンパイル時のデフォルト値を on に変更しました。(Tatsuo Ishii) + + + + は、ドキュメントとpgpool.confですでにonになっています。 + よってそれらと同期しました。 + + + + + + + + デフォルトでストリーミングレプリケーションのチェックを有効にしました。(Tatsuo Ishii) + + + + のコンパイル時のデフォルト値を0から10に変更しました。 + これは、ストリーミングレプリケーションモードで動作している場合、ストリーミングレプリケーションのチェックがデフォルトで有効になっていることを意味します。 + このパラメータは、pgpool.conf.sample ですでに10に設定されています。 + したがって、唯一の違いは、がコメント化されている場合です。 + + + + + + + + のコンパイル時のデフォルトを'none'から'if_over_threshold'に変更しました。(Tatsuo Ishii) + + + + コンパイル時のデフォルトは'none'でしたが、サンプルのpgpool.confのデフォルト値は'if_over_threshold'でした。 + 'if_over_threshold'はほとんどのユーザにとってより便利なので、コンパイル時のデフォルトも'if_over_threshold'に変更しました。 + + + + + + + + いくつかのコンパイル時のデフォルト値を修正しました。(Tatsuo Ishii) + + + + src/config/pool_config_variable.cで定義されているいくつかのデフォルト値は、ドキュメントが想定するものとは異なっていました。 + すなわち: + + ("false" から "true" に変更) + ("postgres" から "template1" に変更) + ("32" から "2" に変更) + ("0" から "60" に変更) + + + + + + + + + + バグ修正 + + + + + このリリースでは、Pgpool-II 4.2.5と同じバグ修正がすでに適用されています。 + これらの修正の詳細については、を参照してください。 + + + + + + + + 変更 + + + + + + + watchdogノードのメンバー・非メンバーの概念を導入することにより、動的にwatchdogクラスタの概念を定義できるようになりました(Muhammad Usama)。 + + + + watchdogノードからノードのメンバーが削除されると、クラスタは以後の多数決ルールの計算を調整するために、動的に自分自身を補正します。 + + + + 3つの新しい設定パラメータが、watchdogノードのメンバー管理の条件を調整するために導入されました。 + + + + + + + + を追加しました。(Masaya Kawamoto) + + + + + + + + で昇格するノード ID を指定できるようにしました。(Tatsuo Ishii) + + + + + + + + 新しい設定パラメータを追加しました。(Tatsuo Ishii) + + + + + + + + 、および コマンドに新しいフィールドを追加しました。(Masaya Kawamoto) + + + + + + + + がすべてのバックエンドノードを一覧表示できるようにしました。(Bo Peng) + + + + + + + + 実際のPostgreSQLの状態を、およびで表示するために、新しいフィールドを追加しました。(Tatsuo Ishii) + + + + + + + + リカバリ元のホスト名を表す新しいパラメータをに追加しました。(Tatsuo Ishii) + + + + + + + + でミリ秒単位でログにタイムスタンプを出力できるようにしました。(Tatsuo Ishii) + + + + + + + + PostgreSQL 14の新しいSQLパーサを取り込みました。(Bo Peng) + + + + + + + + すべてのpgpool.conf.sampleファイルを単一のpgpool.conf.sampleに統合しました。(Tatsuo Ishii) + + + + + + + + サンプルのpgpool.confでコメント化の漏れを修正しました。(Tatsuo Ishii) + + + + はコメント化されていませんでした。 + + + + + + + + + ドキュメントの変更 + + + + + + 新しいネィティブレプリケーションモードとスナップショットアイソレーションモードの設定例を追加しました。(Bo Peng) + + + + + + + + Pgpool-II + Watchdog の設定例とサンプルスクリプトをPostgreSQL 14 向けに更新しました。(Masaya Kawamoto) + + + + + + + diff --git a/doc.ja/src/sgml/release-4.4.sgml b/doc.ja/src/sgml/release-4.4.sgml new file mode 100644 index 000000000..dfde5cef2 --- /dev/null +++ b/doc.ja/src/sgml/release-4.4.sgml @@ -0,0 +1,3886 @@ + + + + + リリース 4.4.17 + + リリース日 + 2026-06-04 + + + + 不具合修正 + + + + + pgprotoで改行データを扱えるようにしました。(Tatsuo Ishii) + + + 現在は\nが改行として認識されます。 + これはCOPYに必要な修正です。 + + + + + + + watchdogのリーダーノードが初期値-2を報告した場合にローカルのprimary_node_idを維持するようにしました。(Tatsuo Ishii) + + + すべてのpgpoolノードを同時に再起動した際に、スタンバイノードが有効なprimary_node_idを初期値-2値で上書きし、未初期化状態のままになる問題を修正しました。 + この修正により、リーダーが初期値-2を報告した場合はローカルのprimary_node_idを維持するようになりました。 + + + この問題はEmond PapegaaijとClaude Codeによって報告されました。 + + + ディスカッション: Primary node detection race at clean startup + + + + + + + アボート状態のトランザクションでの空クエリ処理を修正しました。(Tatsuo Ishii) + + + アボート状態のトランザクションで空クエリが誤ってエラーになる問題を修正しました。 + 空クエリはアボート状態のトランザクションでも許可されるべきですが、以前のコミットによりcheck_transaction_state_and_abort()が空クエリを拒否していました。 + この修正により、SimpleQuery()で空クエリを検出し、チェックを通さないようにしました。 + + + この問題はRonaldo Raivilによって報告されました。 + + + ディスカッション: pgpool ≥ 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + ssl_dh_params_fileの説明を修正しました。(Tatsuo Ishii) + + + パラメータが空の場合だけでなく、不正なパラメータが指定された場合も、組み込みのデフォルト値にフォールバックするようになっていました。 + + + + + + + PCPのメインプロセスが再起動時に子プロセスのPIDを保持するように修正しました。(Tatsuo Ishii) + + + フェイルオーバー/フェイルバック時にPCPのメインプロセスが再起動すると、子PCPワーカープロセスのPID一覧を失ってしまう問題を修正しました。 + + その結果、pcp_promote_nodeなどのコマンドが無限にハングする可能性がありました。 + この修正により、PCPワーカープロセスのPIDを共有メモリに保持し、PCPのメインプロセス再起動後も利用できるようにしました。 + + + この問題はTaiki Koshinoによって報告されました。 + + + ディスカッション: Problem with pcp process + + + + + + + バージョンの不一致があったため 4.4.16 用にコンフィギュアファイルを再作成しました。(Bo Peng) + + + + + + + MERGE文使用時にクエリキャッシュを無効化するように修正しました。(Tatsuo Ishii) + + + MERGEPostgreSQL 15で導入され、Pgpool-II 4.4ではPostgreSQL 15のパーサを取り込んでいました。 + しかしクエリキャッシュサブモジュールに考慮漏れがあり、MERGE文実行時にクエリキャッシュが無効化されていませんでした。 + + + この問題はNadav Shatzによって報告されました。 + + + ディスカッション: Re: Proposal: Recent mutated table tracking in memory + + + + + + + SSLモジュールでのメモリリークを修正しました。(Tatsuo Ishii) + + + 不正なDHパラメータが指定された場合に、load_dh_file()でメモリリークが発生する問題を修正しました。 + この関数はPEM_read_DHparams()が返したメモリを解放していませんでした。 + + また同じファイル内のコピーライト表示を修正し、元のPostgreSQLのコピーライトを保持するようにしました。 + + + ディスカッション: Memory leak in SSL module + + + + + + + SET transaction_read_only = 0の誤ったルーティングを修正しました。(Bo Peng) + + + SET transaction_read_only = 0がstandbyノードに誤って送られ、クエリエラーが発生する問題を修正しました。 + また、不適切なbool型のret = POOL_BOTHを適切なenum型に修正しました。 + + + この問題はliujinyang-highgoによって報告されました。 + + + ディスカッション: set command ‘set transaction_read_only = 0;‘ routed to standby node and execute failed. + + + + + + + セッションローカルのリレーションのキャッシュの処理を修正しました。(Tatsuo Ishii) + + + pool_search_relcache()において、セッションローカルのリレーションのキャッシュが誤って共有リレーションのキャッシュに登録される問題を修正しました。 + 一時テーブル情報が共有リレーションのキャッシュに登録されることで、後続クエリが古いキャッシュ情報を使用し、クエリが誤ったノードにルーティングされる可能性がありました。 + この修正により、セッションローカルのキャッシュの一時テーブル情報は共有リレーションのキャッシュに登録しないようにしました。 + + + ディスカッション: query temp table is routed to standby node. + + + + + + + pool_search_relcache()のロック解放漏れを修正しました。(Tatsuo Ishii) + + + 共有リレーションのキャッシュ更新時に、排他ロックを再取得した後のロック状態が正しく更新されず、共有メモリのロックが解放されない可能性がありました。 + また、分かりづらい変数名lockedlocked_by_othersに変更し、不要なper_node_statement_log出力も修正しました。 + + + ディスカッション: Lock release leak in pool_search_relcache + + + + + + + フォーク前に不要なリッスン中のソケットを閉じるようにしました。(Tatsuo Ishii) + + + フォークされた子プロセスが不要なpgpoolおよびPCPがリッスン中のソケットを継承してしまう問題を修正しました。 + 以前はpcpのメインプロセス、ヘルスチェックプロセス、ライフチェックプロセスなどが使用しないリッスン中のソケットを保持していました。 + その結果、次回pgpool起動時にポートのバインドに失敗する可能性がありました。 + この修正により、close_listening_sockets()を使用して、 + フォーク後に不要なリッスン中のソケットを閉じるようにしました。 + + + ディスカッション: Close listening socokets before forking + + + + + + + ドキュメント修正 + + + + + ignore_leading_white_spaceおよびallow_sql_commentsのドキュメントを修正しました。(Tatsuo Ishii) + + + デフォルト値の説明が不足していました。 + + + + + + + + リリース 4.4.16 + + リリース日 + 2026-02-26 + + + + 変更点 + + + + + 並列でmakeを実行できるようになりました。(Tatsuo Ishii) + + + 以前、makeの並列実行は以下のように失敗していました。 + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + anthonyrousselによってパッチが作成され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Fix parallel build + + + + + + + primary_conninfoのホストが不一致であることを詳細にログに出力するようになりました。(Taiki Koshino) + + + pgpool.confに設定されているPostgreSQLprimary_conninfoのホスト設定が一致しない場合以下のようなログが出力されます。 + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + + サポートされている最小のOpenSSLバージョンを明記しました。(Tatsuo Ishii) + + + こちらは以下を使用したconfigure.acによって実現しています。 + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + サポートされている最小バージョンは1.0.2で、これは現時点ではPostgreSQLと同じです(実際にはAC_DEFINEはPostgreSQLから導入されています)。 + また、インストールされているOpenSSLが3.0などの新しいバージョンである場合、OpenSSLの非推奨警告を回避できる可能性があります。 + さらに、インストールドキュメントに、必要なOpenSSLの最小バージョンは1.0.2であることを記載しました。 + + + + + + + 不具合修正 + + + + + check_transaction_state_and_abort()の考慮不足を修正しました。(Tatsuo Ishii) + + + この関数はフロントエンドがNULLアカウントであるケースを考慮していませんでした。 + + + この問題はCoverityによって発見されました。 + + + + + + + walker()が早めに結果を返すように修正しました。(Tatsuo Ishii) + + + 以前、walker()は対象オブジェクトを見つけたときにfalseを返していましたが、 + trueを返すようにし処理をショートカットするようにしました。 + + またwaker()の設計意図が分かりやすいようにPostgreSQLのコメントを移植しました。 + + + この問題はliujinyang-highgoによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Improper handling in the function view_walker(). + + + + + + + scram-sha-256認証でのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はCoverityによって発見されました。 + + + + + + + malloc()の返り値チェックを修正しました。(Tatsuo Ishii) + + + create_inet_domain_sockets()はソケットのファイルディスクリプタ用メモリを割り当てている間にmalloc()が返す値のチェックをしていませんでした。 + + + + + + + ヘルスチェックが開始しない問題を修正しました。(Tatsuo Ishii) + + + 以前、Pgpool-IIはバックエンドノードがダウンしている場合ヘルスチェックを開始しませんでした。 + これは自動フェイルバックを阻害します。 + Pgpoolはを指定していない場合pool_statusを読み込みます。 + もしpgpool_statusにダウンと記載されている場合はpgpoolはヘルスチェックを開始しませんでした。 + 自動フェイルバックはヘルスチェックから引き起こされるため、ヘルスチェックが起動しないと自動フェイルバックも実行されずバックエンドノードが復帰できませんでした。 + この修正によりノードの状態にかかわらずヘルスチェックが起動するようになりました。 + + + この問題はMeng Feilongによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Nodes in the down state cannot failback + + + + + + + integer型のオーバーフローが起きる可能性がある問題を修正しました。(Tatsuo Ishii) + + + pool_write_flush()pool_flus_it()ではwrite(2)が使用されています。 + write(2)はssize_tを返しますが、コード内には戻り値がint変数に代入されている箇所がいくつかありました。 + その結果、戻り値が負の値として評価され、エラーが発生する可能性がありました。 + + + + + + + + リリース 4.4.15 + + リリース日 + 2025-12-15 + + + + 変更点 + + + + + pgpool_setupで非推奨の「egrep」の代わりに「grep -E」を使用するようにしました。(Bo Peng) + + + 新しいGNUのgrepバージョンでの廃止警告を回避するために、「egrep」を「grep -E」に置き換えました。 + + + + + + + 不具合修正 + + + + + show pool_statusのバッファオーバーフローエラーを修正しました。(Tatsuo Ishii) + + + SHOW POOL_STATUS、pgpool show、および pcp_pool_statusコマンドでバッファオーバーフローが発生する問題を修正しました。 + 問題の原因は、backend_flagがALWAYS_PRIMARYに設定されている場合に、pool_flag_to_str()関数がbackend_flagを文字列化する際に静的バッファの末尾を越えて書き込んでしまうことでした。 + + + この問題はzam bakによって報告され、Bo Pengによってよって分析されました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + 「show pool_status」に表示されるmemqcache_stats_start_timeの出力を修正しました。(Tatsuo Ishii) + + + get_config()がctime()を使って時刻を文字列化していましたが、ctime()の戻り値の末尾には改行が含まれることを考慮していませんでした。 + その結果、memqcache_stats_start_timeの行に余計な改行が入り、さらに次の行が空欄として表示されてしまう問題が発生していました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + + リリース 4.4.14 + + リリース日 + 2025-11-25 + + + + 変更点 + + + + + 不要な application_name の処理を削除しました。(Tatsuo Ishii) + + + 以前のコミットで、既存接続を再利用する際に application_name を設定する処理が追加されました。 + しかしこれは不要です。DISCARD ALLにより接続再利用時に自動的に application_name がリセットされ、 + send_params()によってフロントエンドに必要なパラメータステータス(application_name を含む)が送信されます。 + この冗長な処理を削除することで、特に地理的に離れたバックエンドノードでのパフォーマンスが向上します。 + + + ディスカッション: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + 不具合修正 + + + + + CopyOutでのセグメンテーションフォルトを修正しました。(Tatsuo Ishii) + + + 拡張プロトコルでCOPY relname TO STDOUTが実行された場合、Pgpool-IIがセグフォルトを起こしていました。 + + + この問題はhttps://github.com/teteshによって報告されました。 + + + ディスカッション: datanymizer and pg-pool segmentation fault + + + + + + Watchdogのスプリットブレイン回避するよう修正しました。(Tatsuo Ishii) + + + Watchdogはビーコンメッセージとハートビートで通信します。 + ハートビートが有効でない場合、ビーコンが30秒以上届かないとスプリットブレインが発生することがあります。 + 古いリーダーを無効化することで、同時に二人のリーダーが存在しないように修正しました。 + ノードがリーダーからのビーコンを2回以上見逃すと、リーダーはLOST状態となり、 + set_state(WD_JOINING) により新リーダー選出が開始されます。 + + + + + + + 存在しないプリペアドステートメント使用時のFATALエラー防止するよう修正しました。(Tatsuo Ishii) + + + 以前は Bind()が存在しないプリペアドステートメントでFATALエラーを出していました。 + はステートメントの存在を確認し、存在しない場合はフロントエンドにERRORメッセージを送信するようになりました。ログは残りません。 + + + + + + + -pと -P両方使用時に動作しない問題を修正しました。(Tatsuo Ishii) + + + 元の報告では、pg_enc -p -P実行時にパスワードと暗号キーを求められましたが、 + キーが提供されない場合に失敗していました。 + また、コメント /* prompt for postgres password */ が誤解を招くため、 + /* prompt for password to be encrypted */ に修正されました。 + + + ディスカッション: pg_enc + + + + + + + 32ビット環境でのコンパイルの問題を修正しました。(Tatsuo Ishii) + + + 32ビットシステムでsrc/parser/snprintf.cをコンパイルすると isnan()isinf()が未定義でエラーになりました。 + math.hをインクルードし、ヘッダーファイルの順序も整理しました。 + 元々 PostgreSQLから取り込まれたファイルで、math.hは既に含まれていました。 + 修正は fix compiling issues for 32-bit targets のプルリクエストに記載してあります。 + + + + + + + recovery_1st_stage.sampleでBashのディレクトリ削除を安全に行うよう修正しました。(Taiki Koshino) + + + rmコマンドの変数をクォートし、意図しない削除を防止しました: + rm -rf "${DEST_NODE_PGDATA}" + + + + + + + 指定なしでコンパイルする際のエラーを修正しました。(Tatsuo Ishii) + + + 指定なしでコンパイルするとエラーが発生していました。 + 対応として該当コードブロックを #ifdef USE_MEMCACHEDで囲みました。 + + + この問題はBo Pengによって報告されました。 + + + + + + + クエリキャッシュロックファイルの取り扱い修正を修正しました。(Tatsuo Ishii) + + + クエリキャッシュモジュールは並列制御のため logdir にロックファイルを作成しますが、 + メインプロセスがゴミファイルを作成したり、シャットダウン時に削除されない問題がありました。 + + + この問題はBo Pengによって報告・分析されました。 + + + + + + + ドキュメント修正 + + + + + 8.2. Pgpool-II + Watchdog Setup Example の "PostgreSQLスタンバイ設定" ドキュメントを更新しました。(Taiki Koshino) + + + オンラインリカバリなしでスタンバイを設定する場合、postgresql.auto.confに primary_conninfo を書き込まないよう注意を追加しました。 + + + ディスカッション: Follow primary command not fixing postgresql.auto.conf + + + + + + + watchdog_setupのマニュアルを修正しました。(Tatsuo Ishii) + + + heartbeartがwatchdog_setupに設定されていないと誤記されていた箇所を修正しました。 + + + + + + + 回帰テスト修正 + + + + + 023.ssl_connectionをPostgreSQL 18に対応するよう修正しました。(Tatsuo Ishii) + + + PostgreSQL 18でpsqlの \conninfo出力形式が大幅に変更されたため、 + このテストが失敗していました。 + PostgreSQLバージョンに応じてテストスクリプトを修正しました。 + + + + + + + 010.rewrite_timestampのRubyスクリプトを修正しました。(Tatsuo Ishii) + + + RubyのFile.existsは新しいバージョンで非推奨のため、File.existに置き換えました。 + + + + + + + 034と075のタイムアウトを調整しました。(Tatsuo Ishii) + + + 034.promote_nodeと075.detach_primary_left_down_nodeのスクリプト終了タイムアウトを60秒から120秒に変更し、 + 誤エラーが発生する可能性を減らしました。 + + + + + + + 023.ssl_connectionにssl_ecdh_curveのテストを追加しました。(Tatsuo Ishii) + + + 023.ssl_connectionはssl_ecdh_curveのテストをカバーしていなかったため、 + 不正なssl_ecdh_curveパラメータでフロントエンドとpgpoolの接続が失敗するか確認しました。 + + + + + + + + リリース 4.4.13 + + リリース日 + 2025-08-21 + + + + 不具合修正 + + + + + watchdog が不適切な NOTICE メッセージを出力する問題を修正しました。 (Tatsuo Ishii) + + + read_ipc_socket_and_process() は、IPCソケットへのコマンド書き込みのたびに、書き込みが成功した場合でも通知メッセージを出力していました。これを修正し、書き込みが失敗した場合にのみ通知メッセージを出力するようにしました。 + log_min_messages が notice 以上に設定されている場合にのみメッセージが表示されるため、このバグが発見されていませんでした。 + + + ディスカッション: pgpool IPC socket connection issue + + + + + + + + スタートアップパケットを読んでいるときのメモリーリークを修正しました。(Tatsuo Ishii) + + + pool_push_pending_data でのリソースリークを修正しました。 + + + + + + + ビッグエンディアンマシン上の scram-sha-256 認証の不具合を修正しました。(Tatsuo Ishii) + + + scram-sha-256 認証を実行する際、ハッシュ関数 pg_sha_256_final が使用されます。 + これは PostgreSQL からインポートされたもので、プリプロセッサ定義 WORDS_BIGENDIAN を使用してホストマシンのエンディアンを判断します。 + WORDS_BIGENDIAN は configure 時に定義する必要がありますが、pg_sha_256_final(およびその他)が PostgreSQL からインポートされた際にこの部分が省略されていました。 + その結果、scram-sha-256 はリトルエンディアンマシンでのみ動作していました。 + configure.ac に AC_C_BIGENDIAN マクロを追加することでこの問題を修正しました。。 + + + この問題は Christoph Berg によって報告され、 pranavkaruvally によって分析されました。 + + + ディスカッション: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + ソースコードのタイプミスを修正しました。 (Bo Peng) + + + + + + + ハートビートデバイスの処理を修正しました。(Tatsuo Ishii) + + + pgpool.conf の処理中に、heartbeat_device が誤って処理され、最初のデバイスが無視されていました。 + + + この問題は Bo Peng によって分析されました。 + + + + + + + pgpool.confのコメントのタイプミスを修正しました。 (Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + 「8.3. ネイティブレプリケーション/スナップショットアイソレーションモードの構築の例」のドキュメントを改善しました。(Taiki Koshino) + + + サンプルスクリプトのリンクと「事前設定」説明を改善しました。 + + + + + + + リロードによって反映されないパラメータのドキュメントを修正しました。 (Taiki Koshino) + + + authentication_timeoutmemqcache_oiddir はリロードしても反映されません。 + ドキュメントが「このパラメータはサーバー起動時にのみ設定できます。」に変更されました。 + + + + + + + + watchdog リーダーの用語を統一しました。(Tatsuo Ishii) + + + 以前は「leader」「active」「coordinater」という用語が、watchdog のリーダーノードを指すために使用されていました。このコミットではこれらを「leader」に統一しました。 + advanced.sgml も修正しました。 + + + + + + + + サンプルスクリプトを修正しました。(Taiki Koshino) + + + 「8.2. Pgpool-II + Watchdogの構築の例」のサンプルスクリプトを修正しました。 + + + + + + + ロードバランスの説明で論理レプリケーションモードと Slony モードが抜けている問題を修正しました(Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Bo Peng) + + + 「replication_state」と「replication_sync_state」を正しく表示するには、各 backend_application_nameXprimary_conninfoapplication_name に指定された値と一致する必要があることを明確にしました。 + + + + + + + カーネルの資源に関するセクションを追加しました。 (Tatsuo Ishii) + + + Pgpool-II は System V の共有メモリとセマフォを使用します。 + 要件についてはドキュメントを参照することをお勧めします。 + + + + + + + configure の オプションの説明を追加しました。(Tatsuo Ishii) + + + これは LDAPサポートがv4.2で導入されたときに見落としていました。 + + + + + + + Pgpool-II でサポートされているプラットフォームを明確にしました。 (Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Tatsuo Ishii) + + + + + + + 回帰テスト修正 + + + + + 029.cert_passphrase 回帰テストを安定化しました。 (Tatsuo Ishii) + + + ssl_passphrase_command が有効でない場合、エラーメッセージは通常「bad decrypt」ですが、「wrong tag」となる場合もありました。 + + + + + + + + リリース 4.4.12 + + リリース日 + 2025-05-15 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + Pgpool-IIのクライアント認証メカニズムには認証バイパスの脆弱性があります。 + 本来であれば認証が必要な場合でも、認証処理がスキップされてしまう可能性があります。 + この脆弱性を悪用することで、攻撃者が任意のユーザとしてログインし、データベース内の情報を参照・改ざんしたり、データベースを停止させたりすることができる可能性があります。(CVE-2025-46801) + + + なお、本脆弱性の影響を受けるのは、下記のパターン1から3いずれかの条件を満たす場合に限られます。 + + + + + パターン 1:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + pool_hba.confpassword認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードが設定されていない + + + + + pg_hba.confscram-sha-256またはmd5認証方式を使用している + + + + + + + + パターン 2:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + enable_pool_hba = off + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + + パターン 3:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + rawモードを使用している (backend_clustering_mode = 'raw') + + + + + pool_hba.confmd5認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードがテキストまたはAES形式で登録されている + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + この脆弱性の影響を受けるのは、Pgpool-II 4.0系および4.1系のすべてのバージョン、4.2.0-4.2.21、4.3.0-4.3.14、4.4.0-4.4.11、4.5.0-4.5.6、4.6.0です。 + Pgpool-II 4.6.1、4.5.7、4.4.12、4.3.15、4.2.22以降へのアップグレードを強くお勧めします。 + それができない場合は、発生条件パターンに当てはまらない設定の組み合わせに変更してください。 + + + + + 変更点 + + + + + 設定ファイルにメジャーバージョンを追加しました。 (Bo Peng) + + + + + + + 不具合修正 + + + + + クライアント認証が正しく実行されない場合があるのを修正しました。(Tatsuo Ishii) + + + enable_pool_hbaがonで、auth methodが"password"、pool_passwdにパスワードが登録されておらず、pg_hba.confの認証方式が"scram-sha-256"か"md5"の場合、クライアントが最初にpgpoolに接続したときには認証が期待通りに実行されます。 + しかし、クライアントがキャッシュされたコネクションに接続すると、任意のパスワードが通ってしまいます。 + + + また、enable_pool_hba = offのいくつかのケースでは、本来パスワードが聞かれるはずが、最初からパスワードが聞かれない、あるいはキャッシュされたコネクションに接続した時にはパスワードが聞かれないことがありました。 + + + 上記を修正するのに加え、以下の変更を行いました。 + + + + + 認証コードを単純化するために、PostgreSQLが1台の時のコードパスを削除しました。 + + + + + crypt認証のサポートをフロントエンドとバックエンドから削除しました。 + この機能はドキュメントに書かれておらず、テストもされていませんでした。 + また、crypt認証はPostgreSQLではだいぶ以前(8.4, 2009)に削除されています。 + + + + + 新しい回帰テストの"040.client_auth"を追加しました。 + このテストは、CSV形式のテスト設定ファイルを使って、包括的なクライアント認証のテストを実施します。 + + + + + + + + クエリキャッシュにおける、古くからあるバインド時のバグを修正しました。(Tatsuo Ishii) + + + 名前付きステートメントを準備すると、バインド後にパースメッセージなしで実行することが可能です。 + 問題は、実行時またはCOMMIT時にクエリキャッシュを無効化するために必要なテーブルOIDが、パースメッセージ処理(Parse())でのみ収集されていたことです。 + そのため、前回の実行後にパースなしでバインドを実行すると、テーブルOIDが収集されず、pgpoolはクエリキャッシュの無効化に失敗していました。 + バインド時にもテーブルOIDを収集するよう修正しました。 + 006.memqcacheに回帰テストを追加しました。 + + + この問題はEmond Achilleas Mantzios によって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + クエリキャッシュの無効化に失敗する問題を修正しました。 (Tatsuo Ishii) + + + 実行メッセージを受信すると、pgpoolは最大行数パラメータをチェックします。この値が0でない場合、pgpoolはpool_handle_query_cache()にクエリキャッシュを作成しないよう指示するために、"partial_fetch"フラグを設定します。 + 問題は、コミット2a99aa5d1が、INSERT/UPDATE/DELETEであっても実行メッセージパラメータが0以外(ほとんどの場合1)に設定され、pgpoolがSELECT以外の場合でもこのフラグを設定することを見落としていることです。 + この結果、このフラグが true の場合、pool_handle_query_cache() 内の後続のコードでキャッシュの無効化がスキップされるため、クエリキャッシュの無効化に失敗していました。 + フラグを設定する前にクエリが読み取り専用の SELECT であるかどうかを確認するように Execute() を修正しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + OpenBSDへ移植する際の問題を修正しました。 (Tatsuo Ishii) + + + ディスカッション: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + このパッチはMartijn van Durenによって作成されました。 + + + + + + json_writerが特殊文字を正確にエンコードできない問題を修正しました。(Bo Peng) + + + が特殊文字を含んでいる状態でwatchdogを起動するとPgpool-IIがクラッシュしていました。 + + + このパッチはMartijn van Durenによって作成され、Bo Pengによって微修正されました。 + + + + + + リロード時にを開くようにストリーミングレプリケーションチェックとヘルスチェックプロセスを修正しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションチェックとヘルスチェックはリロード前にを開いていませんでした。 + もしが空文字列の時は、からパスワードを得ます。 + そのためこれらのプロセスはリロード時にの古いコンテンツを読み取ります。 + + + + + + ドキュメント修正 + + + + + の説明を改善しました。(Tatsuo Ishii) + + + が計算されるタイミングは、接続キャッシュを保持しているプロセスからクライアントが切断されたときであることを追記しました。 + + + ディスカッション: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + についての説明を改善しました。 (Tatsuo Ishii) + + + スーパーユーザーかpg_monitorグループであるべきです。 + + + + + + + + リリース 4.4.11 + + リリース日 + 2025-02-28 + + + + 変更点 + + + + + サンプルフォロープライマリスクリプトからpg_basebackupの処理を削除しました。(Bo Peng) + + + pg_rewindが失敗した場合、ユーザーにとって最も安全な方法は手動で復旧することです。 + + + + + + + 不具合修正 + + + + + per_node_error_log()のエラーメッセージでコロンが重複して出力される不具合を修正しました。(Bo Peng) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + pool_signalの不具合を修正しました。(Tatsuo Ishii) + + + 以前は、pool_signalSA_RESTARTフラグを設定していませんでした。 + そのため、シグナルによって中断されたシステムコールは再起動されません。 + 一部のコードは、システムコールがシグナルによって中断された場合に再起動するように準備されています。 + しかし、すべての箇所で対応できているかは不明なため、フラグを追加しました。 + なお、PostgreSQLでは常にこのフラグが使用されています。 + + + + + + + パラメータにデフォルト値以外のファイルが指定されている場合に、pg_md5pg_encがパスワードファイルを更新しない問題を修正しました。(Bo Peng) + + + この問題はSadhuprasad Patroによって報告されました。 + + + + + + + ストリーミングレプリケーションモードにおけるクエリキャッシュのいくつかの不具合を修正しました。(Tatsuo Ishii) + + + + + クエリキャッシュが有効で、フロントエンドから実行メッセージが送信された場合、クエリキャッシュデータが使用可能であれば、Pgpool-IIはそのデータをバックエンドメッセージバッファに挿入します。 + しかし、キャッシュされたメッセージが不適切な位置に挿入されることで、Pgpool-IIが誤って「kind mismatch」エラーを発生させることがありました。 + + + + + また、クエリキャッシュが有効で、クエリが拡張クエリモードで実行されている場合に、Pgpool-II がストリーミングレプリケーションモードで動作していると、実行メッセージが誤った結果を返す可能性がありました。 + + + + + さらに、複数の実行メッセージが連続して送信された場合、Pgpool-IIは各実行メッセージに対してクエリキャッシュから同じ結果を返していましたが、これは誤りです。 + 本来、2回目以降の実行では0行が返されるべきでした。 + + + ディスカッション: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + ドキュメント修正 + + + + + クライアント認証の章を強化しました。(Tatsuo Ishii) + + + pool_passwdに関する説明部分を追加しました。 + これまで、概要ページにはpool_hba.confの説明のみが記載されていましたが、今回pool_passwdの一般的なガイドを追加しました。 + これにより、ユーザーがこの章をより理解しやすくなりました。 + + + + + + + 回帰テスト修正 + + + + + 032.dml_adaptive_loadbalanceテストの安定性を向上させました。(Tatsuo Ishii) + + + + + + + + リリース 4.4.10 + + リリース日 + 2024-11-28 + + + + 不具合修正 + + + + + + バックエンドがエラーメッセージを送信した場合に、SSLネゴシエーションを中止するよう修正しました。(Tatsuo Ishii) + + + SSLネゴシエーションのクライアント側実装(pool_ssl_negotiate_clientserver())では、 + 中間者攻撃者がSSLネゴシエーションフェーズ中に長いエラーメッセージを送信することで、 + Pgpool-IIやクライアントを混乱させる可能性がありました。 + このコミットでは、ネゴシエーションを直ちに拒否(FATALエラーを発行)し、 + そのような攻撃を防ぐためにセッションを終了するよう修正しました。 + + + これは、PostgreSQLのCVE-2024-10977に似ています。 + + + + + + + リロード処理がWatchdogプロセスに反映されない問題を修正しました。(Bo Peng) + + + Pgpool-IIの + reload_config()関数は、 + WatchdogププロセスにSIGHUPシグナルを送信する必要がありました。 + + + + + + + do_query関数の不具合を修正しました。(Tatsuo Ishii) + + + htons/htonlの代わりにntohs/ntohlを使用するようにdo_queryを修正しました。 + + + + + + + pool_passwdを更新してリロードした後の認証失敗問題を修正しました。(Tatsuo Ishii) + + + pool_hba.confが無効になっている場合、Pgpool-IIのリロードが実行されても、Pgpool-IIの子プロセスはpool_passwdの更新を認識しませんでした。 + リロード処理関数check_config_reload()は、が有効な場合にのみpool_passwdを再オープンする必要があると誤って判断していたことが原因でした。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html + + + + + + + COPYがハングする問題を修正しました。(#79) (Tatsuo Ishii) + + + COPY IN状態(つまり、COPY FROM STDIN)中、フロントエンドはFlushまたはSyncメッセージを送信できます。 + F/Bプロトコル仕様によると、これらは無視されるはずですが、Pgpool-IIは無効なメッセージとして処理し、これがCOPYのハングの原因でした。 + + + リグレッションテストも追加しました。 + + + + + + + シャットダウン中にPgpool-IIの子プロセスがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + 実際のクラッシュはclose_all_backend_connections()内で発生していました。 + この関数は、on_system_exitchild_will_go_down()を登録するために呼び出されます。 + この時点では、Pgpool-II子プロセスが起動し、pool_init_cp()を実行した直後であるようです。 + 接続プールオブジェクトが完全に初期化されていなかったため、クラッシュが発生していました。 + + + この問題はEmond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + 認証失敗による散発的なヘルスチェックの失敗を修正しました。(Tatsuo Ishii) + + + が空文字列の場合、ヘルスチェックプロセスはpool_passwdファイルからパスワードを検索します。 + 問題は、このファイルのファイルディスクリプタが親pgpoolプロセスから継承されている点です。 + pgpoolメインプロセスとヘルスチェックプロセス(複数存在する可能性あり)が同じディスクリプタを共有するため、さまざまな問題が発生していました。 + この問題を解決するために、ヘルスチェックプロセスが開始される際にファイルを再度開き、 + それぞれのヘルスチェックプロセスが独自のファイルディスクリプタを持つようにしました。 + + + なお、pgpoolの子プロセス(フロントエンドセッションを担当)はすでにファイルディスクリプタを再度開く処理を行っており、これが今回の問題には関連していません。 + + + この問題は、Emond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + ALTER ROLEのクエリキャッシュ無効化を最適化しました。(Tatsuo Ishii) + + + コミット6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89は、ALTER ROLE/USERステートメントが使用される際にクエリキャッシュを無効にしています。 + しかし、実際にはこれが過剰です。 + 次のクエリはロールの権限に影響を与えないため、クエリキャッシュを無効にする必要はありません。 + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + したがって、これらのコマンドが使用される場合には、クエリキャッシュを無効にしないようにしました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Pgpool-IIの子プロセスが終了したときにPgpool-IIがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスが終了すると、close_all_backend_connections()が呼び出され、接続プール内のすべてのバックエンド接続が閉じられます。 + しかし、誤ってMAIN_CONNECTIONマクロが使用されていました。 + このマクロは現在アクティブな接続には適していますが、接続プールが作成された時点でのメインノードが異なる可能性があるため、プールされた接続には適していませでした。 + この問題を修正するために、代わりにin_use_backend()を使用するよう変更しました。 + + + Emond Papegaaijによって報告されました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードのバグを修正しました。(#69) (Tatsuo Ishii) + + + INSERTコマンドを受信すると、Pgpool-IIはターゲットテーブルに対して自動的にテーブルLOCKコマンドを発行しますが、メインノード以外のノードにコマンドを送信し忘れていました。 + この問題は拡張クエリモードの場合にのみ発生していました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードの別のバグを修正しました。(Tatsuo Ishii) + + + insert_lock()は、メインノード以外のノードに行ロックコマンド(lock_kind == 3 の場合)を送信するのを忘れていました。 + + + + + + + pool_memqcache.cのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はコミット6fdba5c33によって導入されました。 + + + + + + + + ドキュメント修正 + + + + + ドキュメントとサンプル設定ファイルのタイポを修正しました。(Bo Peng) + + + + + + + 回帰テスト修正 + + + + + テスト024.cert_authをOpenSSL 3.2に対応するよう修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.4.9 + + リリース日 + 2024-09-09 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + クエリキャッシュ機能()が有効な時に、データベースユーザがクエリキャッシュ経由で本来読み出せない行を読むことが可能でした。(CVE-2024-45624) + + + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22より古く、クエリキャッシュ機能を持つすべてのバージョン(クエリキャッシュ機能は3.2で実装されました)がこの脆弱性の影響を受けます。 + + + + + + あるユーザのクエリキャッシュがテーブルに対して作成されていると、そのテーブルへのアクセス権がREVOKEコマンドで剥奪されても、アクセス権を持たないそのユーザがクエリキャッシュを通じてテーブルにアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュがテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、アクセス権を持たないBがクエリキャッシュを通じてアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュが行セキュリティが有効なテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、本来Bが見えない行をクエリキャッシュを通じて取り出すことが可能でした。 + + + + + Pgpool-II 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22以降へのアップグレードを強くお勧めします。 + それができない場合は、クエリキャッシュ機能を無効にしてください。 + + + なお、この脆弱性を修正するために、いくつかのコマンド(ALTER DATABASE, ALTER ROLE, ALTER TABLE, REVOKE)を実行すると、クエリキャッシュのすべてのデータを削除するようになりました。 + これにより、クエリキャッシュの性能に影響があるかも知れません。 + + + + + 変更点 + + + + + をバックポートしました。 (Tatsuo Ishii) + + + これは主にテストのためです。v4.1までバックポートしました。 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + 不具合修正 + + + + + + レプリケーションモードとスナップショットアイソレーションモードで発生する複数の不具合を修正しました。(Tatsuo Ishii) + + + 次の不具合を修正しました。 + + + + + レプリケーションモードおよびスナップショットアイソレーションモードでコマンドを実行すると、Pgpool-IIはクエリ準備完了メッセージを待ちますが、一部のコマンド(SET ROLEなど)がパラメータステータスメッセージを生成することを忘れていました。 + その結果、Pgpool-IIはクエリ準備完了メッセージの前に他のメッセージが到着したことをエラーとして出力していました。 + + + + + + 前のクエリがパラメータステータスメッセージを生成した場合、後続のparse()はそれを読み取って処理する必要があります。 + これは、パラメータステータスメッセージの後に続くはずのクエリ準備完了メッセージを読み取る必要があるためです。 + + + ただし、ParameterStatus()が呼び出されると、クエリ進行中フラグが設定され、このparse()呼び出しで処理されるクエリが負荷分散されている場合、バックエンドからのパラメータステータスメッセージの1つだけが処理される可能性がありました。 + パラメータステータスメッセージはSETコマンドによって生成され、SETコマンドはレプリケーションモードおよびスナップショットアイソレーションモードのすべての生きているバックエンドに送信されるため、すべての生きているバックエンドから送信される可能性がありました。 + そのため、ParameterStatus()を呼び出す前に、クエリ進行中フラグを設定解除するように修正しました。 + + + + + + + + + + + リリース 4.4.8 + + リリース日 + 2024-08-15 + + + + 変更点 + + + + + + サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 (Bo Peng) + + + postgresqlxx-serverがインストールされていない可能性があるため、サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 + + + + + + + + 不具合修正 + + + + + + フラッシュメッセージを受信した後にハングする問題を修正しました。 (#59) (Tatsuo Ishii) + + + + + + + セグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Pgpool-IIの子プロセスがpool_do_authでセグメント違反になることがありました。 + 原因はMAIN_CONNECTION()がNULLを返すことでした。 + my_main_node_idが不正なノードID 0に設定されていたようですが、これは実際にはダウン状態でした。 + そのため、cp->slots[0]には接続がありませんでした。 + + + この問題はEmond Papegaaijによって報告されました。 + Discussion: [pgpool-general: 9175] + + + + + + + 動的プロセス管理を修正しました。 (Tatsuo Ishii) + + + プロセス排除アルゴリズムで使用されるpooled_connectionの計算が正しくありませんでした。 + 数値は常にmax_poolになっていました。 + + + Discussion: [pgpool-hackers: 4490] + + + + + + + 設定ファイルの解析時に発生するセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 設定値が一重引用符で囲まれていない場合にpgpool.confを解析するときにセグメンテーション違反が発生していました。 + + + このパッチはCarlos Chapiによって作成され、Tatsuo Ishiiによってレビューおよび修正されました。 + + + + + + + MAIN_NODEマクロを使用しないようにセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 一部の関数 (close_idle_connection()、new_connection()、pool_create_cp())では、MAIN*とVALID_BACKENDが不適切な場所で使用されていました。 + MAIN*とVALID_BACKENDは、バックエンドへの現在の接続に対してのみ有効であり、プールされた接続には有効ではありません。 + プールされた接続では、どのバックエンドがメインノードであるか、または稼働中であるかは、バックエンドへの現在の接続と必ず同じであるためです。 + これらのマクロを誤って使用すると、セグメンテーション違反が発生することがありました。 + + + この問題はEmond Papegaaij によって報告されました。 + Discussion: [pgpool-general: 9114] + + + + + + + MAIN_NODEマクロ(実際は pool_virtual_main_db_node_id())を修正しました。 (Tatsuo Ishii) + + + セッションコンテキストがない場合、マクロはREAL_MAIN_NODE_IDに使用されます。 + フェイルオーバー/フェイルバックが発生すると、いつでもREAL_MAIN_NODE_IDが変更される可能性があるため、これは誤りでした。 + + + REAL_MAIN_NODE_ID == my_main_node_id == 1と仮定します。 + その後、フェイルバックにより、REAL_MAIN_NODE_IDは0に変更されます。 + その後、MAIN_CONNECTION(cp)はNULLを返し、これへの参照はセグメンテーションエラーを引き起こします。 + この問題を回避するには、代わりにmy_main_node_idを返すように修正しました。 + + + + + + + show pool_processesで行の説明が2回表示されないように修正しました。(Tatsuo Ishii) + + + processes_reporting()が誤ってsend_row_description()とsend_row_description_and_data_rows()の両方を呼び出していました。 + + + Discussion: [pgpool-hackers: 4471] + + + + + + + 子プロセスでのセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + ネットワークが短時間中断されると、Watchdogが停止し、Pgpool-IIが強制終了する問題を修正しました。 (#823) (Muhammad Usama) + + + ネットワーク監視を有効にすると、Pgpool-IIノードはすべてのネットワークインターフェイスまたは割り当てられたIPアドレスを失った場合に直ちにシャットダウンし、通信できないノードをクラスタからすばやく削除することで追加の保護を提供します。 + + + 問題は、ネットワーク監視が無効になっている場合でも、Pgpool-IIがネットワークブラックアウトイベントに応答していたことです。 + この修正により、ネットワーク監視が有効になっていない場合にネットワーク監視ソケットがオープンされなくなり、不要なシャットダウンが防止されます。 + + + + + + + Watchdogが有効な場合にpgpool resetコマンドが動作しない問題を修正しました。 (Tatsuo Ishii) + + + バグはkeiseoによって報告・問題分析されました。 + Disscussion: [pgpool-hackers: 4465] + + + + + + + psql_scanのクラッシュを修正しました。 (#54) (Tatsuo Ishii) + + + 長いクエリ内の文字列がpsql変数(つまり「:」で始まる)であるかどうかを判別しているときに、psql_scanがクラッシュする問題がありました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントとプログラムソースコードの大量なタイポミスを修正しました。(Tatsuo Ishii) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + 強制終了するプロセスを選択するための基準をのドキュメントに追加しました。(Bo Peng) + + + + + + + フェイルオーバーのドキュメントを改良しました。(Tatsuo Ishii) + + + が有効な場合のフェイルオーバーの条件を明確にしました。 + + + + + + + 仮想IP関連パラメータのデフォルト値をドキュメントに追加しました。(Bo Peng) + + + + + + + + + リリース 4.4.7 + + リリース日 + 2024-05-16 + + + + 不具合修正 + + + + + -Werror=implicit-function-declarationオプションで発生するコンパイルエラーを修正しました。(Bo Peng) + + + 非推奨のldap関数のプロトタイプを含めるためにLDAP_DEPRECATEDを追加しました。 + また、autoconfチェックで不足していたヘッダーファイルを追加しました。 + + + パッチはVladimir Petkoによって作成されました。 + + + + + + + セグメンテーション違反のさまざまな原因を修正しました。(Tatsuo Ishii) + + + フェイルオーバーが関与している特定のケースでは、Pgpool-IIとその子プロセスのセグメント違反が発生していました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + 初期化されていないメモリエラーを修正しました。(Tatsuo Ishii) + + + read_startup_packetの初期化されていないメモリエラーを含むいくつかのエラーがvalgrindによって報告されました。 + valgrindは、キャンセルまたはSSL要求の場合にpallocを使用してスタートアップパケット内のユーザー名にメモリを割り当て、その後、そのメモリがpstrdupによって使用されます。 + pallocによって割り当てられたメモリは未定義であったため、これをpalloc0に修正しました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + load_balance_modeがオフの場合に発生するエラー/ハングアップを修正しました。(Tatsuo Ishii) + + + load_balance_modeがオフで、プライマリノードIDが0でない場合には、BEGINなどクエリでエラー/ハングアップが発生していました。 + コミット 3f3c1656の修正によって導入された問題です。 + + + バグはEmond Papegaaijによって発見・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + 特定のCFLAGSによるコンパイルエラーを修正しました。(Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42によって報告されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + サンプルpgpool.conf内のコメントを修正しました。(Bo Peng) + + + sr_check_periodのデフォルト値は10秒であるため、修正しました。コメント内のいくつかのタイポも修正しました。 + + + パッチはhiroinによって作成され、Bo Pengによって修正されました。 + + + + + + + 拡張クエリが終了していない場合でもリセットクエリを実行できるようにしました。(Tatsuo Ishii) + + + コミット240c668dが原因で、拡張クエリメッセージが終了していない場合、リセットクエリが失敗していました。 + このコミットでは、SimpleQuery()でリセットクエリを実行しているかどうかをチェックすることで、この問題を修正しました。 + また、テストケースも追加しました。 + + + + + + + Coverityによって指摘されたメモリリークを修正しました。(Takuma Hoshiai) + + + + + + + 不適切なプロトコルデータから保護するように修正しました。(Tatsuo Ishii) + + + 拡張クエリメッセージのシーケンスが終了する前にシンプルクエリメッセージが到着すると、Pgpool-IIがハングする可能性がありました。 + これは、シンプルクエリのセッションコンテキスト内のクエリコンテキストが、拡張クエリメッセージのクエリコンテキストによって上書きされたためです。 + + + このコミットでは、拡張クエリプロトコルメッセージが終了したかどうかをチェックするように実装しました。 + 終了していない場合は、FATALエラーを発生させます。このチェックによって検出された既知の例は、JDBCドライバーの「autosave=always」オプションです。 + つまり、このコミットの後、問題(拡張クエリメッセージプロトコルが終了する前にシンプルプロトコルメッセージを送信する)がJDBCドライバー側で修正されるまで、 + Pgpool-IIはこのオプションを受け入れません。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + ドキュメント修正 + + + + + + 「上位サーバへの接続」ドキュメントを改善します。(Bo Peng) + + + + + + + 日本語ドキュメントの言語クリーンアップしました。(Masaya Kawamoto) + + + + + + + PostgreSQLノードが2台の場合にpcp_promote_nodeを使用する際の注意点を追加しました。(Masaya Kawamoto) + + + PostgreSQLノードが2台であっても、follow_primary_commandを設定する必要があるケースがあります。 + + + + + + + + 回帰テスト修正 + + + + + + Java 21での非推奨警告を回避するために回帰テスト005.jdbcを修正しました。(Bo Peng) + + + Java 21での非推奨警告を回避するには、Runtime.exec(String)をRuntime.exec(String[])に置き換えました。 + + + パッチはVladimir Petkoによって作成され、Bo Pengによって修正されました。 + + + + + + + + + リリース 4.4.6 + + リリース日 + 2024-02-29 + + + + 変更点 + + + + + サンプルスクリプトからrestore_commandの設定を削除しました。 (Bo Peng) + + + レプリケーションスロットが有効になっているため、restore_commandは不要です。 + この設定により、フェールオーバーが失敗するケースがあるからです。 + + + + + + + 不具合修正 + + + + + , + および + のデフォルト値を修正しました。 (Bo Peng) + + + recovery_userデフォルト値はと同じである必要があるため、 + デフォルト値を''から'nobody'に変更しました。 + + + failover_on_backend_shutdownの正しいデフォルト値は「false」、 + insert_lockの正しいデフォルト値は「on」であるため、修正しました。 + + + + + + + BEGINなどでのの不具合を修正しました。 (Tatsuo Ishii) + + + statement_level_load_balanceが有効な場合、 + が無効であっても、 + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE ALL/DISCARDがプライマリノードとすべてのスタンバイノードに送信されていました。 + これは明らかに間違っているだけでなく、スタンバイノードの1つがリモートネットワークにある場合、速度が低下する原因となります。 + + + load_balance_modeがオフの場合、 + Pgpool-IIはそのようなクエリをプライマリノードにのみ送信するように修正しました。 + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + ドキュメント修正 + + + + + 日本語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + Watchdog「リーダー」ではなく「マスター」を誤って使用していました。 + + + + + + + 英語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + PostgreSQL「プライマリ」ではなく「メイン」を誤って使用していました。 + + + + + + + + リリース 4.4.5 + + リリース日 + 2023-11-30 + + + + 変更点 + + + + + 大文字のホスト名をサポートするようにサンプルスクリプトのレプリケーションスロット名の変換処理を変更しました。(Bo Peng) + + + フェイルオーバやオンラインリカバリの時に実行されるスクリプトで、自動的にレプリケーションスロットを削除/作成しています。 + レプリケーションスロット名には大文字を使用できないため、ホスト名を小文字に変換するようにこれらのスクリプトを修正しました。 + + + パッチはSheikh Wasiu Al Hasibによって作成され、Bo Pengによって修正されました。 + + + + + + + パラメータ用のサンプルスクリプトescalation.sh.sampleでSSH接続時のタイムアウト時間を指定するようにしました。(Bo Peng) + + + + + + + 不具合修正 + + + + + 不要なログ行を削除しました。(Tatsuo Ishii) + + + デバッグメッセージ「unset_tx_started_by_multi_statement_query is called in CommandComplete」が誤って残っていました。 + + + + + + + DECLAREによって作成されたポータルでアボートしないようにDescribe()を修正しました。(Tatsuo Ishii) + + + DECLARE foo CURSOR FORを実行すると、PostgreSQLによって「foo」という名前のポータルが自動的に作成されます。 + このポータルはPgpool-IIによって管理されないため、Describe fooメッセージは「unable to execute Describe. unable to get the bind message」エラーで失敗していました。 + + + これを修正するため、Describe()でダミーの書き込みクエリコンテキストを作成し、Describeメッセージをプライマリ(ストリーミングレプリケーションモード)またはすべてのノード(レプリケーション/スナップショットアイソレーションモード)に送信するようにしました。 + + + 新たなテストケース080も追加しました。 + + + この問題はHeather Lapointeによって報告・分析されました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + NAMEDATALENの重複定義を削除しました。(Tatsuo Ishii) + + + src/include/pg_config_manual.hのみでNAMEDATALENを定義するようにしました。 + また、src/utils/pool_select_walker.c内のPOOL_NAMEDATALENNAMEDATALENに置き換えました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + ドキュメント修正 + + + + + PCPがすべてのアドレスをリッスンするにはpcp_listen_addresses = '*'の設定が必要である旨を「Pgpool-II + Watchdogの構築の例」に記載しました。 + + + + + + + のドキュメントを修正しました。(Tatsuo Ishii) + + + 実際のバックエンドのステータスは、pg_isreadyではなくPQpingParamsを使用して取得しています。 + + + + + + + のドキュメントの説明を強化しました。(Tatsuo Ishii) + + + を使用しない場合は、の実行が必要である旨を記載しました。 + + + + + + + 回帰テスト修正 + + + + + pgpool_setupを強化しました。(Tatsuo Ishii) + + + フェイルオーバスクリプトおよびフォロープライマリスクリプトでより適切なログを出力できるようにpgpool_setupを改善しました。 + + + + + + + + リリース 4.4.4 + + リリース日 + 2023-08-17 + + + + 変更点 + + + + + 共有メモリの初期化後にのみ、システム終了コールバックを呼び出すようにしました。(Muhammad Usama) + + + 共有メモリの取得に失敗して、終了時コールバックが呼び出された場合、クリーンアップ関数は、共有メモリに存在するprocess_infoにアクセスする際にセグメンテーション違反を引き起こす可能性がありました。 + process_infoがNULLのときに終了コールバックからの中断で修正することもできますが、共有メモリの初期化に成功した後に関数をインストールする方がより良いアプローチです。 + なぜなら、システムの残りの部分は常にprocess_infoがNULLになることはないと想定しており、また、子プロセスが生成される前にクリーンアップをする必要はないからです。 + + + + + + + がdynamicのとき、より大きな値で設定できないようにしました。(Muhammad Usama) + + + num_init_childrenmax_spare_childrenよりも小さい場合、設定の後処理の段階でエラーが発生していました。 + このコミットでは、process_management_strategyの設定に基き、起動時に生成される子プロセスの数も調整するようにしました。 + aggressiveのプロセス管理戦略の場合はmax_spare_childrenの数のプロセス、それ以外の2つの戦略の場合はmin_spare_childrenの数のプロセスが生成されます。 + + + + + + + ログメッセージをダウングレードしました。(Tatsuo Ishii) + + + https://www.pgpool.net/mantisbt/view.php?id=806で、ログファイルに以下ログエントリがあることが指摘されています: + + + LOG: pool_pending_message_set_flush_request: msg: Parse + + + デバッグ用のメッセージであるため、ロブレベルはDEBUG*であるべきでした。そのため、ログレベルをLOGからDEBUG5に変更しました。 + + + + + + + 一部のシステムカタログ照会関数にスキーマ修飾を追加しました。(Tatsuo Ishii) + + + + + + + 不具合修正 + + + + + Coverityの警告を修正しました。(Tatsuo Ishii) + + + クエリキャッシュのモジュールで、time_tの値がint32変数に割り当てられる問題を修正しました。 + Coverityの指摘に従いまして、変数の型をint64に変更しました。 + また、time_tの差分を計算するためにdifftime()を使用しました。これは推奨される方法です。 + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + find_primary_node_repeatedlyが指定時間内で終了しない問題を修正しました。(Bo Peng) + + + + + + + v2プロトコルを利用する場合のクラッシュを修正しました。(bug 807)(Tatsuo Ishii) + + + read_kind_from_backend()で統計データを蓄積する際、v2プロトコルのケースには対応していませんでした。 + + + MCanivezからバグ報告とパッチを提供いただきました。 + + + + + + + マルチステートメントにおけるPREPAREの利用を修正しました。(Tatsuo Ishii) + + + マルチステートメントの二番目以降の位置にPREPAREが含まれている場合、その後のbindメッセージでプリペアドステートメントを利用すると、送信されたメッセージにプリペアドステートメントが保存されないため、「unable to bind」エラーが発生していました。 + + + この問題を修正するために、ステートメントを解析した後にそのようなケースが見つかった場合、名前付きステートメントのクエリコンテキストを作成し、送信メッセージのリストに追加するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + この修正のため、リグレッションテスト079..multi_prepareを追加しました。 + + + + + + + pgprotoをパラメータを使用するbindメッセージを処理できるようにしました。(Tatsuo Ishii) + + + 以前、pgprotoはパラメータを持たないbindメッセージしか処理できませんでした。 + + + + + + + ログメッセージのタイポを修正しました。(Bo Peng) + + + + + + + CTE SEARCHおよびCYCLEのリライトが抜けていた問題を修正しました。(Bo Peng) + + + ネイティブレプリケーションモードでは、Pgpool-IIはWRITEクエリ内の日付/時刻関数をタイムスタンプにリライトする必要がありますが、CTE SEARCHおよびCYCLEのリライト処理が不足していました。 + + + + + + + src/sample/pgpool.conf.sample-streamにある重複したpcp_listen_address設定を削除しました。(Bo Peng) + + + + + + + 共有ロック中のクエリキャッシュの更新を回避しました。(Tatsuo Ishii) + + + 期限切れのクエリキャッシュエントリが共有ロックの下で変更される可能性があるとbug 795で指摘されていました。 + これは、クエリキャッシュで使用される共有メモリの破損を引き起こす可能性がありました。 + これを修正するために、キャッシュエントリを変更する前に一時的に共有ロックを解除し、その後排他ロックを取得するようにしました。 + ロック解除と再取得の間に、他の誰かによってメタデータが変更されていないことを確認するために、再びキャッシュエントリのメタデータを取得する必要があります。 + + + V4.4でクエリキャッシュの共有ロックが導入されたため、V4.4 STABLEブランチにバックポートされました。 + + + + + + + を修正しました。(Tatsuo Ishii) + + + 4.4 でdelay_threshold_by_timeが導入された時にこれらが壊されていました。 + + + + + where_to_send内でdelay_threshold_by_timeがチェックされていなかったため、レプリケーションが遅延している場合に負荷分散が壊れていました。 + + + + + + + delay_threshold_by_timeprefer_lower_standby_delayの両方が有効な場合、select_load_balancing_nodeが機能しなくなっていました。 + + + + + この問題を修正するため、where_to_sendとselect_load_balancing_nodeを修正しました。 + また、delay_threshold_by_timeのテストケースを033.prefer_lower_standby_delayに追加しました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-general/2023-June/008864.html + + + + + + + サンプルスクリプトreplication_mode_recovery_2nd_stage.sample内の変数名が間違っていたため修正しました。(Bo Peng) + + + + + + + ドキュメント修正 + + + + + loggerプロセスのアプリケーション名記載漏れを修正しました。(Bo Peng) + + + + + + + 停止モードの意味を明確にしました。(Tatsuo Ishii) + + + + + + + 4.2.10リリースノートにあった誤った情報を削除しました。(Bo Peng) + + + 「pgpool_recovery拡張のスクリプトを修正しました。 (Tatsuo Ishii)」の記載を削除しました。 + + + + + + + 「8.2. Pgpool-II + Watchdogの構築の例」のSSH公開鍵認証の説明を補足しました。(Bo Peng) + + + + + + + 負荷分散章の説明を修正しました。(Tatsuo Ishii) + + + 一部の文章で「ストリーミングレプリケーションモード」と記述されるべきの箇所が「ネイティブレプリケーションモード」となっていました。 + また、ストリーミングレプリケーションモードにおける負荷分散の追加要件に関する説明を改善しました。 + いくつかのインデックスを追加しました。 + + + + + + + オンラインリカバリーの説明を改善しました。(Bo Peng) + + + 複数のpgpoolノードでwatchdogが有効になっていない場合、オンラインリカバリーのセカンドステージが適切に機能しないことについて言及しました。 + + + + + + + 回帰テスト修正 + + + + + 時折発生する069.memory_leak_extendedテストの失敗を修正しました。(Tatsuo Ishii) + + + 偶発するテストの失敗の原因は、pgbenchが終了した後にpsコマンドを実行する前にpgpoolの子プロセスが消えてしまうことにあると判明しました。 + これにより、「DISCARD ALL cannot be executed within a pipeline」というkind mismatchのFATALエラーが発生していました。 + これを修正するために、pgbenchをバックグラウンドで実行し、pgbenchが終了する前にプロセスのサイズを取得するようにしました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + リリース 4.4.3 + + リリース日 + 2023-05-18 + + + + 変更点 + + + + + マルチステートメントのクエリを判定するために、psqlscanのソースコードをPgpool-IIにインポートしました。(Tatsuo Ishii) + + + psqlscanは、PostgreSQLソースツリー内のモジュールです。 + これは本質的にPostgreSQL SQLスキャナのサブセットですが、各SQLステートメントの終わりの検出に特化しています。 + したがって、これを使用してクエリ文字列内のSQLステートメントの数をカウントできます。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + 複数のステートメントを幅広く使用できるようにしました。 (Tatsuo Ishii) + + + このコミットは、複数のステートメント (マルチステートメント) に関するPgpool-IIの長年の制限を排除しました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + 内部クエリでスキーマ修飾を使用するように変更しました。(Tatsuo Ishii) + + + 関数やキャストなどの一部のオブジェクトは、「pg_catalog.」スキーマ修飾を使用していませんでした。 + これによって直ちにセキュリティ上の懸念が生じるわけではありませんが、スキーマ修飾を使用することは常に良い習慣ですので、変更しました。 + + + + + + + 不具合修正 + + + + + の不具合を修正しました。(bug 798) (Tatsuo Ishii) + + + クライアントがPgpool-IIに接続すると、スタンバイの1つがロードバランシングノードとして選択されます。 + セッションの継続中にスタンバイ遅延がdelay_thresholdを超えた場合、prefer_lower_delay_standbyは遅延が最小のスタンバイノードを新しいロードバランシングノードとして選択し、ターゲットバックエンドをそのノードに設定します。 + 残念ながら、SELECTクエリに書き込み機能などが含まれているかどうかを確認する前に決定が下されたため、Pgpool-IIはスタンバイで実行できないSELECTを送信していました。 + これを修正するために、prefer_lower_delay_standbyの処理を書き込み関数等のチェック後に移動しました。 + + + また、上記のケースを含めるように033.prefer_lower_standby_delay回帰テストも修正しました。 + + + + + + + musl libcを使用するシステムでのコンパイルエラーを修正しました。(bug 790) (Tatsuo Ishii) + + + パッチはleimaohuiによって提供されました。 + + + + + + + 複数のクエリキャッシュの不具合を修正しました。(Tatsuo Ishii) + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + 特殊なケースでsrワーカーが間違ったクエリをスタンバイサーバに送信する不具合を修正しました。(Tatsuo Ishii) + + + ALWAYS_PRIMARYフラグが設定されている場合、PRIMARY_NODE_IDマクロは、プライマリがダウンしている場合でも、-1ではなくノードIDを返していました。 + この場合、ストリーミングレプリケーション遅延をチェックするワーカープロセスは、PostgreSQLのバージョンに応じてSELECT pg_current_wal_lsn()またはSELECT pg_current_xlog_location()をスタンバイに送信し、当然エラーが発生していました。 + + + 議論: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + DEALLOCATEによる種類不一致エラーを修正しました。 + (bug 780) (Tatsuo Ishii) + + + 以下の条件がすべて満たされた場合、種類不一致エラーが発生していました。 + + + + ストリーミングレプリケーションモード + + + + + + + ロードバランスノードがプライマリ以外のノード + + + + + + + PREPAREがマルチステートメントクエリで使用されている + + + + + + + + + + 回帰テストのコンパイルエラーを修正しました。(Takuma Hoshiai) + + + gcc10を使用したタイムスタンプテストでエラーが発生していました。 + + + + + + + 共有relcacheをコミットする際に、より強力なロックを取得するように修正しました。(Tatsuo Ishii) + + + + + + + show pool_versionで行の説明が2回表示される問題を修正しました。(Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + の説明を追加しました。(Chen Ningwei) + + + + + + + PREPARE/EXECUTE/DEALLOCATEに関する制限を追加しました。(Tatsuo Ishii) + + + + + + + Pgpool-IIで-Dオプションを使用する場合の注意点を追加しました。(Tatsuo Ishii) + + + + + + + 「RPMからのインストール」セクションを強化しました。(Bo Peng) + + + + + + + 「サーバの準備と運用」の章に「PostgreSQLデータベースのバックアップ」セクションを追加しました。(Tatsuo Ishii) + + + + + + + 「Pgpool-II + Watchdogの構築の例」から「-D」起動オプションの設定を削除しました。(Bo Peng) + + + + + + + 「制限事項」セクションを修正しました。(Tatsuo Ishii) + + + + + + SCRAM-SHA-256認証に関する記述を追加 + + + + + + + スナップショットアイソレーションモードに関する記述を追加 + + + + + + + + + + PostgreSQLノードのステータスが「unknown」と表示される場合の説明を追加しました。(Tatsuo Ishii) + + + + + + + 実行時に、プロモートするターゲットノードが稼働中の必要であることを記載しました。(Tatsuo Ishii) + + + + + + + AES256をサポートするにはオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + .pcppassを使用するには、pcpコマンドの-wオプションが必要であることを記載しました。(Tatsuo Ishii) + + + + + + + 「2.8 insert_lockテーブルの作成」セクションを修正しました。(Tatsuo Ishii) + + + スナップショットアイソレーションモードについても言及する必要があったのに、ネイティブレプリケーションモードについてのみ言及していました。 + + + + + + + を強化しました。(Tatsuo Ishii) + + + + + + + テストツール修正 + + + + + 設定ファイルの末尾にいくつかのパラメータを追加するようにpgpool_setupを修正しました。(Bo Peng) + + + + + + + 回帰テスト修正 + + + + + 071.execute_and_deallocate/test.shをリファクタリングしました。(Tatsuo Ishii) + + + + + + + いくつかの回帰テストを強化しました。(Tatsuo Ishii) + + + + + + + 時折発生する005.jdbcテストの失敗を修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.4.2 + + リリース日 + 2023-01-23 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + 以下の条件をすべて満たす場合、コマンドによりのパスワードが公開されます。このコマンドは、Pgpool-IIに接続できるすべてのユーザーが実行できます。(CVE-2023-22332) + + + + + + バージョン3.3以降 + + + + + + onに設定されている + + + + + + queryが設定されている + + + + + + にプレーンテキストのパスワードが設定されている + + + + + + 上記条件のすべてに該当するユーザは、このバージョンにアップグレードするか (show pool_statusコマンドでが表示されなくなる)、次の回避策のいずれかを使用することを強くお勧めします。 + + + + 4.0.x~4.4.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + には空文字を設定し、パスワードはpool_passwdファイルに設定する。 + + + + + + にAESで暗号化したパスワードを設定する。 + + + + + + いずれにせよ、PostgreSQLでを変更することをお勧めします。 + + + + 3.3.x~3.7.xユーザ向けの回避策: + + + + + + Watchdogを無効にする。(offに設定する) + + + + + + heartbeatを設定する。 + + + + + + いずれにせよ、PostgreSQLを変更することをお勧めします。 + + + + Pgpool-II 3.7.xおよび以前のバージョンはサポートが終了しているため、これらのバージョンのマイナーアップデートはリリースされません。 + + + + + 変更点 + + + + + + およびコマンドでwd_lifecheck_passwordを表示しないように修正しました。(CVE-2023-22332) (Bo Peng) + + + + + + + ドキュメントに記載されているように、のデフォルト値を空の文字列に変更しました。(Bo Peng) + + + + + + + + 不具合修正 + + + + + + pgpool_adm: pcp_pool_status関数がPostgreSQL 15で失敗する問題を修正しました。(Tatsuo Ishii) + + + pcp_pool_status関数は実際にはSETOF recordを返しますが、「RETURNS record」と宣言されていました。 + これはPostgreSQL 14までは許容されていましたが、PostgreSQL 15ではより厳しくなりました。 + これを修正するために、pcp_pool_statusの戻り値の型を「RETURNS record」から「RETURNS SETOF record」に変更しました。 + + + また、pgpool_adm拡張機能のバージョンを1.5に上げました。 + + + + + + + ストリーミングレプリケーションチェックでの整数オーバーフローを修正しました。(Tatsuo Ishii) + + + が有効で、レプリケーションの遅延が約36分を超えると、整数オーバーフローエラーがログに記録され、レプリケーションチェックが失敗しました。 + + + + + + + pgpool-regclass.cのコンパイラ警告を修正しました。(Florian Weimer, Tatsuo Ishii) + + + + + + + Coverityによって指摘された初期化されていない変数を修正しました。(Takuma Hoshiai) + + + + + + + + ドキュメント修正 + + + + + + 共有メモリ使用時の設定の章のいくつかの誤りを修正し、説明を強化しました。(Tatsuo Ishii) + + + + + + + の説明を強化しました。(zam bak, Tatsuo Ishii) + + + + + + + + + リリース 4.4.1 + + リリース日 + 2022-12-22 + + + + 変更点 + + + + + ストリーミングレプリケーションLOGメッセージ"standby_delay: 54"をDEBUG1にダウングレードしました。(Tatsuo Ishii) + + + + + + + LOGメッセージ"we have hit the ceiling"をDEBUG5にダウングレードしました。(Tatsuo Ishii) + + + + + + + + 不具合修正 + + + + + + タイムスタンプのリライト処理の不具合を修正しました。(Tatsuo Ishii) + + + Pgpool-II 4.4のoutfuncsモジュールでは、boolean定数が無視され、空の文字列になり、構文エラーが発生しました。 + + + この問題はMichiel van Leeningによって報告されました。 + 議論: [pgpool-general: 8521] + + + + + + + の問題を修正しました。(Muhammad Usama) + + + Watchdogクラスタ全体のヘルスチェックパラメータの最大値に基づいて、フェイルオーバコマンドのタイムアウトを動的に設定するように修正しました。 + + + Tatsuo Ishiiによってレビューおよびテストされました。 + 議論: [pgpool-hackers: 4227] + + + + + + + + ドキュメント修正 + + + + + + Doc: パフォーマンスセクションを強化しました。(Tatsuo Ishii) + + + 動的なプロセス管理について言及しました。 + + + + + + + Doc: Aurora設定例内のタイポを修正しました。(Tatsuo Ishii) + + + + + + + Doc: 動的なプロセス管理ドキュメントを強化しました。(Tatsuo Ishii) + + + + + + + + 回帰テスト修正 + + + + + + 環境変数を使ってPGPOOLDIRを定義できるようにしました。 + (bug 766) (Bo Peng) + + + + + + + + + リリース 4.4.0 + + リリース日 + 2022-12-06 + + + + 概要 + + このバージョンには、設定と管理を容易にするために多くの機能拡張が追加されています。 + 動的スペアプロセス管理機能を追加しました。 + ストリーミングレプリケーションの遅延は、バイト単位だけでなく時間単位で制御できるようにしました。 + Pgpool-IIとPCPが複数のIPアドレスをリッスンできるようになりました。 + Unixドメインソケットディレクトリの完全な設定が可能になりました。 + trusted_serversが上位接続を確認するために使用するコマンドを指定できるようになりました。 + 新しいPostgreSQL 15のSQLパーサが取り込まれました。 + クエリキャッシュのパフォーマンスも向上しました。 + + + + 以下は主な機能拡張です。 + + + + + + 新たに動的スペアプロセス管理機能を追加しました。 + この機能により、静的プロセス管理モードと動的プロセス管理モードを選択することができます。 + + + + + + ストリーミングレプリケーションモードで、レプリケーションの遅延を時間で指定できるようにしました。 + この目的のために、新しいパラメータを追加しました。 + + + + + + Pgpool-IIはPostgreSQLと同じように、 + および + をサポートするようになり、UNIXドメインソケットをより柔軟かつ正確に制御できるようになりました。 + + + + + + およびで、カンマ区切りの複数のリッスンIPアドレスを設定できるようになりました。 + これにより、接続を受け付けるネットワークインターフェイスを制御でき、安全でないネットワークインターフェイスで悪意のある接続要求が繰り返されるのを防ぐことができます。 + + + + + + が上位接続を確認するために使用するコマンドを指定できるようになりました。 + この目的のために、新しいパラメータを追加しました。 + + + + + + PostgreSQL 15 のSQLパーサを取り込みました。 + + + + + + ロックの競合を減らして、クエリキャッシュを高速化しました。これにより、同時実行中のクライアントは、キャッシュの内容をより迅速に取得できるようになりました。 + + + + + + + + バージョン 4.4 への移行 + + + + + 設定パラメータsocket_dirに名前変更しました。 + + + + + + 設定パラメータdelegate_IPに名前変更しました。 + 古いバージョンとの互換性のために、古いパラメータdelegate_IPは引き続き使用できますが、 + delegate_ipに変換され、警告メッセージが出力されます。 + + + + + + バックエンドからのパラメータステータスメッセージがフロントエンドに転送されるようになりました。 + これまでは、バックエンドからパラメータステータスメッセージが届くと、Pgpool-IIはそれを記憶していましたが、フロントエンドには転送しませんでした。 + この変更により、それらのメッセージはフロントエンドに転送されます。 + Pgpool-IIを使用するアプリケーションでは、これらのメッセージを受け入れる準備をする必要があります。 + しかし、PostgreSQLはフロントエンドに既に送信しているため、PostgreSQLを使用しているアプリケーションはこの変更の影響を受けないはずです。 + + + + + + + + 変更点 + + + + + + 新たに動的スペア(アイドル状態)プロセス管理機能を追加しました。(Jianshen Zhou、Muhammad Usama) + + + この機能により、静的プロセス管理モードと動的プロセス管理モードを選択することができます。 + 静的プロセス管理は、Pgpool-IIの既存の動作と同じで、起動時にすべての子プロセスを生成します。 + 新しい動的モードは、アイドル状態のプロセスを追跡し、この数を指定された範囲内に維持するためにプロセスをforkまたはkillします。 + + + プロセス管理の動作を設定するために、、およびという4つの新しい設定パラメータが追加され、process_management_strategyでは3つのスケーリングダウン戦略を選択できます。 + + + + + + + レプリケーションの遅延を時間で指定できるようにしました。(Tatsuo Ishii) + + + では、レプリケーション遅延の上限をバイト単位で指定します。 + 今回はというパラメータを追加して、レプリケーション遅延の上限を時間(秒)で指定できるようにしました。 + 新しいパラメータが0より大きい場合に有効になります。 + この場合は、のレプリケーションの遅延は秒単位で表示します。 + このパラメータが0に設定されている場合には、 + delay_threshold_by_timeは無視され、delay_thresholdモードに戻ります。 + + + この目的のために、共有メモリデータBackendinfoの新しいメンバstandby_delay_by_timeを追加し、レプリケーションの遅延がバイト単位(standby_delay_by_time = false)で測定するか、秒単位(standby_delay_by_time = true)で測定するかを区別します。 + standby_delay_by_timeがtrueの場合は、standby_delayは秒 * 1000000で測定されるため、精度は小数点以下6桁です。 + + + + + + + unix_socket_directoriesおよび関連パラメータをサポートするようになりました。(Masaya Kawamoto) + + + 設定パラメータsocket_dirに名前変更し、新しいパラメータおよびを追加しました。 + + + + + + + 新しい設定値パラメータを追加しました。(Takuma Hoshiai) + + + この機能により、が上位接続を確認するために使用するコマンドを指定できるようになりました。 + これまでは、pingコマンドのみが使用され、ハードコーディングされていました。 + + + デフォルトは'ping -q -c3 %h'で、以前と同じです。 + + + + + + + およびでカンマ区切りの複数のリッスンIPアドレスを設定できるようにしました。(Tatsuo Ishii) + + + これまでは、に単一のホスト名/IPアドレス、または'*'しか設定できませんでした。 + 今回はPostgreSQLと同じように、パラメータに複数のリッスンIPアドレスを設定できるようになりました。 + + + また、もカンマで区切られた複数のリッスンIPアドレスを受け付けるようになりました。 + + + + + + + PostgreSQL 15の新しいSQLパーサを取り込みました。(Bo Peng, Tatsuo Ishii) + + + PostgreSQL 15パーサのおもな変更点は次のとおりです。 + + + + + + 新しいSQL MERGE文が追加されました。 + + +MERGE INTO ... USING ... + + + + + + COPY FROMに新しいオプションHEADER MATCHが追加されました。 + + +COPY ... FROM stdin WITH (HEADER MATCH); + + + + + + 外部キーON DELETE SETアクションを指定できるようになりました。 + + +CREATE TABLE t1 ( +... +FOREIGN KEY (c1, c2) REFERENCES t2 ON DELETE SET NULL (c2) +); + + + + + + ALTER TABLEでSET ACCESS METHODを指定できるようになりました。 + + +ALTER TABLE ... SET ACCESS METHOD ...; + + + + + + + + + + クエリキャッシュにおける排他ロックを共有ロックに置き換えました。(Tatsuo Ishii) + + + これまでは、クエリキャッシュモジュールはセマフォを使用して、クエリキャッシュモジュールの重要な領域を保護していました。 + ただし、セマフォを使用したロックは排他ロックであるため、これには重大な欠点があります。 + これにより、多数の同時クライアントが存在する場合に、キャッシュの読み取りに不要な待機が発生し、パフォーマンスが低下します。 + + + この問題を解決するには、ロックの実装を共有ロックを許可するflock(2)に置き換えました。 + これにより、クライアントはキャッシュから読み取る際に、ロックを取得するために待たなくて済むため、同時実行性が向上します。 + + + この目的のために、Pgpool-IIのメインプロセスはダミーファイルをlogdir/memq_lock_fileとして作成し、それを開きます。 + ファイル記述子はすべての子プロセスに継承されるため、ファイルに対してflock(2)を発行できます。 + + + + + + + およびのパスワード形式を検証する処理を追加しました。(Masaya Kawamoto) + + + + + + + パラメータのステータス処理を強化しました。(Tatsuo Ishii) + + + これまでは、バックエンドからパラメータステータスメッセージが届くと、Pgpool-IIはそれを記憶していましたが、フロントエンドには転送しませんでした。 + この修正により、パラメータステータスメッセージはフロントエンドに転送されるようになります。 + + + + + + + を指定した場合のレプリケーション遅延の取得方法を変更しました。(Tatsuo Ishii) + + + pg_stat_replication.replay_lagを使用し、レプリケーション遅延を取得します。 + この方法により、コードがはるかに単純になり、より正確なレプリケーション遅延を取得できます。 + 唯一の欠点は、pg_stat_replication.replay_lagはPostgreSQL 10以降でのみ使用できることです (以前の方法は9.5以降で使用できます)。 + + + + + + + フラッシュ追跡機能を実装しました。(Tatsuo Ishii) + + + フラッシュメッセージがフロントエンドから到着すると、バックエンドからの保留中のメッセージはすべてフラッシュされ、フロントエンドに送信される必要があります。 + そのために、「フラッシュ追跡」機能を実装しました。 + つまり、フラッシュメッセージが到着すると、Pgpool-IIは保留中の各メッセージに「保留中のフラッシュ」フラグを設定します。 + バックエンドからの応答メッセージが、フラッシュ保留フラグが設定されている保留中のメッセージに対応する場合、 + メッセージはバッファリングされるのではなく、すぐにフロントエンドにフラッシュされます。 + + + + + + + pgprotoを強化しました。(Tatsuo Ishii) + + + ParameterStatusのパラメータ名と値を表示できるようにしました。 + + + 新しいコマンド'z'を追加しました。 + これは'y'と似ていますが、'z'は 1 つのメッセージのみを読み取り、"ready for query" が到着するまで待機しません(または、1 秒以内にメッセージが到着しない場合はタイムアウトします)。 + + + + + + LOGメッセージ"new IPC connection received"をDEBUG1にダウングレードしました。 + (bug 775) (Bo Peng) + + + これは定期的に出力される正常なメッセージで、LOGとして記録すべきではありません。 + パッチはpstefによって作成され、Bo Pengによってレビューされます。 + + + + + + + バグ修正 + + + + このリリースでは、Pgpool-II 4.3.4と同じバグ修正がすでに適用されています。 + これらの修正の詳細については、を参照してください。 + + + + + + + ドキュメントの変更 + + + + + Doc: AWS設定例のドキュメントを更新し、AWS向けのサンプルスクリプトを追加しました。(Bo Peng) + + + + + + diff --git a/doc.ja/src/sgml/release-4.5.sgml b/doc.ja/src/sgml/release-4.5.sgml new file mode 100644 index 000000000..7e6c149cd --- /dev/null +++ b/doc.ja/src/sgml/release-4.5.sgml @@ -0,0 +1,2907 @@ + + + + + リリース 4.5.12 + + リリース日 + 2026-06-04 + + + + 不具合修正 + + + + + pgprotoで改行データを扱えるようにしました。(Tatsuo Ishii) + + + 現在は\nが改行として認識されます。 + これはCOPYに必要な修正です。 + + + + + + + watchdogのリーダーノードが初期値-2を報告した場合にローカルのprimary_node_idを維持するようにしました。(Tatsuo Ishii) + + + すべてのpgpoolノードを同時に再起動した際に、スタンバイノードが有効なprimary_node_idを初期値-2値で上書きし、未初期化状態のままになる問題を修正しました。 + この修正により、リーダーが初期値-2を報告した場合はローカルのprimary_node_idを維持するようになりました。 + + + この問題はEmond PapegaaijとClaude Codeによって報告されました。 + + + ディスカッション: Primary node detection race at clean startup + + + + + + + elog(DEBUG)内でpool_get_transaction_isolation()を呼び出さないように修正しました。(Tatsuo Ishii) + + + where_to_send_main_replica()およびwhere_to_send_native_replication()のDEBUGログ出力が原因で、アボート状態のトランザクションでFATALエラーが発生する問題を修正しました。 + DEBUGログ内で呼び出していたpool_get_transaction_isolation()が、内部でdo_query()を実行していたことが原因です。 + この修正によりDEBUGログからこれらの呼び出しを削除しました。 + + + + + + + アボート状態のトランザクションでの空クエリ処理を修正しました。(Tatsuo Ishii) + + + アボート状態のトランザクションで空クエリが誤ってエラーになる問題を修正しました。 + 空クエリはアボート状態のトランザクションでも許可されるべきですが、以前のコミットによりcheck_transaction_state_and_abort()が空クエリを拒否していました。 + この修正により、SimpleQuery()で空クエリを検出し、チェックを通さないようにしました。 + + + この問題はRonaldo Raivilによって報告されました。 + + + ディスカッション: pgpool ≥ 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + ssl_dh_params_fileの説明を修正しました。(Tatsuo Ishii) + + + パラメータが空の場合だけでなく、不正なパラメータが指定された場合も、組み込みのデフォルト値にフォールバックするようになっていました。 + + + + + + + PCPのメインプロセスが再起動時に子プロセスのPIDを保持するように修正しました。(Tatsuo Ishii) + + + フェイルオーバー/フェイルバック時にPCPのメインプロセスが再起動すると、子PCPワーカープロセスのPID一覧を失ってしまう問題を修正しました。 + + その結果、pcp_promote_nodeなどのコマンドが無限にハングする可能性がありました。 + この修正により、PCPワーカープロセスのPIDを共有メモリに保持し、PCPのメインプロセス再起動後も利用できるようにしました。 + + + この問題はTaiki Koshinoによって報告されました。 + + + ディスカッション: Problem with pcp process + + + + + + + MERGE文使用時にクエリキャッシュを無効化するように修正しました。(Tatsuo Ishii) + + + MERGEPostgreSQL 15で導入され、Pgpool-II 4.4ではPostgreSQL 15のパーサを取り込んでいました。 + しかしクエリキャッシュサブモジュールに考慮漏れがあり、MERGE文実行時にクエリキャッシュが無効化されていませんでした。 + + + この問題はNadav Shatzによって報告されました。 + + + ディスカッション: Re: Proposal: Recent mutated table tracking in memory + + + + + + + SSLモジュールでのメモリリークを修正しました。(Tatsuo Ishii) + + + 不正なDHパラメータが指定された場合に、load_dh_file()でメモリリークが発生する問題を修正しました。 + この関数はPEM_read_DHparams()が返したメモリを解放していませんでした。 + + また同じファイル内のコピーライト表示を修正し、元のPostgreSQLのコピーライトを保持するようにしました。 + + + ディスカッション: Memory leak in SSL module + + + + + + + SET transaction_read_only = 0の誤ったルーティングを修正しました。(Bo Peng) + + + SET transaction_read_only = 0がstandbyノードに誤って送られ、クエリエラーが発生する問題を修正しました。 + また、不適切なbool型のret = POOL_BOTHを適切なenum型に修正しました。 + + + この問題はliujinyang-highgoによって報告されました。 + + + ディスカッション: set command ‘set transaction_read_only = 0;‘ routed to standby node and execute failed. + + + + + + + where_to_send_main_replica()の不要なSTREAMチェックを削除しました。(Tatsuo Ishii) + + + このチェックは既にcheck_replication_delay()で行われています。 + + + + + + + セッションローカルのリレーションのキャッシュの処理を修正しました。(Tatsuo Ishii) + + + pool_search_relcache()において、セッションローカルのリレーションのキャッシュが誤って共有リレーションのキャッシュに登録される問題を修正しました。 + 一時テーブル情報が共有リレーションのキャッシュに登録されることで、後続クエリが古いキャッシュ情報を使用し、クエリが誤ったノードにルーティングされる可能性がありました。 + この修正により、セッションローカルのキャッシュの一時テーブル情報は共有リレーションのキャッシュに登録しないようにしました。 + + + ディスカッション: query temp table is routed to standby node. + + + + + + + pool_search_relcache()のロック解放漏れを修正しました。(Tatsuo Ishii) + + + 共有リレーションのキャッシュ更新時に、排他ロックを再取得した後のロック状態が正しく更新されず、共有メモリのロックが解放されない可能性がありました。 + また、分かりづらい変数名lockedlocked_by_othersに変更し、不要なper_node_statement_log出力も修正しました。 + + + ディスカッション: Lock release leak in pool_search_relcache + + + + + + + フォーク前に不要なリッスン中のソケットを閉じるようにしました。(Tatsuo Ishii) + + + フォークされた子プロセスが不要なpgpoolおよびPCPがリッスン中のソケットを継承してしまう問題を修正しました。 + 以前はpcpのメインプロセス、ヘルスチェックプロセス、ライフチェックプロセスなどが使用しないリッスン中のソケットを保持していました。 + その結果、次回pgpool起動時にポートのバインドに失敗する可能性がありました。 + この修正により、close_listening_sockets()を使用して、 + フォーク後に不要なリッスン中のソケットを閉じるようにしました。 + + + ディスカッション: Close listening socokets before forking + + + + + + + ドキュメント修正 + + + + + ignore_leading_white_spaceおよびallow_sql_commentsのドキュメントを修正しました。(Tatsuo Ishii) + + + デフォルト値の説明が不足していました。 + + + + + + + 回帰テスト修正 + + + + + 以前のコミットに対する001.load_balanceテストを追加しました。(Tatsuo Ishii) + + + + + + + + リリース 4.5.11 + + リリース日 + 2026-02-26 + + + + 変更点 + + + + + 並列でmakeを実行できるようになりました。(Tatsuo Ishii) + + + 以前、makeの並列実行は以下のように失敗していました。 + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + anthonyrousselによってパッチが作成され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Fix parallel build + + + + + + + primary_conninfoのホストが不一致であることを詳細にログに出力するようになりました。(Taiki Koshino) + + + pgpool.confに設定されているPostgreSQLprimary_conninfoのホスト設定が一致しない場合以下のようなログが出力されます。 + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + + サポートされている最小のOpenSSLバージョンを明記しました。(Tatsuo Ishii) + + + こちらは以下を使用したconfigure.acによって実現しています。 + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + サポートされている最小バージョンは1.0.2で、これは現時点ではPostgreSQLと同じです(実際にはAC_DEFINEはPostgreSQLから導入されています)。 + また、インストールされているOpenSSLが3.0などの新しいバージョンである場合、OpenSSLの非推奨警告を回避できる可能性があります。 + さらに、インストールドキュメントに、必要なOpenSSLの最小バージョンは1.0.2であることを記載しました。 + + + + + + + 不具合修正 + + + + + check_transaction_state_and_abort()の考慮不足を修正しました。(Tatsuo Ishii) + + + この関数はフロントエンドがNULLアカウントであるケースを考慮していませんでした。 + + + この問題はCoverityによって発見されました。 + + + + + + + walker()が早めに結果を返すように修正しました。(Tatsuo Ishii) + + + 以前、walker()は対象オブジェクトを見つけたときにfalseを返していましたが、 + trueを返すようにし処理をショートカットするようにしました。 + + またwaker()の設計意図が分かりやすいようにPostgreSQLのコメントを移植しました。 + + + この問題はliujinyang-highgoによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Improper handling in the function view_walker(). + + + + + + + scram-sha-256認証でのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はCoverityによって発見されました。 + + + + + + + malloc()の返り値チェックを修正しました。(Tatsuo Ishii) + + + create_inet_domain_sockets()はソケットのファイルディスクリプタ用メモリを割り当てている間にmalloc()が返す値のチェックをしていませんでした。 + + + + + + + ヘルスチェックが開始しない問題を修正しました。(Tatsuo Ishii) + + + 以前、Pgpool-IIはバックエンドノードがダウンしている場合ヘルスチェックを開始しませんでした。 + これは自動フェイルバックを阻害します。 + Pgpoolはを指定していない場合pool_statusを読み込みます。 + もしpgpool_statusにダウンと記載されている場合はpgpoolはヘルスチェックを開始しませんでした。 + 自動フェイルバックはヘルスチェックから引き起こされるため、ヘルスチェックが起動しないと自動フェイルバックも実行されずバックエンドノードが復帰できませんでした。 + この修正によりノードの状態にかかわらずヘルスチェックが起動するようになりました。 + + + この問題はMeng Feilongによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Nodes in the down state cannot failback + + + + + + + nodes.hに定義されているenum型のNodeTag値の重複を修正しました。(Tatsuo Ishii) + + + PostgreSQLから取り込んだnodes.hのNodeTag定義とPgpool-II独自の定義で起きていた重複を解消しました。 + + + この問題はliujinyang-highgoによって報告・検討され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: an issue about NodeTag definition. + + + + + + + integer型のオーバーフローが起きる可能性がある問題を修正しました。(Tatsuo Ishii) + + + pool_write_flush()pool_flus_it()ではwrite(2)が使用されています。 + write(2)はssize_tを返しますが、コード内には戻り値がint変数に代入されている箇所がいくつかありました。 + その結果、戻り値が負の値として評価され、エラーが発生する可能性がありました。 + + + + + + + + リリース 4.5.10 + + リリース日 + 2025-12-15 + + + + 変更点 + + + + + pgpool_setupで非推奨の「egrep」の代わりに「grep -E」を使用するようにしました。(Bo Peng) + + + 新しいGNUのgrepバージョンでの廃止警告を回避するために、「egrep」を「grep -E」に置き換えました。 + + + + + + + 不具合修正 + + + + + show pool_statusのバッファオーバーフローエラーを修正しました。(Tatsuo Ishii) + + + SHOW POOL_STATUS、pgpool show、および pcp_pool_statusコマンドでバッファオーバーフローが発生する問題を修正しました。 + 問題の原因は、backend_flagがALWAYS_PRIMARYに設定されている場合に、pool_flag_to_str()関数がbackend_flagを文字列化する際に静的バッファの末尾を越えて書き込んでしまうことでした。 + + + この問題はzam bakによって報告され、Bo Pengによってよって分析されました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + 「show pool_status」に表示されるmemqcache_stats_start_timeの出力を修正しました。(Tatsuo Ishii) + + + get_config()がctime()を使って時刻を文字列化していましたが、ctime()の戻り値の末尾には改行が含まれることを考慮していませんでした。 + その結果、memqcache_stats_start_timeの行に余計な改行が入り、さらに次の行が空欄として表示されてしまう問題が発生していました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + 回帰テスト修正 + + + + + 037.failover_sessionのテストを安定させました。(Tatsuo Ishii) + + + 特定の環境では、test1の後にshutdownallが終了しないことがありました。 + これは、テスト中のフェイルオーバー処理が、shutdownallからの終了シグナルを受け取れるようにしているシグナルハンドラの復元に失敗していることが原因と考えられます。 + shutdownall の前にsleep 5を追加することで、この問題が緩和されることを確認しました。 + + + + + + + + リリース 4.5.9 + + リリース日 + 2025-11-25 + + + + 変更点 + + + + + 不要な application_name の処理を削除しました。(Tatsuo Ishii) + + + 以前のコミットで、既存接続を再利用する際に application_name を設定する処理が追加されました。 + しかしこれは不要です。DISCARD ALLにより接続再利用時に自動的に application_name がリセットされ、 + send_params()によってフロントエンドに必要なパラメータステータス(application_name を含む)が送信されます。 + この冗長な処理を削除することで、特に地理的に離れたバックエンドノードでのパフォーマンスが向上します。 + + + ディスカッション: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + 不具合修正 + + + + + CopyOutでのセグメンテーションフォルトを修正しました。(Tatsuo Ishii) + + + 拡張プロトコルでCOPY relname TO STDOUTが実行された場合、Pgpool-IIがセグフォルトを起こしていました。 + + + この問題はhttps://github.com/teteshによって報告されました。 + + + ディスカッション: datanymizer and pg-pool segmentation fault + + + + + + Watchdogのスプリットブレイン回避するよう修正しました。(Tatsuo Ishii) + + + Watchdogはビーコンメッセージとハートビートで通信します。 + ハートビートが有効でない場合、ビーコンが30秒以上届かないとスプリットブレインが発生することがあります。 + 古いリーダーを無効化することで、同時に二人のリーダーが存在しないように修正しました。 + ノードがリーダーからのビーコンを2回以上見逃すと、リーダーはLOST状態となり、 + set_state(WD_JOINING) により新リーダー選出が開始されます。 + + + + + + + 存在しないプリペアドステートメント使用時のFATALエラー防止するよう修正しました。(Tatsuo Ishii) + + + 以前はBind()が存在しないプリペアドステートメントでFATALエラーを出していました。 + はステートメントの存在を確認し、存在しない場合はフロントエンドにERRORメッセージを送信するようになりました。ログは残りません。 + + + + + + + -pと -P両方使用時に動作しない問題を修正しました。(Tatsuo Ishii) + + + 元の報告では、pg_enc -p -P実行時にパスワードと暗号キーを求められましたが、 + キーが提供されない場合に失敗していました。 + また、コメント /* prompt for postgres password */ が誤解を招くため、 + /* prompt for password to be encrypted */ に修正されました。 + + + ディスカッション: pg_enc + + + + + + + 32ビット環境でのコンパイルの問題を修正しました。(Tatsuo Ishii) + + + 32ビットシステムでsrc/parser/snprintf.cをコンパイルするとisnan()isinf()が未定義でエラーになりました。 + math.hをインクルードし、ヘッダーファイルの順序も整理しました。 + 元々 PostgreSQLから取り込まれたファイルで、math.hは既に含まれていました。 + 修正は fix compiling issues for 32-bit targets のプルリクエストに記載してあります。 + + + + + + + recovery_1st_stage.sampleでBashのディレクトリ削除を安全に行うよう修正しました。(Taiki Koshino) + + + rmコマンドの変数をクォートし、意図しない削除を防止しました: + rm -rf "${DEST_NODE_PGDATA}" + + + + + + + 指定なしでコンパイルする際のエラーを修正しました。(Tatsuo Ishii) + + + 指定なしでコンパイルするとエラーが発生していました。 + 対応として該当コードブロックを #ifdef USE_MEMCACHEDで囲みました。 + + + この問題はBo Pengによって報告されました。 + + + + + + + クエリキャッシュロックファイルの取り扱い修正を修正しました。(Tatsuo Ishii) + + + クエリキャッシュモジュールは並列制御のため logdir にロックファイルを作成しますが、 + メインプロセスがゴミファイルを作成したり、シャットダウン時に削除されない問題がありました。 + + + この問題はBo Pengによって報告・分析されました。 + + + + + + + ドキュメント修正 + + + + + 8.2. Pgpool-II + Watchdog Setup Example の "PostgreSQLスタンバイ設定" ドキュメントを更新しました。(Taiki Koshino) + + + オンラインリカバリなしでスタンバイを設定する場合、postgresql.auto.confに primary_conninfo を書き込まないよう注意を追加しました。 + + + ディスカッション: Follow primary command not fixing postgresql.auto.conf + + + + + + + watchdog_setupのマニュアルを修正しました。(Tatsuo Ishii) + + + heartbeartがwatchdog_setupに設定されていないと誤記されていた箇所を修正しました。 + + + + + + + 回帰テスト修正 + + + + + 023.ssl_connectionをPostgreSQL 18に対応するよう修正しました。(Tatsuo Ishii) + + + PostgreSQL 18でpsqlの \conninfo出力形式が大幅に変更されたため、 + このテストが失敗していました。 + PostgreSQLバージョンに応じてテストスクリプトを修正しました。 + + + + + + + 010.rewrite_timestampのRubyスクリプトを修正しました。(Tatsuo Ishii) + + + RubyのFile.existsは新しいバージョンで非推奨のため、File.existに置き換えました。 + + + + + + + 034と075のタイムアウトを調整しました。(Tatsuo Ishii) + + + 034.promote_nodeと075.detach_primary_left_down_nodeのスクリプト終了タイムアウトを60秒から120秒に変更し、 + 誤エラーが発生する可能性を減らしました。 + + + + + + + 023.ssl_connectionにssl_ecdh_curveのテストを追加しました。(Tatsuo Ishii) + + + 023.ssl_connectionはssl_ecdh_curveのテストをカバーしていなかったため、 + 不正なssl_ecdh_curveパラメータでフロントエンドとpgpoolの接続が失敗するか確認しました。 + + + + + + + + リリース 4.5.8 + + リリース日 + 2025-08-21 + + + + 不具合修正 + + + + + watchdog が不適切な NOTICE メッセージを出力する問題を修正しました。 (Tatsuo Ishii) + + + read_ipc_socket_and_process() は、IPCソケットへのコマンド書き込みのたびに、書き込みが成功した場合でも通知メッセージを出力していました。これを修正し、書き込みが失敗した場合にのみ通知メッセージを出力するようにしました。 + log_min_messages が notice 以上に設定されている場合にのみメッセージが表示されるため、このバグが発見されていませんでした。 + + + ディスカッション: pgpool IPC socket connection issue + + + + + + + + スタートアップパケットを読んでいるときのメモリーリークを修正しました。(Tatsuo Ishii) + + + pool_push_pending_data でのリソースリークを修正しました。 + + + + + + + ビッグエンディアンマシン上の scram-sha-256 認証の不具合を修正しました。(Tatsuo Ishii) + + + scram-sha-256 認証を実行する際、ハッシュ関数 pg_sha_256_final が使用されます。 + これは PostgreSQL からインポートされたもので、プリプロセッサ定義 WORDS_BIGENDIAN を使用してホストマシンのエンディアンを判断します。 + WORDS_BIGENDIAN は configure 時に定義する必要がありますが、pg_sha_256_final(およびその他)が PostgreSQL からインポートされた際にこの部分が省略されていました。 + その結果、scram-sha-256 はリトルエンディアンマシンでのみ動作していました。 + configure.ac に AC_C_BIGENDIAN マクロを追加することでこの問題を修正しました。。 + + + この問題は Christoph Berg によって報告され、 pranavkaruvally によって分析されました。 + + + ディスカッション: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + ソースコードのタイプミスを修正しました。 (Bo Peng) + + + + + + + ハートビートデバイスの処理を修正しました。(Tatsuo Ishii) + + + pgpool.conf の処理中に、heartbeat_device が誤って処理され、最初のデバイスが無視されていました。 + + + この問題は Bo Peng によって分析されました。 + + + + + + + pgpool.confのコメントのタイプミスを修正しました。 (Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + 「8.3. ネイティブレプリケーション/スナップショットアイソレーションモードの構築の例」のドキュメントを改善しました。(Taiki Koshino) + + + サンプルスクリプトのリンクと「事前設定」の説明を改善しました。 + + + + + + + リロードによって反映されないパラメータのドキュメントを修正しました。 (Taiki Koshino) + + + authentication_timeoutmemqcache_oiddir はリロードしても反映されません。 + ドキュメントが「このパラメータはサーバー起動時にのみ設定できます。」に変更されました。 + + + + + + + + watchdog リーダーの用語を統一しました。(Tatsuo Ishii) + + + 以前は「leader」「active」「coordinater」という用語が、watchdog のリーダーノードを指すために使用されていました。このコミットではこれらを「leader」に統一しました。 + advanced.sgml も修正しました。 + + + + + + + + サンプルスクリプトを修正しました。(Taiki Koshino) + + + 「8.2. Pgpool-II + Watchdogの構築の例」のサンプルスクリプトを修正しました。 + + + + + + + ロードバランスの説明で論理レプリケーションモードと Slony モードが抜けている問題を修正しました(Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Bo Peng) + + + 「replication_state」と「replication_sync_state」を正しく表示するには、各 backend_application_nameXprimary_conninfoapplication_name に指定された値と一致する必要があることを明確にしました。 + + + + + + + カーネルの資源に関するセクションを追加しました。 (Tatsuo Ishii) + + + Pgpool-II は System V の共有メモリとセマフォを使用します。 + 要件についてはドキュメントを参照することをお勧めします。 + + + + + + + configure の オプションの説明を追加しました。(Tatsuo Ishii) + + + これは LDAPサポートがv4.2で導入されたときに見落としていました。 + + + + + + + Pgpool-II でサポートされているプラットフォームを明確にしました。 (Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Tatsuo Ishii) + + + + + + + 回帰テスト修正 + + + + + 029.cert_passphrase 回帰テストを安定化しました。 (Tatsuo Ishii) + + + ssl_passphrase_command が有効でない場合、エラーメッセージは通常「bad decrypt」ですが、「wrong tag」となる場合もありました。 + + + + + + + + リリース 4.5.7 + + リリース日 + 2025-05-15 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + Pgpool-IIのクライアント認証メカニズムには認証バイパスの脆弱性があります。 + 本来であれば認証が必要な場合でも、認証処理がスキップされてしまう可能性があります。 + この脆弱性を悪用することで、攻撃者が任意のユーザとしてログインし、データベース内の情報を参照・改ざんしたり、データベースを停止させたりすることができる可能性があります。(CVE-2025-46801) + + + なお、本脆弱性の影響を受けるのは、下記のパターン1から3いずれかの条件を満たす場合に限られます。 + + + + + パターン 1:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + pool_hba.confpassword認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードが設定されていない + + + + + pg_hba.confscram-sha-256またはmd5認証方式を使用している + + + + + + + + パターン 2:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + enable_pool_hba = off + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + + パターン 3:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + rawモードを使用している (backend_clustering_mode = 'raw') + + + + + pool_hba.confmd5認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードがテキストまたはAES形式で登録されている + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + この脆弱性の影響を受けるのは、Pgpool-II 4.0系および4.1系のすべてのバージョン、4.2.0-4.2.21、4.3.0-4.3.14、4.4.0-4.4.11、4.5.0-4.5.6、4.6.0です。 + Pgpool-II 4.6.1、4.5.7、4.4.12、4.3.15、4.2.22以降へのアップグレードを強くお勧めします。 + それができない場合は、発生条件パターンに当てはまらない設定の組み合わせに変更してください。 + + + + + 変更点 + + + + + 設定ファイルにメジャーバージョンを追加しました。 (Bo Peng) + + + + + + + 不具合修正 + + + + + クライアント認証が正しく実行されない場合があるのを修正しました。(Tatsuo Ishii) + + + enable_pool_hbaがonで、auth methodが"password"、pool_passwdにパスワードが登録されておらず、pg_hba.confの認証方式が"scram-sha-256"か"md5"の場合、クライアントが最初にpgpoolに接続したときには認証が期待通りに実行されます。 + しかし、クライアントがキャッシュされたコネクションに接続すると、任意のパスワードが通ってしまいます。 + + + また、enable_pool_hba = offのいくつかのケースでは、本来パスワードが聞かれるはずが、最初からパスワードが聞かれない、あるいはキャッシュされたコネクションに接続した時にはパスワードが聞かれないことがありました。 + + + 上記を修正するのに加え、以下の変更を行いました。 + + + + + 認証コードを単純化するために、PostgreSQLが1台の時のコードパスを削除しました。 + + + + + crypt認証のサポートをフロントエンドとバックエンドから削除しました。 + この機能はドキュメントに書かれておらず、テストもされていませんでした。 + また、crypt認証はPostgreSQLではだいぶ以前(8.4, 2009)に削除されています。 + + + + + 新しい回帰テストの"040.client_auth"を追加しました。 + このテストは、CSV形式のテスト設定ファイルを使って、包括的なクライアント認証のテストを実施します。 + + + + + + + + クエリキャッシュにおける、古くからあるバインド時のバグを修正しました。(Tatsuo Ishii) + + + 名前付きステートメントを準備すると、バインド後にパースメッセージなしで実行することが可能です。 + 問題は、実行時またはCOMMIT時にクエリキャッシュを無効化するために必要なテーブルOIDが、パースメッセージ処理(Parse())でのみ収集されていたことです。 + そのため、前回の実行後にパースなしでバインドを実行すると、テーブルOIDが収集されず、pgpoolはクエリキャッシュの無効化に失敗していました。 + バインド時にもテーブルOIDを収集するよう修正しました。 + 006.memqcacheに回帰テストを追加しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + クエリキャッシュの無効化に失敗する問題を修正しました。 (Tatsuo Ishii) + + + 実行メッセージを受信すると、pgpoolは最大行数パラメータをチェックします。この値が0でない場合、pgpoolはpool_handle_query_cache()にクエリキャッシュを作成しないよう指示するために、"partial_fetch"フラグを設定します。 + 問題は、コミット2a99aa5d1が、INSERT/UPDATE/DELETEであっても実行メッセージパラメータが0以外(ほとんどの場合1)に設定され、pgpoolがSELECT以外の場合でもこのフラグを設定することを見落としていることです。 + この結果、このフラグが true の場合、pool_handle_query_cache() 内の後続のコードでキャッシュの無効化がスキップされるため、クエリキャッシュの無効化に失敗していました。 + フラグを設定する前にクエリが読み取り専用の SELECT であるかどうかを確認するように Execute() を修正しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + OpenBSDへ移植する際の問題を修正しました。 (Tatsuo Ishii) + + + ディスカッション: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + このパッチはMartijn van Durenによって作成されました。 + + + + + + json_writerが特殊文字を正確にエンコードできない問題を修正しました。(Bo Peng) + + + が特殊文字を含んでいる状態でwatchdogを起動するとPgpool-IIがクラッシュしていました。 + + + このパッチはMartijn van Durenによって作成され、Bo Pengによって微修正されました。 + + + + + + リロード時にを開くようにストリーミングレプリケーションチェックとヘルスチェックプロセスを修正しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションチェックとヘルスチェックはリロード前にを開いていませんでした。 + もしが空文字列の時は、からパスワードを得ます。 + そのためこれらのプロセスはリロード時にの古いコンテンツを読み取ります。 + + + + + + ドキュメント修正 + + + + + の説明を改善しました。(Tatsuo Ishii) + + + が計算されるタイミングは、接続キャッシュを保持しているプロセスからクライアントが切断されたときであることを追記しました。 + + + ディスカッション: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + についての説明を改善しました。 (Tatsuo Ishii) + + + スーパーユーザーかpg_monitorグループであるべきです。 + + + + + + + 回帰テスト修正 + + + + + 回帰テストで複数のソケットディレクトリを使用できるように修正しました。(Taiki Koshino, Tatsuo Ishii, Bo Peng) + + + + + + + + リリース 4.5.6 + + リリース日 + 2025-02-28 + + + + 変更点 + + + + + サンプルフォロープライマリスクリプトからpg_basebackupの処理を削除しました。(Bo Peng) + + + pg_rewindが失敗した場合、ユーザーにとって最も安全な方法は手動で復旧することです。 + + + + + + + 不具合修正 + + + + + per_node_error_log()のエラーメッセージでコロンが重複して出力される不具合を修正しました。(Bo Peng) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + pool_signalの不具合を修正しました。(Tatsuo Ishii) + + + 以前は、pool_signalSA_RESTARTフラグを設定していませんでした。 + そのため、シグナルによって中断されたシステムコールは再起動されません。 + 一部のコードは、システムコールがシグナルによって中断された場合に再起動するように準備されています。 + しかし、すべての箇所で対応できているかは不明なため、フラグを追加しました。 + なお、PostgreSQLでは常にこのフラグが使用されています。 + + + + + + + パラメータにデフォルト値以外のファイルが指定されている場合に、pg_md5pg_encがパスワードファイルを更新しない問題を修正しました。(Bo Peng) + + + この問題はSadhuprasad Patroによって報告されました。 + + + + + + + ストリーミングレプリケーションモードにおけるクエリキャッシュのいくつかの不具合を修正しました。(Tatsuo Ishii) + + + + + クエリキャッシュが有効で、フロントエンドから実行メッセージが送信された場合、クエリキャッシュデータが使用可能であれば、Pgpool-IIはそのデータをバックエンドメッセージバッファに挿入します。 + しかし、キャッシュされたメッセージが不適切な位置に挿入されることで、Pgpool-IIが誤って「kind mismatch」エラーを発生させることがありました。 + + + + + また、クエリキャッシュが有効で、クエリが拡張クエリモードで実行されている場合に、Pgpool-II がストリーミングレプリケーションモードで動作していると、実行メッセージが誤った結果を返す可能性がありました。 + + + + + さらに、複数の実行メッセージが連続して送信された場合、Pgpool-IIは各実行メッセージに対してクエリキャッシュから同じ結果を返していましたが、これは誤りです。 + 本来、2回目以降の実行では0行が返されるべきでした。 + + + ディスカッション: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + ドキュメント修正 + + + + + クライアント認証の章を強化しました。(Tatsuo Ishii) + + + pool_passwdに関する説明部分を追加しました。 + これまで、概要ページにはpool_hba.confの説明のみが記載されていましたが、今回pool_passwdの一般的なガイドを追加しました。 + これにより、ユーザーがこの章をより理解しやすくなりました。 + + + + + + + 回帰テスト修正 + + + + + 032.dml_adaptive_loadbalanceテストの安定性を向上させました。(Tatsuo Ishii) + + + + + + + + リリース 4.5.5 + + リリース日 + 2024-11-28 + + + + 不具合修正 + + + + + + バックエンドがエラーメッセージを送信した場合に、SSLネゴシエーションを中止するよう修正しました。(Tatsuo Ishii) + + + SSLネゴシエーションのクライアント側実装(pool_ssl_negotiate_clientserver())では、 + 中間者攻撃者がSSLネゴシエーションフェーズ中に長いエラーメッセージを送信することで、 + Pgpool-IIやクライアントを混乱させる可能性がありました。 + このコミットでは、ネゴシエーションを直ちに拒否(FATALエラーを発行)し、 + そのような攻撃を防ぐためにセッションを終了するよう修正しました。 + + + これは、PostgreSQLのCVE-2024-10977に似ています。 + + + + + + + リロード処理がWatchdogプロセスに反映されない問題を修正しました。(Bo Peng) + + + Pgpool-IIの + reload_config()関数は、 + WatchdogププロセスにSIGHUPシグナルを送信する必要がありました。 + + + + + + + do_query関数の不具合を修正しました。(Tatsuo Ishii) + + + htons/htonlの代わりにntohs/ntohlを使用するようにdo_queryを修正しました。 + + + + + + + pool_passwdを更新してリロードした後の認証失敗問題を修正しました。(Tatsuo Ishii) + + + pool_hba.confが無効になっている場合、Pgpool-IIのリロードが実行されても、Pgpool-IIの子プロセスはpool_passwdの更新を認識しませんでした。 + リロード処理関数check_config_reload()は、が有効な場合にのみpool_passwdを再オープンする必要があると誤って判断していたことが原因でした。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html + + + + + + + COPYがハングする問題を修正しました。(#79) (Tatsuo Ishii) + + + COPY IN状態(つまり、COPY FROM STDIN)中、フロントエンドはFlushまたはSyncメッセージを送信できます。 + F/Bプロトコル仕様によると、これらは無視されるはずですが、Pgpool-IIは無効なメッセージとして処理し、これがCOPYのハングの原因でした。 + + + リグレッションテストも追加しました。 + + + + + + + シャットダウン中にPgpool-IIの子プロセスがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + 実際のクラッシュはclose_all_backend_connections()内で発生していました。 + この関数は、on_system_exitchild_will_go_down()を登録するために呼び出されます。 + この時点では、Pgpool-II子プロセスが起動し、pool_init_cp()を実行した直後であるようです。 + 接続プールオブジェクトが完全に初期化されていなかったため、クラッシュが発生していました。 + + + この問題はEmond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + 認証失敗による散発的なヘルスチェックの失敗を修正しました。(Tatsuo Ishii) + + + が空文字列の場合、ヘルスチェックプロセスはpool_passwdファイルからパスワードを検索します。 + 問題は、このファイルのファイルディスクリプタが親pgpoolプロセスから継承されている点です。 + pgpoolメインプロセスとヘルスチェックプロセス(複数存在する可能性あり)が同じディスクリプタを共有するため、さまざまな問題が発生していました。 + この問題を解決するために、ヘルスチェックプロセスが開始される際にファイルを再度開き、 + それぞれのヘルスチェックプロセスが独自のファイルディスクリプタを持つようにしました。 + + + なお、pgpoolの子プロセス(フロントエンドセッションを担当)はすでにファイルディスクリプタを再度開く処理を行っており、これが今回の問題には関連していません。 + + + この問題は、Emond Papegaaijによって報告され、分析されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + ALTER ROLEのクエリキャッシュ無効化を最適化しました。(Tatsuo Ishii) + + + コミット6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89は、ALTER ROLE/USERステートメントが使用される際にクエリキャッシュを無効にしています。 + しかし、実際にはこれが過剰です。 + 次のクエリはロールの権限に影響を与えないため、クエリキャッシュを無効にする必要はありません。 + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + したがって、これらのコマンドが使用される場合には、クエリキャッシュを無効にしないようにしました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Pgpool-IIの子プロセスが終了したときにPgpool-IIがクラッシュする問題を修正しました。(Tatsuo Ishii) + + + Pgpool-IIの子プロセスが終了すると、close_all_backend_connections()が呼び出され、接続プール内のすべてのバックエンド接続が閉じられます。 + しかし、誤ってMAIN_CONNECTIONマクロが使用されていました。 + このマクロは現在アクティブな接続には適していますが、接続プールが作成された時点でのメインノードが異なる可能性があるため、プールされた接続には適していませでした。 + この問題を修正するために、代わりにin_use_backend()を使用するよう変更しました。 + + + Emond Papegaaijによって報告されました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードのバグを修正しました。(#69) (Tatsuo Ishii) + + + INSERTコマンドを受信すると、Pgpool-IIはターゲットテーブルに対して自動的にテーブルLOCKコマンドを発行しますが、メインノード以外のノードにコマンドを送信し忘れていました。 + この問題は拡張クエリモードの場合にのみ発生していました。 + + + + + + + ネイティブレプリケーションモードとスナップショットアイソレーションモードの別のバグを修正しました。(Tatsuo Ishii) + + + insert_lock()は、メインノード以外のノードに行ロックコマンド(lock_kind == 3 の場合)を送信するのを忘れていました。 + + + + + + + pool_memqcache.cのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はコミット6fdba5c33によって導入されました。 + + + + + + + + ドキュメント修正 + + + + + ドキュメントとサンプル設定ファイルのタイポを修正しました。(Bo Peng) + + + + + + + 回帰テスト修正 + + + + + テスト024.cert_authをOpenSSL 3.2に対応するよう修正しました。(Tatsuo Ishii) + + + + + + + + リリース 4.5.4 + + リリース日 + 2024-09-09 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + クエリキャッシュ機能()が有効な時に、データベースユーザがクエリキャッシュ経由で本来読み出せない行を読むことが可能でした。(CVE-2024-45624) + + + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22より古く、クエリキャッシュ機能を持つすべてのバージョン(クエリキャッシュ機能は3.2で実装されました)がこの脆弱性の影響を受けます。 + + + + + + あるユーザのクエリキャッシュがテーブルに対して作成されていると、そのテーブルへのアクセス権がREVOKEコマンドで剥奪されても、アクセス権を持たないそのユーザがクエリキャッシュを通じてテーブルにアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュがテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、アクセス権を持たないBがクエリキャッシュを通じてアクセスすることが可能でした。 + + + + + + ユーザAのクエリキャッシュが行セキュリティが有効なテーブルに対して作成されていて、同じセッション内でSET ROLEあるいはSET SESSION_AUTHORIZATIONで他のユーザBに切り替えてそのテーブルにアクセスすると、本来Bが見えない行をクエリキャッシュを通じて取り出すことが可能でした。 + + + + + Pgpool-II 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22以降へのアップグレードを強くお勧めします。 + それができない場合は、クエリキャッシュ機能を無効にしてください。 + + + なお、この脆弱性を修正するために、いくつかのコマンド(ALTER DATABASE, ALTER ROLE, ALTER TABLE, REVOKE)を実行すると、クエリキャッシュのすべてのデータを削除するようになりました。 + これにより、クエリキャッシュの性能に影響があるかも知れません。 + + + + + 不具合修正 + + + + + + レプリケーションモードとスナップショットアイソレーションモードで発生する複数の不具合を修正しました。(Tatsuo Ishii) + + + 次の不具合を修正しました。 + + + + + レプリケーションモードおよびスナップショットアイソレーションモードでコマンドを実行すると、Pgpool-IIはクエリ準備完了メッセージを待ちますが、一部のコマンド(SET ROLEなど)がパラメータステータスメッセージを生成することを忘れていました。 + その結果、Pgpool-IIはクエリ準備完了メッセージの前に他のメッセージが到着したことをエラーとして出力していました。 + + + + + + 前のクエリがパラメータステータスメッセージを生成した場合、後続のparse()はそれを読み取って処理する必要があります。 + これは、パラメータステータスメッセージの後に続くはずのクエリ準備完了メッセージを読み取る必要があるためです。 + + + ただし、ParameterStatus()が呼び出されると、クエリ進行中フラグが設定され、このparse()呼び出しで処理されるクエリが負荷分散されている場合、バックエンドからのパラメータステータスメッセージの1つだけが処理される可能性がありました。 + パラメータステータスメッセージはSETコマンドによって生成され、SETコマンドはレプリケーションモードおよびスナップショットアイソレーションモードのすべての生きているバックエンドに送信されるため、すべての生きているバックエンドから送信される可能性がありました。 + そのため、ParameterStatus()を呼び出す前に、クエリ進行中フラグを設定解除するように修正しました。 + + + + + + + + + + + リリース 4.5.3 + + リリース日 + 2024-08-15 + + + + 変更点 + + + + + + サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 (Bo Peng) + + + postgresqlxx-serverがインストールされていない可能性があるため、サンプルスクリプトでinitdb -Vの代わりにpsql -Vを使用するように修正しました。 + + + + + + + + 不具合修正 + + + + + + フラッシュメッセージを受信した後にハングする問題を修正しました。 (#59) (Tatsuo Ishii) + + + + + + + セグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Pgpool-IIの子プロセスがpool_do_authでセグメント違反になることがありました。 + 原因はMAIN_CONNECTION()がNULLを返すことでした。 + my_main_node_idが不正なノードID 0に設定されていたようですが、これは実際にはダウン状態でした。 + そのため、cp->slots[0]には接続がありませんでした。 + + + この問題はEmond Papegaaijによって報告されました。 + Discussion: [pgpool-general: 9175] + + + + + + + 動的プロセス管理を修正しました。 (Tatsuo Ishii) + + + プロセス排除アルゴリズムで使用されるpooled_connectionの計算が正しくありませんでした。 + 数値は常にmax_poolになっていました。 + + + Discussion: [pgpool-hackers: 4490] + + + + + + + 設定ファイルの解析時に発生するセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 設定値が一重引用符で囲まれていない場合にpgpool.confを解析するときにセグメンテーション違反が発生していました。 + + + このパッチはCarlos Chapiによって作成され、Tatsuo Ishiiによってレビューおよび修正されました。 + + + + + + + MAIN_NODEマクロを使用しないようにセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + 一部の関数 (close_idle_connection()、new_connection()、pool_create_cp())では、MAIN*とVALID_BACKENDが不適切な場所で使用されていました。 + MAIN*とVALID_BACKENDは、バックエンドへの現在の接続に対してのみ有効であり、プールされた接続には有効ではありません。 + プールされた接続では、どのバックエンドがメインノードであるか、または稼働中であるかは、バックエンドへの現在の接続と必ず同じであるためです。 + これらのマクロを誤って使用すると、セグメンテーション違反が発生することがありました。 + + + この問題はEmond Papegaaij によって報告されました。 + Discussion: [pgpool-general: 9114] + + + + + + + MAIN_NODEマクロ(実際は pool_virtual_main_db_node_id())を修正しました。 (Tatsuo Ishii) + + + セッションコンテキストがない場合、マクロはREAL_MAIN_NODE_IDに使用されます。 + フェイルオーバー/フェイルバックが発生すると、いつでもREAL_MAIN_NODE_IDが変更される可能性があるため、これは誤りでした。 + + + REAL_MAIN_NODE_ID == my_main_node_id == 1と仮定します。 + その後、フェイルバックにより、REAL_MAIN_NODE_IDは0に変更されます。 + その後、MAIN_CONNECTION(cp)はNULLを返し、これへの参照はセグメンテーションエラーを引き起こします。 + この問題を回避するには、代わりにmy_main_node_idを返すように修正しました。 + + + + + + + show pool_processesで行の説明が2回表示されないように修正しました。(Tatsuo Ishii) + + + processes_reporting()が誤ってsend_row_description()とsend_row_description_and_data_rows()の両方を呼び出していました。 + + + Discussion: [pgpool-hackers: 4471] + + + + + + + 子プロセスでのセグメンテーション違反を修正しました。 (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + ネットワークが短時間中断されると、Watchdogが停止し、Pgpool-IIが強制終了する問題を修正しました。 (#823) (Muhammad Usama) + + + ネットワーク監視を有効にすると、Pgpool-IIノードはすべてのネットワークインターフェイスまたは割り当てられたIPアドレスを失った場合に直ちにシャットダウンし、通信できないノードをクラスタからすばやく削除することで追加の保護を提供します。 + + + 問題は、ネットワーク監視が無効になっている場合でも、Pgpool-IIがネットワークブラックアウトイベントに応答していたことです。 + この修正により、ネットワーク監視が有効になっていない場合にネットワーク監視ソケットがオープンされなくなり、不要なシャットダウンが防止されます。 + + + + + + + Watchdogが有効な場合にpgpool resetコマンドが動作しない問題を修正しました。 (Tatsuo Ishii) + + + バグはkeiseoによって報告・問題分析されました。 + Disscussion: [pgpool-hackers: 4465] + + + + + + + psql_scanのクラッシュを修正しました。 (#54) (Tatsuo Ishii) + + + 長いクエリ内の文字列がpsql変数(つまり「:」で始まる)であるかどうかを判別しているときに、psql_scanがクラッシュする問題がありました。 + + + + + + + + ドキュメント修正 + + + + + + ドキュメントとプログラムソースコードの大量なタイポミスを修正しました。(Tatsuo Ishii) + + + パッチはUmar Hayatによって作成されました。 + + + + + + + 強制終了するプロセスを選択するための基準をのドキュメントに追加しました。(Bo Peng) + + + + + + + フェイルオーバーのドキュメントを改良しました。(Tatsuo Ishii) + + + が有効な場合のフェイルオーバーの条件を明確にしました。 + + + + + + + 仮想IP関連パラメータのデフォルト値をドキュメントに追加しました。(Bo Peng) + + + + + + + + + リリース 4.5.2 + + リリース日 + 2024-05-16 + + + + 不具合修正 + + + + + -Werror=implicit-function-declarationオプションで発生するコンパイルエラーを修正しました。(Bo Peng) + + + 非推奨のldap関数のプロトタイプを含めるためにLDAP_DEPRECATEDを追加しました。 + また、autoconfチェックで不足していたヘッダーファイルを追加しました。 + + + パッチはVladimir Petkoによって作成されました。 + + + + + + + セグメンテーション違反のさまざまな原因を修正しました。(Tatsuo Ishii) + + + フェイルオーバーが関与している特定のケースでは、Pgpool-IIとその子プロセスのセグメント違反が発生していました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + 初期化されていないメモリエラーを修正しました。(Tatsuo Ishii) + + + read_startup_packetの初期化されていないメモリエラーを含むいくつかのエラーがvalgrindによって報告されました。 + valgrindは、キャンセルまたはSSL要求の場合にpallocを使用してスタートアップパケット内のユーザー名にメモリを割り当て、その後、そのメモリがpstrdupによって使用されます。 + pallocによって割り当てられたメモリは未定義であったため、これをpalloc0に修正しました。 + + + この問題は、Emond Papegaaijによって報告・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + load_balance_modeがオフの場合に発生するエラー/ハングアップを修正しました。(Tatsuo Ishii) + + + load_balance_modeがオフで、プライマリノードIDが0でない場合には、BEGINなどクエリでエラー/ハングアップが発生していました。 + コミット 3f3c1656の修正によって導入された問題です。 + + + バグはEmond Papegaaijによって発見・分析されました。 + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + 特定のCFLAGSによるコンパイルエラーを修正しました。(Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42によって報告されました。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + サンプルpgpool.conf内のコメントを修正しました。(Bo Peng) + + + sr_check_periodのデフォルト値は10秒であるため、修正しました。コメント内のいくつかのタイポも修正しました。 + + + パッチはhiroinによって作成され、Bo Pengによって修正されました。 + + + + + + + configディレクトリ配下のファイルを削除しました。(Takuma Hoshiai) + + + autoconfによって生成されるMakefile.inなどを削除しました。 + src/config配下に.gitignoreを作成し、bisonとflexによって生成されるファイルを追加しました。 + + + + + + + 拡張クエリが終了していない場合でもリセットクエリを実行できるようにしました。(Tatsuo Ishii) + + + コミット240c668dが原因で、拡張クエリメッセージが終了していない場合、リセットクエリが失敗していました。 + このコミットでは、SimpleQuery()でリセットクエリを実行しているかどうかをチェックすることで、この問題を修正しました。 + また、テストケースも追加しました。 + + + + + + + Coverityによって指摘されたメモリリークを修正しました。(Takuma Hoshiai) + + + + + + + 不適切なプロトコルデータから保護するように修正しました。(Tatsuo Ishii) + + + 拡張クエリメッセージのシーケンスが終了する前にシンプルクエリメッセージが到着すると、Pgpool-IIがハングする可能性がありました。 + これは、シンプルクエリのセッションコンテキスト内のクエリコンテキストが、拡張クエリメッセージのクエリコンテキストによって上書きされたためです。 + + + このコミットでは、拡張クエリプロトコルメッセージが終了したかどうかをチェックするように実装しました。 + 終了していない場合は、FATALエラーを発生させます。このチェックによって検出された既知の例は、JDBCドライバーの「autosave=always」オプションです。 + つまり、このコミットの後、問題(拡張クエリメッセージプロトコルが終了する前にシンプルプロトコルメッセージを送信する)がJDBCドライバー側で修正されるまで、 + Pgpool-IIはこのオプションを受け入れません。 + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + ドキュメント修正 + + + + + + 「上位サーバへの接続」ドキュメントを改善します。(Bo Peng) + + + + + + + 日本語ドキュメントの言語クリーンアップしました。(Masaya Kawamoto) + + + + + + + PostgreSQLノードが2台の場合にpcp_promote_nodeを使用する際の注意点を追加しました。(Masaya Kawamoto) + + + PostgreSQLノードが2台であっても、follow_primary_commandを設定する必要があるケースがあります。 + + + + + + + + 回帰テスト修正 + + + + + 037.failover_sessionを修正しました。(Tatsuo Ishii) + + + テストスクリプトは終了前にshutdownallを実行するのを忘れていました。 + + + + + + + Java 21での非推奨警告を回避するために回帰テスト005.jdbcを修正しました。(Bo Peng) + + + Java 21での非推奨警告を回避するには、Runtime.exec(String)をRuntime.exec(String[])に置き換えました。 + + + パッチはVladimir Petkoによって作成され、Bo Pengによって修正されました。 + + + + + + + + + リリース 4.5.1 + + リリース日 + 2024-02-29 + + + + 変更点 + + + + + サンプルスクリプトからrestore_commandの設定を削除しました。 (Bo Peng) + + + レプリケーションスロットが有効になっているため、restore_commandは不要です。 + この設定により、フェールオーバーが失敗するケースがあるからです。 + + + + + + + 不具合修正 + + + + + , + および + のデフォルト値を修正しました。 (Bo Peng) + + + recovery_userデフォルト値はと同じである必要があるため、 + デフォルト値を''から'nobody'に変更しました。 + + + failover_on_backend_shutdownの正しいデフォルト値は「false」、 + insert_lockの正しいデフォルト値は「on」であるため、修正しました。 + + + + + + + BEGINなどでのの不具合を修正しました。 (Tatsuo Ishii) + + + statement_level_load_balanceが有効な場合、 + が無効であっても、 + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE ALL/DISCARDがプライマリノードとすべてのスタンバイノードに送信されていました。 + これは明らかに間違っているだけでなく、スタンバイノードの1つがリモートネットワークにある場合、速度が低下する原因となります。 + + + load_balance_modeがオフの場合、 + Pgpool-IIはそのようなクエリをプライマリノードにのみ送信するように修正しました。 + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + ドキュメント修正 + + + + + 日本語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + Watchdog「リーダー」ではなく「マスター」を誤って使用していました。 + + + + + + + 英語のWatchdogドキュメントを修正しました。 (Tatsuo Ishii) + + + PostgreSQL「プライマリ」ではなく「メイン」を誤って使用していました。 + + + + + + + 日本語のドキュメントの間違いを修正しました。 (Bo Peng) + + + 単位を指定しない場合は、秒でなく、ミリ秒と見なします。 + + + + + + + 回帰テスト修正 + + + + + 037.failover_session/test.shを強化しました。 (Tatsuo Ishii) + + + 以前は、pgbenchをバックグラウンドで起動した後、誤ってpg_ctl stopを実行していました。 + スマートシャットダウンでは、クライアントセッションの継続中にバックエンドがシャットダウンしないため、 + pgbench -Cオプションが設定されていない状態でも pgbenchを常に正常に実行できました。 + + + pgbenchの実行中にバックエンドをシャットダウンするには、バックエンドのダウンをできるだけ早く検出できる + ようにヘルスチェックパラメーターを調整するように修正しました。 + これにより、pgbenchの実行中にフェイルオーバーがトリガーされるようになります。 + + + + + + + + リリース 4.5.0 + + リリース日 + 2023-12-12 + + + + 概要 + + このリリースでは、マルチステートメントの適用範囲や、一部のセッション切断問題など、いくつかの長年の問題が解決されました。 + また、構成と管理を容易にするために、多くの機能拡張も追加されています。 + + + + 主な機能拡張は以下の通りです。 + + + + + + クエリ文字列内でより多くの場合にマルチステートメントを使用できるようになりました。 + + + + + + PREPARE/EXECUTE/DEALLOCATEの負荷分散が可能になりました。 + + + + + + をミリ秒単位で設定できるようになりました。 + + + + + + フェイルオーバ、フェイルバック、およびバックエンドエラー発生時の一部のセッション切断問題を改善しました。 + + + + + + 特定のユーザ接続からの参照クエリを特定のバックエンドノードに振り分けできるようになりました。 + + + + + + で複数のディレクトリを指定できるようになりました。 + + + + + + PostgreSQL 16のSQLパーサを取り込みました。 + + + + + + + + + バージョン4.5への移行 + + + + + 次の通常のERRORメッセージをDEBUGメッセージにダウングレードしました。(Bo Peng) + + + + + 次の2つのメッセージは、クライアントがpgpoolへの接続を切断する前に終了メッセージを送信しなかった場合に発生します。 + たとえば、クライアントプロセスが強制終了された場合に、このエラーが発生します。これらのメッセージは無害ですが、場合によってはユーザを混乱させる可能性があります。 + + +ERROR:unable to flush data to frontend + + +ERROR: unable to read data from frontend +DETAIL: EOF encountered with frontend + + + + + がゼロ以外の値に設定されている場合、クライアントが前回のクエリからアイドル状態のままでいるときに、コネクションは切断されます。 + このコネクションの切断はPgpool-IIの設定によるものなので、ERRORではなくDEBUGとして処理すべきです。 + + +ERROR: unable to read data +DETAIL: child connection forced to terminate due to client_idle_limit:30 is reached + + + + + + + + + PCPコマンドで-w/--no-passwordオプションを指定しなくても、パスワードファイル (~/.pcppass) に格納されたパスワードを使用するように動作を変更しました。(Chen Ningwei) + + + 以前はパスワードファイル (~/.pcppass) に格納されたパスワードを使用するために、オプションを指定する必要があり、PostgreSQLの動作と一致していませんでした。 + + + + + + + 変更点 + + + + + + パラメータ用のサンプルスクリプトescalation.sh.sampleでSSH接続時のタイムアウト時間を指定するようにしました。(Bo Peng) + + + + + + + をミリ秒単位で設定できるようにしました。(Tatsuo Ishii) + + + 以前は秒単位での設定のみが許可されていました。リファクタリングも行いました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004372.html + + + + + + + PostgreSQL 16の新しいパーサーを取り込みました。(Chen Ningwei) + + + PostgreSQL 16パーサーの主な変更点は次のとおりです。 + + + + + + COPY FROMに新しいオプションDEFAULTが追加されました。 + + +COPY ... FROM stdin WITH (default 'xx'); + + + + + + CREATE TABLEでSTORAGEタイプを指定できるようになりました。 + + +CREATE TABLE t1 ( + c1 VARCHAR(10) STORAGE PLAIN, + c2 TEXT STORAGE EXTENDED +); + + + + + + パラメータ化されたクエリの汎用プランを表示するために、EXPLAINオプションGENERIC_PLANが追加されました。 + + +EXPLAIN (GENERIC_PLAN) SELECT ...; + + + + + + FROM句のサブクエリでエイリアスを省略できるようになりました。 + + +SELECT COUNT(*) FROM (SELECT ... FROM ...); + + + + + + SQL/JSONコンストラクターが追加されました。 + + + + + + VACUUMオプションが追加されました。 + 凍結されたすべての統計情報をスキップまたは更新するVACUUMオプションSKIP_DATABASE_STATS、ONLY_DATABASE_STATSが追加されました。 + TOASTテーブルのみを処理するVACUUMオプションPROCESS_MAINが追加されました。 + + +VACUUM (SKIP_DATABASE_STATS); +VACUUM (PROCESS_MAIN FALSE) t1 ; + + + + + + + + + 新しいフィールドload_balance_nodeに追加しました。(Tatsuo Ishii) + + + クライアントセッションがロードバランスノードとして使用されている場合は、load_balance_nodeフィールドが「1」になります。 + これらのコマンドを実行することで、バックエンドをロードバランスノードとして使用するセッションであるかどうかを確認できます。 + その場合は、バックエンドをシャットダウンするとセッションが切断される可能性があります。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-July/004353.html + + + + + + + フェイルオーバ、フェイルバック、およびバックエンドエラー発生時の一部のセッション切断の問題を軽減しました。(Tatsuo Ishii) + + + 以前は、Pgpool-IIはさまざまな場合にクライアントセッションを切断していました。 + このリリースでは、フェイルオーバ、フェイルバック、およびバックエンドエラーの発生時に、ダウンしたバックエンドがプライマリまたはメインノードではなく、ロードバランスノードでもない一部の場合に、セッションを切断しないようになりました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-July/004352.html + + + + + + + 特定のユーザからの参照クエリを特定のバックエンドノードに振り分けできるように、設定パラメータを追加しました。(Bo Peng) + + + + + + + で複数のディレクトリ指定できるようになりました。(Chen Ningwei) + + + + + + + PREPARE/EXECUTE/DEALLOCATEの負荷分散が可能になりました。(Tatsuo Ishii) + + + 以前は、PREPARE/EXECUTE/DEALLOCATEは負荷分散されませんでした。 + ストリーミングレプリケーション/論理レプリケーションモードでは、常にプライマリノードに送信されていました。 + ネイティブレプリケーション/スナップショットアイソレーションモードでは、常にすべてのノードに送信されていました。 + + + このリリースでは、PREPAREおよびEXECUTEコマンドによるプリペアドステートメントで読み取りのみの場合に負荷分散できるようになりました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004334.html + + + + + + + PCPプロセスの正常な起動および停止ログの出力を無効にする設定パラメータを追加しました。(Tatsuo Ishii) + + + 以前はpcpコマンドを実行するたびに、エラーがなくても、fork/exitログが記録されていました。 + + + パラメータが無効になっている場合でも、異常なfork/exitイベントはログに記録されます。 + + + パッチはMaximilien Cuonyによって作成され、Tatsuo Ishiiによってレビューされました。 + + + + + + + マルチステートメントを幅広く使用できるようにしました。(Tatsuo Ishii) + + + このリリースでは、複数のステートメント(マルチステートメント)に関するPgpool-IIの長年の制限を排除しました。 + たとえば、以下のようなクエリは以前はエラーになっていました。 + +BEGIN;SELECT; +SAVEPOINT foo; + + + + なお、依然として、マルチステートメントの各クエリは負荷分散されないことに留意してください。 + + + この機能は新機能ですが、バグ修正の意味合いもあるので、4.4~4.1にバックポートしています。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + マルチステートメントのクエリを判定するために、psqlscanのソースコードをPgpool-IIにインポートしました。(Tatsuo Ishii) + + + psqlscanは、PostgreSQLソースツリー内のモジュールです。 + これは本質的にPostgreSQLSQLスキャナのサブセットですが、各SQLステートメントの終わりの検出に特化しています。 + したがって、これを使用してクエリ文字列内のSQLステートメントの数をカウントできます。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004291.html + + + + + + + 新しい設定パラメータを追加しました。(Tatsuo Ishii) + + + この新しいパラメータを有効にすると、バックエンドごとにクエリのNOTICEメッセージを発行できます。 + これはに似ていますが、ログレベルがNOTICEであるため、ログはクライアントの端末に出力されるため、ユーザはpgpoolログファイルを調べなくてもクエリの宛先を知ることができます。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004276.html + + + + + + + ステータスファイルの読み込みに関するログを強化しました。(Tatsuo Ishii) + + + 以前はpgpool_statusが存在し、ステータスがダウンの場合にのみ、ログメッセージが出力されていました。 + しかし、ステータス(稼働中または未使用)に関係なく、pgpool_statusが存在し、pgpoolの起動時に読み取られたことが有用な情報です。 + + + + + + + gitリポジトリからpool_config.cscan.cを削除しました。(Tatsuo Ishii) + + + これらは自動的に生成されるファイルなので、gitリポジトリに保存すべきではありません。 + + + + + + + autoconfで生成されるMakefile.inなどを削除しました。(Tatsuo Ishii) + + + また、いくつかの .gitignoreファイルを更新し、いくつかの新しい.gitignoreファイルを追加しました。 + 生成されたファイルはgitによって提供されなくなったため、開発者はコンパイル前にautoconf/autoreconfを実行する必要があります。 + + + + + + + バグ修正 + + + + + Pgpool-IIメインプロセスとpcp子プロセスの競合状態を修正しました。(Tatsuo Ishii) + + + pcp子プロセスがフォークされると、pgpoolメインプロセスはすべてのシグナルのブロックを解除します。 + これにより、シグナルハンドラーが設定される前にシグナルがpcpプロセスに送信されると、競合状態が発生する可能性がありました。 + シグナルハンドラーがセットアップされるまでシグナルのブロックを解除しないように修正しました。 + + + ディスカッション: https://www.pgpool.net/pipermail/pgpool-hackers/2023-September/004398.html + + + + + + このリリースでは、4.3.xと同じバグ修正がすでに適用されています。これらの修正の詳細については、を参照してください。 + + + + + + + ドキュメントの変更 + + + + + 設定例「8.2. Pgpool-II + Watchdog Setup Example」をPgpool-II 4.5とPostgreSQL 16に更新しました。(Bo Peng) + + + + + + + 回帰テスト修正 + + + + + 001.load_balanceテストのタイムアウトを修正しました。(Tatsuo Ishii) + + + + + + + 001.load_balanceを強化しました。(Tatsuo Ishii) + + + + + + diff --git a/doc.ja/src/sgml/release-4.6.sgml b/doc.ja/src/sgml/release-4.6.sgml new file mode 100644 index 000000000..63beff86d --- /dev/null +++ b/doc.ja/src/sgml/release-4.6.sgml @@ -0,0 +1,1902 @@ + + リリース 4.6.7 + + リリース日 + 2026-06-04 + + + + 不具合修正 + + + + + pgprotoで改行データを扱えるようにしました。(Tatsuo Ishii) + + + 現在は\nが改行として認識されます。 + これはCOPYに必要な修正です。 + + + + + + + watchdogのリーダーノードが初期値-2を報告した場合にローカルのprimary_node_idを維持するようにしました。(Tatsuo Ishii) + + + すべてのpgpoolノードを同時に再起動した際に、スタンバイノードが有効なprimary_node_idを初期値-2値で上書きし、未初期化状態のままになる問題を修正しました。 + この修正により、リーダーが初期値-2を報告した場合はローカルのprimary_node_idを維持するようになりました。 + + + この問題はEmond PapegaaijとClaude Codeによって報告されました。 + + + ディスカッション: Primary node detection race at clean startup + + + + + + + elog(DEBUG)内でpool_get_transaction_isolation()を呼び出さないように修正しました。(Tatsuo Ishii) + + + where_to_send_main_replica()およびwhere_to_send_native_replication()のDEBUGログ出力が原因で、アボート状態のトランザクションでFATALエラーが発生する問題を修正しました。 + DEBUGログ内で呼び出していたpool_get_transaction_isolation()が、内部でdo_query()を実行していたことが原因です。 + この修正によりDEBUGログからこれらの呼び出しを削除しました。 + + + + + + + アボート状態のトランザクションでの空クエリ処理を修正しました。(Tatsuo Ishii) + + + アボート状態のトランザクションで空クエリが誤ってエラーになる問題を修正しました。 + 空クエリはアボート状態のトランザクションでも許可されるべきですが、以前のコミットによりcheck_transaction_state_and_abort()が空クエリを拒否していました。 + この修正により、SimpleQuery()で空クエリを検出し、チェックを通さないようにしました。 + + + この問題はRonaldo Raivilによって報告されました。 + + + ディスカッション: pgpool ≥ 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + ssl_dh_params_fileの説明を修正しました。(Tatsuo Ishii) + + + パラメータが空の場合だけでなく、不正なパラメータが指定された場合も、組み込みのデフォルト値にフォールバックするようになっていました。 + + + + + + + PCPのメインプロセスが再起動時に子プロセスのPIDを保持するように修正しました。(Tatsuo Ishii) + + + フェイルオーバー/フェイルバック時にPCPのメインプロセスが再起動すると、子PCPワーカープロセスのPID一覧を失ってしまう問題を修正しました。 + + その結果、pcp_promote_nodeなどのコマンドが無限にハングする可能性がありました。 + この修正により、PCPワーカープロセスのPIDを共有メモリに保持し、PCPのメインプロセス再起動後も利用できるようにしました。 + + + この問題はTaiki Koshinoによって報告されました。 + + + ディスカッション: Problem with pcp process + + + + + + + MERGE文使用時にクエリキャッシュを無効化するように修正しました。(Tatsuo Ishii) + + + MERGEPostgreSQL 15で導入され、Pgpool-II 4.4ではPostgreSQL 15のパーサを取り込んでいました。 + しかしクエリキャッシュサブモジュールに考慮漏れがあり、MERGE文実行時にクエリキャッシュが無効化されていませんでした。 + + + この問題はNadav Shatzによって報告されました。 + + + ディスカッション: Re: Proposal: Recent mutated table tracking in memory + + + + + + + SSLモジュールでのメモリリークを修正しました。(Tatsuo Ishii) + + + 不正なDHパラメータが指定された場合に、load_dh_file()でメモリリークが発生する問題を修正しました。 + この関数はPEM_read_DHparams()が返したメモリを解放していませんでした。 + + また同じファイル内のコピーライト表示を修正し、元のPostgreSQLのコピーライトを保持するようにしました。 + + + ディスカッション: Memory leak in SSL module + + + + + + + SET transaction_read_only = 0の誤ったルーティングを修正しました。(Bo Peng) + + + SET transaction_read_only = 0がstandbyノードに誤って送られ、クエリエラーが発生する問題を修正しました。 + また、不適切なbool型のret = POOL_BOTHを適切なenum型に修正しました。 + + + この問題はliujinyang-highgoによって報告されました。 + + + ディスカッション: set command ‘set transaction_read_only = 0;‘ routed to standby node and execute failed. + + + + + + + where_to_send_main_replica()の不要なSTREAMチェックを削除しました。(Tatsuo Ishii) + + + このチェックは既にcheck_replication_delay()で行われています。 + + + + + + + セッションローカルのリレーションのキャッシュの処理を修正しました。(Tatsuo Ishii) + + + pool_search_relcache()において、セッションローカルのリレーションのキャッシュが誤って共有リレーションのキャッシュに登録される問題を修正しました。 + 一時テーブル情報が共有リレーションのキャッシュに登録されることで、後続クエリが古いキャッシュ情報を使用し、クエリが誤ったノードにルーティングされる可能性がありました。 + この修正により、セッションローカルのキャッシュの一時テーブル情報は共有リレーションのキャッシュに登録しないようにしました。 + + + ディスカッション: query temp table is routed to standby node. + + + + + + + pool_search_relcache()のロック解放漏れを修正しました。(Tatsuo Ishii) + + + 共有リレーションのキャッシュ更新時に、排他ロックを再取得した後のロック状態が正しく更新されず、共有メモリのロックが解放されない可能性がありました。 + また、分かりづらい変数名lockedlocked_by_othersに変更し、不要なper_node_statement_log出力も修正しました。 + + + ディスカッション: Lock release leak in pool_search_relcache + + + + + + + フォーク前に不要なリッスン中のソケットを閉じるようにしました。(Tatsuo Ishii) + + + フォークされた子プロセスが不要なpgpoolおよびPCPがリッスン中のソケットを継承してしまう問題を修正しました。 + 以前はpcpのメインプロセス、ヘルスチェックプロセス、ライフチェックプロセスなどが使用しないリッスン中のソケットを保持していました。 + その結果、次回pgpool起動時にポートのバインドに失敗する可能性がありました。 + この修正により、close_listening_sockets()を使用して、 + フォーク後に不要なリッスン中のソケットを閉じるようにしました。 + + + ディスカッション: Close listening socokets before forking + + + + + + + ドキュメント修正 + + + + + ignore_leading_white_spaceおよびallow_sql_commentsのドキュメントを修正しました。(Tatsuo Ishii) + + + デフォルト値の説明が不足していました。 + + + + + + + 回帰テスト修正 + + + + + 以前のコミットに対する001.load_balanceテストを追加しました。(Tatsuo Ishii) + + + + + + + + リリース 4.6.6 + + リリース日 + 2026-02-26 + + + + 変更点 + + + + + 並列でmakeを実行できるようになりました。(Tatsuo Ishii) + + + 以前、makeの並列実行は以下のように失敗していました。 + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + anthonyrousselによってパッチが作成され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Fix parallel build + + + + + + + primary_conninfoのホストが不一致であることを詳細にログに出力するようになりました。(Taiki Koshino) + + + pgpool.confに設定されているPostgreSQLprimary_conninfoのホスト設定が一致しない場合以下のようなログが出力されます。 + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + + サポートされている最小のOpenSSLバージョンを明記しました。(Tatsuo Ishii) + + + こちらは以下を使用したconfigure.acによって実現しています。 + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + サポートされている最小バージョンは1.0.2で、これは現時点ではPostgreSQLと同じです(実際にはAC_DEFINEはPostgreSQLから導入されています)。 + また、インストールされているOpenSSLが3.0などの新しいバージョンである場合、OpenSSLの非推奨警告を回避できる可能性があります。 + さらに、インストールドキュメントに、必要なOpenSSLの最小バージョンは1.0.2であることを記載しました。 + + + + + + + 不具合修正 + + + + + check_transaction_state_and_abort()の考慮不足を修正しました。(Tatsuo Ishii) + + + この関数はフロントエンドがNULLアカウントであるケースを考慮していませんでした。 + + + この問題はCoverityによって発見されました。 + + + + + + + walker()が早めに結果を返すように修正しました。(Tatsuo Ishii) + + + 以前、walker()は対象オブジェクトを見つけたときにfalseを返していましたが、 + trueを返すようにし処理をショートカットするようにしました。 + + またwaker()の設計意図が分かりやすいようにPostgreSQLのコメントを移植しました。 + + + この問題はliujinyang-highgoによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Improper handling in the function view_walker(). + + + + + + + scram-sha-256認証でのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はCoverityによって発見されました。 + + + + + + + malloc()の返り値チェックを修正しました。(Tatsuo Ishii) + + + create_inet_domain_sockets()はソケットのファイルディスクリプタ用メモリを割り当てている間にmalloc()が返す値のチェックをしていませんでした。 + + + + + + + ヘルスチェックが開始しない問題を修正しました。(Tatsuo Ishii) + + + 以前、Pgpool-IIはバックエンドノードがダウンしている場合ヘルスチェックを開始しませんでした。 + これは自動フェイルバックを阻害します。 + Pgpoolはを指定していない場合pool_statusを読み込みます。 + もしpgpool_statusにダウンと記載されている場合はpgpoolはヘルスチェックを開始しませんでした。 + 自動フェイルバックはヘルスチェックから引き起こされるため、ヘルスチェックが起動しないと自動フェイルバックも実行されずバックエンドノードが復帰できませんでした。 + この修正によりノードの状態にかかわらずヘルスチェックが起動するようになりました。 + + + この問題はMeng Feilongによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Nodes in the down state cannot failback + + + + + + + nodes.hに定義されているenum型のNodeTag値の重複を修正しました。(Tatsuo Ishii) + + + PostgreSQLから取り込んだnodes.hのNodeTag定義とPgpool-II独自の定義で起きていた重複を解消しました。 + + + この問題はliujinyang-highgoによって報告・検討され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: an issue about NodeTag definition. + + + + + + + pcp_connectでのメモリリークを修正しました。(Tatsuo Ishii) + + + この関数は複数個所でfreeaddrinfo()を呼び出していませんでした。 + + + + + + + integer型のオーバーフローが起きる可能性がある問題を修正しました。(Tatsuo Ishii) + + + pool_write_flush()pool_flus_it()ではwrite(2)が使用されています。 + write(2)はssize_tを返しますが、コード内には戻り値がint変数に代入されている箇所がいくつかありました。 + その結果、戻り値が負の値として評価され、エラーが発生する可能性がありました。 + + + + + + + + リリース 4.6.5 + + リリース日 + 2025-12-15 + + + + 変更点 + + + + + pgpool_setupで非推奨の「egrep」の代わりに「grep -E」を使用するようにしました。(Bo Peng) + + + 新しいGNUのgrepバージョンでの廃止警告を回避するために、「egrep」を「grep -E」に置き換えました。 + + + + + + + 不具合修正 + + + + + show pool_statusのバッファオーバーフローエラーを修正しました。(Tatsuo Ishii) + + + SHOW POOL_STATUS、pgpool show、および pcp_pool_statusコマンドでバッファオーバーフローが発生する問題を修正しました。 + 問題の原因は、backend_flagがALWAYS_PRIMARYに設定されている場合に、pool_flag_to_str()関数がbackend_flagを文字列化する際に静的バッファの末尾を越えて書き込んでしまうことでした。 + + + この問題はzam bakによって報告され、Bo Pengによってよって分析されました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + 「show pool_status」に表示されるmemqcache_stats_start_timeの出力を修正しました。(Tatsuo Ishii) + + + get_config()がctime()を使って時刻を文字列化していましたが、ctime()の戻り値の末尾には改行が含まれることを考慮していませんでした。 + その結果、memqcache_stats_start_timeの行に余計な改行が入り、さらに次の行が空欄として表示されてしまう問題が発生していました。 + + + ディスカッション: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + 回帰テスト修正 + + + + + 037.failover_sessionのテストを安定させました。(Tatsuo Ishii) + + + 特定の環境では、test1の後にshutdownallが終了しないことがありました。 + これは、テスト中のフェイルオーバー処理が、shutdownallからの終了シグナルを受け取れるようにしているシグナルハンドラの復元に失敗していることが原因と考えられます。 + shutdownall の前にsleep 5を追加することで、この問題が緩和されることを確認しました。 + + + + + + + + リリース 4.6.4 + + リリース日 + 2025-11-25 + + + + 変更点 + + + + + 不要なapplication_nameの処理を削除しました。(Tatsuo Ishii) + + + 以前のコミットで、既存接続を再利用する際にapplication_nameを設定する処理が追加されました。 + しかしこれは不要です。DISCARD ALLにより接続再利用時に自動的にapplication_nameがリセットされ、 + send_params()によってフロントエンドに必要なパラメータステータス(application_nameを含む)が送信されます。 + この冗長な処理を削除することで、特に地理的に離れたバックエンドノードでのパフォーマンスが向上します。 + + + ディスカッション: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + 時間計算を常にlong longに変更しました。(Tatsuo Ishii) + + + 以前、Pgpool-II はtime_tを単なるlongとして扱っており、OpenBSDのようなシステムではコンパイル時警告が発生していました。 + 計算をlong longにアップキャストするようにしてトランケーションを防ぎ、 + 64ビットクリーンなtime_tシステムでもY2038問題後も正しく動作するようにしています。 + また、json_get_long_value_for_keyはjson_get_llong_value_for_keyに変更され、パラメータもlong longになりました。 + これにより_json_valueのint64型と整合性が取れ、32ビット環境でも大きな整数を正しく扱えるようになりました。 + + + この問題はTatsuo IshiiとGyorgy Sarvariによって分析されました。 + + + ディスカッション: Fix time_t warnings on OpenBSD + + + ディスカッション: Fix time_t warnings on OpenBSD + + + ディスカッション: fix compiling issues for 32-bit targets + + + + + + + GCC 15 (C23) でコンパイル可能にしました。(Tatsuo Ishii) + + + Fedora 42 + GCC 15でPgpool-IIをコンパイルできるよう修正しました。 + pool_type.hをstdbool.hに変更し、TRUE/FALSEを (bool)1 / (bool)0と定義しました。 + 関数ポインタの引数が呼び出し先プロトタイプと一致するよう修正され、 + pool_create_relcache()のプロトタイプも更新されました。 + raw_expression_tree_walker()内のwalker()呼び出しは、WALKマクロを使い (Node *) キャストされるよう変更されました。 + OpenSSLに関する警告はまだ残っており、将来的に対応予定です。 + + + ディスカッション: 4.6.X build issue against GCC 15 + + + + + + + 不具合修正 + + + + + CopyOutでのセグメンテーションフォルトを修正しました。(Tatsuo Ishii) + + + 拡張プロトコルでCOPY relname TO STDOUTが実行された場合、Pgpool-IIがセグフォルトを起こしていました。 + + + この問題はhttps://github.com/teteshによって報告されました。 + + + ディスカッション: datanymizer and pg-pool segmentation fault + + + + + + Watchdogのスプリットブレイン回避するよう修正しました。(Tatsuo Ishii) + + + Watchdogはビーコンメッセージとハートビートで通信します。 + ハートビートが有効でない場合、ビーコンが30秒以上届かないとスプリットブレインが発生することがあります。 + 古いリーダーを無効化することで、同時に二人のリーダーが存在しないように修正しました。 + ノードがリーダーからのビーコンを2回以上見逃すと、リーダーはLOST状態となり、 + set_state(WD_JOINING) により新リーダー選出が開始されます。 + + + + + + + 存在しないプリペアドステートメント使用時のFATALエラー防止するよう修正しました。(Tatsuo Ishii) + + + 以前はBind()が存在しないプリペアドステートメントでFATALエラーを出していました。 + はステートメントの存在を確認し、存在しない場合はフロントエンドにERRORメッセージを送信するようになりました。ログは残りません。 + + + + + + + が -pと -P両方使用時に動作しない問題を修正しました。(Tatsuo Ishii) + + + 元の報告では、pg_enc -p -P実行時にパスワードと暗号キーを求められましたが、 + キーが提供されない場合に失敗していました。 + + + ディスカッション: pg_enc + + + + + + + 32ビット環境でのコンパイルの問題を修正しました。(Tatsuo Ishii) + + + 32ビットシステムでsrc/parser/snprintf.cをコンパイルするとisnan()isinf()が未定義でエラーになりました。 + math.hをインクルードし、ヘッダーファイルの順序も整理しました。 + 元々 PostgreSQLから取り込まれたファイルで、math.hは既に含まれていました。 + 修正は fix compiling issues for 32-bit targets のプルリクエストに記載してあります。 + + + + + + + recovery_1st_stage.sampleでBashのディレクトリ削除を安全に行うよう修正しました。(Taiki Koshino) + + + rmコマンドの変数をクォートし、意図しない削除を防止しました: + rm -rf "${DEST_NODE_PGDATA}" + + + + + + + クエリキャッシュ無効化時の不要な警告が出ないよう修正しました。(Tatsuo Ishii) + + + memcachedサポートが無効な場合、クエリキャッシュ無効化時に不要な警告が出ていました。 + これにより006.memcachedリグレッションテストが失敗していました。 + + + + + + + 指定なしでコンパイルする際のエラーを修正しました。(Tatsuo Ishii) + + + 指定なしでコンパイルするとエラーが発生していました。 + 対応として該当コードブロックを #ifdef USE_MEMCACHEDで囲みました。 + + + この問題はBo Pengによって報告されました。 + + + + + + + クエリキャッシュのロックファイルの取り扱い修正を修正しました。(Tatsuo Ishii) + + + クエリキャッシュモジュールは並列制御のためlogdirにロックファイルを作成しますが、 + メインプロセスがゴミファイルを作成したり、シャットダウン時に削除されない問題がありました。 + + + この問題はBo Pengによって報告・分析されました。 + + + + + + + ドキュメント修正 + + + + + 8.2. Pgpool-II + Watchdog Setup Exampleの"PostgreSQLスタンバイ設定"ドキュメントを更新しました。(Taiki Koshino) + + + オンラインリカバリなしでスタンバイを設定する場合、postgresql.auto.confにprimary_conninfoを書き込まないよう注意を追加しました。 + + + ディスカッション: Follow primary command not fixing postgresql.auto.conf + + + + + + + watchdog_setupのマニュアルを修正しました。(Tatsuo Ishii) + + + heartbeartがwatchdog_setupに設定されていないと誤記されていた箇所を修正しました。 + + + + + + + 回帰テスト修正 + + + + + 023.ssl_connectionをPostgreSQL 18に対応するよう修正しました。(Tatsuo Ishii) + + + PostgreSQL 18でpsqlの\conninfo出力形式が大幅に変更されたため、 + このテストが失敗していました。 + PostgreSQLバージョンに応じてテストスクリプトを修正しました。 + + + + + + + 039.log_backend_messagesを修正しました。(Tatsuo Ishii) + + + 同期コミットパラメータがpgpool.confに誤って設定されていました。 + 正しいpostgresql.confに移動し、クラスタリングモードがストリーミングレプリケーションかを確認することでテストを修復しました。 + + + + + + + 039.log_backend_messagesテストを安定化しました。(Tatsuo Ishii) + + + テスト中、プライマリに行を挿入後、レプリケーション遅延によりスタンバイで行が見つからない場合がありました。 + remote_applyオプションを用いた同期レプリケーションを利用して問題を改善しました。 + + + + + + + 010.rewrite_timestampのRubyスクリプトを修正しました。(Tatsuo Ishii) + + + RubyのFile.existsは新しいバージョンで非推奨のため、File.existに置き換えました。 + + + + + + + 034と075のタイムアウトを調整しました。(Tatsuo Ishii) + + + 034.promote_nodeと075.detach_primary_left_down_nodeのスクリプト終了タイムアウトを60秒から120秒に変更し、 + 誤エラーが発生する可能性を減らしました。 + + + + + + + 023.ssl_connectionにssl_ecdh_curveのテストを追加しました。(Tatsuo Ishii) + + + 023.ssl_connectionはssl_ecdh_curveのテストをカバーしていなかったため、 + 不正なssl_ecdh_curveパラメータでフロントエンドとpgpool の接続が失敗するか確認しました。 + + + + + + + + リリース 4.6.3 + + リリース日 + 2025-08-21 + + + + 変更点 + + + + + バックエンドへの接続プロセスを強化しました。 (Tatsuo Ishii) + + + 特定の環境(特に k8s)では、DNS ルックアップが不安定になり、バックエンドプロセスへの接続に失敗します。これは、connect_inet_domain_socket_by_port() 内の getaddrinfo() の呼び出しで発生します。 + この状況を改善するために、getaddrinfo() が EAI_AGAIN で失敗した場合、最大 5 回まで再試行します(再試行ごとに 1 秒間スリープします)。 + connect_inet_domain_socket_by_port() が "retry" 引数を false に設定して呼び出された場合、再試行は行われないことに注意してください。 + ヘルスチェックは、再試行フラグを false に設定して connect_inet_domain_socket_by_port() を呼び出すため、再試行はヘルスチェック自身のパラメータによって制御されます。 + + + ディスカッション: A single DNS lookup failure will trigger backend failover + + + + + + + 不具合修正 + + + + + watchdog が不適切な NOTICE メッセージを出力する問題を修正しました。 (Tatsuo Ishii) + + + read_ipc_socket_and_process() は、IPCソケットへのコマンド書き込みのたびに、書き込みが成功した場合でも通知メッセージを出力していました。これを修正し、書き込みが失敗した場合にのみ通知メッセージを出力するようにしました。 + log_min_messages が notice 以上に設定されている場合にのみメッセージが表示されるため、このバグが発見されていませんでした。 + + + ディスカッション: pgpool IPC socket connection issue + + + + + + + + スタートアップパケットを読んでいるときのメモリーリークを修正しました。(Tatsuo Ishii) + + + pool_push_pending_data でのリソースリークを修正しました。 + + + + + + + + + ビッグエンディアンマシン上の scram-sha-256 認証の不具合を修正しました。(Tatsuo Ishii) + + + scram-sha-256 認証を実行する際、ハッシュ関数 pg_sha_256_final が使用されます。 + これは PostgreSQL からインポートされたもので、プリプロセッサ定義 WORDS_BIGENDIAN を使用してホストマシンのエンディアンを判断します。 + WORDS_BIGENDIAN は configure 時に定義する必要がありますが、pg_sha_256_final(およびその他)が PostgreSQL からインポートされた際にこの部分が省略されていました。 + その結果、scram-sha-256 はリトルエンディアンマシンでのみ動作していました。 + configure.ac に AC_C_BIGENDIAN マクロを追加することでこの問題を修正しました。。 + + + この問題は Christoph Berg によって報告され、 pranavkaruvally によって分析されました。 + + + ディスカッション: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + ソースコードのタイプミスを修正しました。 (Bo Peng) + + + + + + + ハートビートデバイスの処理を修正しました。(Tatsuo Ishii) + + + wd_create_hb_recv_socket()wd_create_hb_send_socket() を修正しました。 + setsockopt(SO_BINDTODEVICE) に struct ifreq を誤って渡すのではなく、NULL で終了するデバイス名文字列を渡すようにしました。 + + + ディスカッション: [pgpool-hackers: 4602] heartbeat and SO_BINDTODEVICE + + + + + + + heartbeat receiver プロセスでのリソースリークを修正しました。 (Tatsuo Ishii) + + + + + + + ハートビートデバイスの処理を修正しました。(Tatsuo Ishii) + + + pgpool.conf の処理中に、heartbeat_device が誤って処理され、最初のデバイスが無視されていました。 + + + この問題は Bo Peng によって分析されました。 + + + + + + + hearbeat receiver プロセスが動作しない問題を修正しました。 (Tatsuo Ishii) + + + ハートビートの IPv6 サポートはバージョン 4.6 で追加されましたが、heartbeat receiver プロセスが誤ってループバックアドレスのみにバインドされ、他のノードからの受信が妨げられていました。 + getaddrinfo() に AI_PASSIVE フラグを追加すると、すべてのネットワークインターフェースにバインドされるようになり、この問題は修正されました。 + + + この問題は Bo Peng によって分析されました。 + + + + + + + pgpool.confのコメントのタイプミスを修正しました。 (Tatsuo Ishii) + + + + + + + ドキュメント修正 + + + + + 「8.3. ネイティブレプリケーション/スナップショットアイソレーションモードの構築の例」のドキュメントを改善しました。(Taiki Koshino) + + + サンプルスクリプトのリンクと「事前設定」の説明を改善しました。 + + + + + + + リロードによって反映されないパラメータのドキュメントを修正しました。 (Taiki Koshino) + + + authentication_timeoutmemqcache_oiddir はリロードしても反映されません。 + ドキュメントが「このパラメータはサーバー起動時にのみ設定できます。」に変更されました。 + + + + + + + + watchdog リーダーの用語を統一しました。(Tatsuo Ishii) + + + 以前は「leader」「active」「coordinater」という用語が、watchdog のリーダーノードを指すために使用されていました。このコミットではこれらを「leader」に統一しました。 + advanced.sgml も修正しました。 + + + + + + + + サンプルスクリプトを修正しました。(Taiki Koshino) + + + 「8.2. Pgpool-II + Watchdogの構築の例」のサンプルスクリプトを修正しました。 + + + + + + + ロードバランスの説明で論理レプリケーションモードと Slony モードが抜けている問題を修正しました(Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Bo Peng) + + + 「replication_state」と「replication_sync_state」を正しく表示するには、各 backend_application_nameXprimary_conninfoapplication_name に指定された値と一致する必要があることを明確にしました。 + + + + + + + カーネルの資源に関するセクションを追加しました。 (Tatsuo Ishii) + + + Pgpool-II は System V の共有メモリとセマフォを使用します。 + 要件についてはドキュメントを参照することをお勧めします。 + + + + + + + configure の オプションの説明を追加しました。(Tatsuo Ishii) + + + これは LDAPサポートがv4.2で導入されたときに見落としていました。 + + + + + + + $PGDATA をエスケープするよう、「8.2. Pgpool-II + Watchdogの構築の例」のコマンドを修正しました。(Bo Peng) + + + + + + + Pgpool-II でサポートされているプラットフォームを明確にしました。 (Tatsuo Ishii) + + + + + + + のドキュメントを改善しました。 (Tatsuo Ishii) + + + + + + + 回帰テスト修正 + + + + + 029.cert_passphrase 回帰テストを安定化しました。 (Tatsuo Ishii) + + + ssl_passphrase_command が有効でない場合、エラーメッセージは通常「bad decrypt」ですが、「wrong tag」となる場合もありました。 + + + + + + + + リリース 4.6.2 + + リリース日 + 2025-05-30 + + + + 変更点 + + + + + 認証失敗時に不要な情報を表示しないように修正しました。(Tatsuo Ishii) + + + 以前は、クライアント認証に失敗した際に「password size does not match」というメッセージが表示されていました。 + これは攻撃者がパスワードを推測する手助けとなる可能性がありました。 + このメッセージを「password does not match」に変更しました。 + + + + + + + pcpクライアントがIPv6アドレスに接続できるようなりました。(Tatsuo Ishii) + + + すでにpcpサーバはIPv6アドレスへの接続を許可していましたが、これまでpcpクライアントは接続できませんでした。 + 今回の変更により、pcpクライアントもIPv6アドレスへ接続可能になります。 + + + ディスカッション: [pgpool-general: 9481] Does pgpool 4.6.0 support pure ipv6 configuration? + + + + + + + 不具合修正 + + + + + IPv6が無効化されている環境におけるwatchdog受信用ソケット作成に関する不具合を修正しました。(#99) (Tatsuo Ishii) + + + IPv6ネットワークが利用できない場合、watchdogプロセスが起動しない問題がありました。 + 従来、wd_create_recv_socket()関数はIPv6ソケットの作成や処理に失敗するとelog(ERROR)を発行していました。 + しかし、wd_create_recv_socket()が呼ばれる時点では例外スタックが確立されておらず、elogはERRORFATALに変換してしまいます。 + これによりwatchdogプロセスが終了し、その結果pgpoolプロセスも終了してしまいました。 + この問題を修正するために、elog(ERROR)の呼び出しをelog(LOG)に変更しました。 + + + + + + + + リリース 4.6.1 + + リリース日 + 2025-05-15 + + + + 概要 + + このリリースには、セキュリティ修正が含まれています。 + + + Pgpool-IIのクライアント認証メカニズムには認証バイパスの脆弱性があります。 + 本来であれば認証が必要な場合でも、認証処理がスキップされてしまう可能性があります。 + この脆弱性を悪用することで、攻撃者が任意のユーザとしてログインし、データベース内の情報を参照・改ざんしたり、データベースを停止させたりすることができる可能性があります。(CVE-2025-46801) + + + なお、本脆弱性の影響を受けるのは、下記のパターン1から3いずれかの条件を満たす場合に限られます。 + + + + + パターン 1:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + pool_hba.confpassword認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードが設定されていない + + + + + pg_hba.confscram-sha-256またはmd5認証方式を使用している + + + + + + + + パターン 2:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + enable_pool_hba = off + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + + パターン 3:次の条件をすべて満たす場合、本脆弱性の影響を受ける可能性があります。 + + + + + rawモードを使用している (backend_clustering_mode = 'raw') + + + + + pool_hba.confmd5認証方式を使用している + + + + + allow_clear_text_frontend_auth = off + + + + + pool_passwdに対象ユーザのパスワードがテキストまたはAES形式で登録されている + + + + + pg_hba.confpasswordpamldapのいずれかの認証方式を使用している + + + + + + + この脆弱性の影響を受けるのは、Pgpool-II 4.0系および4.1系のすべてのバージョン、4.2.0-4.2.21、4.3.0-4.3.14、4.4.0-4.4.11、4.5.0-4.5.6、4.6.0です。 + Pgpool-II 4.6.1、4.5.7、4.4.12、4.3.15、4.2.22以降へのアップグレードを強くお勧めします。 + それができない場合は、発生条件パターンに当てはまらない設定の組み合わせに変更してください。 + + + + + 変更点 + + + + + 設定ファイルにメジャーバージョンを追加しました。 (Bo Peng) + + + + + + + 不具合修正 + + + + + クライアント認証が正しく実行されない場合があるのを修正しました。(Tatsuo Ishii) + + + enable_pool_hbaがonで、auth methodが"password"、pool_passwdにパスワードが登録されておらず、pg_hba.confの認証方式が"scram-sha-256"か"md5"の場合、クライアントが最初にpgpoolに接続したときには認証が期待通りに実行されます。 + しかし、クライアントがキャッシュされたコネクションに接続すると、任意のパスワードが通ってしまいます。 + + + また、enable_pool_hba = offのいくつかのケースでは、本来パスワードが聞かれるはずが、最初からパスワードが聞かれない、あるいはキャッシュされたコネクションに接続した時にはパスワードが聞かれないことがありました。 + + + 上記を修正するのに加え、以下の変更を行いました。 + + + + + 認証コードを単純化するために、PostgreSQLが1台の時のコードパスを削除しました。 + + + + + crypt認証のサポートをフロントエンドとバックエンドから削除しました。 + この機能はドキュメントに書かれておらず、テストもされていませんでした。 + また、crypt認証はPostgreSQLではだいぶ以前(8.4, 2009)に削除されています。 + + + + + 新しい回帰テストの"040.client_auth"を追加しました。 + このテストは、CSV形式のテスト設定ファイルを使って、包括的なクライアント認証のテストを実施します。 + + + + + + + + クエリキャッシュにおける、古くからあるバインド時のバグを修正しました。(Tatsuo Ishii) + + + 名前付きステートメントを準備すると、バインド後にパースメッセージなしで実行することが可能です。 + 問題は、実行時またはCOMMIT時にクエリキャッシュを無効化するために必要なテーブルOIDが、パースメッセージ処理(Parse())でのみ収集されていたことです。 + そのため、前回の実行後にパースなしでバインドを実行すると、テーブルOIDが収集されず、pgpoolはクエリキャッシュの無効化に失敗していました。 + バインド時にもテーブルOIDを収集するよう修正しました。 + 006.memqcacheに回帰テストを追加しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + クエリキャッシュの無効化に失敗する問題を修正しました。 (Tatsuo Ishii) + + + 実行メッセージを受信すると、pgpoolは最大行数パラメータをチェックします。この値が0でない場合、pgpoolはpool_handle_query_cache()にクエリキャッシュを作成しないよう指示するために、"partial_fetch"フラグを設定します。 + 問題は、コミット2a99aa5d1が、INSERT/UPDATE/DELETEであっても実行メッセージパラメータが0以外(ほとんどの場合1)に設定されpgpoolがSELECT以外の場合でもこのフラグを設定することを見落としていることです。 + この結果、このフラグがtrueの場合、pool_handle_query_cache()内の後続のコードでキャッシュの無効化がスキップされるため、クエリキャッシュの無効化に失敗していました。 + フラグを設定する前にクエリが読み取り専用のSELECTであるかどうかを確認するようにExecute()を修正しました。 + + + この問題はEmond Achilleas Mantziosによって報告され、テストプログラムが提供されました。 + + + ディスカッション: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + OpenBSDへ移植する際の問題を修正しました。 (Tatsuo Ishii) + + + ディスカッション: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + このパッチはMartijn van Durenによって作成されました。 + + + + + + + json_writerが特殊文字を正確にエンコードできない問題を修正しました。(Bo Peng) + + + が特殊文字を含んでいる状態でwatchdogを起動するとPgpool-IIがクラッシュしていました。 + + + このパッチはMartijn van Durenによって作成され、Bo Pengによって微修正されました。 + + + + + + + リロード時にを開くようにストリーミングレプリケーションチェックとヘルスチェックプロセスを修正しました。(Tatsuo Ishii) + + + ストリーミングレプリケーションチェックとヘルスチェックはリロード前にを開いていませんでした。 + もしが空文字列の時は、からパスワードを得ます。 + そのためこれらのプロセスはリロード時にの古いコンテンツを読み取ります。 + + + + + + + IPv6が無効化されている環境におけるハートビート処理の不具合を修正しました。(#99) (Tatsuo Ishii) + + + Pgpool-II 4.6.0からは、ハートビートプロセスはIPv6受信機ソケットに対応しています。 + しかし、IPv6が機能していないときこれらのプロセスは機能しません。 + Pgpool-IIのメインプロセスやPostgreSQLのように、IPv4でも通常通り稼働するべきです。 + + + ディスカッション: [pgpool-hackers: 4578] Fix IPv6 in heatbeat + + + + + + + ドキュメント修正 + + + + + クエリキャッシュのドキュメントをを改善しました。(Tatsuo Ishii) + + + Pgpool は、TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を呼び出すクエリのキャッシュを拒否します。 + 同じ名前の関数が複数あり、そのうちの 1 つがTIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す場合、たとえそのうちの 1 つがこれらのデータ型を返さなくても、Pgpoolはキャッシュを拒否します。 + そのため、この問題に関するメモと回避策を追加しました。 + + + + + + + の説明を改善しました。(Tatsuo Ishii) + + + が計算されるタイミングは、接続キャッシュを保持しているプロセスからクライアントが切断されたときであることを追記しました。 + + + ディスカッション: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + + についての説明を改善しました。 (Tatsuo Ishii) + + + スーパーユーザーかpg_monitorグループであるべきです。 + + + + + + + 回帰テスト修正 + + + + + 回帰テストで複数のソケットディレクトリを使用できるように修正しました。(Taiki Koshino, Tatsuo Ishii, Bo Peng) + + + + + + + + リリース 4.6.0 + + リリース日 + 2025-02-28 + + + + 概要 + + このリリースでは、ログ取得やPgpool-IIの管理のための便利な機能を追加しました。 + 新しいPCPコマンドを使って、Pgpool-IIを再起動したり、シグナルを送ることなくログをローテートできます。 + 関連のパラメータが設定ファイルの再読込で変更できるようになりました。 + また、Pgpool-IIを再起動せずにクエリキャッシュを削除するための新しいPCPコマンドが追加されました。 + 他の新しいクエリキャッシュの機能としては、クエリキャッシュのエントリを強制的に作成すること、指定したクエリキャッシュのエントリを削除できるようになりました。 + 新しい設定パラメータのにより、Pgpool-IIPostgreSQLの間の通信を容易に分析することができるようになりました。 + SQLパーサは、PostgreSQL 17バージョンと同期していつものように更新されました。 + 最後に、watchdogのhostnameとheartbeat_hostname設定パラメータでIPv6が使えるようになりました。 + + + + 主な機能の改良は以下の通りです。 + + + + + + + ログのローテーションを指示する新しいPCPコマンド + + + + + + リロードによる関連のパラメータの変更 + + + + + + クエリキャッシュを削除する新しいPCPコマンド + + + + + + クエリキャッシュの強制的な作成 + + + + + + 新しいPGPOOL SET CACHE DELETEコマンド + + + + + + 新しい設定パラメータ + + + + + + PostgreSQL 17のSQLパーサの導入 + + + + + + watchdogのパラメータのIPv6対応 + + + + + + + + バージョン4.6への移行 + + + + + のデフォルト値が'nobody'から''(空文字)に変更されました。 + 4.6ではそれらに適切な値をセットする必要があります。さもなければエラーが生じます。 + + + + + + 文字列型の設定パラメータ、たとえばで、先頭/末尾の空白を無視するようにしました。 + + + + + + を設定していると以下のログメッセージが記録されました。これらは正常時のメッセージであるため、DEBUG1にダウングレードされました。 + + reaper handler + reaper handler: exiting normally + + + + + + + + + 変更点 + + + + + + ログをローテートするを追加しました。(Bo Peng) + + + + + + + Pgpool-IIの設定を再ロードすることにより、関連のパラメータを変更できるようにしました。 (Bo Peng) + + + 以下の関連のパラメータは再ロードで変更できます。 + + + + log_truncate_on_rotation + + + + + log_directory + + + + + log_filename + + + + + log_rotation_age + + + + + log_rotation_size + + + + + log_file_mode + + + + + + + + + + クエリキャッシュを削除するを追加しました。 (Tatsuo Ishii) + + + + + + + 指定のクエリキャッシュを削除するPGPOOL SET CACHE DELETEコマンドを追加しました。(Tatsuo Ishii) + + + + + + + バックエンドからのプロトコルメッセージをログする新しい設定パラメータのを追加しました。(Tatsuo Ishii) + + + + + + + PostgreSQL 17の新しいパーサを取り込みました。(Bo Peng) + + + PostgreSQL 17パーサの変更点には以下のものがあります。 + + +- MERGEでNOT MATCHED BY SOURCEとRETURNING句が使えるようになりました。 + + MERGE INTO ... WHEN NOT MATCHED BY SOURCE ... + MERGE INTO ... RETURNING ... + +- 新しいCOPYオプションのON_ERROR ignoreとLOG_VERBOSITYが追加されました。 + + COPY ... WITH (ON_ERROR ignore); + COPY ... WITH (LOG_VERBOSITY verbose); + +- すべての列に対して'*'を使ってCOPY FROMオプションのFORCE_NOT_NULLとFORCE_NULLが指定できるようになりました。 + + COPY ... WITH (FORCE_NOT_NULL *); + COPY ... WITH (FORCE_NULL *); + +- EXPLAINにオプションのSERIALIZEとMEMORYが追加されました。 + + EXPLAIN (MEMORY) ... + EXPLAIN (ANALYZE, SERIALIZE ...) ... + +- ALTER TABLEでSET STATISTICS DEFAULTを使って指定の列をデフォルトの統計上情報ターゲットにできるようになりました。 + + ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DEFAULT; + +- ALTER TABLEで列の生成式を変更できるようになりました。 + + ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION; + +- ALTER TABLEで .. SET ACCESS METHODのデフォルトを指定できるようになりました。 + + ALTER TABLE ... SET ACCESS METHOD new_access_method DEFAULT; + +- イベントトリガでログインイベントを扱えるようになりました。 + + CREATE EVENT TRIGGER ... ON login ... + +- イベントトリガでREINDEXを扱えるようになりました。 + + + + + + + + パラメータのでIPv6をサポートしました。(Kwangwon Seo) + + + + + + + 文字列型の設定パラメータで、先頭/末尾の空白を無視するようにしました。(Bo Peng) + + + 文字列型のパラメータ(たとえば)に空白が含まれると、起動に失敗することがありました。 + + + + + + + reaper handlerのログをダウングレードしました。(Bo Peng) + + + 以下のメッセージは、たとえばchild_life_timeやchild_max_connectionsの設定で子プロセスが終了する時に現れます。 + これらは正常なメッセージなので、DEBUG1にダウングレードしました。 + + reaper handler + reaper handler: exiting normally + + + + + + + + 拡張問い合わせプロトコルを処理する時の不必要なメモリ獲得を防ぐようにしました。(Tatsuo Ishii) + これは、ストリーミングレプリケーションモードに対してのみ関係します。 + + + + + + + + バグ修正 + + + + このリリースでは、他のマイナーリリースと同じバグ修正がすでに適用されています。 + これらの修正の詳細については、を参照してください。 + + + + + + diff --git a/doc.ja/src/sgml/release-4.7.sgml b/doc.ja/src/sgml/release-4.7.sgml new file mode 100644 index 000000000..a8b0715af --- /dev/null +++ b/doc.ja/src/sgml/release-4.7.sgml @@ -0,0 +1,1049 @@ + + リリース 4.7.2 + + リリース日 + 2026-06-04 + + + + 不具合修正 + + + + + pgprotoで改行データを扱えるようにしました。(Tatsuo Ishii) + + + 現在は\nが改行として認識されます。 + これはCOPYに必要な修正です。 + + + + + + + watchdogのリーダーノードが初期値-2を報告した場合にローカルのprimary_node_idを維持するようにしました。(Tatsuo Ishii) + + + すべてのpgpoolノードを同時に再起動した際に、スタンバイノードが有効なprimary_node_idを初期値-2値で上書きし、未初期化状態のままになる問題を修正しました。 + この修正により、リーダーが初期値-2を報告した場合はローカルのprimary_node_idを維持するようになりました。 + + + この問題はEmond PapegaaijとClaude Codeによって報告されました。 + + + ディスカッション: Primary node detection race at clean startup + + + + + + + elog(DEBUG)内でpool_get_transaction_isolation()を呼び出さないように修正しました。(Tatsuo Ishii) + + + where_to_send_main_replica()およびwhere_to_send_native_replication()のDEBUGログ出力が原因で、アボート状態のトランザクションでFATALエラーが発生する問題を修正しました。 + DEBUGログ内で呼び出していたpool_get_transaction_isolation()が、内部でdo_query()を実行していたことが原因です。 + この修正によりDEBUGログからこれらの呼び出しを削除しました。 + + + + + + + アボート状態のトランザクションでの空クエリ処理を修正しました。(Tatsuo Ishii) + + + アボート状態のトランザクションで空クエリが誤ってエラーになる問題を修正しました。 + 空クエリはアボート状態のトランザクションでも許可されるべきですが、以前のコミットによりcheck_transaction_state_and_abort()が空クエリを拒否していました。 + この修正により、SimpleQuery()で空クエリを検出し、チェックを通さないようにしました。 + + + この問題はRonaldo Raivilによって報告されました。 + + + ディスカッション: pgpool ≥ 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + ssl_dh_params_fileの説明を修正しました。(Tatsuo Ishii) + + + パラメータが空の場合だけでなく、不正なパラメータが指定された場合も、組み込みのデフォルト値にフォールバックするようになっていました。 + + + + + + + PCPのメインプロセスが再起動時に子プロセスのPIDを保持するように修正しました。(Tatsuo Ishii) + + + フェイルオーバー/フェイルバック時にPCPのメインプロセスが再起動すると、子PCPワーカープロセスのPID一覧を失ってしまう問題を修正しました。 + + その結果、pcp_promote_nodeなどのコマンドが無限にハングする可能性がありました。 + この修正により、PCPワーカープロセスのPIDを共有メモリに保持し、PCPのメインプロセス再起動後も利用できるようにしました。 + + + この問題はTaiki Koshinoによって報告されました。 + + + ディスカッション: Problem with pcp process + + + + + + + MERGE文使用時にクエリキャッシュを無効化するように修正しました。(Tatsuo Ishii) + + + MERGEPostgreSQL 15で導入され、Pgpool-II 4.4ではPostgreSQL 15のパーサを取り込んでいました。 + しかしクエリキャッシュサブモジュールに考慮漏れがあり、MERGE文実行時にクエリキャッシュが無効化されていませんでした。 + + + この問題はNadav Shatzによって報告されました。 + + + ディスカッション: Re: Proposal: Recent mutated table tracking in memory + + + + + + + SSLモジュールでのメモリリークを修正しました。(Tatsuo Ishii) + + + 不正なDHパラメータが指定された場合に、load_dh_file()でメモリリークが発生する問題を修正しました。 + この関数はPEM_read_DHparams()が返したメモリを解放していませんでした。 + + また同じファイル内のコピーライト表示を修正し、元のPostgreSQLのコピーライトを保持するようにしました。 + + + ディスカッション: Memory leak in SSL module + + + + + + + SET transaction_read_only = 0の誤ったルーティングを修正しました。(Bo Peng) + + + SET transaction_read_only = 0がstandbyノードに誤って送られ、クエリエラーが発生する問題を修正しました。 + また、不適切なbool型のret = POOL_BOTHを適切なenum型に修正しました。 + + + この問題はliujinyang-highgoによって報告されました。 + + + ディスカッション: set command ‘set transaction_read_only = 0;‘ routed to standby node and execute failed. + + + + + + + where_to_send_main_replica()の不要なSTREAMチェックを削除しました。(Tatsuo Ishii) + + + このチェックは既にcheck_replication_delay()で行われています。 + + + + + + + セッションローカルのリレーションのキャッシュの処理を修正しました。(Tatsuo Ishii) + + + pool_search_relcache()において、セッションローカルのリレーションのキャッシュが誤って共有リレーションのキャッシュに登録される問題を修正しました。 + 一時テーブル情報が共有リレーションのキャッシュに登録されることで、後続クエリが古いキャッシュ情報を使用し、クエリが誤ったノードにルーティングされる可能性がありました。 + この修正により、セッションローカルのキャッシュの一時テーブル情報は共有リレーションのキャッシュに登録しないようにしました。 + + + ディスカッション: query temp table is routed to standby node. + + + + + + + pool_search_relcache()のロック解放漏れを修正しました。(Tatsuo Ishii) + + + 共有リレーションのキャッシュ更新時に、排他ロックを再取得した後のロック状態が正しく更新されず、共有メモリのロックが解放されない可能性がありました。 + また、分かりづらい変数名lockedlocked_by_othersに変更し、不要なper_node_statement_log出力も修正しました。 + + + ディスカッション: Lock release leak in pool_search_relcache + + + + + + + フォーク前に不要なリッスン中のソケットを閉じるようにしました。(Tatsuo Ishii) + + + フォークされた子プロセスが不要なpgpoolおよびPCPがリッスン中のソケットを継承してしまう問題を修正しました。 + 以前はpcpのメインプロセス、ヘルスチェックプロセス、ライフチェックプロセスなどが使用しないリッスン中のソケットを保持していました。 + その結果、次回pgpool起動時にポートのバインドに失敗する可能性がありました。 + この修正により、close_listening_sockets()を使用して、 + フォーク後に不要なリッスン中のソケットを閉じるようにしました。 + + + ディスカッション: Close listening socokets before forking + + + + + + + pcp_proc_infoshow pool_poolsなどで使用されるdebugログレベルを修正しました。(Tatsuo Ishii) + + + 以前のコミットで誤って追加されたLOGレベルのdebugログをDEBUG5へ変更しました。 + + + + + + + ドキュメント修正 + + + + + ignore_leading_white_spaceおよびallow_sql_commentsのドキュメントを修正しました。(Tatsuo Ishii) + + + デフォルト値の説明が不足していました。 + + + + + + + 回帰テスト修正 + + + + + 以前のコミットに対する001.load_balanceテストを追加しました。(Tatsuo Ishii) + + + + + + + + リリース 4.7.1 + + リリース日 + 2026-02-26 + + + + 変更点 + + + + + watchdog/heartbeatプロセスがLISTENするアドレスとポートを指定できるパラメータを追加しました。(Taiki Koshino) + + + を指定することによって、watchdogは指定したアドレスとポートのみでLISTENするようになります。 + heartbeatプロセスについてもでLISTENするアドレスとポートを指定できます。 + + + ディスカッション: Re: Pgpool-II 4.7.0 released. + + + + + + + 並列でmakeを実行できるようになりました。(Tatsuo Ishii) + + + 以前、makeの並列実行は以下のように失敗していました。 + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + anthonyrousselによってパッチが作成され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Fix parallel build + + + + + + + primary_conninfoのホストが不一致であることを詳細にログに出力するようになりました。(Taiki Koshino) + + + pgpool.confに設定されているPostgreSQLprimary_conninfoのホスト設定が一致しない場合以下のようなログが出力されます。 + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + + サポートされている最小のOpenSSLバージョンを明記しました。(Tatsuo Ishii) + + + こちらは以下を使用したconfigure.acによって実現しています。 + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + サポートされている最小バージョンは1.0.2で、これは現時点ではPostgreSQLと同じです(実際にはAC_DEFINEはPostgreSQLから導入されています)。 + また、インストールされているOpenSSLが3.0などの新しいバージョンである場合、OpenSSLの非推奨警告を回避できる可能性があります。 + さらに、インストールドキュメントに、必要なOpenSSLの最小バージョンは1.0.2であることを記載しました。 + + + + + + + RHELのPCPライブラリとのコンフリクトを回避するためにlibpcpをlibpgpoolpcpに名前を変更しました。(Bo Peng) + + + Pgpool-IIから提供されているlibpcp.soライブラリはRHELのlibpcp.soライブラリとコンフリクトします。 + コンフリクトを回避するためにPgpool-IIのlibpcpライブラリ名ををlibpgpoolpcpに変更しました。 + + + ディスカッション: Installing pgpool-II fails due to naming conflict with RHEL provided library + + + + + + + 不具合修正 + + + + + logdirの両方が設定されていないときに起動に失敗する問題を修正しました。(Taiki Koshino) + + + この問題はLuca Ferrariによって報告され、Taiki Koshinoによってレビューされました。 + + + ディスカッション: work_dir and/or logdir not set to default on 4.7 ? + + + + + + + check_transaction_state_and_abort()の考慮不足を修正しました。(Tatsuo Ishii) + + + この関数はフロントエンドがNULLアカウントであるケースを考慮していませんでした。 + + + この問題はCoverityによって発見されました。 + + + + + + + walker()が早めに結果を返すように修正しました。(Tatsuo Ishii) + + + 以前、walker()は対象オブジェクトを見つけたときにfalseを返していましたが、 + trueを返すようにし処理をショートカットするようにしました。 + + またwaker()の設計意図が分かりやすいようにPostgreSQLのコメントを移植しました。 + + + この問題はliujinyang-highgoによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Improper handling in the function view_walker(). + + + + + + + scram-sha-256認証でのメモリリークを修正しました。(Tatsuo Ishii) + + + この問題はCoverityによって発見されました。 + + + + + + + malloc()の返り値チェックを修正しました。(Tatsuo Ishii) + + + create_inet_domain_sockets()はソケットのファイルディスクリプタ用メモリを割り当てている間にmalloc()が返す値のチェックをしていませんでした。 + + + + + + + ヘルスチェックが開始しない問題を修正しました。(Tatsuo Ishii) + + + 以前、Pgpool-IIはバックエンドノードがダウンしている場合ヘルスチェックを開始しませんでした。 + これは自動フェイルバックを阻害します。 + Pgpoolはを指定していない場合pool_statusを読み込みます。 + もしpgpool_statusにダウンと記載されている場合はpgpoolはヘルスチェックを開始しませんでした。 + 自動フェイルバックはヘルスチェックから引き起こされるため、ヘルスチェックが起動しないと自動フェイルバックも実行されずバックエンドノードが復帰できませんでした。 + この修正によりノードの状態にかかわらずヘルスチェックが起動するようになりました。 + + + この問題はMeng Feilongによって報告され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: Nodes in the down state cannot failback + + + + + + + nodes.hに定義されているenum型のNodeTag値の重複を修正しました。(Tatsuo Ishii) + + + PostgreSQLから取り込んだnodes.hのNodeTag定義とPgpool-II独自の定義で起きていた重複を解消しました。 + + + この問題はliujinyang-highgoによって報告・検討され、Tatsuo Ishiiによってレビューされました。 + + + ディスカッション: an issue about NodeTag definition. + + + + + + + pcp_connectでのメモリリークを修正しました。(Tatsuo Ishii) + + + この関数は複数個所でfreeaddrinfo()を呼び出していませんでした。 + + + + + + + integer型のオーバーフローが起きる可能性がある問題を修正しました。(Tatsuo Ishii) + + + pool_write_flush()pool_flus_it()ではwrite(2)が使用されています。 + write(2)はssize_tを返しますが、コード内には戻り値がint変数に代入されている箇所がいくつかありました。 + その結果、戻り値が負の値として評価され、エラーが発生する可能性がありました。 + + + + + + + + リリース 4.7.0 + + リリース日 + 2025-12-23 + + + + 概要 + + このリリースでは、Pgpool-IIに対して複数の機能強化を行いました。 + 主な改善点として、従来のSlonyモードの廃止、セキュリティの強化、フロントエンド/バックエンドプロトコルの互換性向上、運用性の向上などが含まれます。 + + + + 主な機能の改良は以下の通りです。 + + + + + + + Slonyモードの廃止 + + + + + + logdirパラメータ名をに変更 + + + + + + フロントエンド/バックエンドプロトコルバージョン3.2サポートの追加 + + + + + + watchdogとheartbeat receiverのセキュリティ強化 + + + + + + クライアント情報を表示するためのpcp_proc_infoおよびshow pool_poolsに新しいフィールドの追加と、pgpool_adm_pcp_proc_info拡張関数の追加 + + + + + + オンラインリカバリに使用するデータベースを指定できるrecovery_databaseパラメータの追加 + + + + + + PostgreSQL 18のSQLパーサの導入 + + + + + + + + バージョン4.7への移行 + + + + + + Slonyモードを廃止しました。(Tatsuo Ishii) + + + これまで、Pgpool-IIは、slonyモードをの1つとしてサポートしていました。 + Slony-I + (https://www.slony.info/)。最新のSlony-I は2022 年にリリースされましたが、ユーザーから Slonyモードの廃止について何の報告もありませんでした。 + これは、Slony-Iモードを積極的に利用するユーザーがいないことを示唆しています。 + そこで、Slony-Iのサポートを中止することにしました。 + + + ディスカッション: [pgpool-general: 9486] Retiring slony mode + + + ディスカッション: Re: [pgpool-general: 9486] Retiring slony mode + + + + + + + パラメータのデフォルト値をoffに変更しました。(Tatsuo Ishii) + + + 以前のlog_pcp_processesのデフォルトはonでしたが、管理者がPgpool-IIの状態を監視するためにpcpコマンドを頻繁に使用すると、過剰なログ行が生成される可能性がありました。 + また、このログは一種のデバッグメッセージであるため、デフォルト値をoffに変更することをお勧めします。 + + + ディスカッション: Proposal: change log_pcp_processes default to off + + + + + + + オンラインリカバリに使用するデータベースの設定が可能になりました。 (Bo Peng) + + + 新しい設定パラメータが追加され、オンラインリカバリに使用するデータベースをユーザーが指定できるようになりました。 + 以前は、この値はtemplate1としてハードコードされていました。現在のデフォルトはpostgresに設定されています。 + + + 4.6より前のバージョンから移行するユーザーは、template1に設定するか、postgresデータベースにオンラインリカバリに必要な拡張機能を作成することで互換性を維持できます。 + + + + + + + logdirに名称を変更しました。 (Taiki Koshino) + + + 以前は、pgpool_statusおよびロックファイルを保存するディレクトリは、logdirパラメータで指定されていました。 + しかし、logdirという名前は誤解を招く恐れがあったため、このパラメータは、わかりやすくするためにに変更されました。 + デフォルト値は/tmpで、以前のパラメータlogdirと同じです。 + + + 互換性のため、古い logdirパラメータは引き続きサポートされています。 + 古いパラメータlogdirが使用されると、Pgpool-IIはその値をに設定し、警告メッセージを表示します。 + + + + + + + + 変更点 + + + + + + PostgreSQL 18の新しいパーサーをインポートしました。 (Bo Peng) + + + PostgreSQL 18パーサーの主な変更点は以下の通りです。 + + + + + 生成列を仮想列として使用可能 + + + + + DMLクエリのRETURNINGにOLD/NEWのサポートを追加 + + + + + 各種制約の追加(例:WITHOUT OVERLAPS、ENFORCED/NOT ENFORCED) + + + + + + + + + watchdogとheartbeat receiverが、設定されたアドレスのみを受け付けるように制限しました。(Bo Peng) + + + 以前は、watchdogプロセスとheartbeat receiverプロセスはどちらもすべてのインターフェースを受け付けていました。 + セキュリティ上の理由から、現在はhostnameheartbeat_hostnameで指定されたアドレスのみを受け付けるようになりました。 + + + + + + + watchdogのソースコードを整理しました。 (Tatsuo Ishii) + + + + + + wd_is_upper_ok()は定義されていないため、wd_utils.hから削除しました。 + + + + + wd_get_ping_result()wd_issue_ping_command()を静的関数にしました。これはwd_ping.cでのみ使用されます。 + + + + + + + + + + ライフチェックがまだ開始されていない場合、警告を出力するようになりました。(Tatsuo Ishii) + + + 現在、ライフチェックは、ライフチェックの準備が整った場合にのみログを出力します。 + 管理者は、ライフチェックの準備が整うまでログファイルを監視し続ける必要があるため、不便です。このコミットにより、ライフチェックプロセスは、ライフチェックが開始されるまで定期的に追加の警告を出力するようになります。 + 警告の間隔は × 10秒です。 + ただし、ライフチェック開始時の初回は、その時点ではライフチェックの準備が整っていない可能性が高いため、警告は出力されません。 + + + + + + + フロントエンド/バックエンドプロトコル3.2のサポートを追加しました。(Tatsuo Ishii) + + + + + NegotiateProtocolVersionメッセージを実装しました。 + + + フロントエンドがプロトコルバージョン3.2(PostgreSQL 18以降または互換クライアント)を要求し、バックエンドがまだ3.0(PostgreSQL 17以前)しかサポートしていない場合に、このメッセージを実装する必要があります。 + + + このコミットは、接続キャッシュが存在しない場合に、バックエンドからフロントエンドへメッセージを転送するようにメッセージを処理します。 + + + コネクションキャッシュが存在する場合、Pgpool-IIはコネクションキャッシュの作成時に保存されたメッセージをフロントエンドに送信します。 + + + ディスカッション: Feature: implement NegotiateProtocolVersion message + + + + + + プロトコルバージョン3.2にBackendKeyDataとクエリキャンセルメッセージを実装しました。 + + + PostgreSQL 18以降、フロントエンド/バックエンドプロトコルが3.2に変更されました。 + この変更により、BackendKeyDataとクエリキャンセルメッセージが修正され、可変長のキャンセルキーが使用できるようになりました。 + + + 3.2プロトコルを使用してPostgreSQLのフロントエンドとバックエンドに接続できるようになりました。 + + +セッション例: +PGMAXPROTOCOLVERSION="3.2" psql -p 11000 test + + + ディスカッション: Implement protocol 3.2 BackendKeyData and cancel request message + + + + + + + + + を追加しました。(Tatsuo Ishii) + + + を追加しました。 + また、show pool_poolsに、client_host、client_port、SQLステートメントという新しいフィールドが追加しました。 + これらの追加により、Pgpool-IIのクライアント、Pgpool-II本体、そしてPostgreSQL間の関係を追跡できます。 + + + pcp_proc_infoを使用して最後に実行されたコマンド(ステートメント)を確認できるようになりました。 + 以前は、Pgpool-IIのログを確認しない限り、これは不可能でした。 + + + lipcp.so のバージョンが 2.0.0 から 3.0.0 にアップグレードしました。 + + + + + + + ライフチェックのログを強化しました。 (Tatsuo Ishii) + + + 以前は、queryの場合、に「%a」が指定されていると、死活監視はアプリケーション名なしでSQLを出力していました。 + ログの見栄えを良くするために、application_namelifecheck_pingを追加しました。 + + + ディスカッション: [pgpool-hackers: 4603] life check log is not nicea + + + + + + + random()pg_prngrandom関数に置き換えました。 (Martijn van Duren, Tatsuo Ishii) + + + 以前は、負荷分散ノードの選択にrandom()を使用していました。 + しかし、PostgreSQLにはより優れた乱数生成器pg_prng.cがあります。 + このファイルをインポートするように変更し、pg_prng_double()を使用して[0.0, 1.0]の範囲の乱数を生成します。 + シードはpg_strong_random()を使用して生成されます。 + + + ディスカッション: [pgpool-hackers: 4588] Shuffle random functions and use better random numbers + + + + + + + watchdog受信ソケットのバインドを再試行するようにしました。(Tatsuo Ishii) + + + watchdog受信ソケットのバインドに失敗すると、028.watchdog_enable_consensus_with_half_votesがタイムアウトすることがありました。 + バインドを再試行することでこの問題を軽減するようになりました。 + 現在、再試行は最大5回まで実行され、各再試行ごとに1秒間のスリープが行われます。 + + + + + + + PostgreSQLからlikely/unlikely()を移植しました。(Tatsuo Ishii) + + + likely/unlikely()は正しく使用すれことでパフォーマンス向上に役立つだけでなく、コード内でマクロが時折使用されるため、PostgreSQLからPgpool-IIへのコードの移植が容易になります。 + + + ディスカッション: [pgpool-hackers: 4599] Porting likely/unlikely + + + + + + + PostmasterRandmon()pg_strong_random()に置き換えました。(Tatsuo Ishii) + + + PostmasterRandmon()はかなり以前(2016年)にPostgreSQLからインポートされました。 + 同年、PostgreSQLPostmasterRandmon()pg_strong_random()(src/port/pg_strong_random.c)に置き換えているためこちらに準拠しました。 + + + ディスカッション: [pgpool-hackers: 4588] Shuffle random functions and use better random numbers + + + + + + + .pcppassファイルからの読み取りに失敗した場合、パスワードの入力を求めるプロンプトにフォールバックするようになりました。(Bo Peng) + + + .pcppassファイルからのパスワードの読み取りに失敗した場合、PostgreSQL.pgpassを処理するのと同様に、ユーザーに入力を求めるプロンプトにフォールバックします。 + + + 以下のメッセージも変更され、 オプションを必要とせずに表示されます。 + +WARNING: password file \"%s\" is not a plain file +WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less + + + + ディスカッション: [pgpool-hackers: 4589] If reading password from .pcppass file fails, try to read it from prompt. + + + + + + + Pgpool-IIの起動時に不適切なログメッセージを削除またはダウングレードするようになりました。(Tatsuo Ishii) + + + + + + + 設定ファイルにメジャーバージョン情報を追加しました。(Bo Peng) + + + + + + + ドキュメント修正 + + + + + 文字列として扱われていた列挙型パラメータに関するドキュメントを修正しました。(Taiki Koshino) + + + 6つのパラメータのドキュメントを修正しました: + +log_standby_delay +log_backend_messages +wd_lifecheck_method +memqcache_method +disable_load_balance_on_write +backend_clustering_mode + + + + + + + + クエリキャッシュのドキュメントを改善しました。(Tatsuo Ishii) + + + Pgpool-IIは、TIMESTAMP WITH TIMEZONETIME WITH TIMEZONE を返す関数を呼び出すクエリのキャッシュを拒否します。 + 同じ名前の関数が複数あり、そのうちの1つがTIMESTAMP WITH TIMEZONETIME WITH TIMEZONE を返す場合、Pgpool-II は、そのうちの1つがこれらのデータ型を返さなくてもキャッシュを拒否します。 + そのため、この問題に関するメモと回避策を追加しました。 + + + + + + + テストツール修正 + + + + + でVIPを指定できるようになりました。(Tatsuo Ishii) + + + 新しいオプションを使用して、watchdog_setupでVIPパラメータ(delegate_ip)を指定できるようになりました。 + ipが省略された場合は、127.0.0.1が想定されます。 + vip オプションが指定されていても、Pgpool-IIは実際にはシステムにVIPを設定しません。 + は、単にechoコマンドに設定され、ログを出力する以外は何も行いません。 + このオプションは、VIP処理に関するPgpool-IIの動作をトレースすることを目的としています。 + + + ディスカッション: Enhance watchdog_setup + + + + + + + 回帰テスト修正 + + + + + 038.pcp_commandsの回帰テストを修正しました。(Tatsuo Ishii) + + + 以前はテスト結果にローカルホストのIPが表示されていました。 + IPはIPv4またはIPv6のどちらでも構いませんが、テストスクリプトではこれを考慮していませんでした。 + これを修正するため、test.shはIPv4とIPv6のIPをlocalhostに変換するようになりました。 + + + + + + + 029.cert_passphrase回帰テストを安定化しました。 (Tatsuo Ishii) + + + ssl_passphrase_commandが有効でない場合、エラーメッセージは通常「bad decrypt」ですが、「wrong tag」となる場合もあります。 + + + + + diff --git a/doc.ja/src/sgml/release.sgml b/doc.ja/src/sgml/release.sgml index 40a4aa7c4..c1b7fedbb 100644 --- a/doc.ja/src/sgml/release.sgml +++ b/doc.ja/src/sgml/release.sgml @@ -39,66 +39,73 @@ For new features, add links to the documentation sections. --> - リリースノート - + - このリリースノートには、Pgpool-II の各リリースでなされた重要な変更点が記載されています。 - また、主要機能や移行に関する問題点も最初に記載されています。 - リリースノートにはごく一部のユーザにしか影響しない変更点や内部的なものであるためユーザには隠れている変更点は記載されていません。 - - - + The release notes contain the significant changes in each + Pgpool-II release, with major features and migration + issues listed at the top. The release notes do not contain changes + that affect only a few users or changes that are internal and therefore not + user-visible. + --> + このリリースノートには、Pgpool-II の各リリースでなされた重要な変更点が記載されています。 + また、主要機能や移行に関する問題点も最初に記載されています。 + リリースノートにはごく一部のユーザにしか影響しない変更点や内部的なものであるためユーザには隠れている変更点は記載されていません。 + + + - 各リリースにおける変更点の全一覧は、各リリースの - Git ログを参照することで入手できます。 - pgpool-committers - メーリングリストにもすべてのソースコードの変更点が記録されています。 - また、特定のファイルに対する変更点を表示する Web インタフェースが存在します。 - - - + A complete list of changes for each release can be obtained by + viewing the Gitlogs for each release. + The pgpool-committers + email list records all source code changes as well. There is also + a web + interface that shows changes to specific files. + --> + 各リリースにおける変更点の全一覧は、各リリースの + Git ログを参照することで入手できます。 + pgpool-committers + メーリングリストにもすべてのソースコードの変更点が記録されています。 + また、特定のファイルに対する変更点を表示する Web インタフェースが存在します。 + + + - 各項目の後に記述した名前は、その項目の主な開発者の名前です。 - もちろんすべての変更はコミュニティによる議論やパッチレビューが行われていますので、 - 各項目は本当はコミュニティによるものと言えます。 - - - + The name appearing next to each item represents the major developer for + that item. Of course all changes involve community discussion and patch + review, so each item is truly a community effort. + --> + 各項目の後に記述した名前は、その項目の主な開発者の名前です。 + もちろんすべての変更はコミュニティによる議論やパッチレビューが行われていますので、 + 各項目は本当はコミュニティによるものと言えます。 + + + -&release-4.0; -&release-3.7; -&release-3.6; -&release-3.5; -&release-3.4; -&release-3.3; -&release-3.2; -&release-3.1; + &release-4.7; + &release-4.6; + &release-4.5; + &release-4.4; + &release-4.3; + &release-4.2; + &release-4.1; + &release-4.0; + &release-3.7; + &release-3.6; + &release-3.5; + &release-3.4; + &release-3.3; + &release-3.2; + &release-3.1; diff --git a/doc.ja/src/sgml/restrictions.sgml b/doc.ja/src/sgml/restrictions.sgml index c8f4ef2d4..535b60c06 100644 --- a/doc.ja/src/sgml/restrictions.sgml +++ b/doc.ja/src/sgml/restrictions.sgml @@ -1,371 +1,532 @@ - + --> 制限事項 - -この章では、Pgpool-IIの現在の制限事項について説明します。 + + この章では、Pgpool-IIの現在の制限事項について説明します。 - - PostgreSQLの機能 + --> + pg_terminate_backendの利用 - -pg_terminate_backend()を使ってバックエンドを停止すると、フェイルオーバが起こります。 -これは、PostgreSQLが、postmasterの停止と全く同じメッセージをバックエンド停止時に送るためです。 -3.6より前のバージョンには回避策はありません。 -3.6以降では、この制限は緩和されています。 -その関数の引数(プロセスIDです)が定数なら、その関数を使っても安全です。 -しかし、拡張プロトコルでは、その関数は使えません。 + + pg_terminate_backend()を使ってバックエンドを停止すると、フェイルオーバが起こります。 + これは、PostgreSQLが、postmasterの停止と全く同じメッセージをバックエンド停止時に送るためです。 + Pgpool-II 3.6より前のバージョンには回避策はありません。 + 3.6以降では、この制限は緩和されています。 + その関数の引数(プロセスIDです)が定数なら、その関数を使っても安全です。 + しかし、拡張プロトコルでは、その関数は使えません。 + 4.3以降では、offにすることで、pg_terminate_backend()によるフェイルオーバを完全に回避できますが、その代わりpostmasterの停止によるフェイルオーバも起きなくなります。 - + --> 認証/アクセス制御 - - -レプリケーションモードまたマスタ/スレーブモード時にはtrust、reject、clear text password、pam認証方式が利用できます。 -crypt認証は利用できません。 -Pgpool-II 3.0以降では、pool_passwdというファイルを使ってmd5認証も使えます。 -pool_passwdはデフォルトの認証ファイル名です。 -md5認証を有効にする手順を示します。 - + + + trust、reject、pam認証方式が利用できます。 + Pgpool-II 3.0以降では、pool_passwdというファイルを使ってmd5認証も使えます。 + Pgpool-II 4.0以降では、scram-sha-256、cert、clear text password認証も使えます。 + pool_passwdはデフォルトの認証ファイル名です。 + md5認証を有効にする手順を示します。 + - + - - - -DBユーザのOSアカウントでログインし、以下を実行します。 - - pg_md5 --md5auth --username=your_username your_passwd - - -ユーザ名とmd5により暗号化されたパスワードがpool_passwdに登録されます。 -pool_passwdがまだ存在しなければ、pg_md5コマンドは、自動的にpgpool.confと同じディレクトリ内にpool_passwdを作成します。 -pool_passwdのフォーマットは、username:encrypted_passwdです。 - - + + + + DBユーザのOSアカウントでログインし、以下を実行します。 + + pg_md5 --md5auth --username=your_username your_passwd + + + ユーザ名とmd5により暗号化されたパスワードがpool_passwdに登録されます。 + pool_passwdがまだ存在しなければ、pg_md5コマンドは、自動的にpgpool.confと同じディレクトリ内にpool_passwdを作成します。 + pool_passwdのフォーマットは、username:encrypted_passwdです。 + + - - - -また、pool_hba.confに適当なmd5のエントリを作成する必要があります。 -詳細はを見てください。 - - + + + + また、pool_hba.confに適当なmd5のエントリを作成する必要があります。 + 詳細はを見てください。 + + - - - -pool_passwdに登録するパスワードは、PostgreSQLに登録したパスワードと完全に同じでなければなりません。 - - + + + + pool_passwdに登録するパスワードは、PostgreSQLに登録したパスワードと完全に同じでなければなりません。 + + - - - -md5パスワード(もちろんpool_passwdとPostgreSQLの両方)を変更したら、pgpool reload を実行してください。 - - - + + + + md5パスワード(もちろんpool_passwdとPostgreSQLの両方)を変更したら、pgpool reload を実行してください。 + + + + + + scram-sha-256認証の設定については、を参照してください。 + - + --> ラージオブジェクト - - -ストリーミングレプリケーションモードでは、Pgpool-IIはラージオブジェクトをサポートしています。 - - - -ネィティブレプリケーションモードでは、PostgreSQL 8.1以降ならばラージオブジェクトをサポートします。 -その際には、pgpool.confのlobj_lock_tableを有効にしてください。 -なお、バックエンド関数のlo_importを使ったラージオブジェクトのレプリケーションはサポートされていません。 - - - -Slonyモードも含め、その他のモードではラージオブジェクトはサポートされていません。 - + + + では、Pgpool-IIはラージオブジェクトをサポートしています。 + + + + では、PostgreSQL 8.1以降ならばラージオブジェクトをサポートします。 + その際には、pgpool.confのlobj_lock_tableを有効にしてください。 + なお、バックエンド関数のlo_importを使ったラージオブジェクトのレプリケーションはサポートされていません。 + + + + その他のモードではラージオブジェクトはサポートされていません。 + - + 一時テーブル - - -一時テーブルの作成、挿入、更新、削除は、常にマスター(プライマリ)で実行されます。 -テーブルに対するSELECTもマスター上で実行されます。 -しかし、一時テーブル名が文字列としてSELECTで使われると、それを検知する方法がないため、SELECTは負荷分散されます。 -これにより、「テーブルが見つからない」エラーになったり、同じ名前を持つ別のテーブルを検索することになります。 -この問題を回避するには、/*NO LOAD BALANCE*/ SQLコメントを使ってください。 - - - -ちなみに、psqlの\dコマンドのように、システムカタログを問い合わせる中で -文字列としてのテーブル名を使っている場合: - -SELECT 't1'::regclass::oid; - -pgpool-II 3.0以降ではマスタで検索が行なわれるので、問題になりません。 -なぜなら、システムカタログへの検索は常にマスタで行なわれるからです。 - + + + 一時テーブルの作成、挿入、更新、削除は、常にマスター(プライマリ)で実行されます。 + テーブルに対するSELECTもマスター上で実行されます。 + しかし、一時テーブル名が文字列としてSELECTで使われると、それを検知する方法がないため、SELECTは負荷分散されます。 + これにより、「テーブルが見つからない」エラーになったり、同じ名前を持つ別のテーブルを検索することになります。 + この問題を回避するには、SQLコメントを使ってください。 + + + + ちなみに、psqlの\dコマンドのように、システムカタログを問い合わせる中で + 文字列としてのテーブル名を使っている場合: + + SELECT 't1'::regclass::oid; + + pgpool-II 3.0以降ではマスタで検索が行なわれるので、問題になりません。 + なぜなら、システムカタログへの検索は常にマスタで行なわれるからです。 + - - -PostgreSQL 8.3以後を使っているのであれば、CREATE TEMP TABLEによって作成されたテーブルは、reset_query_list中のDISCARD ALLを指定することによってセッションの最後で削除されます。 - - - -8.2.x以前では、CREATE TEMP TABLEによって作成されたテーブルは、セッションを終了した後に削除されません。 -PostgreSQLバックエンドから見ると、コネクションプールによってセッションが維持されているからです。 -これを回避するには、明示的にDROP TABLEを発行するか、トランザクションブロックの内側でCREATE TEMP TABLE ... ON COMMIT DROPを実施します。 - + + + PostgreSQL 8.3以後を使っているのであれば、CREATE TEMP TABLEによって作成されたテーブルは、reset_query_list中のDISCARD ALLを指定することによってセッションの最後で削除されます。 + + + + 8.2.x以前では、CREATE TEMP TABLEによって作成されたテーブルは、セッションを終了した後に削除されません。 + PostgreSQLバックエンドから見ると、コネクションプールによってセッションが維持されているからです。 + これを回避するには、明示的にDROP TABLEを発行するか、トランザクションブロックの内側でCREATE TEMP TABLE ... ON COMMIT DROPを実施します。 + - - ネィティブレプリケーションモードにおける関数などの扱い + --> + における関数などの扱い - - -文脈依存の仕組み(たとえば乱数やトランザクションID、OID、SERIAL、シーケンス)を使って提供されるデータが複数のバックエンドに正しくレプリケーションされる保証はありません。 -SERIALに対しては、insert_lockを使って対応できます。 -SELECT setval()とSELECT nextval()に対してもinsert_lockで対応できます。 - - - -CURRENT_TIMESTAMPCURRENT_DATEnow()を含むINSERT/UPDATEは正しくレプリケーションされます。 -CURRENT_TIMESTAMPCURRENT_DATEnow()をデフォルト値として使うINSERT/UPDATEも正しくレプリケーションされます。 -これは、関数を、クエリ実行時にマスターから取得した定数に置き換えることで達成されています。 -しかし、いくつか制限事項があります。 - - - -Pgpool-II 3.0以前では、テーブルのデフォルト値としての時制データが正しく計算されない場合があります。 -例として以下のテーブル定義を示します。 - -CREATE TABLE rel1( - d1 date DEFAULT CURRENT_DATE + 1 -) - - -これは次と同じに扱われます。 - -CREATE TABLE rel1( - d1 date DEFAULT CURRENT_DATE -) - - -Pgpool-II 3.1以降はこのケースを正しく扱います。 -ですのでd1列はtomorrowがデフォルト値になります。 -しかし、この改善は拡張プロトコル(たとえばJDBC、PHP PDO)やPREPAREが使用されている場合には適用されません。 - - - -列の型が時制ではない場合は書き換えは行われないことに注意してください。 -そのような例を示します。 - -foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision) - - -以下のテーブルがあるとします。 - -CREATE TABLE rel1( - c1 int, - c2 timestamp default now() -) - - - -INSERT INTO rel1(c1) VALUES(1) - - -これは以下に書き換えられるものの、 - -INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09') - + + + 文脈依存の仕組み(たとえば乱数やトランザクションID、OID、SERIAL、シーケンスなど)を使って提供されるデータが複数のバックエンドに正しくレプリケーションされる保証はありません。 + SERIALに対しては、insert_lockを使って対応できます。 + SELECT setval()とSELECT nextval()に対してもinsert_lockで対応できます。 + + + + CURRENT_TIMESTAMPCURRENT_DATEnow()を含むINSERT/UPDATEは正しくレプリケーションされます。 + CURRENT_TIMESTAMPCURRENT_DATEnow()をデフォルト値として使うINSERT/UPDATEも正しくレプリケーションされます。 + これは、関数を、クエリ実行時にPostgreSQLから取得した定数に置き換えることで達成されています。 + しかし、いくつか制限事項があります。 + + + + Pgpool-II 3.0以前では、テーブルのデフォルト値としての時制データが正しく計算されない場合があります。 + 例として以下のテーブル定義を示します。 + + CREATE TABLE rel1( + d1 date DEFAULT CURRENT_DATE + 1 + ) + + + これは次と同じに扱われます。 + + CREATE TABLE rel1( + d1 date DEFAULT CURRENT_DATE + ) + + + Pgpool-II 3.1以降はこのケースを正しく扱います。 + ですのでd1列はtomorrowがデフォルト値になります。 + しかし、この改善は拡張プロトコル(たとえばJDBC、PHP PDO)やPREPAREが使用されている場合には適用されません。 + + + + 列の型が時制ではない場合は書き換えは行われないことに注意してください。 + そのような例を示します。 + + foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision) + + + 以下のテーブルがあるとします。 + + CREATE TABLE rel1( + c1 int, + c2 timestamp default now() + ) + + + + INSERT INTO rel1(c1) VALUES(1) + + + これは以下に書き換えられるものの、 + + INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09') + + + + INSERT INTO rel1(c1) SELECT 1 + + + は変換されません。 + ですので現在の実装では正しくレプリケーションされません。 + 値は挿入されますが、全く変換が行われません。 + + + + + + SQL型コマンド + + + + SQL型コマンドは、拡張クエリモードでは使用できません。 + + + + + + マルチバイト文字 + + + + 現在の実装では、クライアントとPostgreSQLの間でマルチバイト文字の変換処理を行いません。 + クライアントエンコーディング、バックエンドノードのサーバエンコーディングを一致させるようにしてください。 + + + + + + libpq + + + + pgpool-II では libpq をリンクします。 + libpq のバージョンが 2.0 の場合、configureに失敗します。 + 必ず libpq 3.0 以降(PostgreSQL 7.4以降)をリンクするようにしてください。 + + + + + + ParameterStatus + + - -INSERT INTO rel1(c1) SELECT 1 - + When a client connects + to PostgreSQL, PostgreSQL + sends back some parameter/value pairs to clients. This protocol + is + called ParameterStatus. + The parameter/value pairs can be extracted by using some APIs + such as PQParameterStatus of libpq. The + actual parameter names can be + found here. + Pgpool-II collects ParameterStatus + values from multiple PostgreSQL + servers and it is possible that the values vary among the + servers. A typical example is in_hot_standby, + which is introduced in PostgreSQL + 14. The value for the variable is off on + primary server and on on standby + servers. Problem is, Pgpool-II has + to return client only one of them. In this case it chooses the + value reported by the primary + server. So PQParameterStatus will + return off. On the other hand, when the + client issues show in_hot_standby, the + returned value can either on + or off depending on which is the load + balance node for the session. +--> + クライアントがPostgreSQLに接続すると、PostgreSQLは複数のパラメータ/値のペアをクライアントに返します。 + このプロトコルはParameterStatusと呼ばれます。 + このパラメータ/値ペアはある種のAPI、たとえばlibpqのPQParameterStatusで取得できます。 + 該当する実際のパラメータ名はここにあります。 + Pgpool-IIはParameterStatusの値を複数のPostgreSQLサーバから収集するため、その値がサーバによって異なる可能性があります。典型的な例は、PostgreSQL 14で導入されたin_hot_standbyです。 + この値はプライマリサーバではoffで、スタンバイサーバではonになります。 + 問題は、Pgpool-IIはその値のひとつだけをクライアントに返さなければならないことです。 + この場合は、プライマリサーバの値が選択されます。 + ですから、PQParameterStatusoffを返すでしょう。 + 一方で、クライアントがshow in_hot_standbyを発行すると、その時のセッションのロードバランスノードによって、onあるいはoffが返ります。 + + -は変換されません。 -ですので現在の実装では正しくレプリケーションされません。 -値は挿入されますが、全く変換が行われません。 - + その値がin_hot_standby以外で異なる時には、Pgpool-IIはログメッセージを出力することに注意してください。 + これは、in_hot_standbyの値は常に異なるからです。 + - SQL型コマンド + set_config - + + PostgreSQLにはset_configという関数があり、SETコマンドで現在のセッションに対してパラメータの値を変更するのと同じ効果を与えることができます(実際にはSETにない機能もあります。詳細はPostgreSQLのマニュアルを見てください)。 + Pgpool-IIでは、現在のクラスタリングモードがstreaming_replicationの場合、プライマリサーバにのみこの関数を送信します。 + スタンバイサーバにはこの関数が送信されないので、それぞれのサーバでパラメータの値が異なることになります。 + この問題を回避するには、set_configの代わりにSETコマンドを使用してください。 + SETコマンドは、現在のセッションが使用しているすべてのサーバに送信されるので、この問題は起きません。 + ただしPostgreSQLサーバを3台以上使っているときは、をoffにした上でSETコマンドを使用してください。 + がonの場合、現在のセッションが使用しているプライマリサーバ、ロードバランスノードになっているスタンバイサーバに加え、3台目のスタンバイサーバにもクエリを送信する可能性があるからです。 + + + -SQL型コマンドは、拡張クエリモードでは使用できません。 - + どうしてもset_configを使わなければならないのであれば、そのセッションでの負荷分散機能をoffにしてください(set_configだけでなく、そのセッションで負荷分散機能を使わないようにする必要があります)。 + 性能は犠牲になりますが、問題は回避できます。 + diff --git a/doc.ja/src/sgml/runtime.sgml b/doc.ja/src/sgml/runtime.sgml index bcb86896f..2931dacc9 100644 --- a/doc.ja/src/sgml/runtime.sgml +++ b/doc.ja/src/sgml/runtime.sgml @@ -1,34 +1,59 @@ - + --> サーバの準備と運用 - -本章では、Pgpool-IIサーバの設定と実行方法、そしてオペレーティングシステムとの相互作用について説明します。 + --> + 本章では、Pgpool-IIサーバの設定と実行方法、そしてオペレーティングシステムとの相互作用について説明します。 + + カーネルリソースの管理 + + + カーネルリソース + + + + Pgpool-IIを動かすためには、System V共有メモリとSystem Vセマフォが必要です。 + どちらもLinuxでは十分な量が提供されますが、他のプラットフォームではカーネルパラメータの調整が必要かも知れません。 + + + System V共有メモリは、最低でも約140MB必要です。 + デフォルトの64MBより多いクエリキャッシュを使用する場合は、更に追加が必要になるかもしません。 + 共有メモリの必要セグメント数は3です。 + 通常カーネルは十分な共有メモリセグメント数があるはずです。 + + + + System Vセマフォは、約10個ほど使用します。 + 必要セット数は1です。 + 通常カーネルには十分なSystem Vセマフォ数があるはずです。 + + + - + --> <productname>Pgpool-II</productname>ユーザアカウント - + --> Pgpool-IIユーザ - -外部へアクセスできるサーバデーモンと同じように、Pgpool-IIを独立したユーザアカウントで実行することをお勧めします。 -このユーザアカウントは、サーバによって管理されるデータのみを所有する必要があります。 -また、他のデーモンとアカウントを共有しない方が良いです。 -(例えば、nobodyユーザの使用はお勧めできません。) -このユーザによって所有される実行プログラムをインストールすることも好ましくありません。 -システムが攻撃を受けた場合などに、自分自身のバイナリを変更されてしまう可能性があるからです。 + --> + 外部へアクセスできるサーバデーモンと同じように、Pgpool-IIを独立したユーザアカウントで実行することをお勧めします。 + このユーザアカウントは、サーバによって管理されるデータのみを所有する必要があります。 + また、他のデーモンとアカウントを共有しない方が良いです。 + (例えば、nobodyユーザの使用はお勧めできません。) + このユーザによって所有される実行プログラムをインストールすることも好ましくありません。 + システムが攻撃を受けた場合などに、自分自身のバイナリを変更されてしまう可能性があるからです。 - -システムにUnixのユーザアカウントを追加するためには、コマンドuseraddadduserを使用してください。 -pgpoolというユーザ名がよく使われ、本書全体でも使用していますが、好みの名前を使用しても構いません。 + --> + システムにUnixのユーザアカウントを追加するためには、コマンドuseraddadduserを使用してください。 + pgpoolというユーザ名がよく使われ、本書全体でも使用していますが、好みの名前を使用しても構いません。 - + --> pcp.confの設定 - + --> pcpの設定 - -Pgpool-IIは管理者がPgpool-IIのステータス取得や、リモートからのPgpool-IIプロセスの停止といった、管理操作を行うためのインターフェイスを提供しています。 -pcp.confはこのインタフェースの認証に使われるユーザ/パスワードのファイルです。 -全ての動作モードにおいてpcp.confの設定が必要です。 -Pgpool-IIのインストール中に$prefix/etc/pcp.conf.sampleが作られます。 -そのファイルを$prefix/etc/pcp.confという名前でコピーしてユーザ名とパスワードを追加してください。 - - -$ cp $prefix/etc/pcp.conf.sample $prefix/etc/pcp.conf - - - -空白行や#で始まる行はコメントと見なされ無視されます。 -ユーザ名とそれに対応するパスワードは以下の形式を使って1行で書かれなくてはなりません。 - - - -ユーザ名:[md5暗号化されたパスワード] - - - -[md5暗号化されたパスワード]は、$prefix/bin/pg_md5コマンドで作成できます。 - - -$ pg_md5 your_password -1060b7b46a3bd36b3a0d66e0127d0517 - - - - パスワードを引数に渡したくない場合はpg_md5 -pを実行してください。 - - -$ pg_md5 -p -password: your_password - - - -pcp.confは、Pgpool-IIを実行するユーザから読み取り可能になっていなければなりません。 + + Pgpool-IIは管理者がPgpool-IIのステータス取得や、リモートからのPgpool-IIプロセスの停止といった、管理操作を行うためのインターフェイスを提供しています。 + pcp.confはこのインタフェースの認証に使われるユーザ/パスワードのファイルです。 + 全ての動作モードにおいてpcp.confの設定が必要です。 + Pgpool-IIのインストール中に$prefix/etc/pcp.conf.sampleが作られます。 + そのファイルを$prefix/etc/pcp.confという名前でコピーしてユーザ名とパスワードを追加してください。 + + + $ cp $prefix/etc/pcp.conf.sample $prefix/etc/pcp.conf + + + + 空白行や#で始まる行はコメントと見なされ無視されます。 + ユーザ名とそれに対応するパスワードは以下の形式を使って1行で書かれなくてはなりません。 + + + + ユーザ名:[md5暗号化されたパスワード] + + + + [md5暗号化されたパスワード]は、$prefix/bin/pg_md5コマンドで作成できます。 + + + $ pg_md5 your_password + 1060b7b46a3bd36b3a0d66e0127d0517 + + + + パスワードを引数に渡したくない場合はpg_md5 -pを実行してください。 + + + $ pg_md5 -p + password: your_password + + + + pcp.confは、Pgpool-IIを実行するユーザから読み取り可能になっていなければなりません。 - + --> Pgpool-IIの設定 - + --> Pgpool-IIの設定 - - pgpool.confの設定 - - - -pgpool.confPgpool-IIのメインの設定ファイルです。 -Pgpool-IIの起動時にはオプションでこのファイルのパスを指定する必要があります。 -デフォルトではpgpool.conf$prefix/etc/pgpool.confに配置されます。 - + + pgpool.confの設定 + + + + pgpool.confPgpool-IIのメインの設定ファイルです。 + Pgpool-IIの起動時にはオプションでこのファイルのパスを指定する必要があります。 + ソースコードからインストールした場合、デフォルトではpgpool.conf$prefix/etc/pgpool.confに配置されます。 + + + + 各Pgpool-IIのクラスタリングモードについて設定のサンプルがあります。 + + + + + + pgpool.conf中の<xref linkend="guc-backend-clustering-mode">の値 + + + + + + クラスタリングモード + + + + + + + + ストリーミングレプリケーションモード + streaming_replication + + + ネイティブレプリケーションモード + native_replication + + + ロジカルレプリケーションモード + logical_replication + + + スナップショットアイソレーションモード + snapshot_isolation + + + Rawモード + raw + + + +
+ + + + これらの設定ファイルはデフォルトのソースコードからのインストールでは/usr/local/etcに配置されています。 + これらをpgpool.confとしてコピーして使うことが可能です。 + (もしかするとそのためにはroot権限が必要かもしれません。) + +# cd /usr/local/etc +# cp pgpool.conf.sample pgpool.conf + +
+ + Pgpool-IIのクラスタリングモード + + + ストリーミングレプリケーションモード + + + + + メインレプリカモード + + + + + ネィティブレプリケーションモード + + + + + ロジカルレプリケーションモード + + + + + スナップショットアイソレーションモード + + + + Pgpool-IIにはストリーミングレプリケーションモード、ロジカルレプリケーションモード、ネイティブレプリケーションモード、スナップショットアイソレーションモード、rawモードの6つのクラスタリングモードがあります。 + いずれのモードにおいても、Pgpool-IIはコネクションプーリング、自動フェイルオーバの機能を提供します。 + ストリーミングレプリケーションモード、ネイティブレプリケーションモード、スナップショットアイソレーションモードでは、更新処理を受け付けながらデータベースノードの同期を取り直すオンラインリカバリが利用可能です。 + オンラインリカバリの詳細についてはを参照してください。 + + + + これらのモードは互いに排他的であり、サーバ起動後は変更することができません。 + システム設計の初期の段階でどのモードを使うか決めなければなりません。 + どれを使えば良いかわからない場合は、ストリーミングレプリケーションモードかスナップショットアイソレーションモードを使うことを推奨します。 + + + + ストリーミングレプリケーションモードはストリーミングレプリケーションを使用するPostgreSQLサーバ(AWSのAurora、RDSを含みます)と一緒に使うことができます。 + このモードでは、PostgreSQLがデータベースを同期する責任を持ちます。 + このモードは広く使われており、最も推奨されるPgpool-IIの使用法です。 + このモードでは負荷分散が可能です。 + ノードをまたがる可視性の一貫性は保証されません。 + + + + スナップショットアイソレーションモードでは、Pgpool-IIがデータベースを同期する責任を持ちます。 + このモードの利点はデータベース同期が同期的に行われることです。 + すなわち、データベースへの書き込みは全てのPostgreSQLサーバが書き込み操作を完了するまで返ってきません。 + また、スナップショットアイソレーションモードは、ノードをまたがる可視性の一貫性を保証します。 + これは簡単に言うと、単一サーバ上のトランザクション可視性ルールがそのまま複数サーバからなるクラスタでも適用されるということで、Pgpool-IIのスナップショットアイソレーションモードが持つ著しい特徴です。 + 実際、PostgreSQLに改造を加えずにノードをまたがる可視性の一貫性を保証するシステムは、現時点ではPgpool-IIのスナップショットアイソレーションモードだけです。 + これにより、アプリケーションは単一のPostgreSQLではなく複数PostgreSQLからなるクラスタを使っていることを意識しないで済むメリットがあります。 + ただし、このモードではトランザクション分離レベルをREPEATABLE READにする必要があります。 + 具体的には、postgresql.confに以下のように記述します。 + +default_transaction_isolation = 'repeatable read' + + また、トランザクションの一貫性を保つ仕組みのオーバヘッドにより、ストリーミングレプリケーションモードやネイティブレプリケーションモードに比べると性能が低下します。 + + + + ネイティブレプリケーションモードでは、Pgpool-IIがデータベースを同期する責任を持ちます。 + このモードの利点は同期が同期的に行われることです。 + すなわち、データベースへの書き込みは全てのPostgreSQLサーバが書き込み操作を完了するまで返ってきません。 + このモードではノードをまたがる可視性の一貫性は保証されないので、トランザクション分離レベルをREPEATABLE READに限定したくない場合を除き、スナップショットアイソレーションモードを使うことをお勧めします。 + このモードでは負荷分散が可能です。 + + + + + ロジカルレプリケーションモードはロジカルレプリケーションを使用するPostgreSQLサーバと一緒に使うことができます。 + このモードでは、PostgreSQLがテーブルを同期する責任を持ちます。 + このモードでは負荷分散が可能です。 + ロジカルレプリケーションは必ずしもすべてのテーブルをレプリケーションしないので、負荷分散させるテーブルがレプリケーションされるようにするのはユーザの責任です。 + Pgpool-IIはすべてのテーブルをロードバランスします。 + このことは、テーブルがレプリケーションされていない場合には、Pgpool-IIがサブスクライバー側の更新されていない古いテーブルを見てしまうかもしれないことを意味します。 + + + + + rawモードでは、Pgpool-IIはデータベースの同期に関しては関与しません。 + システム全体に意味の有る動作をさせるのはユーザの責任となります。 + このモードでは負荷分散はできません。 + + + + + + プロセス管理モード + + + dynamic process management + + + + static process management + + + + Pgpool-IIは、各子プロセスが常に1つのクライアント接続を処理できるマルチプロセスアーキテクチャを実装しています。 + Pgpool-IIが処理できるクライアントの最大同時接続数は、設定パラメーターによって設定されます。 + Pgpool-IIは、2つの子プロセス管理モードdynamicおよびstaticをサポートしています。 + 静的(static)プロセス管理モードでは、Pgpool-IIは起動時にnum_init_childrenの設定値の数の子プロセスを事前にフォークし、各子プロセスは、クライアント接続をリッスンし続けます。 + 動的(dynamic)プロセス管理モードでは、Pgpool-IIはアイドル状態のプロセスを追跡し、プロセスの数を指定された範囲内に維持するために、プロセスをforkまたはkillします。 + + + + は、Pgpool-II V4.4より以前のバージョンでは使用できません。 + + + +
+ + + + バックエンド情報の設定 + + + + Pgpool-IIがPostgreSQLバックエンドサーバを認識するために、pgpool.confbackend*を設定する必要があります。 + 手始めに、Pgpool-IIを起動するには少なくてもパラメータが設定されている必要があります。 + + + + + バックエンドの設定 + + + + Pgpool-IIに使用されるバックエンドPostgreSQLがpgpool.confで指定されている必要があります。 + を参照してください。 + + + + + + + + + - Pgpool-IIの動作モード - - - ストリーミングレプリケーションモード - + Pgpool-IIとPostgreSQLの起動 - + - マスタースレーブモード - + Pgpool-IIを起動するには、以下を実行してください。 + +$ pgpool -f /usr/local/etc/pgpool.conf -F /usr/local/etc/pcp.conf + + + これにより、サーバがバックグラウンドモードで起動します。 + "-f"はpgpoolの主設定ファイルへのパスを指定します。 + "-F"はPgpool-IIの管理サーバであるpcpサーバの設定ファイルへのパスを指定します。 + 他のオプションに関しては、のマニュアルを見てください。 + - + - ネィティブレプリケーションモード - + Before starting Pgpool-II, you must + start PostgreSQL because if + PostgreSQL has not started yet, + Pgpool-II triggers failover process and + makes PostgreSQL is in down status. +--> + Pgpool-IIを起動する前に、PostgreSQLを起動しなければなりません。 + なぜなら、もしPostgreSQLが起動していなければ、Pgpool-IIはフェイルオーバの処理を起動し、PostgreSQLをダウン状態にしてしまうからです。 + - + - ロジカルレプリケーションモード - + If you have difficulty in controlling the startup sequence of + PostgreSQL, for example + Pgpool-II and + PostgreSQL are installed on different + servers, you can make longer (the default is 5 + minutes) so that Pgpool-II waits for + PostgreSQL starts up until expires. If + PostgreSQL starts up before expires, + Pgpool-II should start up without + problem. If + expires before PostgreSQL starts up, no + primary node will be detected, which means you cannot execute + DML/DDL. You need to restart Pgpool-II + in this case. To confirm that the primary node exists you can use + command. +--> +たとえばPgpool-IIPostgreSQLが別のサーバにインストールされているような理由でPostgreSQLの起動順序を制御するのが難しい場合は、を長めにし(デフォルトは5分です)、Pgpool-IIが、が終了するまでPostgreSQLの起動を待つようにすることができます。 +PostgreSQLが、が完了するまでの間に起動すれば問題ありません。 +もしPostgreSQLが起動する前にが完了すると、プライマリノードが検出されず、DML/DDLを実行できなくなります。 +こうなったら、Pgpool-IIを再起動する必要があります。 +プライマリノードが存在するかどうかを確認するには、コマンドを使ってください。 + - + -Pgpool-IIにはストリーミングレプリケーションモード、ロジカルレプリケーションモード、マスタースレーブモード(slonyモード)、ネイティブレプリケーションモード、rawモードの5つの動作モードがあります。 -いずれのモードにおいても、Pgpool-IIはコネクションプーリング、自動フェイルオーバ、オンラインリカバリの機能を提供します。 -各モードのためのサンプルの設定ファイルが提供されています。 -これらは$prefix/etc/以下に配置されており、$prefix/etc/pgpool.confとしてコピーして使用することができます。 - + Please note can + only be used in the streaming replication mode because the + parameter is only valid in the mode. See for more details about streaming + replication mode. For other mode, tweak the health check (see ) parameters so that there's + enough time before PostgreSQL becomes + available. +--> +はストリーミングレプリケーションモードでのみ使用できることに注意してください。 +そのパラメータはストリーミングレプリケーションモードにしかないからです。 +ストリーミングレプリケーションモードの詳細はをご覧ください。 +他のモードでは、ヘルスチェック(参照)のパラメータを調整し、PostgreSQLが使えるようになるまでに十分時間が取れるようにしてください。 + - + -これらのモードは互いに排他的であり、サーバ起動後は変更することができません。 -システム設計の初期の段階でどのモードを使うか決めなければなりません。 -どれを使えば良いかわからない場合は、ストリーミングレプリケーションモードを使うことを推奨します。 - + If health check detects that PostgreSQL + is not available before Pgpool-II starts + up, some or all PostgreSQL are + recognized in "down" status. In this case you need to manually put + the PostgreSQL server in "up" state by + using command. If a client tries + to connect to Pgpool-II before + PostgreSQL is available, failover could + be triggered. In this case you also need to execute command to put the + PostgreSQL server in "up" state. +--> +Pgpool-IIが起動するまでにPostgreSQLが使えないことをヘルスチェックが検出すると、PostgreSQLのいくつかが「down」状態であると認識されます。 +この場合は手動でコマンドを使ってPostgreSQLサーバを「up」状態にしなければなりません。 +クライアントがPostgreSQLが利用可能になる前にPgpool-IIに接続しようとすると、フェイルオーバが起こることがあります。 +この場合もコマンドを使ってPostgreSQLサーバを「up」状態にしなければなりません。 + + - + -ストリーミングレプリケーションモードはストリーミングレプリケーションを使用するPostgreSQLサーバと一緒に使うことができます。 -このモードでは、PostgreSQLがデータベースを同期する責任を持ちます。 -このモードは広く使われており、最も推奨されるPgpool-IIの使用法です。 -このモードでは負荷分散が可能です。 -サンプルの設定ファイルは$prefix/etc/pgpool.conf.sample-streamです。 - - - - -ロジカルレプリケーションモードはロジカルレプリケーションを使用するPostgreSQLサーバと一緒に使うことができます。 -このモードでは、PostgreSQLがテーブルを同期する責任を持ちます。 -このモードでは負荷分散が可能です。 -ロジカルレプリケーションは必ずしもすべてのテーブルをレプリケーションしないので、負荷分散させるテーブルがレプリケーションされるようにするのはユーザの責任です。 -Pgpool-IIはすべてのテーブルをロードバランスします。 -このことは、テーブルがレプリケーションされていない場合には、Pgpool-IIがサブスクライバー側の更新されていない古いテーブルを見てしまうかもしれないことを意味します。 -サンプルの設定ファイルは$prefix/etc/pgpool.conf.sample-logicalです。 - - - + Pgpool-IIとPostgreSQLの停止 + + + shutdown + + + -マスタスレーブモード(slonyモード)はSlony-Iを使用するPostgreSQLサーバと一緒に使うことができます。 -このモードでは、Slony/PostgreSQLがデータベースを同期する責任を持ちます。 -Slonyはストリーミングレプリケーションの登場により廃れつつあるため、Slonyを使う特別な理由が無い限りこのモードの使用を推奨しません。 -このモードでは負荷分散が可能です。 -サンプルの設定ファイルは$prefix/etc/pgpool.conf.sample-master-slaveです。 - - - +Pgpool-IIを停止するには、以下を実行してください。 + +$ pgpool -f /usr/local/etc/pgpool.conf -F /usr/local/etc/pcp.conf -m fast stop + -ネイティブレプリケーションモードでは、Pgpool-IIがデータベースを同期する責任を持ちます。 -このモードの利点は同期が同期的に行われることです。 -すなわち、データベースへの書き込みは全てのPostgreSQLサーバが書き込み操作を完了するまで返ってきません。 -しかし、PostgreSQL 9.6以降では、ストリーミングレプリケーションでsynchronous_commit = remote_applyと設定することにより、同様の効果が得られます。 -ネイティブレプリケーションモードのを回避できるので、この設定が使える場合には、ネイティブレプリケーションモードではなくてこの設定を使うことをお勧めします。 - PostgreSQLはノードをまたがるスナップショット管理を提供しないため、セッションYがノードBでコミットする前に、ノードAでコミットしたデータをセッションXが見ることがあり得ます。 -もしセッションXが、そのときノードAで見た見たデータに基づいてノードBのデータを更新しようとすると、ノードAとノードBのデータ一貫性は損なわれるかもしれません。 -この問題を回避するには、ユーザは明示的にノードAのデータをロックしなければなりません。 -これがストリーミングレプリケーションとsynchronous_commit = remote_applyを使用することをおすすめするもう一つの理由です。 - - -このモードでは負荷分散が可能です。 -サンプルの設定ファイルは$prefix/etc/pgpool.conf.sample-replicationです。 - - - + "-m" option specifies how gently stops + Pgpool-II. "fast" means shutdown + Pgpool-II immediately even if there are + existing connections from clients. You can specify "smart" to the + option, which force Pgpool-II to wait + until all clients are disconnected from + Pgpool-II. But this could make + Pgpool-II wait forever and this may + result in sending SIGKILL signal from the operating system and + leaving garbage, which will bring troubles next time when you start + Pgpool-II. +--> +"-m"オプションはPgpool-IIをどのくらい優しく停止するかを指定します。 +"fast"は接続済みのクライアントがあってもPgpool-IIを直ちに停止することを指定します。 +"smart"を指定すると、Pgpool-IIはすべてのクライアントが接続を切るまで待つことを余儀なくされます。 +しかし、これはPgpool-IIを永遠に待たせることになり、結果的にオペレーティングシステムが送信したSIGKILLシグナルを受け取ってゴミを残すことになるかも知れません。 +そうすると、次にPgpool-IIを起動した時に問題が起きるでしょう。 + + + -rawモードでは、Pgpool-IIはデータベースの同期に関しては関与しません。 -システム全体に意味の有る動作をさせるのはユーザの責任となります。 -このモードでは負荷分散はできません。 -サンプルの設定ファイルは$prefix/etc/pgpool.conf.sampleです。 - - - +Pgpool-IIを停止してからPostgreSQLを停止することができます。 +
- - - バックエンド情報の設定 + PostgreSQLの一時的な停止 + + + shutdown + - -Pgpool-IIがPostgreSQLバックエンドサーバを認識するために、pgpool.confbackend*を設定する必要があります。 -手始めに、Pgpool-IIを起動するには少なくてもパラメータが設定されている必要があります。 +保守やバージョンアップの目的で一時的にPostgreSQLを停止したいことがあります。 +この節では最小限の停止時間でこの仕事を実行する方法を説明します。 - - - バックエンドの設定 + + pcp_detach_nodeコマンドの活用 + + pg_ctlPostgreSQLを停止すると、Pgpool-IIがそのことをヘルスチェックで検知するまではフェイルオーバが発生せず、ヘルスチェックの設定によってはPostgreSQLの切り離しに時間がかかります。 + とりわけWatchdogが有効かつがonなら、Pgpool-IIは過半数のWatchdogがPostgreSQLの停止に合意するまで、フェイルオーバを開始しません。 + でノードを切り離せば、ヘルスチェックの設定に関わらず直ちにフェイルオーバが開始されます。 + 切り離されたノードは実際にはPostgreSQLが停止しておらず、必要なら手動で停止させなければならないことに注意してください。 + + - - -Pgpool-IIに使用されるバックエンドPostgreSQLがpgpool.confで指定されている必要があります。 -を参照してください。 - + + backend_flagの活用 + + + PostgreSQLを停止、再起動するとフェイルオーバが発生します。 + ストリーミングレプリケーションモードでない場合、あるいはストリーミングレプリケーションモードであってもサーバがスタンバイサーバであればあまり大きな問題にはなりませ + ん。 + しかし、サーバがクラスタのプライマリサーバなら、スタンバイサーバの一つが昇格してしまいます。 + 更には、クラスタに1台のサーバしか残っていなければ、昇格できるスタンバイサーバがないことになります。 + + + + + この場合はを使ってフェイルオーバを避けることができます。 + 以下のようにpgpool.confを設定すると、backend0のフェイルオーバが起こりません。 + +backend_flag0 = DISALLOW_TO_FAILOVER + + + この設定は、Pgpool-IIの再読込か再起動で有効になります。 + このフラグが設定されると、バックエンドが使用不可能になってもフェイルオーバが起きません。 + バックエンドが使用不可の間、クライアントは以下のエラーメッセージを受け取ります。 + +psql: error: could not connect to server: FATAL: failed to create a backend connection +DETAIL: executing failover on backend + + + バックエンドを再起動すると、クライアントは通常通り接続ができます。 + 再びフェイルオーバを有効にするには、以下を設定します。 + +backend_flag0 = ALLOW_TO_FAILOVER + + + そして、Pgpool-IIの再読込か、再起動を行います。 + + + + + PostgreSQLデータベースのバックアップ - + + backup + + + +pg_dumppg_basebackupその他のツールを使ってPostgreSQLデータベースをバックアップする際は、そうしたコマンドをPostgreSQLで直接実行することを強くお勧めします。 +Pgpool-IIはproxyソフトウェアなので、メッセージパケットを転送する際にオーバヘッドが生じるからです。 +バックアップの取得は大量のパケットを生じるので、データベースが非常に小さくない限り、Pgpool-II経由でバックアップを取得するのは、直接PostgreSQLに接続するよりも遅くなります。 + + + + + + また、パラレルpg_dumpでは、データベース依存のオブジェクトであるスナップショットIDを扱うため、Pgpool-II経由で実行するとエラーになってしまいます。 + + + + 多くの場合、プライマリサーバをバックアップ取得対象に選ぶと思います。 + スタンバイサーバを選ぶ場合は、正しいPostgreSQLサーバを選ぶようにしましょう。 +  データが古ければ、バックアップも古いものになってしまう可能性が高いからです。 + あるいはを使って対象のスタンバイサーバがプライマリサーバに追いついているかどうかを知ることができます。 + diff --git a/doc.ja/src/sgml/ssl.sgml b/doc.ja/src/sgml/ssl.sgml index b83a54b5a..c55c91caf 100644 --- a/doc.ja/src/sgml/ssl.sgml +++ b/doc.ja/src/sgml/ssl.sgml @@ -1,219 +1,389 @@ - Secure Sockect Layer (SSL) + Secure Socket Layer (SSL) - + --> SSLの設定 - - ssl (boolean) - - - ssl 設定パラメータ - + + ssl (boolean) + + + ssl 設定パラメータ + + + + onに設定すると,Pgpool-IIはフロントエンドとバックエンドの両方の通信でのSSLが可能になります。 + デフォルトはoffです。 + + - -onに設定すると,Pgpool-IIはフロントエンドとバックエンドの両方の通信でのSSLが可能になります。 -デフォルトはoffです。 + + フロントエンド接続でSSLを動作させるには、が設定されてなければなりません。 - - - -フロントエンド接続にSSLするには、が設定されてなければなりません。 - - - - - -SSLサポートを有効にするためには、Pgpool-IIをOpenSSLサポート付きでビルドする必要があります。 -Pgpool-IIのビルドについて詳細はをご覧ください。 - - + + - -このパラメータはサーバ起動時にのみ設定可能です。 + + SSLサポートを有効にするためには、Pgpool-IIをOpenSSLサポート付きでビルドする必要があります。 + Pgpool-IIのビルドについて詳細はをご覧ください。 - - - - - ssl_key (string) - - - ssl_key 設定パラメータ - + + + + このパラメータはサーバ起動時にのみ設定可能です。 + + + + + + ssl_key (string) + + + ssl_key 設定パラメータ + - - -フロントエンドとの接続に使用するプライベートキーファイルのパスを指定します。 -このオプションのデフォルト値はありません。 -設定がない場合は、フロントエンドとの接続でSSLが使用されなくなります。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - ssl_cert (string) - - - ssl_cert 設定パラメータ - + + + フロントエンドとの接続に使用するプライベートキーファイルのパスを指定します。 + 相対パスで指定した場合、Pgpool-IIの設定ファイルディレクトリが基準となります。 + このオプションのデフォルト値はありません。 + 設定がない場合は、フロントエンドとの接続でSSLが使用されなくなります。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_cert (string) + + + ssl_cert 設定パラメータ + - - -フロントエンドとの接続に使用する公開x509証明書のフルパスを指定します。 -このオプションのデフォルト値はありません。 -設定がない場合は、フロントエンドとの接続でSSLが使用されなくなります。 - + + + フロントエンドとの接続に使用する公開x509証明書のパスを指定します。 + 相対パスで指定した場合、Pgpool-IIの設定ファイルディレクトリが基準となります。 + このオプションのデフォルト値はありません。 + 設定がない場合は、フロントエンドとの接続でSSLが使用されなくなります。 + - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - ssl_ca_cert (string) - - - ssl_ca_cert 設定パラメータ - + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_ca_cert (string) + + + ssl_ca_cert 設定パラメータ + - - - PEM形式のCAルート証明書のパスを指定します。 - これはバックエンドサーバ証明書の検証に用いられます。 - このオプションはOpenSSL verify(1)コマンドにおける-CAfileオプションと同様の機能を提供します。 - + + + PEM形式のCAルート証明書のパスを指定します。 + これはバックエンドサーバ証明書の検証に用いられます。 + このオプションはOpenSSL verify(1)コマンドにおける-CAfileオプションと同様の機能を提供します。 + - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - - - - ssl_ca_cert_dir (string) - - - ssl_ca_cert_dir 設定パラメータ - + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_ca_cert_dir (string) + + + ssl_ca_cert_dir 設定パラメータ + - - - PEM形式のCAルート証明書ファイルが格納されているディレクトリへのパスを指定します。 - これはバックエンドサーバ証明書の検証に用いられます。 - このオプションはOpenSSL verify(1)コマンドにおける-CAfileオプションと同様の機能を提供します。 - - - -デフォルトでは値が設定されておらず検証は行われません。 -このオプションが設定されていない場合においても、オプションが設定されている場合には検証が行われます。 - - - -このパラメータはサーバ起動時にのみ設定可能です。 - - - + + + PEM形式のCAルート証明書ファイルが格納されているディレクトリへのパスを指定します。 + これはバックエンドサーバ証明書の検証に用いられます。 + 相対パスで指定した場合、Pgpool-IIの設定ファイルディレクトリが基準となります。 + このオプションはOpenSSL verify(1)コマンドにおける-CApathオプションと同様の機能を提供します。 + + + + デフォルトでは値が設定されておらず検証は行われません。 + このオプションが設定されていない場合においても、オプションが設定されている場合には検証が行われます。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_crl_file (string) + + ssl_crl_file設定パラメータ + + + + + SSLサーバ証明書失効リスト(CRL)が入っているファイルのパスを設定します。 + 相対パスで指定した場合、Pgpool-IIの設定ファイルディレクトリが基準となります。 + デフォルトは空で、この場合CRLファイルは読み込まれません。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_ciphers (string) + + + ssl_ciphers設定パラメータ + + + + + SSL接続で使用できるSSL暗号スイートのリストを指定します。 + 設定構文と使用可能な値のリストについてはOpenSSLパッケージの + ciphersマニュアルをご覧ください。 + TLSバージョン1.2あるいはそれ以下のバージョンのみが影響を受けます。 + 今の所、TLSバージョン1.3接続で使用される暗号の選択を制御する設定はありません。 + デフォルト値はHIGH:MEDIUM:+3DES:!aNULLで、PostgreSQLと同じです。 + この値が選ばれた理由については、PostgreSQLのマニュアルをご覧ください。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_prefer_server_ciphers (boolean) + + ssl_prefer_server_ciphers設定パラメータ + + + + + + クライアントではなく、サーバ指定のSSL暗号を選択します。 + デフォルト値はoffです。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_ecdh_curve (string) + + ssl_ecdh_curve設定パラメータ + + + + + + ECDHキー交換で使われる曲線の名前を指定します。 + 接続する全てのクライアントがこの設定をサポートしている必要があります。 + サーバの楕円曲線キーで使用されるのと同じ曲線である必要はありません。 + デフォルト値はprime256v1です。 + + + + よく使われる曲線の OpenSSL 名は、 + prime256v1 (NIST P-256), + secp384r1 (NIST P-384), + secp521r1 (NIST P-521) です。 + + 利用できる曲線の完全なリストはopenssl ecparam -list_curvesで得られます。 + ただし、TLSではこのすべてが利用できるわけではありません。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_dh_params_file (string) + + ssl_dh_params_file設定パラメータ + + + + + いわゆる短命DH系SSL暗号で使用するディフィー・ヘルマンパラメータを格納するファイル名を指定します。 + デフォルトは空です。 + ファイル名が空、あるいは不正なファイルである場合には、コンパイル時に決められたデフォルトのDHパラメータが使用されます。 + 攻撃者が、よく知られたコンパイル時設定のDHパラメータを解読しようとしている場合には、カスタムDHパラメータを使うことでその危険性を低減できます。 + openssl dhparam -out dhparams.pem 2048を使って、独自のDHパラメータファイルを作ることができます。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + + + + ssl_passphrase_command (string) + + ssl_passphrase_command設定パラメータ + + + + + 秘密鍵などのSSLファイルを復号する際に、パスフレーズの入手が必要な時に起動される外部コマンドを設定します。 + デフォルトではこのパラメータは空文字で、この場合はパスフレーズが要求されてもSSLファイルはロードされません。 + + + このコマンドは、パスフレーズを標準出力に書き出し、コード0で終了しなければなりません。 + パラメータの値の%pはプロンプト文字列に置き換えられます。 + (%を使いたい場合は%%としてください。) + プロンプト文字列はおそらく空白文字を含むので、適切に引用符付けするように注意してください。 + 出力の最後に一個の改行があれば、削除されます。 + + + このコマンドは実際にはパスフレーズ用にユーザにプロンプトを表示する必要はありません。 + ファイルからパスフレーズが読めるなら、キーチェーン機構やその他から取得します。 + 選択された仕組みが適切にセキュアかどうかを確認するのはユーザ次第です。 + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + ただし、新しいパラメータが不正な場合、Pgpool-IIを再起動するまで以前の値が維持されますが、 + "pgpool show"で表示されるのは新しいパラメータです。 + + + - + --> SSL証明書の生成 - -証明書の扱いについてはこのマニュアルの範囲外です。 -PostgreSQLドキュメントSSLによる安全なTCP/IP接続の章に自分で認証する証明書を作成するコマンドの例があります。 + + 証明書の扱いについてはこのマニュアルの範囲外です。 + PostgreSQLドキュメントSSLによる安全なTCP/IP接続の章に自分で認証する証明書を作成するコマンドの例があります。 diff --git a/doc.ja/src/sgml/start.sgml b/doc.ja/src/sgml/start.sgml index 07cbff592..58273d52b 100644 --- a/doc.ja/src/sgml/start.sgml +++ b/doc.ja/src/sgml/start.sgml @@ -1,586 +1,601 @@ - - さあ始めましょう + + さあ始めましょう - - - インストール + + + インストール - - -この節では、の説明に基づいて、すでにPgpool-IIをインストール済みであると見なしています。 -他の方法としては、を使ってPgpool-IIPostgreSQLを一時的にインストールすることもできます。 - - + + + この節では、の説明に基づいて、すでにPgpool-IIをインストール済みであると見なしています。 + 他の方法としては、を使ってPgpool-IIPostgreSQLを一時的にインストールすることもできます。 + + - - - はじめてのレプリケーション + + + はじめてのレプリケーション - - -この節では、Pgpool-IIを使って、もっとも一般的な設定の一つである、PostgreSQLクラスターをストリーミングレプリケーション構成で管理する方法を説明します。 - + + + この節では、Pgpool-IIを使って、もっとも一般的な設定の一つである、PostgreSQLクラスタをストリーミングレプリケーション構成で管理する方法を説明します。 + - - -先に進む前に、ストリーミングレプリケーションモードでpgpool.confを設定しましょう。 -このためには、少なくとも次の2つの項目を設定しなければなりません。 - -master_slave_mode = on -master_slave_sub_mode = 'stream' - - - - -pgpool_setupを使うということであれば、次のようにタイプして下さい。 - -pgpool_setup - - -これにより、ストリーミングレプリケーション設定のPgpool-IIPostgreSQLプライマリサーバのインストール、それにPostgreSQLの非同期スタンバイのインストールが行われます。 - - - -ここからは、pgpool_setupを使ってカレントディレクトリ以下にインストールを行うことを前提とします。 - - - -システム全体を起動するには、次のようにタイプして下さい。 - -./startall - - - - -システムが起動すれば、任意のデータベースに擬似SQLコマンドの"show pool_node"を発行して、クラスタの状態を確認することができます。 -pgpool_setupは、自動的に"test"データベースを作ります。 -このデータベースを使います。 -pgpool_setupにより、Pgpool-IIにデフォルトポート番号として11000がアサインされていることに注意してください。 - -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 -(2 rows) - - -この結果は、"status"カラムが"up"であることを示しています。 -これは、PostgreSQLが稼働中で、問題ないということです。 - - + + + 先に進む前に、ストリーミングレプリケーションモードでpgpool.confを設定しましょう。 + Pgpool-IIでは設定のサンプルが用意されています。 + これらの設定ファイルはデフォルトのソースコードからのインストールでは/usr/local/etcに配置されています。 + pgpool.conf.samplepgpool.confとしてコピーします。 + + cp /usr/local/etc/pgpool.conf.sample pgpool.conf + + + + + pgpool_setupを使うということであれば、次のようにタイプして下さい。 + + pgpool_setup + + + これにより、ストリーミングレプリケーション設定のPgpool-IIPostgreSQLプライマリサーバのインストール、それにPostgreSQLの非同期スタンバイのインストールが行われます。 + pgpool_setupでは、pgpool.confの設定も自動で行われます。 + + + + ここからは、pgpool_setupを使ってカレントディレクトリ以下にインストールを行うことを前提とします。 + + + + システム全体を起動するには、次のようにタイプして下さい。 + + ./startall + + + + + システムが起動すれば、任意のデータベースに擬似SQLコマンドの"show pool_nodes"を発行して、クラスタの状態を確認することができます。 + pgpool_setupは、自動的に"test"データベースを作ります。 + このデータベースを使います。 + pgpool_setupにより、Pgpool-IIにデフォルトポート番号として11000がアサインされていることに注意してください。 + + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 | 2019-01-31 10:23:09 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 | 2019-01-31 10:23:09 + (2 rows) + + + この結果は、"status"カラムが"up"であることを示しています。 + これは、PostgreSQLが稼働中で、問題ないということです。 + + - - - 負荷分散を試してみる - - -Pgpool-IIでは、読み込みクエリの負荷分散が可能です。 -デフォルトでこの機能は有効です。 -その効果を確かめるために、pgbench -Sコマンドを使ってみましょう。 - -$ pgbench -p 11000 -c 10 -S -T 10 test -starting vacuum...end. -transaction type: <builtin: select only> -scaling factor: 1 -query mode: simple -number of clients: 10 -number of threads: 1 -duration: 10 s -number of transactions actually processed: 148044 -latency average = 0.676 ms -tps = 14802.897506 (including connections establishing) -tps = 14810.213749 (excluding connections establishing) + + + レプリケーションを試してみる -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 75152 | true | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 72893 | false | 0 -(2 rows) - - -"select_cnt"カラムは、いくつSELECTが各々のノードに送られたかを示します。 -設定がデフォルトで、Pgpool-IIは同じ数のSELECTを送ろうとするので、そのカラムはほぼ同じ値を示しています。 - - - -Pgpool-IIでは、負荷分散の更に洗練された戦略の利用が可能です。 -詳細はをご覧ください。 - - + + + PostgreSQLに同梱されているベンチマークツールのpgbenchを使って、レプリケーション機能を試してみましょう。 + + $ pgbench -i -p 11000 test + + + レプリケーションが正しく動いているかどうか確かめるために、直接プライマリとスタンバイサーバに接続して、両方が同じ結果を返すかどうか見てみます。 + + $ psql -p 11002 test + \dt + List of relations + Schema | Name | Type | Owner + --------+------------------+-------+--------- + public | pgbench_accounts | table | t-ishii + public | pgbench_branches | table | t-ishii + public | pgbench_history | table | t-ishii + public | pgbench_tellers | table | t-ishii + (4 rows) + \q + $ psql -p 11003 test + \dt + List of relations + Schema | Name | Type | Owner + --------+------------------+-------+--------- + public | pgbench_accounts | table | t-ishii + public | pgbench_branches | table | t-ishii + public | pgbench_history | table | t-ishii + public | pgbench_tellers | table | t-ishii + (4 rows) + + + プライマリサーバ(ポート11002)とスタンバイサーバ(ポート11003)は、同一の結果を返しています。 + 次に、pgbenchをしばらく走らせて、結果を見てみます。 + + $ pgbench -p 11000 -T 10 test + starting vacuum...end. + transaction type: <builtin: TPC-B (sort of)> + scaling factor: 1 + query mode: simple + number of clients: 1 + number of threads: 1 + duration: 10 s + number of transactions actually processed: 4276 + latency average = 2.339 ms + tps = 427.492167 (including connections establishing) + tps = 427.739078 (excluding connections establishing) - - - レプリケーションを試してみる + $ psql -p 11002 -c "SELECT sum(abalance) FROM pgbench_accounts" test + sum + -------- + 216117 + (1 row) - - -PostgreSQLに同梱されているベンチマークツールのpgbenchを使って、レプリケーション機能を試してみましょう。 - -$ pgbench -i -p 11000 test - - -レプリケーションが正しく動いているかどうか確かめるために、直接プライマリとスタンバイサーバに接続して、両方が同じ結果を返すかどうか見てみます。 - -$ psql -p 11002 test -\dt - List of relations - Schema | Name | Type | Owner ---------+------------------+-------+--------- - public | pgbench_accounts | table | t-ishii - public | pgbench_branches | table | t-ishii - public | pgbench_history | table | t-ishii - public | pgbench_tellers | table | t-ishii -(4 rows) -\q -$ psql -p 11003 test -\dt - List of relations - Schema | Name | Type | Owner ---------+------------------+-------+--------- - public | pgbench_accounts | table | t-ishii - public | pgbench_branches | table | t-ishii - public | pgbench_history | table | t-ishii - public | pgbench_tellers | table | t-ishii -(4 rows) - - -プライマリサーバ(ポート11002)とスタンバイサーバ(ポート11003)は、同一の結果を返しています。 -次に、pgbenchをしばらく走らせて、結果を見てみます。 - -$ pgbench -p 11000 -T 10 test -starting vacuum...end. -transaction type: <builtin: TPC-B (sort of)> -scaling factor: 1 -query mode: simple -number of clients: 1 -number of threads: 1 -duration: 10 s -number of transactions actually processed: 2171 -latency average = 4.692 ms -tps = 213.147520 (including connections establishing) -tps = 213.258008 (excluding connections establishing) + $ psql -p 11003 -c "SELECT sum(abalance) FROM pgbench_accounts" test + sum + -------- + 216117 + (1 row) + + + ここでも結果は同じでした。 + + -$ psql -p 11002 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) + + + 負荷分散を試してみる + + + Pgpool-IIでは、参照クエリの負荷分散が可能です。 + デフォルトでこの機能は有効です。 + その効果を確かめるために、pgbench -Sコマンドを使ってみましょう。 + + $ ./shutdownall + $ ./startall + $ pgbench -p 11000 -c 10 -j 10 -S -T 60 test + starting vacuum...end. + transaction type: <builtin: select only> + scaling factor: 1 + query mode: simple + number of clients: 10 + number of threads: 10 + duration: 60 s + number of transactions actually processed: 1086766 + latency average = 0.552 ms + tps = 18112.487043 (including connections establishing) + tps = 18125.572952 (excluding connections establishing) -$ psql -p 11003 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) - - -ここでも結果は同じでした。 - - + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 537644 | false | 0 | 2019-01-31 11:51:58 + 1 | /tmp | 11003 | up | 0.500000 | standby | 548582 | true | 0 | 2019-01-31 11:51:58 + (2 rows) + + + "select_cnt"カラムは、いくつSELECTが各々のノードに送られたかを示します。 + 設定がデフォルトで、Pgpool-IIは同じ数のSELECTを送ろうとするので、そのカラムはほぼ同じ値を示しています。 + + + + Pgpool-IIでは、負荷分散の更に洗練された戦略の利用が可能です。 + 詳細はをご覧ください。 + + - - - フェイルオーバを試してみる + + + フェイルオーバを試してみる - - -PostgreSQLサーバが停止した際に、Pgpool-IIは自動フェイルオーバさせることができます。 -この場合、Pgpool-IIはステータスを"down"にして、残ったサーバでデータベースの運用を継続します。 - -$ pg_ctl -D data1 stop -waiting for server to shut down.... done -server stopped -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 2172 | true | 0 - 1 | /tmp | 11003 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) + + + PostgreSQLサーバが停止した際に、Pgpool-IIは自動フェイルオーバさせることができます。 + この場合、Pgpool-IIはステータスを"down"にして、残ったサーバでデータベースの運用を継続します。 + + $ pg_ctl -D data1 stop + waiting for server to shut down.... done + server stopped + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 4276 | true | 0 | 2019-01-31 12:00:09 + 1 | /tmp | 11003 | down | 0.500000 | standby | 1 | false | 0 | 2019-01-31 12:03:07 + (2 rows) + + + スタンバイノードをpg_ctlコマンドで停止しました。 + Pgpool-IIはそのことを検出し、そのスタンバイノードを切り離します。 + "show pool_nodes"コマンドは、スタンバイノードがダウンしていることを表示します。 + このスタンバイノードなしで、クラスタの運用を継続できます。 + + $ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test + sum + -------- + 216117 + (1 row) + + + プライマリサーバが落ちたらどうなるでしょう? + この場合、残ったスタンバイサーバの一つが新しいプライマリサーバへと昇格します。 + テストのため、両方のノードが稼働中である状態から始めます。 + + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 | 2019-01-31 12:04:58 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 | 2019-01-31 12:04:58 + (2 rows) -$ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) - - -スタンバイノードをpg_ctlコマンドで停止しました。 -Pgpool-IIはそのことを検出し、そのスタンバイノードを切り離します。 -"show pool_nodes"コマンドは、スタンバイノードがダウンしていることを表示します。 -このスタンバイノードなしで、クラスタの運用を継続できます。 - -$ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) - - -プライマリサーバが落ちたらどうなるでしょう? -この場合、残ったスタンバイサーバの一つが新しいプライマリサーバへと昇格します。 -テストのため、両方のノードが稼働中である状態から始めます。 - -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 2173 | true | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 -(2 rows) + $ pg_ctl -D data0 stop + waiting for server to shut down.... done + server stopped + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | down | 0.500000 | standby | 0 | false | 0 | 2019-01-31 12:05:20 + 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 | 2019-01-31 12:05:20 + (2 rows) + + + プライマリノードが0から1へと変わりました。 + 内部では何が起きたのでしょう? + ノード0がダウンした時、Pgpool-IIはそのことを検出し、pgpool.confに定義されたfailover_commandを実行します。 + その内容を以下に示します。 + + #! /bin/sh + # Execute command by failover. + # special values: %d = node id + # %h = host name + # %p = port number + # %D = database cluster path + # %m = new main node id + # %M = old main node id + # %H = new main node host name + # %P = old primary node id + # %R = new main database cluster path + # %r = new main port number + # %% = '%' character + failed_node_id=$1 + failed_host_name=$2 + failed_port=$3 + failed_db_cluster=$4 + new_main_id=$5 + old_main_id=$6 + new_main_host_name=$7 + old_primary_node_id=$8 + new_main_port_number=$9 + new_main_db_cluster=${10} + mydir=/home/t-ishii/tmp/Tutorial + log=$mydir/log/failover.log + pg_ctl=/usr/local/pgsql/bin/pg_ctl + cluster0=$mydir/data0 + cluster1=$mydir/data1 -$ pg_ctl -D data0 stop -waiting for server to shut down.... done -server stopped -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | down | 0.500000 | standby | 2173 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 -(2 rows) - - -プライマリノードが0から1へと変わりました。 -内部では何が起きたのでしょう? -ノード0がダウンした時、Pgpool-IIはそのことを検出し、pgpool.confに定義された"fail_over_script"を実行します。 -その内容を以下に示します。 - -#! /bin/sh -# Execute command by failover. -# special values: %d = node id -# %h = host name -# %p = port number -# %D = database cluster path -# %m = new master node id -# %M = old master node id -# %H = new master node host name -# %P = old primary node id -# %R = new master database cluster path -# %r = new master port number -# %% = '%' character -failed_node_id=$1 -failed_host_name=$2 -failed_port=$3 -failed_db_cluster=$4 -new_master_id=$5 -old_master_id=$6 -new_master_host_name=$7 -old_primary_node_id=$8 -new_master_port_number=$9 -new_master_db_cluster=${10} -mydir=/home/t-ishii/tmp/Tutorial -log=$mydir/log/failover.log -pg_ctl=/usr/local/pgsql/bin/pg_ctl -cluster0=$mydir/data0 -cluster1=$mydir/data1 + date >> $log + echo "failed_node_id $failed_node_id failed_host_name $failed_host_name failed_port $failed_port failed_db_cluster $failed_db_cluster new_main_id $new_main_id old_main_id $old_main_id new_main_host_name $new_main_host_name old_primary_node_id $old_primary_node_id new_main_port_number $new_main_port_number new_main_db_cluster $new_main_db_cluster" >> $log -date >> $log -echo "failed_node_id $failed_node_id failed_host_name $failed_host_name failed_port $failed_port failed_db_cluster $failed_db_cluster new_master_id $new_master_id old_master_id $old_master_id new_master_host_name $new_master_host_name old_primary_node_id $old_primary_node_id new_master_port_number $new_master_port_number new_master_db_cluster $new_master_db_cluster" >> $log + if [ a"$failed_node_id" = a"$old_primary_node_id" ];then # main failed + ! new_primary_db_cluster=${mydir}/data"$new_main_id" + echo $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over + $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over + sleep 2 + fi + + + そのスクリプトは、パラメータとして必要な情報をPgpool-IIから受け取ります。 + プライマリサーバが落ちた時に、"pg_ctl -D data1 promote"を実行し、スタンバイサーバは新しいプライマリサーバへと昇格します。 + + -if [ a"$failed_node_id" = a"$old_primary_node_id" ];then # master failed -! new_primary_db_cluster=${mydir}/data"$new_master_id" - echo $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over - $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over -fi - - -そのスクリプトは、パラメータとして必要な情報をPgpool-IIから受け取ります。 -プライマリサーバが落ちた時に、"pg_ctl -D data1 promote"を実行し、スタンバイサーバは新しいプライマリサーバへと昇格します。 - - + + + オンラインリカバリを試してみる + + + Pgpool-IIは、「オンラインリカバリ」という技術を使ってダウンしたノードを復旧させることができます。 + これはプライマリノードからデータをスタンバイノードへとコピーし、プライマリと同期させます。 + それには長い時間がかかることがあり、その間にデータが更新されるかもしれません。 + これは問題になりません。なぜなら、ストリーミングレプリケーション構成では、スタンバイはWALログを受け取り、それを適用することによってプライマリに追い付くことができるからです。 + オンラインリカバリをテストするために、ノード0が落ちている先ほどのクラスタから始めましょう。 + + $ pcp_recovery_node -p 11001 -n 0 + Password: + pcp_recovery_node -- Command Successful - - - オンラインリカバリを試してみる - - -Pgpool-IIは、「オンラインリカバリ」という技術を使ってダウンしたノードを復旧させることができます。 -これはプライマリノードからデータをスタンバイノードへとコピーし、プライマリと同期させます。 -それには長い時間がかかることがあり、その間にデータが更新されるかもしれません。 -これは問題になりません。なぜなら、ストリーミングレプリケーション構成では、スタンバイはWALログを受け取り、それを適用することによってプライマリに追い付くことができるからです。 -オンラインリカバリをテストするために、ノード0が落ちている先ほどのクラスタから始めましょう。 - -$ pcp_recovery_node -p 11001 0 -Password: -pcp_recovery_node -- Command Successful + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | standby | 0 | false | 0 | 2019-01-31 12:06:48 + 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 | 2019-01-31 12:05:20 + (2 rows) + + + は、インストールされたPgpool-IIに含まれる管理コマンドの一つです。 + 引数の-pは、コマンドにアサインされたポート番号です。 + pgpool_setupは11001に設定しています。 + 引数の-nは、リカバリされるノードの番号です。 + コマンドを実行すると、ノード0は"up"状態に復帰します。 + + + + pcp_recovery_nodeが実行するスクリプトは、pgpool.confで"recovery_1st_stage_command"として指定されています。 + pgpool_setupがインストールするファイルはこれです。 + + #! /bin/sh + psql=/usr/local/pgsql/bin/psql + DATADIR_BASE=/home/t-ishii/tmp/Tutorial + PGSUPERUSER=t-ishii -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | standby | 2173 | true | 0 - 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | false | 0 -(2 rows) - - -は、インストールされたPgpool-IIに含まれる管理コマンドの一つです。 -引数の-pは、コマンドにアサインされたポート番号です。 -pgpool_setupは11001に設定しています。 -次の引数はターゲットになるノードIDです。 -コマンドを実行すると、ノード0は"up"状態に復帰します。 - - - -pcp_recovery_nodeが実行するスクリプトは、pgpool.confで"recovery_1st_stage_command"として指定されています。 -pgpool_setupがインストールするファイルはこれです。 - -#! /bin/sh -psql=/usr/local/pgsql/bin/psql -DATADIR_BASE=/home/t-ishii/tmp/Tutorial -PGSUPERUSER=t-ishii + main_db_cluster=$1 + recovery_node_host_name=$2 + DEST_CLUSTER=$3 + PORT=$4 + recovery_node=$5 -master_db_cluster=$1 -recovery_node_host_name=$2 -DEST_CLUSTER=$3 -PORT=$4 + pg_rewind_failed="true" -log=$DATADIR_BASE/log/recovery.log + log=$DATADIR_BASE/log/recovery.log + echo >> $log + date >> $log + if [ $pg_rewind_failed = "true" ];then -$psql -p $PORT -c "SELECT pg_start_backup('Streaming Replication', true)" postgres + $psql -p $PORT -c "SELECT pg_start_backup('Streaming Replication', true)" postgres -echo "source: $master_db_cluster dest: $DEST_CLUSTER" > $log + echo "source: $main_db_cluster dest: $DEST_CLUSTER" >> $log -rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \ ---exclude postmaster.opts --exclude pg_log \ ---exclude recovery.conf --exclude recovery.done \ ---exclude pg_xlog \ -$master_db_cluster/ $DEST_CLUSTER/ + rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \ + --exclude postmaster.opts --exclude pg_log \ + --exclude recovery.conf --exclude recovery.done \ + --exclude pg_xlog \ + $main_db_cluster/ $DEST_CLUSTER/ -rm -fr $DEST_CLUSTER/pg_xlog -mkdir $DEST_CLUSTER/pg_xlog -chmod 700 $DEST_CLUSTER/pg_xlog -rm $DEST_CLUSTER/recovery.done -cat > $DEST_CLUSTER/recovery.conf <<REOF -standby_mode = 'on' -primary_conninfo = 'port=$PORT user=$PGSUPERUSER' -recovery_target_timeline='latest' -REOF + rm -fr $DEST_CLUSTER/pg_xlog + mkdir $DEST_CLUSTER/pg_xlog + chmod 700 $DEST_CLUSTER/pg_xlog + rm $DEST_CLUSTER/recovery.done + fi + cat > $DEST_CLUSTER/recovery.conf <<REOF + standby_mode = 'on' + primary_conninfo = 'port=$PORT user=$PGSUPERUSER' + recovery_target_timeline='latest' + restore_command = 'cp $DATADIR_BASE/archivedir/%f "%p" 2> /dev/null' + REOF + if [ $pg_rewind_failed = "true" ];then + $psql -p $PORT -c "SELECT pg_stop_backup()" postgres + fi -$psql -p $PORT -c "SELECT pg_stop_backup()" postgres - - - + if [ $pg_rewind_failed = "false" ];then + cp /tmp/postgresql.conf $DEST_CLUSTER/ + fi + + + - - - 基礎的な構造 + + + 基礎的な構造 - - -Pgpool-IIは、クライアントとPostgreSQLの間に位置するproxyサーバです。 -Pgpool-IIは、"frontend and backend protocol"と呼ばれるネットワーク上のプロトコルを理解します。 -プロトコルの詳細については、PostgreSQLのマニュアルをご覧ください。 -Pgpool-IIを利用するにあたって、PostgreSQLを変更する必要はありません。 -(正確には、Pgpool-IIのすべての機能を使うためには、少数の拡張をインストールする必要があります) -したがって、Pgpool-IIは色々なバージョンのPostgreSQLと協調することができます。 -理論的には、最初期のバージョンのPostgreSQLさえ、Pgpool-IIで使用できます。 -クライアント側についても同じことが言えます。 -プロトコルに従う限り、どのような言語やドライバを使おうと、Pgpool-IIは問題なく接続を受け付けます。 - - - -Pgpool-IIは複数のプロセスから構成されます。 -他のすべてのプロセスの親となるメインプロセスがあります。 -メインプロセスは、クライアントからのコネクションを受け付ける子プロセスをforkする役割があります。 -また、メインプロセスからforkされるいくつかのワーカープロセスがあります。 -ワーカープロセスは、ストリーミングレプリケーションの遅延を検出する役目があります。 -また、「PCPCプロセス」と呼ばれる特殊なプロセスがあります。これは、Pgpool-IIの管理専用に使用されます。 -Pgpool-IIには、組み込みの"watchdog"と呼ばれる組み込みの高可用性機能があります。 -watchdogはいくつかのプロセスから構成されています。 -watchdogの詳細についてはをご覧ください。 - - -
- - <productname>Pgpool-II</productname>のプロセス構造 - - - - - -
-
+ + + Pgpool-IIは、クライアントとPostgreSQLの間に位置するproxyサーバです。 + Pgpool-IIは、"frontend and backend protocol"と呼ばれるネットワーク上のプロトコルを理解します。 + プロトコルの詳細については、PostgreSQLのマニュアルをご覧ください。 + Pgpool-IIを利用するにあたって、PostgreSQLを変更する必要はありません。 + (正確には、Pgpool-IIのすべての機能を使うためには、少数の拡張をインストールする必要があります) + したがって、Pgpool-IIは色々なバージョンのPostgreSQLと協調することができます。 + 理論的には、最初期のバージョンのPostgreSQLさえ、Pgpool-IIで使用できます。 + クライアント側についても同じことが言えます。 + プロトコルに従う限り、どのような言語やドライバを使おうと、Pgpool-IIは問題なく接続を受け付けます。 + + + + Pgpool-IIは複数のプロセスから構成されます。 + 他のすべてのプロセスの親となるメインプロセスがあります。 + メインプロセスは、クライアントからのコネクションを受け付ける子プロセスをforkする役割があります。 + また、メインプロセスからforkされるいくつかのワーカープロセスがあります。 + ワーカープロセスは、ストリーミングレプリケーションの遅延を検出する役目があります。 + また、「PCPプロセス」と呼ばれる特殊なプロセスがあります。これは、Pgpool-IIの管理専用に使用されます。 + Pgpool-IIには、"watchdog"と呼ばれる組み込みの高可用性機能があります。 + watchdogはいくつかのプロセスから構成されています。 + watchdogの詳細についてはをご覧ください。 + + +
+ + <productname>Pgpool-II</productname>のプロセス構造 + + + + + +
+
-
+
diff --git a/doc.ja/src/sgml/stream-check.sgml b/doc.ja/src/sgml/stream-check.sgml index f722bec70..491d1e429 100644 --- a/doc.ja/src/sgml/stream-check.sgml +++ b/doc.ja/src/sgml/stream-check.sgml @@ -1,332 +1,592 @@ - - ストリーミングレプリケーションのチェック - - - -Pgpool-IIPostgreSQL 9.0から利用可能になったPostgreSQL組み込みのストリーミングレプリケーション機能と一緒に動作することができます。 -ストリーミングレプリケーション向けにPgpool-IIを設定するには、を有効にして'stream'に設定します。 - - - -Pgpool-IIではストリーミングレプリケーションとHot Standbyを併用することを前提にしています。 -すなわちスタンバイデータベースでは参照クエリのみを扱うことができます。 - - - - - - sr_check_period (integer) - - - sr_check_period 設定パラメータ - - - - - - -ストリーミングレプリケーションの遅延チェックの間隔を秒単位で指定します。 -デフォルト値は0で、これはチェックを行わないことを意味します - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - - sr_check_user (string) - - - sr_check_user 設定パラメータ - - - - - - -ストリーミングレプリケーションのチェックを行うPostgreSQLユーザ名を指定します。 -このユーザは、すべてのバックエンドに存在しなければなりません。 - - - - -sr_check_userは、が0(無効)であっても、プライマリサーバの特定に使用されます。 - - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - - sr_check_password (string) - - - sr_check_password 設定パラメータ - - - - - - -ストリーミングレプリケーションのチェックを行う PostgreSQLユーザのパスワードを指定します。 -ユーザがパスワードが必要としなければ空文字('')を使用します。 - - - -sr_check_passwordが空白のままの場合、 Pgpool-IIは空のパスワードを使用する前にまずファイルからのパスワードを取得できるか試みます。 - - - -sr_check_passwordにAES256-CBCで暗号化されたパスワードも指定することができます。 -AESで暗号化されたパスワードを指定するためには、パスワード文字列は暗号化(aes-256-cbcアルゴリズムを使用)およびbase64でエンコードした後、AESを接頭辞として付けなければいけません。 - - - -暗号化されていないクリアテキストパスワードを指定するためには、TEXTをパスワード文字列の前に付けます。 -例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定すべきです。 -有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 - - - -正しくフォーマットされたAES暗号化パスワードをコマンドを使用して作成することもできます。 - - - - -Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 -Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 - - - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - - sr_check_database (string) - - - sr_check_database 設定パラメータ - - - - - - -ストリーミングレプリケーションの遅延チェックを行うデータベース名を指定します。 -デフォルトは「postgres」です。 - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - - delay_threshold (integer) - - - delay_threshold 設定パラメータ - - - - - - -プライマリサーバに対するスタンバイサーバのレプリケーション遅延の許容度をWALバイト単位で指定します。 -Pgpool-IIは、スタンバイサーバの遅延がこの設定レベルを超えた場合には、 が有効であっても、プライマリに追いつくまでそのスタンバイノードにはSELECTクエリを送信せず、全てプライマリサーバに送るようにします。 -このパラメータが0の場合は、遅延のチェックを行ないません。 -この遅延閾値のチェックは毎に行われます。 -デフォルト値は0です。 - - - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - - - - - - log_standby_delay (string) - - - log_standby_delay 設定パラメータ - - - - - - -レプリケーションの遅延状況をログ出力する条件を指定します。 -以下の表にこのパラメータでとることができる値のリストを示します。 -'none'を指定すると、ログを出力しません。 'always'ならレプリケーションの遅延チェックを実行するたびに必ず出力します。 'if_over_threshold'を指定すると、delay_thresholdを超えたときだけ ログが出力されます。 デフォルト値は'none'です。 - - - - - スタンバイ遅延のログ出力オプション - - - - - - 説明 - - - - - - 'none' - - スタンバイの遅延はログ出力されない - - - - 'always' - - レプリケーション遅延がチェックされる度に、スタンバイの遅延がログ出力される - - - - 'if_over_threshold' - - の値を超えた時だけ、スタンバイの遅延がログ出力される - - - -
- - - -このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 - - -
-
- -
+ + ストリーミングレプリケーションのチェック + + + + Pgpool-IIPostgreSQL 9.0から利用可能になったPostgreSQL組み込みのストリーミングレプリケーション機能と一緒に動作することができます。 + ストリーミングレプリケーション向けにPgpool-IIを設定するには、'streaming_replication'を設定します。 + + + + Pgpool-IIではストリーミングレプリケーションとHot Standbyを併用することを前提にしています。 + すなわちスタンバイデータベースでは参照クエリのみを扱うことができます。 + + + + + + sr_check_period (integer) + + + sr_check_period 設定パラメータ + + + + + + + ストリーミングレプリケーションの遅延チェックの間隔を秒単位で指定します。 + デフォルト値は10です。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + + sr_check_user (string) + + + sr_check_user 設定パラメータ + + + + + + + ストリーミングレプリケーションのチェックを行うPostgreSQLユーザ名を指定します。 + デフォルトは''(空文字)です。 + このユーザはLOGIN権限を持ち、すべてのバックエンドに存在しなければなりません。 + 更にこのユーザは、PostgreSQLのスーパーユーザか、"pg_monitor"グループに所属していなければなりません。 + + + をpg_monitorグループに所属させるには、以下のSQLコマンドをPostgreSQLスーパーユーザーで実行してください("sr_check_user"をの設定値で置き換えてください) + +GRANT pg_monitor TO sr_check_user; + + PostgreSQL 9.6にはpg_monitorグループがないので、PostgreSQLのスーパーユーザーでなければなりません。 + + + + + + SSLが有効なら、ストリーミングレプリケーションチェックプロセスはSSL接続を使うかもしれません。 + + + + は、が0 (無効)の場合でもプライマリサー + バの特定のために使用されます。 + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + + sr_check_password (string) + + + sr_check_password 設定パラメータ + + + + + + + ストリーミングレプリケーションのチェックを行う PostgreSQLユーザのパスワードを指定します。 + ユーザがパスワードが必要としなければ空文字('')を使用します。 + + + + sr_check_passwordが空のままの場合、 Pgpool-IIは空のパスワードを使用する前にまずファイルからのパスワードを取得できるか試みます。 + + + sr_check_passwordは以下の書式で指定します。 + + + AES256-CBC暗号化パスワード + + + パスワードを格納する最もセキュアで推奨できる方法です。 + パスワード文字列はAESで始まっていなければなりません。 + ユーティリティを使って正しくAESで暗号化された文字列を作ることができます。 + Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 + Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 + + + + + + MD5ハッシュパスワード + + + AESほどはセキュアではありませんが、平文パスワードよりは良いです。 + パスワード文字列はMD5で始まっていなければなりません。 + バックエンドにはMD5認証を設定しなければならないことに注意してください。 + ユーティリティを使って正しいMD5ハッシュパワード文字列を作ることができます。 + + + + + + 平文パスワード + + + 暗号化されていない平文のパスワードです。 + 可能ならば使用を避けるべきです。 + パスワード文字列はTEXTで始まっていなければなりません。 + 例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定します。 + 有効な接頭辞がない場合、Pgpool-IIは平文のパスワードとして文字列を見なします。 + + + + + + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + + sr_check_database (string) + + + sr_check_database 設定パラメータ + + + + + + + ストリーミングレプリケーションの遅延チェックを行うデータベース名を指定します。 + デフォルトは「postgres」です。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + + delay_threshold (integer) + + + delay_threshold 設定パラメータ + + + + + + + プライマリサーバに対するスタンバイサーバのレプリケーション遅延の許容度をWALバイト単位で指定します。 + Pgpool-IIは、スタンバイサーバの遅延がこの設定レベルを超えた場合には、 が有効であっても、プライマリに追いつくまでそのスタンバイノードにはSELECTクエリを送信せず、全てプライマリサーバに送るようにします。 + このパラメータが0の場合は、遅延のチェックを行ないません。 + この遅延閾値のチェックは毎に行われます。 + デフォルト値は0です。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + delay_threshold_by_time (integer) + + + delay_threshold_by_time 設定パラメータ + + + + + + + プライマリサーバに対するスタンバイサーバのレプリケーション遅延の許容時間を指定します。 + この値が単位無しで指定された場合は、ミリ秒単位であると見なします。 + 0よりも大きい値が指定されると、は無視されます。 + Pgpool-IIは、スタンバイサーバの遅延がこの設定レベルを超えた場合には、 が有効であっても、プライマリに追いつくまでそのスタンバイノードにはSELECTクエリを送信せず、全てプライマリサーバに送るようにします。 + このパラメータが0の場合は、遅延のチェックを行ないません。 + この遅延閾値のチェックは毎に行われます。 + デフォルト値は0です。 + + + + + レプリケーション遅延はPostgreSQLのシステムビューであるpg_stat_replication.replay_lagから取得します。 + このビューはPostgreSQL 10以降でサポートされています。 + もしそれ以前のバージョンのPostgreSQLを使用すると、Pgpool-IIは自動的にを使用するようになり、は無視されます。 + + + + + このパラメータは、が正しく設定され、PostgreSQLのスタンバイのprimary_conninfoのapplication_nameと一致していることに依存しています。 + + + + + もしこのパラメータが指定されていると、はレプリケーション遅延をバイト単位ではなく、秒単位で表示します。 + + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + + prefer_lower_delay_standby (boolean) + + + prefer_lower_delay_standby 設定パラメータ + + + + + + このパラメータはあるいはを使用しているときに有効です。 + onに設定すると、負荷分散先のスタンバイサーバがdelay_thresholdを超えて遅延したときに、プライマリサーバでなく、 + が0より大きくて1番遅延の少ないスタンバイサーバを負荷分散ノードにします。 + 全てのスタンバイサーバがあるいはを超えて遅延しているか、負荷分散先として最初からプライマリが選ばれた場合はプライマリサーバに送ります。 + デフォルトはoffです。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + log_standby_delay (enum) + + + log_standby_delay 設定パラメータ + + + + + + + レプリケーションの遅延状況をログ出力する条件を指定します。 + 以下の表にこのパラメータでとることができる値のリストを示します。 + + + + + スタンバイ遅延のログ出力オプション + + + + + + 説明 + + + + + + none + + スタンバイの遅延はログ出力されない + + + + always + + スタンバイの遅延が0より大きければ、レプリケーション遅延がチェックされる度に、スタンバイの遅延がログ出力される + + + + if_over_threshold + + あるいはの値を超えた時だけ、スタンバイの遅延がログ出力される(デフォルト) + + + +
+ + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + +
+
+ + + replication_delay_source_cmd (string) + + + replication_delay_source_cmd設定パラメータ + + + + + + レプリカノードからレプリケーション遅延情報を読み取るための外部コマンドを指定します。 + このパラメータが空文字以外に設定されていると、Pgpool-IIはレプリケーション遅延取得するために、組み込みのデータベースへの問い合わせではなく、その外部コマンドを使います。 + そのコマンドは、Pgpool-IIのプロセスユーザとして実行されます。 + + + + そのコマンドはレプリカノードから、ノード識別子を位置引数として受け取りますが、プライマリーノードは省略されます。 + 各識別子は<hostname>:<port>の形式で、たとえば、server1:5432 server2:5432となります。 + その順序は、Pgpool-IIのバックエンドの順(プライマリを除く)と同じであり、(AWS CloudWatch for Auroraのような)外部メトリクスと関連付けることを可能にします。 + + + + コマンドは、引数と同じ順に、一つの空白文字で区切られたレプリカごとの値を含む1行を標準出力に書き出さなければなりません。 + 行の終端は改行文字を伴っても、伴わなくても構いません。 + プライマリノードの遅延は暗黙的に0とみなされ、出力に含まれるべきではありません。 + 遅延の値は、整数値でも浮動小数点値でも構いません。 + + + + 特別な値-1は、Pgpool-IIのヘルスチェックがまだ検出していないレプリカのダウンを表します。 + Pgpool-IIはこの状況をログに書き出しますが、これがフェイルオーバを引き起こすかどうかは自身のヘルスチェックのロジックに依存しており、単に-1を受け取っただけではフェイルオーバは起こりません。 + + + + 3ノードクラスタ(プライマリ一つ、レプリカ2つ)の例を考えます。コマンドがserver1:5432 server2:5432の引数を受け取ると、"25.5 100"を出力し、その意味は最初のレプリカの遅延が25.5msで、2つ目が100msの遅延となります。 + + + + デフォルトは空文字です(組み込みのレプリケーション遅延クエリを使用します)。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + + + replication_delay_source_timeout (integer) + + + replication_delay_source_timeout設定パラメータ + + + + + + 秒単位でで指定した外部コマンドのタイムアウトを指定します。 + コマンドがこのタイムアウト以内に終了しない場合は、Pgpool-IIはエラーをログします。 + + + + デフォルトは10秒です。 + 有効な値の範囲は1-3600秒の範囲です。 + + + + このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。 + + + + +
diff --git a/doc.ja/src/sgml/stylesheet.css b/doc.ja/src/sgml/stylesheet.css index c4e185f0e..1cb5f406f 100644 --- a/doc.ja/src/sgml/stylesheet.css +++ b/doc.ja/src/sgml/stylesheet.css @@ -122,7 +122,7 @@ BLOCKQUOTE.NOTE, BLOCKQUOTE.TIP, table.CAUTION, table.WARNING, div.note, div.tip max-width: 720px; border-width: 1px; border-style: solid; - overfileow: auto; + overflow: auto; -moz-border-radius: 8px; -webkit-border-radius: 8px; -khtml-border-radius: 8px; diff --git a/doc.ja/src/sgml/version.sgml b/doc.ja/src/sgml/version.sgml index 997e1f0d5..001c98a34 100644 --- a/doc.ja/src/sgml/version.sgml +++ b/doc.ja/src/sgml/version.sgml @@ -1 +1 @@ - + diff --git a/doc.ja/src/sgml/watchdog.sgml b/doc.ja/src/sgml/watchdog.sgml index c04a798c9..a2ae4382c 100644 --- a/doc.ja/src/sgml/watchdog.sgml +++ b/doc.ja/src/sgml/watchdog.sgml @@ -1,894 +1,1482 @@ - Watchdog + Watchdog - - + --> Watchdogの設定 - - -Watchdogの設定パラメータはpgpool.confに記述されています。 -pgpool.conf.sampleのWATCHDOG節に設定の例があります。 -以下のすべてのオプションがwatchdogプロセスでは指定されている必要があります。 - - - - - Watchdogを有効にする + + + Watchdogの設定パラメータはpgpool.confに記述されています。 + pgpool.conf.sampleのWATCHDOG節に設定の例があります。 + 以下のすべてのオプションがwatchdogプロセスでは指定されている必要があります。 + + + + + Watchdogを有効にする - - - use_watchdog (boolean) - - - use_watchdog設定パラメータ - - - - - -onならwatchdogを有効にします。 -デフォルトはoffです。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - - - - Watchdog通信 - - - - - wd_hostname (string) - - - wd_hostname設定パラメータ - - - - - -Pgpool-IIサーバのホスト名またはIPアドレスを指定します。 -クエリやパケットの送受信の他、watchdogの識別子としても用います。 - - - - - - - - - wd_port (integer) - - - wd_port 設定パラメータ - - - - - -watchdogが接続を受け付けるために監視するポート番号です。 -デフォルト値は9000です。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - wd_authkey (string) - - - wd_authkey設定パラメータ - - - + + + use_watchdog (boolean) + + + use_watchdog設定パラメータ + + + + + + onならwatchdogを有効にします。 + デフォルトはoffです。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + Pgpool-II 4.2より前では、watchdogは自ノードとそれを基準に他ノードの設定を記述するため、 + ノードごとに異なる設定を記述する必要がありました。 + Pgpool-II 4.2以降では、watchdogの設定はノード間で共通するようにしました。 + そのため、Pgpool-II 4.2以降、Watchdog機能が有効になっている場合、 + どの設定がどのホストであるかを区別するには、 + 設定ファイルpgpool.confを格納するディレクトリにpgpool_node_idファイルの作成が必要になります。 + そのファイルにpgpool(watchdog)ホストを識別するためのノード番号(0、1、2など)を指定します。 + + + pgpool_node_idの設定例 + + Pgpool ノードが3つあり、それぞれのホスト名が server1、server2、server3 の場合、各ホスト上でpgpool_node_idファイルを以下のように作成します。 + RPMからインストールした場合は、pgpool.conf/etc/pgpool-II/配下にインストールされます。 + + + - -wachdog間通信で用いられる認証キーを指定します。 -全てのPgpool-IIで同じキーを指定する必要があります。 -認証キーが異なるwatchdogからの通信は拒絶されます。 -死活監視をheartbeatモードで行う場合には、この認証はハートビート信号にも適用されます。 + server1 + +[server1]# cat /etc/pgpool-II/pgpool_node_id +0 + + + - -Pgpool-IIV3.5以降ではwd_authkeyがwatchdog IPCクライアントの認証にも使われるため、Pgpool-IIと通信するwatchdogプロセスは、"IPCAuthKey"のコマンドのJSONデータにwd_authkey値を設定しなければなりません。 + server2 + +[server2]# cat /etc/pgpool-II/pgpool_node_id +1 + + + - -デフォルトは''(空文字)で、この場合watchdogの認証は行われません。 + server3 - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - + +[server3]# cat /etc/pgpool-II/pgpool_node_id +2 + + + + + + + + - - - 上流サーバへの接続 + + + Watchdog通信 - + - - trusted_servers (string) - - - trusted_servers設定パラメータ - - - - - -上位接続を確認するための信頼できるサーバのリストを指定します。 -リスト中の各サーバは、pingの応答に答える必要があります。 -"hostA,hostB,hostC"のようにカンマで区切って複数のサーバを指定できます。 -全てのサーバに到達できなくなると、watchdogはPgpool-IIに障害が発生したと判断します。 -そのため、複数のサーバを指定することを推奨します。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - ping_path (string) - - - ping_path設定パラメータ - - - - - -上位サーバへの接続監視に利用するpingコマンドのパスを指定します。 -"/bin"のようにパスだけを指定します。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - - - - 仮想IP制御 + + hostnameX (string) + + + hostnameX設定パラメータ + + + + + + Pgpool-IIサーバのホスト名またはIPアドレス(IPv4 あるいは IPv6)を指定します。 + クエリやパケットの送受信の他、watchdogの識別子としても用います。 + パラメータ名の最後にある数字は「pgpool ノードID」で、0から始まります(たとえばhostname0)。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - + + wd_listen_address (string) + + + wd_listen_address設定パラメータ + + + + + + watchdogがLISTENするソケットのホスト名またはIPアドレス(IPv4 あるいは IPv6)を指定します。 + デフォルトは''(空文字)です。 + 1つのみを指定してください。 + デフォルト値以外が設定されている場合自ノードのhostnameXの値は無視されwd_listen_addressで指定したアドレスでLISTENするソケットが作成されます。 + wd_listen_addressについても*を指定することで全アドレスをLISTENします。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - delegate_IP (string) - - - delegate_IP設定パラメータ - - - - - -(アプリケーションサーバなど)クライアントサーバから接続されるpgpool-IIの仮想IP(VIP) アドレスを指定します。 -Pgpool-IIがスタンバイからアクティブに切り替わった時、Pgpool-IIはこのVIPを引き継ぎます。 -デフォルトは''(空文字)で、この場合仮想IPは決して立ち上がりません。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + wd_portX (integer) + + + wd_port設定パラメータ + + + + + + watchdogが接続を受け付けるために監視するポート番号です。 + デフォルト値は9000です。 + パラメータ名の最後にある数字は「pgpool ノードID」で、0から始まります(たとえばwd_port0)。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - if_cmd_path (string) - - - if_cmd_path設定パラメータ - - - - - -Pgpool-IIが仮想IPを切り替えるために使用するコマンドへのパスを指定します。 -"/bin"のようにパスだけを指定します。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + wd_listen_port (integer) + + + wd_listen_port設定パラメータ + + + + + + watchdogがLISTENするためのソケットのポートを指定するパラメータです。 + デフォルト値は0です。 + デフォルト値以外の設定があれば自ノードのwd_portXの値は無視され、wd_listen_portで指定したポートでLISTENするソケットが作成されます。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - if_up_cmd (string) - - - if_up_cmd設定パラメータ - - - - - -仮想IPを起動するために実行するコマンドを指定します。 -"ip addr add $_IP_$/24 dev eth0 label eth0:0"のようにコマンドとパラメータを指定します。 -$_IP_$で指定されたIPアドレスに置換されます。 - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + pgpool_portX (integer) + + + pgpool_portX設定パラメータ + + + + + + Pgpool-IIサーバのポート番号を指定します。 + デフォルト値は9999です。 + パラメータ名の最後にある数字は「pgpool ノードID」で、0から始まります(たとえばpgpool_port0)。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + Watchdogの設定例 + + + Pgpool ノードが3つあり、それぞれのホスト名が server1、server2、server3 の場合、 + + 及びを以下のように設定します。 + + hostname0 = 'server1' + wd_port0 = 9000 + pgpool_port0 = 9999 + + hostname1 = 'server2' + wd_port1 = 9000 + pgpool_port1 = 9999 + + hostname2 = 'server3' + wd_port2 = 9000 + pgpool_port2 = 9999 + + + + + - - if_down_cmd (string) - - - if_down_cmd設定パラメータ - - - - - -仮想IPを停止するために実行するコマンドを指定します。 -"ip addr del $_IP_$/24 dev eth0"のようにコマンドとパラメータを指定します。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + wd_authkey (string) + + + wd_authkey設定パラメータ + + + + + + watchdog間通信で用いられる認証キーを指定します。 + 全てのPgpool-IIで同じキーを指定する必要があります。 + 認証キーが異なるwatchdogからの通信は拒絶されます。 + 死活監視をheartbeatモードで行う場合には、この認証はハートビート信号にも適用されます。 + + + + Pgpool-IIV3.5以降ではwd_authkeyがwatchdog IPCクライアントの認証にも使われるため、Pgpool-IIと通信するwatchdogプロセスは、"IPCAuthKey"のコマンドのJSONデータにwd_authkey値を設定しなければなりません。 + + + + デフォルトは''(空文字)で、この場合watchdogの認証は行われません。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + - - arping_path (string) - - - arping_path設定パラメータ - - - - - -IPアドレス切り替え後にPgpool-IIがARPリクエストを送信するコマンドへのパス指定します。 -"/usr/sbin"のようにパスだけを指定します。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + + 上位サーバへの接続 - - arping_cmd (string) - - - arping_cmd設定パラメータ - - - - - -IPアドレス切り替え後にARPリクエストを送信するコマンドです。 -"arping -U $_IP_$ -w 1"のようにコマンドとパラメータを指定します。 -$_IP_$delegate_IPで指定されたIPアドレスに置換されます。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + + Pgpool-IIのサービス提供先(DB クライアント)のサーバを上位サーバと呼びます。 + Pgpool-IIが生きていてPostgreSQLと繋がっている場合でも、 + 上位サーバとのリンクが切れていれば、Pgpool-IIはサービスを提供できません。 + そのため、watchdogは上位サーバとのリンクが繋がっているかどうかも監視します。 + + + + + trusted_servers (string) + + + trusted_servers設定パラメータ + + + + + + 上位サーバとの接続を確認するための信頼できるサーバのリストを指定します。 + 例えば、上位サーバ、あるいは上位サーバへの経路上にあるルーターのリストを指定します。 + リスト中の各サーバは、pingの応答に答える必要があります。 + "hostA,hostB,hostC"のようにカンマで区切って複数のサーバを指定できます。 + 全てのサーバに到達できなくなると、watchdogはPgpool-IIに障害が発生したと判断します。 + そのため、複数のサーバを指定することを推奨します。 + なお、このパラメータにPostgreSQLサーバを指定することはしないでください。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + trusted_server_command (string) + + + trusted_server_command設定パラメータ + + + + + + 信頼できるサーバのping応答を確認するユーザコマンドを指定します。 + %hはtrusted_serversで指定された各ホスト名に置換されます。 + デフォルトはping -q -c3 %hです。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - + - - - 昇格および降格時の振る舞い - - -Pgpool-IIがアクティブ(仮想IPを保持しているステータス)に昇格した時の振る舞いを指定します。 - + + + 仮想IP制御 - + - - clear_memqcache_on_escalation (boolean) - - - clear_memqcache_on_escalation設定パラメータ - - - - - -このオプションがonの場合、pgpool-II がアクティブに昇格した時に、共有メモリ上のクエリキャッシュを全て削除します。 - これにより、新しいアクティブのPgpool-IIが旧アクティブと非整合な古いクエリキャッシュを使うことを防止します。 - - - -デフォルトはonです。 - - - -が'shmem'の場合のみ有効です。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + delegate_ip (string) + + + delegate_ip設定パラメータ + + + + + + (アプリケーションサーバなど)クライアントサーバから接続されるPgpool-IIの仮想IP(VIP)アドレスを指定します。 + Pgpool-IIがスタンバイからリーダーに切り替わった時、Pgpool-IIはこのVIPを引き継ぎます。 + クォーラムが存在しなければVIPは立ち上がりません。 + デフォルトは''(空文字)で、この場合仮想IPは決して立ち上がりません。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - wd_escalation_command (string) - - - wd_escalation_command設定パラメータ - - - - - -マスターwatchdogに昇格した時に、ここで指定したコマンドがwatchdogによって実行されます。 - - - -コマンドは、そのノードに仮想IPが設定されていた場合、それが立ち上がる直前のタイミングで実行されます。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + if_cmd_path (string) + + + if_cmd_path設定パラメータ + + + + + + Pgpool-IIが仮想IPを切り替えるために使用するコマンドへのパスを指定します。 + "/sbin"のようにパスだけを指定します。 + if_up_cmdif_down_cmdに指定したコマンドが"/"で始まる場合、 + フルパスとみなしif_cmd_pathの設定を無視します。 + デフォルト値は/sbinです。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - wd_de_escalation_command (string) - - - wd_de_escalation_command設定パラメータ - - - - - -Pgpool-IIのマスターwatchdogが責務を辞退し降格するときに、ここで指定したコマンドが実行されます。 -マスターwatchdogノードは、そのマスターノードのPgpool-IIが停止したとき、ネットワーク切断やクォーラムが失われたことを検出した時に、マスターから辞任します。 - - - -このコマンドは、watchdogノードに仮想IPアドレスが設定されていた場合、それが停止される直前のタイミングで実行されます。 - - - -wd_de_escalation_commandは、Pgpool-IIV3.5より前のバージョンには提供されていません。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + + if_up_cmd (string) + + + if_up_cmd設定パラメータ + + + + + + 仮想IPを起動するために実行するコマンドを指定します。 + "ip addr add $_IP_$/24 dev eth0 label eth0:0"のようにコマンドとパラメータを指定します。 + このコマンドを実行するにはroot権限が必要となりますので、一般ユーザが実行できるように + ipコマンドにsetuidを設定するか、 + Pgpool-II起動ユーザ(デフォルトではpostgres)がパスワードなしにsudoを実行できるように設定し、 + sudoを介したコマンドを"/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev eth0 label eth0:0"のように指定します。 + $_IP_$で指定されたIPアドレスに置換されます。 + + + + デフォルト値は/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev eth0 label eth0:0です。 + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + if_down_cmd (string) + + + if_down_cmd設定パラメータ + + + + + + 仮想IPを停止するために実行するコマンドを指定します。 + "ip addr del $_IP_$/24 dev eth0"のようにコマンドとパラメータを指定します。 + このコマンドを実行するにはroot権限が必要となりますので、一般ユーザが実行できるように + ipコマンドにsetuidを設定するか、 + Pgpool-II起動ユーザ(デフォルトではpostgres)がパスワードなしにsudoを実行できるように設定し、 + sudoを介したコマンドを"/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev eth0"のように指定します。 + $_IP_$で指定されたIPアドレスに置換されます。 + + + + デフォルト値は/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev eth0です。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + arping_path (string) + + + arping_path設定パラメータ + + + + + + IPアドレス切り替え後にPgpool-IIがARPリクエストを送信するコマンドへのパス指定します。 + "/usr/sbin"のようにパスだけを指定します。 + arping_cmdに指定したコマンドが"/"で始まる場合、 + フルパスとみなしarping_pathの設定を無視します。 + デフォルト値は/usr/sbinです。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + arping_cmd (string) + + + arping_cmd設定パラメータ + + + + + + IPアドレス切り替え後にARPリクエストを送信するコマンドです。 + "arping -U $_IP_$ -w 1 -I eth0"のようにコマンドとパラメータを指定します。 + このコマンドを実行するにはroot権限が必要となりますので、一般ユーザが実行できるように + arpingコマンドにsetuidを設定するか、 + Pgpool-II起動ユーザ(デフォルトではpostgresユーザ)がパスワードなしにsudoを実行できるように設定し、 + sudoを介したコマンドを"/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I eth0"のように設定します。 + $_IP_$で指定されたIPアドレスに置換されます。 + + + + デフォルト値は/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I eth0です。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + ping_path (string) + + + ping_path設定パラメータ + + + + + + 仮想IPの起動を確認するために利用するpingコマンドのパスを指定します。 + "/bin"のようにパスだけを指定します。 + デフォルト値は/binです。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - + - - - フェイルオーバの挙動の制御 + + + 昇格および降格時の振る舞い + + + Pgpool-IIがリーダー(仮想IPを保持しているステータス)に昇格した時の振る舞いを指定します。 + - - -これらの設定は、watchdog機能が有効な場合に、バックエンドノードのフェイルオーバの動作を制御するために使用されます。 -これらの設定の影響は、内部的なPgpool-IIのフェイルオーバ/縮退要求のみに影響します。 -一方、(PCPコマンドを使った)ユーザが起動したバックエンド切り離し操作では、これらの設定項目は迂回され適用されません。 - + - + + clear_memqcache_on_escalation (boolean) + + + clear_memqcache_on_escalation設定パラメータ + + + + + + このオプションがonの場合、pgpool-II がリーダーに昇格した時に、共有メモリ上のクエリキャッシュを全て削除します。 + これにより、新しいリーダーのPgpool-IIが旧リーダーと非整合な古いクエリキャッシュを使うことを防止します。 + + + + デフォルトはonです。 + + + + が'shmem'の場合のみ有効です。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - failover_when_quorum_exists (boolean) - - - failover_when_quorum_exists 設定パラメータ - - - - + + wd_escalation_command (string) + + + wd_escalation_command設定パラメータ + + + + + + リーダーwatchdogに昇格した時に、ここで指定したコマンドがwatchdogによって実行されます。 + + + + コマンドは、そのノードに仮想IPが設定されていた場合、それが立ち上がる直前のタイミングで実行されます。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + wd_de_escalation_command (string) + + + wd_de_escalation_command設定パラメータ + + + + + + Pgpool-IIのリーダーwatchdogが責務を辞退し降格するときに、ここで指定したコマンドが実行されます。 + リーダーwatchdogノードは、そのリーダーノードのPgpool-IIが停止したとき、ネットワーク切断やクォーラム(quorum)クォーラムquorumが失われたことを検出した時に、リーダーから辞任します。 + + + + このコマンドは、watchdogノードに仮想IPアドレスが設定されていた場合、それが停止される直前のタイミングで実行されます。 + + + + wd_de_escalation_commandは、Pgpool-IIV3.5より前のバージョンには提供されていません。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + + + + + フェイルオーバの挙動の制御 + + + + これらの設定は、watchdog機能が有効な場合に、バックエンドノードのフェイルオーバの動作を制御するために使用されます。 + これらの設定は、内部的なPgpool-IIのフェイルオーバ/縮退要求のみに影響します。 + 一方、(PCPコマンドを使った)ユーザが起動したバックエンド切り離し操作では、これらの設定項目は迂回され適用されません。 + + + + + + failover_when_quorum_exists (boolean) + + + failover_when_quorum_exists 設定パラメータ + + + + + このパラメータを有効にすると、Pgpool-IIがバックエンドノードの縮退/フェイルオーバを実行する際にクォーラムquorumクォーラムが存在するかどうかを考慮するようになります。 + + + 「クォーラムが存在する」とは、生きているwatchdogノードの数(Pgpool-IIの数)を全部足して、すべてのwatchdogノードの数に対して多数派を形成できる場合のことを指します。 + たとえば、watchdogノード数が5のとき、生きているノード数が3以上なら多数派を形成できるのでクォーラムは存在しますが、生きているノード数が2以下なら多数派を形成できないのでクォーラムは存在しません。 + + + クォーラムが存在すると、一つのwatchdogノードがバックエンドの障害を誤検知しても他の多数派のノードに否決されるので、障害誤検知に対して堅牢になります。 + これはがオン(デフォルト)の動作ですが、設定によって多数派を形成しなくても直ちにフェイルオーバするようにすることもできます。 + バックエンドの障害を誤って検出したPgpool-IIノードは、障害の発生したバックエンドノードを隔離します。 + + + クォーラムの存在の有無は、コマンドを--verboseオプション付きで起動することで確認できます。 + Quorum stateQUORUM EXISTまたはQUORUM IS ON THE EDGEならクォーラムは存在します。 + Quorum stateQUORUM ABSENTならクォーラムは存在しません。 + + + + クォーラムが存在しない場合、クォーラムが再び存在するまで、バックエンドの障害を検出したPgpool-IIノードは、障害の発生したバックエンドノードを隔離します。 + + + + 隔離されたノードをpcp_detach_nodeコマンドで強制的にフェイルオーバさせることは可能ですが、pcp_attach_nodeコマンドで再びアタッチ状態にすることはできません。 + + + + quarantine隔離隔離されたノードの動作は切り離されたバックエンドノードと似ていますが、フェイルオーバ/縮退と異なり、隔離ステータスはwatchdogクラスタ内の他のPgpool-IIノードに伝播されません。 + したがって、他のPgpool-IIノードは引き続きそのバックエンドを使用し続ける可能性があります。 + + + + 隔離とフェイルオーバ操作には多くの類似点がありますが、どちらも非常に基本的な方法で異なります。 + 隔離操作はを実行せず、障害の発生したノードを隔離します。 + この隔離されたノードがプライマリの場合、Pgpool-IIはスタンバイをプライマリに昇格させないので、プライマリノードが隔離されている間は、使用可能なプライマリバックエンドノードはありません。 + + + 更に、障害ノードとは違い、Pgpool-IIは隔離されたノードに対してはヘルスチェックを実行し続けます。 + 隔離されたノードが到達可能になり次第、そのノードは自動的に再度アタッチされます。 + これはPgpool-II V4.1以降にのみ適用されることに注意してください。 + それ以前のバージョンをお使いの場合は、隔離されたノードに対する接続性の問題が解決されたら、を使ってそのノードを復帰させなければなりません。 + + + + Pgpool-II V4.1以後では、プライマリノードのフェイルオーバに関してwatchdogのリーダーノードが合意形成に失敗し、その結果プライマリバックエンドが隔離状態になった場合、そのリーダーノードはリーダーの役割を辞退し、次のリーダーの選挙の際にwd_priorityを引き下げることにより、クラスタが新しいリーダーを選ぶように仕向けます。 + + + スタンバイバックエンドの障害時にリーダーノードが合意形成に失敗した場合は、特にアクションは起こしません。 + watchdogリーダが管理する隔離されたスタンバイバックエンドは新しいリーダーの選挙を引き起こしません。 + + + + + このパラメータがoffなら、クォーラムが存在しなくても障害が発生するとフェイルオーバします。 + + + + + デフォルト値はonです。 + + + + failover_when_quorum_existsはPgpool-II V3.7より前では利用できません。 + + + + このパラメータは、サーバーの起動時にのみ設定できます。 + + + + + ネイティブレプリケーションモードではfailover_when_quorum_exists機能は利用できません。 + + + + + + + failover_require_consensus (boolean) + + + failover_require_consensus 設定パラメータ + + + + + + このパラメータを有効にすると、Pgpool-IIは、watchdogクォーラムが存在し、少なくともクォーラム投票に必要なノードの最小数があれば、バックエンドノードで縮退/フェイルオーバを実行します。 + + + + たとえば、3ノードのwatchdogのクラスタでは、フェイルオーバは、少なくとも2つのノードが特定のバックエンドノードに対してフェイルオーバの実行要求をするときのみ実行されます。 + + + + このパラメータがoffなら、投票で合意が取れなくてもフェイルオーバします。 + + + + + デフォルト値はonです。 + + + + + + + failover_require_consensusが有効な場合、Pgpool-IIは他 のPgpool-IIノードから充分な投票を得るまでフェイルオーバしません。 + ですから、正しくバックエンドの障害を検出するために、すべてのPgpool-IIノードでヘルスチェックを有効にすることを強く推奨します。 + ヘルスチェックに関する詳細については、をご覧ください。 + + + + + + + ネイティブレプリケーションモードではfailover_require_consensus機能は利用できません。 + + + + + Pgpool-II V3.7より前ではfailover_require_consensusは利用できません。 + が有効な場合にのみ有効です。 + + + + このパラメータは、サーバの起動時にのみ設定できます。 + + + + + + allow_multiple_failover_requests_from_node (boolean) + + + allow_multiple_failover_requests_from_node 設定パラメータ + + + + + + このパラメータは、と連携して動作します。 + 有効にすると、単一のPgpool-IIノードが複数のフェイルオーバ投票をできます。 + + + + たとえば、3ノードのwatchdogクラスタでは、1つのPgpool-IIノードが特定のバックエンドノードのフェイルオーバに対して2つのフェイルオーバ要求を送信すると、両方の要求が別の投票としてカウントされ、たとえ他のPgpool-IIノードからの投票を得なくても、Pgpool-IIがフェイルオーバを実行します。 + + + + たとえば、ヘルスチェックでエラーが検出されても有効投票数に達しない場合、障害が引き続き発生していて次のヘルスチェックで再度エラーが検出されれば、都合2票が投票されることになります。ほかのwatchdogが検出しない恒久的な障害が発生した際にフェイルオーバを引き起こしたい時に有用です。 + + + + + デフォルト値はoffです。 + + + + allow_multiple_failover_requests_from_nodeは、Pgpool-II V3.7以前では利用できません。 + の両方が有効な場合にのみ有効です。 + + + + このパラメータは、サーバの起動時にのみ設定できます。 + + + + + + enable_consensus_with_half_votes (boolean) + + enable_consensus_with_half_votes設定パラメータ + + + + + このパラメータはPgpool-IIが、クォーラムとフェイルオーバにおける合意を解決する際に、どのように多数決ルールにおける計算を行うかを設定します。 + + + + + このパラメータはバックエンドのフェイルオーバの挙動のみならず、Pgpool-II自身のクォーラムとフェイルオーバの挙動にも影響を与えます。 + + + + + このパラメータがオンなら、クォーラムとフェイルオーバの合意のために、全体のうち半数の投票だけでよくなります。 + そうでなければ、全体のうち少なくとも半数に加えて1票の投票が必要になります。 + フェイルオーバにおいては、これはと同期して動作します。 + クォーラムの存在決定、フェイルオーバにおける合意形成の両方において、watchdogクラスタが偶数のPgpool-IIノードから構成されている場合にのみこのパラメータは効果があります。 + 参加者が奇数のwatchdogクラスタにおける多数決決定の際には、このパラメータの設定値は影響しません。 + + + たとえば、このパラメータがオンのときは、2ノードのwatchdogクラスタではクォーラムが存在するためには一つのPgpool-IIノードが生きている必要があります。 + このパラメータがオフのときは、2ノードのwatchdogクラスタではクォーラムが存在するためには2つのPgpool-IIノードが生きている必要があります。 + + + このパラメータがオンのときは、4ノードのwatchdogクラスタではクォーラムが存在するためには2つのPgpool-IIノードが生きている必要があります。 + このパラメータがオフのときは、4ノードのwatchdogクラスタではクォーラムが存在するためには3つのPgpool-IIノードが生きている必要があります。 + + + このパラメータがオンのときは、split-brainが発生するリスクがあることに注意してください。 + たとえば、ノードA, B, C, Dからなる4ノードのクラスタでは、(A, B)と(C, D)の分断された2つのネットワークになる可能性があります。 + (A, B)と(C, D)にとっては、それぞれ生きた2つのノードが存在するので、クォーラムは依然として存在します。 + 各々のグループはそれぞれのリーダーwatchdogを選び、これはすなわちsplit-brainです。 + + + デフォルト値はオフです。 + + + enable_consensus_with_half_votesPgpool-IIV4.1よりも前には存在しません。 + 以前のバージョンは、あたかもこのパラメータがオンであるかのように動作します。 + + + このパラメータは、サーバの起動時にのみ設定できます。 + + + + + + + -このパラメータを有効にすると、クォーラムが存在する場合、Pgpool-IIはバックエンドノードで縮退/フェイルオーバを実行します。 -クォーラムが存在しない場合、クォーラムが再び存在するまで、バックエンドの障害を検出するPgpool-IIノードは、障害の発生したバックエンドノードを隔離します。 - - + watchdogクラスタメンバーシップの管理 + -隔離されたノードの動作は切り離されたバックエンドノードと似ていますが、フェイルオーバ/縮退と異なり、隔離ステータスはwatchdogクラスタ内の他のPgpool-IIノードに伝播されません。 -したがって、他のPgpool-IIノードは引き続きそのバックエンドを使用し続ける可能性があります。 - - + By default the watchdog cluster consists of all watchdog nodes + that are defined in the pgpool.conf file + irrespective of the current state of the node. Whether the node + is LOST, SHUTDOWN + or never started, the node is considered as the member of the + watchdog cluster definition as long as it is configured in the + configuration file. + All the majority rule computations for identifying the existence + of a quorum and resolving the consensus are made based on the + number of watchdog nodes that makes up the watchdog cluster. +--> + デフォルトではwatchdogクラスタは、現在のノードの状態とは無関係にpgpool.confファイルに定義されたすべてのwatchdogノードから構成されます。 + ノードがLOSTSHUTDOWN、あるいはノードが起動されなかった場合でも、設定ファイルにて設定されている限りはそのノードはwatchdogクラスタの定義に含まれると考えられます。 + クォーラムの存在と、合意の解決のためのすべての多数決ルールの計算は、watchdogクラスタを構成するwatchdogノードの数に基づいて行われます。 + + + -隔離とフェイルオーバ操作には多くの類似点がありますが、どちらも非常に基本的な方法で異なります。 -隔離操作はを実行せず、障害の発生したノードを隔離します。 -この隔離されたノードがマスタの場合、Pgpool-IIはスタンバイをマスタに昇格させないので、マスタノードが隔離されている間は、使用可能なマスタバックエンドノードはありません。 - - + Pgpool-II V4.3ではメンバー非メンバーの概念を導入することにより動的にクラスタの定義を変えることができるようになりました。 + + -デフォルト値はonです。 - - + 設定されたノードの合計数ではなく、メンバーwatchdogの数に基づいてすべての多数決ルールの計算が行われます。 + + + -failover_when_quorum_existsはPgpool-II V3.7より前では利用できません。 - - + For example: In a five node cluster (pgpool.conf has five + watchdog nodes defined) at-least three nodes need to be alive to make the quorum. + With the dynamic cluster membership mechanism the cluster can re-adjust + itself to only count the MEMBER nodes + (Member node doesn't necessarily need to be alive). + That means effectively a single alive node + can also fulfill the quorum requirements (depending on the membership criteria settings) + if at some point in time the cluster only has one or two member nodes. +--> + たとえば5つのノードのクラスタ(pgpool.confに5つのwatchdogノードが定義されています)では、クォーラムを作成するためには少なくとも3つのノードが生きていることが必要です。 + 動的なクラスタメンバー管理の機構では、クラスタはメンバーノード(メンバーノードは必ずしも生きている必要はありません)だけを数えるために、自分自身を再調整できます。 + このことは、ある時点でクラスタが1つあるいは2つのノードだけから構成されているときに、実質的に単一の生きているノードが(メンバーシップ管理の設定によって)クォーラム存在の条件を満たすことができることを意味します。 + + + + + -このパラメータは、サーバーの起動時にのみ設定できます。 - - - + 動的クラスタメンバーシップを使うことにより、split-brainが起こるリスクがあります。 + 設定において動的クラスタメンバーシップが必要かどうかを注意深くレビューし、関連する設定に保守的な設定を行うことを検討することを強く推奨します。 + + + - - failover_require_consensus (boolean) - + - failover_require_consensus 設定パラメータ - - - - + これらの設定項目は非メンバーであると印をつけられたノードを設定します。 + これらの設定をデフォルト値のままにしておくと、V4.3以前の振る舞いになります。 + + + + + + wd_remove_shutdown_nodes (boolean) + -このパラメータを有効にすると、Pgpool-IIは、watchdogクォーラムが存在し、少なくともクォーラム投票に必要なノードの最小数があれば、バックエンドノードで縮退/フェイルオーバを実行します。 - - + wd_remove_shutdown_nodes設定パラメータ + + + + -たとえば、3ノードのwatchdogのクラスタでは、フェイルオーバは、少なくとも2つのノードが特定のバックエンドノードに対してフェイルオーバの実行要求をするときのみ実行されます。 - - + 有効ならば、SHUTDOWNノードは直ちに非メンバーであると印を付けられ、クラスタから削除されます。 + 以前停止されたノードが再起動すると、自動的にクラスタに追加されます。 + -デフォルト値はonです。 - - + デフォルトはoffです。 + + + + + wd_lost_node_removal_timeout (integer) + - - -failover_require_consensusが有効な場合、Pgpool-IIは他 のPgpool-IIノードから充分な投票を得るまでフェイルオーバしません。 -ですから、正しくバックエンドの障害を検出するために、すべてのPgpool-IIノードでヘルスチェックを有効にすることを強く推奨します。 -ヘルスチェックに関する詳細については、をご覧ください。 - - - -Pgpool-II V3.7より前ではfailover_require_consensusは利用できません。 -が有効な場合にのみ有効です。 - - + wd_lost_node_removal_timeout設定パラメータ + + + + -このパラメータは、サーバの起動時にのみ設定できます。 - - - - - - allow_multiple_failover_requests_from_node (boolean) - + LOST状態のwatchdogノードに非メンバーであると印を付けて、クラスタから削除するまでのタイムアウトの秒単位の時間です。 + LOSTノードが再接続すると、クラスタメンバーシップは復元されます。 + + - allow_multiple_failover_requests_from_node 設定パラメータ - - - - + タイムアウトを0にすると、LOSTノードをクラスタから削除しません。 + -このパラメータは、と連携して動作します。 -有効にすると、単一のPgpool-IIノードが複数のフェイルオーバ投票をできます。 - - + + デフォルトは0です。 + + + + + wd_no_show_node_removal_timeout (integer) + -たとえば、3ノードのwatchdogクラスタでは、1つのPgpool-IIノードが特定のバックエンドノードのフェイルオーバに対して2つのフェイルオーバ要求を送信すると、両方の要求が別の投票としてカウントされ、たとえ他のPgpool-IIノードからの投票を得なくても、Pgpool-IIがフェイルオーバを実行します。 - - + wd_no_show_node_removal_timeout設定パラメータ + + + + -デフォルト値はoffです。 - - + クラスタ起動時にノードが現れない(NO-SHOW)場合に、非メンバーであると印を付けるまでのタイムアウトの秒単位の時間です。 + そのノードが起動してクラスタに接続すると、直ちにその非メンバーノードはクラスタメンバーになります。 + + -allow_multiple_failover_requests_from_nodeは、Pgpool-II V3.7以前では利用できません。 -の両方が有効な場合にのみ有効です。 - - + タイムアウトを0にすると、NO-SHOWノードをクラスタから削除しません。 + -このパラメータは、サーバの起動時にのみ設定できます。 - - - + デフォルトは0です。 + + - + - - - <productname>Pgpool-II</productname>の死活監視 + + + <productname>Pgpool-II</productname>の死活監視 - - -Watchdogは、定期的にpgpool-IIの状態を監視します。 + + + Watchdogは、定期的にpgpool-IIの状態を監視します。 - + - + - - wd_lifecheck_method (string) - - + --> wd_lifecheck_method設定パラメータ - - - - - -死活監視の方法を指定します。 -指定できる値は 'heartbeat' (デフォルト)、'query'、または'external' です。 - - - -'heartbeat'を指定した場合には、監視は「ハートビートモード」で行われます。 -watchdog は一定間隔でハートビート信号(UDP パケット)を他のPgpool-IIへ送信します。 -またwatchdogは他のPgpool-IIから送られてくる信号を受信します。 -これが一定時間以上途絶えた場合にはそのPgpool-IIに障害が発生したと判断します。 - - - -query: このモードではwatchdogは監視用のクエリをPgpool-IIに発行し、それが成功するかどうかで pgpool-II が生きているかどうかを判断します。 - + + + + + + 死活監視の方法を指定します。 + 指定できる値は heartbeat (デフォルト)、query、またはexternal です。 + + + + heartbeatを指定した場合には、監視は「ハートビートモード」で行われます。 + watchdog は一定間隔でハートビート信号(UDP パケット)を他のPgpool-IIへ送信します。 + またwatchdogは他のPgpool-IIから送られてくる信号を受信します。 + これが一定時間以上途絶えた場合にはそのPgpool-IIに障害が発生したと判断します。 + + + + query: このモードではwatchdogは監視用のクエリをPgpool-IIに発行し、それが成功するかどうかで pgpool-II が生きているかどうかを判断します。 + Pgpool-IIサーバ間の設置場所が離れている場合、queryモードが有効かもしれません。 + - -クエリモードでは、を十分大きな値にしてください。 -watchdogプロセスもPgpool-IIにクライアントとして接続するからです。 - + --> + クエリモードでは、を十分大きな値にしてください。 + watchdogプロセスもPgpool-IIにクライアントとして接続するからです。 + - - - -external: このモードでは、Pgpool-IIに組み込みの死活監視は無効になり、watchdogはローカルとリモートのノード死活監視を行うために外部システムを使います。 - + --> + external: このモードでは、Pgpool-IIに組み込みの死活監視は無効になり、watchdogはローカルとリモートのノード死活監視を行うために外部システムを使います。 + - - -externalモードはPgpool-II V3.5よりも前のバージョンでは提供されていません。 - + --> + externalモードはPgpool-II V3.5よりも前のバージョンでは提供されていません。 + - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + - + wd_monitoring_interfaces_list (string) - - + --> wd_monitoring_interfaces_list設定パラメータ - + - - -watchdogプロセスがネットワークリンクの状態を監視するネットワークデバイス名をカンマ区切りのリストで指定します。 -リスト中の全てのネットワークインタフェースが(無効化あるいはケーブルを抜かれることで)非アクティブになると、watchdog はネットワークが完全に故障したと見なし自らを停止させませす。 -''(空文字)を指定するとネットワークインタフェースの監視が無効になります。 -'any'を指定すると、ループバック以外の存在する全てのネットワークインタフェースを監視します。 -デフォルトの値は''空リスト '' (監視は無効)です。 - - - - + watchdogプロセスがネットワークリンクの状態を監視するネットワークデバイス名をカンマ区切りのリストで指定します。 + リスト中の全てのネットワークインタフェースが(無効化あるいはケーブルを抜かれることで)非アクティブになると、watchdog はネットワークが完全に故障したと見なし自らを停止させます。 + ''(空リスト)を指定するとネットワークインタフェースの監視が無効になります。 + 'any'を指定すると、ループバック以外の存在する全てのネットワークインタフェースを監視します。 + デフォルトの値は''空リスト '' (監視は無効)です。 + + + + -wd_monitoring_interfaces_listは、Pgpool-II V3.5よりも前のバージョンでは提供されていません。 - + --> + wd_monitoring_interfaces_listは、Pgpool-II V3.5よりも前のバージョンでは提供されていません。 + - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - wd_interval (integer) - + + wd_interval (integer) + wd_interval configuration parameter - - - - - - + + + + + -Pgpool-IIが死活監視を行う間隔を秒単位で指定します(1以上の数字)。 -デフォルトは10です。 - + --> + Pgpool-IIが死活監視を行う間隔を秒単位で指定します(1以上の数字)。 + デフォルトは10です。 + - - -このパラメータは、サーバ起動時にのみ設定できます。 - - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + - - wd_priority (integer) - - + --> wd_priority設定パラメータ - - - - - -このパラメータによってローカルのwatchdogノードがマスターに選ばれる優先度を上げることができます。 -クラスタの初期起動時や古いマスターノードが故障した状況でクラスタがマスターノードの選択を行う際に、wd_priorityが高いノードがマスターwatchdogノードに選ばれます。 - - - -wd_priorityは、Pgpool-II V3.5よりも前のバージョンでは提供されていません。 - + as leader watchdog node when cluster will be electing its new leader node + in the event of old leader watchdog node failure. + wd_priority is also valid at the time of cluster startup. + When some watchdog nodes start up at same time,a node with the higher wd_priority + value is selected as a leader node. + So we should start watchdog nodes in order of wd_priority priority to prevent + unintended nodes from being selected as leader. + If wd_priority of each nodes has the same value, + leader node will be decided on base of starting time of watchdog. + --> + このパラメータによってローカルのwatchdogノードがリーダーに選ばれる優先度を上げることができます。 + 古いリーダーノードが故障した状況でクラスタがリーダーノードの選択を行う際に、wd_priorityが高いノードがリーダーwatchdogノードに選ばれます。 + wd_priorityはクラスタの初期起動時にも有効なので、 + 複数のwatchdogノードを同時に起動した場合、wd_priorityが高いノードがリーダーwatchdogノードに選ばれます。 + このため、watchdogノードは意図しないノードがリーダーに選ばれることが無いようにwd_priorityの優先順位が高い順に起動するべきです。 + もしwd_priorityが同じなら、早いもの勝ちでリーダーになります。 + + + + wd_priorityは、Pgpool-II V3.5よりも前のバージョンでは提供されていません。 + - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - wd_ipc_socket_dir (string) - - + --> wd_ipc_socket_dir設定パラメータ - - - - - -Pgpool-II watchdog のIPC通信で受け付ける UNIX ドメインソケットが作成されるディレクトリを指定します。 -デフォルトは'/tmp'です。 -このソケットが cron ジョブで削除されることのないよう気をつけてください。 -この値は '/var/run'などのディレクトリに設定することを推奨します。 - - - + Pgpool-II watchdog のIPC通信で受け付ける UNIX ドメインソケットが作成されるディレクトリを指定します。 + デフォルトは'/tmp'です。 + このソケットが cron ジョブで削除されることのないよう気をつけてください。 + この値は '/var/run'などのディレクトリに設定することを推奨します。 + + + -wd_ipc_socket_dirは、Pgpool-II V3.5よりも前のバージョンでは提供されていません。 - - - + wd_ipc_socket_dirは、Pgpool-II V3.5よりも前のバージョンでは提供されていません。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + - + - - + + - - - 死活監視:ハートビートモードの設定 + + + 死活監視:ハートビートモードの設定 - - - wd_heartbeat_port (integer) - - - wd_heartbeat_port設定パラメータ - - - - - + heartbeat_hostnameX設定パラメータ + + + + + + ハートビート信号を送受信するためのIPアドレス(IPv4 あるいは IPv6)、または ホスト名を指定します。 + パラメータ名の最後にある数字は「pgpool ノードID」で、0から始まります(たとえばheartbeat_hostname0)。 + 複数のハートビート信号の送り先をセミコロン(;)で区切って指定することができます。 + + + -ハートビート信号を受信するUDPポート番号を指定します。 -デフォルトは 9694 です。 -'heartbeat'に設定されている場合のみ有効です。 - - - + heartbeat_hostnameXは、'heartbeat'に設定されている場合のみ有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - wd_heartbeat_keepalive (integer) - - - wd_heartbeat_keepalive設定パラメータ - - - - - -ハートビート信号を送信する間隔(秒)を指定します。 -デフォルトは2です。 -wd_heartbeat_keepaliveは、'heartbeat'に設定されている場合のみ有効です。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - + wd_heartbeat_listen_addresses設定パラメータ + + + + + + ハートビート信号を受信するためのIPアドレス(IPv4 あるいは IPv6)、またはホスト名を指定します。 + デフォルトは''(空文字)です。 + ハートビート信号を LISTEN する複数のソケットのアドレスをセミコロン(;)で区切って指定することができます。 + デフォルト値以外を設定している場合、自ノードのheartbeat_hostnameXの設定値は無視され、wd_heartbeat_listen_addressesで指定したアドレスでLISTENするソケットが作成されます。 + wd_heartbeat_listen_addressesについても*を指定することで全アドレスをLISTENします。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - - - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - wd_heartbeat_deadtime (integer) - - - wd_heartbeat_deadtime設定パラメータ - - - - - + heartbeat_portX設定パラメータ + + + + + + ハートビート信号を受信するためのUDPポート番号を指定します。 + 1つのみを指定してください。デフォルトは9694です。 + パラメータ名の最後にある数字は「pgpool ノードID」で、0から始まります(たとえばheartbeat_port0)。 + + + -このオプションで指定された間隔(秒)の間ハートビート信号が途絶えた場合、リモートのwatchdogに障害が発生したとみなされます。 -デフォルトは30です。 - - - + heartbeat_portXは、'heartbeat'に設定されている場合のみ有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - - - heartbeat_destination0 (string) + + wd_heartbeat_listen_port (integer) - - heartbeat_destination設定パラメータ - - - - - -ハートビート信号の送る先のIPアドレスまたは ホスト名を指定します。 -複数のハートビート信号の送り先が指定可能です。 -0から始まるパラメータの最後の部分は送り先の番号です。 - - - -heartbeat_destinationは、'heartbeat'に設定されている場合のみ有効です。 - - - + wd_heartbeat_listen_port設定パラメータ + + + + + + ハートビート信号を受信するためのUDPポート番号を指定します。 + 1つのみを指定してください。 + デフォルトは0です。 + デフォルト値以外の設定があれば自ノードのheartbeat_portXの値は無視され、wd_heartbeat_listen_portで指定したポートでLISTENするソケットが作成されます。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - - - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + - - heartbeat_destination_port0 (integer) - - - heartbeat_destination_port設定パラメータ - - - - - -ハートビート信号の送る先のポート番号を指定します。 -複数のハートビート信号の送り先が指定可能です。 -0から始まるパラメータの最後の部分は送り先の番号です。 - - - + heartbeat_deviceX設定パラメータ + + + + + + ハートビートの送受信に用いるネットワークデバイス名を指定します。 + パラメータ名の最後にある数字は「pgpool ノードID」で、0から始まります(たとえばheartbeat_device0)。 + 複数のネットワークデバイス名をセミコロン(;)で区切って指定することができます。 + + + - heartbeat_destination_portは、'heartbeat'に設定されている場合のみ有効です。 - - - + heartbeat_deviceXは、Pgpool-IIをroot権限で起動しているときのみ使用可能です。 + それ以外の場合は空文字('')のままにしておいてください。 + + + heartbeat_deviceXは、'heartbeat'に設定されている場合のみ有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + + + + Heartbeat 信号を用いた死活監視の設定例 + + + Pgpool ノードが3つあり、それぞれのホスト名が server1、server2、server3 の場合、 + + 及びを以下のように設定します。 + +heartbeat_hostname0 = 'server1' +heartbeat_port0 = 9694 +heartbeat_device0 = '' + +heartbeat_hostname1 = 'server2' +heartbeat_port1 = 9694 +heartbeat_device1 = '' + +heartbeat_hostname2 = 'server3' +heartbeat_port2 = 9694 +heartbeat_device2 = '' + + + - + - - heartbeat_device0 (string) - - - heartbeat_device設定パラメータ - - - - - -heartbeat_destinationX:heartbeat_destination_portXで指定されるハートビートの送信先に用いるネットワークデバイス名を指定します。 -パラメータ名の最後にあるXの値(送信先番号)を変えることにより、ハートビートの送信先ごとに異なるハートビートデバイス番号を設定することが可能です。 -送信先番号は0から始まります。 - - - + wd_heartbeat_keepalive設定パラメータ + + + + + -heartbeat_deviceは、'heartbeat'に設定されている場合のみ有効です。 - - - + ハートビート信号を送信する間隔(秒)を指定します。 + デフォルトは2です。 + wd_heartbeat_keepaliveは、'heartbeat'に設定されている場合のみ有効です。 + + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + - + - - + + wd_heartbeat_deadtime (integer) + + + wd_heartbeat_deadtime設定パラメータ + + + + + + このオプションで指定された間隔(秒)の間ハートビート信号が途絶えた場合、リモートのwatchdogに障害が発生したとみなされます。 + デフォルトは30です。 + + + + このパラメータは、サーバ起動時にのみ設定できます。 + + + + + - - 死活監視:クエリモードの設定 + + 死活監視:クエリモードの設定 - - wd_life_point (integer) - - + --> wd_life_point設定パラメータ - - - - - -監視クエリの応答が得られなかった場合のリトライ回数を指定します。 -有効な値は1以上の整数です。 - - - + 監視クエリの応答が得られなかった場合のリトライ回数を指定します。 + 有効な値は1以上の整数です。 + デフォルトは3です。 + + + -'query'の場合のみ、wd_life_pointは有効です。 - - - + 'query'の場合のみ、wd_life_pointは有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + - + - - wd_lifecheck_query (string) - - + --> wd_lifecheck_query設定パラメータ - - - - - -リモートのPgpool-IIの死活監視に使うクエリを指定します。 -デフォルトは"SELECT 1"です。 - - - + リモートのPgpool-IIの死活監視に使うクエリを指定します。 + デフォルトは"SELECT 1"です。 + + + -'query'の場合のみ、wd_life_check_queryは有効です。 - - - + 'query'の場合のみ、wd_lifecheck_queryは有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + - + - - wd_lifecheck_dbname (string) - - + --> wd_lifecheck_dbname設定パラメータ - - - - - -リモートのPgpool-IIの死活監視用の接続先のデータベース名です。 -デフォルトは'template1'です。 - - - + リモートのPgpool-IIの死活監視用の接続先のデータベース名です。 + デフォルトは'template1'です。 + + + -'query'の場合のみ、wd_life_check_dbnameは有効です。 - - - + 'query'の場合のみ、wd_lifecheck_dbnameは有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + - + - - wd_lifecheck_user (string) - - + --> wd_lifecheck_user設定パラメータ - - - - - -リモートのPgpool-IIの死活監視用の接続先のユーザ名です。 -デフォルトは'nobody'です。 - - - + リモートのPgpool-IIの死活監視用の接続先のユーザ名です。 + デフォルトは''(空文字)です。 + + + -'query'の場合のみ、wd_life_check_userは有効です。 - - - + 'query'の場合のみ、wd_lifecheck_userは有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + このパラメータは、サーバ起動時にのみ設定できます。 + - + - - wd_lifecheck_password (string) - - + --> wd_lifecheck_password設定パラメータ - - - - - -リモートのPgpool-IIの死活監視用の接続先のパスワードです。 -デフォルトは''(空文字)です。 - - - -wd_lifecheck_passwordが空白のままであった場合、Pgpool-IIは空のパスワードを使用する前にファイルからのパスワードの取得を試みます。 - - - -wd_lifecheck_passwordにAES256-CBCで暗号化されたパスワードも指定することができます。 -AESで暗号化されたパスワードを指定するためには、パスワード文字列は暗号化(aes-256-cbcアルゴリズムを使用)およびbase64でエンコードした後、AESを接頭辞として付けなければいけません。 - - - -暗号化されていないクリアテキストパスワードを指定するためには、TEXTをパスワード文字列の前に付けます。 -例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定すべきです。 - - - -正しくフォーマットされたAESで暗号化されたパスワード文字列をコマンドを使用して作成することもできます。 + --> + リモートのPgpool-IIの死活監視用の接続先のパスワードです。 + デフォルトは''(空文字)です。 + + + + wd_lifecheck_passwordが空白のままであった場合、Pgpool-IIは空のパスワードを使用する前にファイルからのパスワードの取得を試みます。 + + + + wd_lifecheck_passwordにAES256-CBCで暗号化されたパスワードも指定することができます。 + AESで暗号化されたパスワードを指定するためには、パスワード文字列は暗号化(aes-256-cbcアルゴリズムを使用)およびbase64でエンコードした後、AESを接頭辞として付けなければいけません。 + + + + 暗号化されていないクリアテキストパスワードを指定するためには、TEXTをパスワード文字列の前に付けます。 + 例えば、パスワードとしてmypassを設定したい場合、パスワードフィールドにTEXTmypassと指定すべきです。 + + + + 正しくフォーマットされたAESで暗号化されたパスワード文字列をコマンドを使用して作成することもできます。 - - -Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 -Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 - + + + Pgpool-IIは暗号化されたパスワードを使うために起動時に有効な復号鍵を要求します。 + Pgpool-IIに復号鍵を提供する方法の詳細はを参照してください。 + - - + + - -'query'の場合のみ、wd_life_check_passwordは有効です。 - - - + 'query'の場合のみ、wd_lifecheck_passwordは有効です。 + + + -このパラメータは、サーバ起動時にのみ設定できます。 - - - + このパラメータは、サーバ起動時にのみ設定できます。 + + + -デフォルトは''(空文字)です. - - - - - - - - - - Watchdogサーバの設定 - - - - other_pgpool_hostname0 (string) - - - other_pgpool_hostname設定パラメータ - - - - - -リモートのwatchdogノードに対するPgpool-IIサーバのホスト名を指定します。 -パラメータ名の最後にある数字は「サーバ番号」で、0から始まります。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - other_pgpool_port0 (integer) - - - other_pgpool_port設定パラメータ - - - - - -リモートのwatchdogノードに対するPgpool-IIサーバのポート番号を指定します。 -パラメータ名の最後にある数字は「サーバ番号」で、0から始まります。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - - - - - - other_wd_port0 (integer) - - - other_wd_port0設定パラメータ - - - - - -リモートのPgpool-IIサーバにおけるwatchdogのポート番号を指定します。 -パラメータ名の最後にある数字は「サーバ番号」で、0から始まります。 - - - -このパラメータは、サーバ起動時にのみ設定できます。 - + --> + デフォルトは''(空文字)です. + - + - - + + diff --git a/doc/Makefile.in b/doc/Makefile.in deleted file mode 100644 index cfadaedd3..000000000 --- a/doc/Makefile.in +++ /dev/null @@ -1,635 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = doc -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src -all: all-recursive - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps doc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps doc/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool cscopelist-am ctags \ - ctags-am distclean distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/doc/src/Makefile.in b/doc/src/Makefile.in deleted file mode 100644 index 5a63874c9..000000000 --- a/doc/src/Makefile.in +++ /dev/null @@ -1,640 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = doc/src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = figures/process-diagram.gif \ - figures/process-diagram.odp \ - figures/cluster.gif \ - figures/cluster.odp - -SUBDIRS = sgml -all: all-recursive - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps doc/src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps doc/src/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool cscopelist-am ctags \ - ctags-am distclean distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/doc/src/figures/cluster_40.gif b/doc/src/figures/cluster_40.gif new file mode 100644 index 000000000..8b15c742a Binary files /dev/null and b/doc/src/figures/cluster_40.gif differ diff --git a/doc/src/figures/cluster_40.odp b/doc/src/figures/cluster_40.odp new file mode 100644 index 000000000..16504700f Binary files /dev/null and b/doc/src/figures/cluster_40.odp differ diff --git a/doc/src/figures/detach_false_primary.gif b/doc/src/figures/detach_false_primary.gif index 6e8765163..a5c51492c 100644 Binary files a/doc/src/figures/detach_false_primary.gif and b/doc/src/figures/detach_false_primary.gif differ diff --git a/doc/src/figures/detach_false_primary.odp b/doc/src/figures/detach_false_primary.odp index 8dc358c56..0a1352d6a 100644 Binary files a/doc/src/figures/detach_false_primary.odp and b/doc/src/figures/detach_false_primary.odp differ diff --git a/doc/src/figures/process-diagram.gif b/doc/src/figures/process-diagram.gif index 0bf7ec2df..ae6b3bd27 100644 Binary files a/doc/src/figures/process-diagram.gif and b/doc/src/figures/process-diagram.gif differ diff --git a/doc/src/figures/process-diagram.odp b/doc/src/figures/process-diagram.odp index aa61834eb..41a074ab7 100644 Binary files a/doc/src/figures/process-diagram.odp and b/doc/src/figures/process-diagram.odp differ diff --git a/doc/src/sgml/Makefile.am b/doc/src/sgml/Makefile.am index 35c383738..72bebca42 100644 --- a/doc/src/sgml/Makefile.am +++ b/doc/src/sgml/Makefile.am @@ -5,8 +5,7 @@ DEFS = @DEFS@ \ all: html man1 man8 -GENERATED_SGML = bookindex.sgml version.sgml \ - features-supported.sgml features-unsupported.sgml errcodes-table.sgml +GENERATED_SGML = bookindex.sgml version.sgml ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML) diff --git a/doc/src/sgml/Makefile.in b/doc/src/sgml/Makefile.in deleted file mode 100644 index af322706d..000000000 --- a/doc/src/sgml/Makefile.in +++ /dev/null @@ -1,620 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@STYLE_ENV_SET_TRUE@am__append_1 = -V website-stylesheet -@STYLE_ENV_SET_TRUE@am__append_2 = --param website.stylesheet 1 -subdir = doc/src/sgml -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ $(am__append_2) -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -GENERATED_SGML = bookindex.sgml version.sgml \ - features-supported.sgml features-unsupported.sgml errcodes-table.sgml - -ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML) - -# Sometimes we don't want this one. -ALMOSTALLSGML := $(filter-out %bookindex.sgml,$(ALLSGML)) -SPFLAGS = -wall -wno-unused-param -wno-empty -wfully-tagged -OUTDIR = html - -#jade -G -t sgml -i html -d stylesheet.dsl#html -o abas pgpool-en.sgm -JADE.html.call = $(JADE) $(JADEFLAGS) $(SPFLAGS) $(SGMLINCLUDE) \ - $(CATALOG) -d stylesheet.dsl -t sgml -i output-html \ - $(am__append_1) -JADE.tex.call = $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t tex -V tex-backend -i output-print -i include-index -JADE.rtf.call = $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t rtf -V rtf-backend -i output-print -i include-index -JADE_html = $(JADE) $(SPFLAGS) -d stylesheet.dsl\#html -t sgml -i html -V website-stylesheet -EXTRA_DIST = $(ALLSGML) html man1 man8 stylesheet.dsl stylesheet.css stylesheet-man.xsl stylesheet-common.xsl -FOP = fop -CLEANFILES = *.html *.tex-pdf pgpool-en.rtf pgpool-en.txt html/* HTML.index bookindex.sgml man-stamp man1/* man3/* pgpool.xml -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps doc/src/sgml/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps doc/src/sgml/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - - -all: html man1 man8 - -#if DOCBOOKSTYLE -#CATALOG = -c $(DOCBOOKSTYLE)/catalog -#endif - -#override XSLTPROCFLAGS += --stringparam pgpool.version '$(VERSION)' -override XSLTPROCFLAGS += --stringparam pg.version '$(VERSION)' - -man1 man8 distprep-man: man-stamp - -man-stamp: stylesheet-man.xsl pgpool.xml - $(XMLLINT) --noout --valid pgpool.xml - $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_MAN_FLAGS) $^ - touch $@ - -# The draft target creates HTML output in draft mode, without index (for faster build). -draft: pgpool.sgml $(ALMOSTALLSGML) stylesheet.dsl - $(MKDIR_P) html - $(JADE.html.call) -V draft-mode $< - cp $(srcdir)/stylesheet.css html/ - -html: html-stamp - -html-stamp: pgpool.sgml $(ALLSGML) stylesheet.dsl - $(MKDIR_P) html - $(JADE.html.call) -i include-index $< - cp $(srcdir)/stylesheet.css html/ - cp ../figures/*.gif html - -# single-page HTML -pgpool.html: pgpool.sgml $(ALLSGML) stylesheet.dsl - $(JADE.html.call) -V nochunks -V rootchunk -V '(define %root-filename% #f)' -V '(define use-output-dir #f)' -i include-index $< - -# single-page text -pgpool.txt: pgpool.html - $(LYNX) -force_html -dump -nolist $< > $@ - -HTML.index: pgpool.sgml $(ALMOSTALLSGML) stylesheet.dsl - $(MKDIR_P) html - $(JADE.html.call) -V html-index $< - -bookindex.sgml: HTML.index - LC_ALL=C $(PERL) $(COLLATEINDEX) -f -g -i 'bookindex' -o $@ $< - -# single-page text -#pgpool-en.txt: pgpool-en.html -# $(LYNX) -force_html -dump -nolist $< > $@ - -# single-page HTML -#pgpool-en.html: pgpool-en.sgml $(ALLSGML) stylesheet.dsl -# $(JADE.html.call) -V nochunks -V rootchunk -i include-index $< >$@ - -%.rtf: %.sgml $(ALLSGML) - $(JADE.rtf.call) $< - -%-A4.tex-ps: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texdvi-output -V '%paper-type%'=A4 -o $@ $< - -%-US.tex-ps: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texdvi-output -V '%paper-type%'=USletter -o $@ $< - -%-A4.tex-pdf: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texpdf-output -V '%paper-type%'=A4 -o $@ $< - -%-US.tex-pdf: %.sgml $(ALLSGML) - $(JADE.tex.call) -V texpdf-output -V '%paper-type%'=USletter -o $@ $< - -%.pdf: %.tex-pdf - @rm -f $*.aux $*.log $*.out -# multiple runs are necessary to create proper intra-document links - pdfjadetex $< - pdfjadetex $< - pdfjadetex $< - -#pgpool-en.pdf: pgpool-en-A4.tex-pdf pgpool-en-US.tex-pdf - -# This generates an XML version of the flow-object tree. It's useful -# # for debugging DSSSL code, and possibly to interface to some other -# # tools that can make use of this. -%.fot: %.sgml $(ALLSGML) - $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d stylesheet.dsl -t fot -i output-print -i include-index -o $@ $< - -%.ps: %.dvi - dvips -o $@ $< - -pgpool-en.xml: $(ALLSGML) - $(OSX) -D. -x lower -i include-xslt-index $< >pgpool-en.xmltmp - $(PERL) -p -e 's/\[(aacute|acirc|aelig|agrave|amp|aring|atilde|auml|bull|copy|eacute|egrave|gt|iacute|lt|mdash|nbsp|ntilde|oacute|ocirc|oslash|ouml|pi|quot|scaron|uuml) *\]/\&\1;/gi;' \ - -e '$$_ .= qq{\n} if $$. == 1;' \ - $@ - rm pgpool-en.xmltmp - -pgpool.xml: $(srcdir)/pgpool.sgml $(ALMOSTALLSGML) - $(OSX) -D. -x lower -i include-xslt-index $< >pgpool.xmltmp - $(PERL) -p -e 's/\[(aacute|acirc|aelig|agrave|amp|aring|atilde|auml|bull|copy|eacute|egrave|gt|iacute|lt|mdash|nbsp|ntilde|oacute|ocirc|oslash|ouml|pi|quot|scaron|uuml) *\]/\&\1;/gi;' \ - -e '$$_ .= qq{\n} if $$. == 1;' \ - $@ - rm pgpool.xmltmp - -.PHONY: xslthtml-stamp - -xslthtml: xslthtml-stamp - -xslthtml: xslthtml-stamp - -xslthtml-stamp: stylesheet.xsl pgpool.xml - $(XMLLINT) --noout --valid pgpool.xml - $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $^ - cp $(srcdir)/stylesheet.css html/ - -htmlhelp: stylesheet-hh.xsl pgpool.xml - $(XMLLINT) --noout --valid pgpool.xml - $(XSLTPROC) $(XSLTPROCFLAGS) $^ - -%-A4.fo.tmp: stylesheet-fo.xsl %.xml - $(XMLLINT) --noout --valid $*.xml - $(XSLTPROC) $(XSLTPROCFLAGS) --stringparam paper.type A4 -o $@ $^ - -%-US.fo.tmp: stylesheet-fo.xsl %.xml - $(XMLLINT) --noout --valid $*.xml - $(XSLTPROC) $(XSLTPROCFLAGS) --stringparam paper.type USletter -o $@ $^ - -#xslthtml-stamp: stylesheet.xsl pgpool-en.xml -# $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $^ -# cp $(srcdir)/stylesheet.css html/ - -# reformat FO output so that locations of errors are easier to find -%.fo: %.fo.tmp - $(XMLLINT) --format --output $@ $^ - -epub: pgpool.epub - pgpool.epub: pgpool.xml - $(XMLLINT) --noout --valid $< - $(DBTOEPUB) $< - -version.sgml: $(top_srcdir)/configure - { \ - echo ""; \ - } > $@ - -# tabs are harmless, but it is best to avoid them in SGML files -check-tabs: - @( ! grep ' ' $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml $(srcdir)/*.dsl $(srcdir)/*.xsl) ) || (echo "Tabs appear in SGML/XML files" 1>&2; exit 1) - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/doc/src/sgml/advanced.sgml b/doc/src/sgml/advanced.sgml index c6d9618b2..7bfdd069a 100644 --- a/doc/src/sgml/advanced.sgml +++ b/doc/src/sgml/advanced.sgml @@ -1,23 +1,30 @@ - Watchdog + Watchdog - - Introduction + + Introduction - Watchdog is a sub process of Pgpool-II - to add high availability. Watchdog is used to resolve the single - point of failure by coordinating multiple pgpool-II - nodes. The watchdog was first introduced in pgpool-II - V3.2 and is significantly enhanced in - pgpool-II V3.5, to ensure the presence of a - quorum at all time. This new addition to watchdog makes it more fault tolerant - and robust in handling and guarding against the split-brain syndrome - and network partitioning. However to ensure the quorum mechanism properly - works, the number of pgpool-II nodes must be odd in number and greater than or - equal to 3. + Watchdog is a sub process of + Pgpool-II to add high + availability. Watchdog is used to resolve the single point of + failure by coordinating multiple + Pgpool-II nodes. The watchdog was first + introduced in pgpool-II + V3.2 and is significantly enhanced in + Pgpool-II V3.5, to + ensure the presence of a quorum at all time. This new addition to + watchdog makes it more fault tolerant and robust in handling and + guarding against the split-brain syndrome and network + partitioning. In addition, V3.7 introduced + quorum failover (see ) to reduce the false + positives of PostgreSQL server + failures. To ensure the quorum mechanism properly works, the number + of Pgpool-II nodes must be odd in number + and greater than or equal to 3. @@ -26,25 +33,25 @@ WATCHDOG - - Watchdog coordinates multiple Pgpool-II nodes - by exchanging information with each other. - - - At the startup, if the watchdog is enabled, Pgpool-II node - sync the status of all configured backend nodes from the master watchdog node. - And if the node goes on to become a master node itself it initializes the backend - status locally. When a backend node status changes by failover etc.., - watchdog notifies the information to other Pgpool-II - nodes and synchronizes them. When online recovery occurs, watchdog restricts - client connections to other Pgpool-II - nodes for avoiding inconsistency between backends. - - - - Watchdog also coordinates with all connected Pgpool-II nodes to ensure - that failback, failover and follow_master commands must be executed only on one pgpool-II node. - + + Watchdog coordinates multiple Pgpool-II nodes + by exchanging information with each other. + + + At the startup, if the watchdog is enabled, Pgpool-II node + sync the status of all configured backend nodes from the leader watchdog node. + And if the node goes on to become a leader node itself it initializes the backend + status locally. When a backend node status changes by failover etc.., + watchdog notifies the information to other Pgpool-II + nodes and synchronizes them. When online recovery occurs, watchdog restricts + client connections to other Pgpool-II + nodes for avoiding inconsistency between backends. + + + + Watchdog also coordinates with all connected Pgpool-II nodes to ensure + that failback, failover and follow_primary commands must be executed only on one pgpool-II node. + @@ -54,55 +61,55 @@ WATCHDOG - - Watchdog lifecheck is the sub-component of watchdog to monitor - the health of Pgpool-II nodes participating - in the watchdog cluster to provide the high availability. - Traditionally Pgpool-II watchdog provides - two methods of remote node health checking. "heartbeat" - and "query" mode. - The watchdog in Pgpool-II V3.5 - adds a new "external" to , - which enables to hook an external third party health checking - system with Pgpool-II watchdog. - - - Apart from remote node health checking watchdog lifecheck can also check - the health of node it is installed on by monitoring the connection to upstream servers. - If the monitoring fails, watchdog treats it as the local Pgpool-II - node failure. - - - - In heartbeat mode, watchdog monitors other Pgpool-II - processes by using heartbeat signal. - Watchdog receives heartbeat signals sent by other Pgpool-II - periodically. If there is no signal for a certain period, - watchdog regards this as the failure of the Pgpool-II. - For redundancy you can use multiple network connections for heartbeat - exchange between Pgpool-II nodes. - This is the default and recommended mode to be used for health checking. - - - - In query mode, watchdog monitors Pgpool-II - service rather than process. In this mode watchdog sends queries to other - Pgpool-II and checks the response. - - - Note that this method requires connections from other Pgpool-II, - so it would fail monitoring if the parameter isn't large enough. - This mode is deprecated and left for backward compatibility. - - - - - - external mode is introduced by Pgpool-II - V3.5. This mode basically disables the built in lifecheck - of Pgpool-II watchdog and expects that the external system - will inform the watchdog about health of local and all remote nodes participating in the watchdog cluster. - + + Watchdog lifecheck is the sub-component of watchdog to monitor + the health of Pgpool-II nodes participating + in the watchdog cluster to provide the high availability. + Traditionally Pgpool-II watchdog provides + two methods of remote node health checking. "heartbeat" + and "query" mode. + The watchdog in Pgpool-II V3.5 + adds a new "external" to , + which enables to hook an external third party health checking + system with Pgpool-II watchdog. + + + Apart from remote node health checking watchdog lifecheck can also check + the health of node it is installed on by monitoring the connection to upstream servers. + If the monitoring fails, watchdog treats it as the local Pgpool-II + node failure. + + + + In heartbeat mode, watchdog monitors other Pgpool-II + processes by using heartbeat signal. + Watchdog receives heartbeat signals sent by other Pgpool-II + periodically. If there is no signal for a certain period, + watchdog regards this as the failure of the Pgpool-II. + For redundancy you can use multiple network connections for heartbeat + exchange between Pgpool-II nodes. + This is the default and recommended mode to be used for health checking. + + + + In query mode, watchdog monitors Pgpool-II + service rather than process. In this mode watchdog sends queries to other + Pgpool-II and checks the response. + + + Note that this method requires connections from other Pgpool-II, + so it would fail monitoring if the parameter isn't large enough. + This mode is deprecated and left for backward compatibility. + + + + + + external mode is introduced by Pgpool-II + V3.5. This mode basically disables the built in lifecheck + of Pgpool-II watchdog and expects that the external system + will inform the watchdog about health of local and all remote nodes participating in the watchdog cluster. + @@ -112,28 +119,28 @@ WATCHDOG - - At startup watchdog verifies the Pgpool-II - configuration of the local node for the consistency with the configurations - on the master watchdog node and warns the user of any differences. - This eliminates the likelihood of undesired behavior that can happen - because of different configuration on different Pgpool-II nodes. - + + At startup watchdog verifies the Pgpool-II + configuration of the local node for the consistency with the configurations + on the leader watchdog node and warns the user of any differences. + This eliminates the likelihood of undesired behavior that can happen + because of different configuration on different Pgpool-II nodes. + - Changing active/standby state when certain fault is detected + Changing leader/standby state when certain fault is detected WATCHDOG - - When a fault of Pgpool-II is detected, - watchdog notifies the other watchdogs of it. - If this is the active Pgpool-II, - watchdogs decide the new active Pgpool-II - by voting and change active/standby state. - + + When a fault of Pgpool-II is detected, + watchdog notifies the other watchdogs of it. + If this is the leader Pgpool-II, + watchdogs decide the new leader Pgpool-II + by voting and change leader/standby state. + @@ -142,13 +149,13 @@ WATCHDOG - - When a standby Pgpool-II server promotes to active, - the new active server brings up virtual IP interface. Meanwhile, the previous - active server brings down the virtual IP interface. This enables the active - Pgpool-II to work using the same - IP address even when servers are switched. - + + When a standby Pgpool-II server promotes to leader, + the new leader server brings up virtual IP interface. Meanwhile, the previous + leader server brings down the virtual IP interface. This enables the leader + Pgpool-II to work using the same + IP address even when servers are switched. + @@ -157,12 +164,12 @@ WATCHDOG - - When the broken server recovers or new server is attached, the watchdog process - notifies this to the other watchdogs in the cluster along with the information of the new server, - and the watchdog process receives information on the active server and - other servers. Then, the attached server is registered as a standby. - + + When the broken server recovers or new server is attached, the watchdog process + notifies this to the other watchdogs in the cluster along with the information of the new server, + and the watchdog process receives information on the leader server and + other servers. Then, the attached server is registered as a standby. + @@ -171,54 +178,54 @@ WATCHDOG - - The watchdog process starts and stops automatically as sub-processes - of the Pgpool-II, therefore there is no - dedicated command to start and stop watchdog. - - - Watchdog controls the virtual IP interface, the commands executed by - the watchdog for bringing up and bringing down the VIP require the - root privileges. Pgpool-II requires the - user running Pgpool-II to have root - privileges when the watchdog is enabled along with delegate IP. - This is however not good security practice to run the - Pgpool-II as root user, the alternative - and preferred way is to run the Pgpool-II - as normal user and use either the custom commands for - , , + + The watchdog process starts and stops automatically as sub-processes + of the Pgpool-II, therefore there is no + dedicated command to start and stop watchdog. + + + Watchdog controls the virtual IP interface, the commands executed by + the watchdog for bringing up and bringing down the VIP require the + root privileges. Pgpool-II requires the + user running Pgpool-II to have root + privileges when the watchdog is enabled along with virtual IP. + This is however not good security practice to run the + Pgpool-II as root user, the alternative + and preferred way is to run the Pgpool-II + as normal user and use either the custom commands for + , , and using sudo - or use setuid ("set user ID upon execution") - on if_* commands - - - Lifecheck process is a sub-component of watchdog, its job is to monitor the - health of Pgpool-II nodes participating in - the watchdog cluster. The Lifecheck process is started automatically - when the watchdog is configured to use the built-in life-checking, - it starts after the watchdog main process initialization is complete. - However lifecheck process only kicks in when all configured watchdog - nodes join the cluster and becomes active. If some remote node fails - before the Lifecheck become active that failure will not get caught by the lifecheck. - + or use setuid ("set user ID upon execution") + on if_* commands + + + Lifecheck process is a sub-component of watchdog, its job is to monitor the + health of Pgpool-II nodes participating in + the watchdog cluster. The Lifecheck process is started automatically + when the watchdog is configured to use the built-in life-checking, + it starts after the watchdog main process initialization is complete. + However lifecheck process only kicks in when all configured watchdog + nodes join the cluster and becomes active. If some remote node fails + before the Lifecheck become active that failure will not get caught by the lifecheck. + - + - - Integrating external lifecheck with watchdog + + Integrating external lifecheck with watchdog - - Pgpool-II watchdog process uses the - BSD sockets for communicating with - all the Pgpool-II processes and the - same BSD socket can also be used by any third - party system to provide the lifecheck function for local and remote - Pgpool-II watchdog nodes. - The BSD socket file name for IPC is constructed - by appending Pgpool-II wd_port after - "s.PGPOOLWD_CMD." string and the socket file is - placed in the directory. - + + Pgpool-II watchdog process uses the + BSD sockets for communicating with + all the Pgpool-II processes and the + same BSD socket can also be used by any third + party system to provide the lifecheck function for local and remote + Pgpool-II watchdog nodes. + The BSD socket file name for IPC is constructed + by appending Pgpool-II wd_port after + "s.PGPOOLWD_CMD." string and the socket file is + placed in the directory. + Watchdog IPC command packet format @@ -226,42 +233,42 @@ WATCHDOG - - The watchdog IPC command packet consists of three fields. - Below table details the message fields and description. - - - - Watchdog IPC command packet format - - - - Field - Type - Description - - - - - - TYPE - BYTE1 - Command Type - - - LENGTH - INT32 in network byte order - The length of data to follow - - - DATA - DATA in JSON format - Command data in JSON format - - - - -
+ + The watchdog IPC command packet consists of three fields. + Below table details the message fields and description. + + + + Watchdog IPC command packet format + + + + Field + Type + Description + + + + + + TYPE + BYTE1 + Command Type + + + LENGTH + INT32 in network byte order + The length of data to follow + + + DATA + DATA in JSON format + Command data in JSON format + + + + +
@@ -270,42 +277,42 @@ WATCHDOG - - The watchdog IPC command result packet consists of three fields. - Below table details the message fields and description. - - - - Watchdog IPC result packet format - - - - Field - Type - Description - - - - - - TYPE - BYTE1 - Command Type - - - LENGTH - INT32 in network byte order - The length of data to follow - - - DATA - DATA in JSON format - Command result data in JSON format - - - - -
+ + The watchdog IPC command result packet consists of three fields. + Below table details the message fields and description. + + + + Watchdog IPC result packet format + + + + Field + Type + Description + + + + + + TYPE + BYTE1 + Command Type + + + LENGTH + INT32 in network byte order + The length of data to follow + + + DATA + DATA in JSON format + Command result data in JSON format + + + + +
@@ -314,72 +321,72 @@ WATCHDOG - - The first byte of the IPC command packet sent to watchdog process - and the result returned by watchdog process is identified as the - command or command result type. - The below table lists all valid types and their meanings - - - - Watchdog IPC command packet types - - - - Name - Byte Value - Type - Description - - - - - - REGISTER FOR NOTIFICATIONS - '0' - Command packet - Command to register the current connection to receive watchdog notifications - - - NODE STATUS CHANGE - '2' - Command packet - Command to inform watchdog about node status change of watchddog node - - - GET NODES LIST - '3' - Command packet - Command to get the list of all configured watchdog nodes - - - NODES LIST DATA - '4' - Result packet - The JSON data in packet contains the list of all configured watchdog nodes - - - CLUSTER IN TRANSITION - '7' - Result packet - Watchdog returns this packet type when it is not possible to process the command because the cluster is transitioning. - - - RESULT BAD - '8' - Result packet - Watchdog returns this packet type when the IPC command fails - - - RESULT OK - '9' - Result packet - Watchdog returns this packet type when IPC command succeeds - - - - -
+ + The first byte of the IPC command packet sent to watchdog process + and the result returned by watchdog process is identified as the + command or command result type. + The below table lists all valid types and their meanings + + + + Watchdog IPC command packet types + + + + Name + Byte Value + Type + Description + + + + + + REGISTER FOR NOTIFICATIONS + '0' + Command packet + Command to register the current connection to receive watchdog notifications + + + NODE STATUS CHANGE + '2' + Command packet + Command to inform watchdog about node status change of watchdog node + + + GET NODES LIST + '3' + Command packet + Command to get the list of all configured watchdog nodes + + + NODES LIST DATA + '4' + Result packet + The JSON data in packet contains the list of all configured watchdog nodes + + + CLUSTER IN TRANSITION + '7' + Result packet + Watchdog returns this packet type when it is not possible to process the command because the cluster is transitioning. + + + RESULT BAD + '8' + Result packet + Watchdog returns this packet type when the IPC command fails + + + RESULT OK + '9' + Result packet + Watchdog returns this packet type when IPC command succeeds + + + + +
@@ -388,352 +395,355 @@ WATCHDOG - - "GET NODES LIST" ,"NODES LIST DATA" and "NODE STATUS CHANGE" - IPC messages of watchdog can be used to integration an external - lifecheck systems. Note that the built-in lifecheck of pgpool - also uses the same channel and technique. - + + "GET NODES LIST" ,"NODES LIST DATA" and "NODE STATUS CHANGE" + IPC messages of watchdog can be used to integration an external + lifecheck systems. Note that the built-in lifecheck of pgpool + also uses the same channel and technique. + - - Getting list of configured watchdog nodes + + Getting list of configured watchdog nodes - WATCHDOG + WATCHDOG - - Any third party lifecheck system can send the "GET NODES LIST" - packet on watchdog IPC socket with a JSON - data containing the authorization key and value if - is set or empty packet data - when is not configured to get - the "NODES LIST DATA" result packet. - - - The result packet returnd by watchdog for the "GET NODES LIST" - will contains the list of all configured watchdog nodes to do - health check on in the JSON format. - The JSON of the watchdog nodes contains the - "WatchdogNodes" Array of all watchdog nodes. - Each watchdog JSON node contains the - "ID", "NodeName", - "HostName", "DelegateIP", - "WdPort" and "PgpoolPort" - for each node. - - - - -- The example JSON data contained in "NODES LIST DATA" + + Any third party lifecheck system can send the "GET NODES LIST" + packet on watchdog IPC socket with a JSON + data containing the authorization key and value if + is set or empty packet data + when is not configured to get + the "NODES LIST DATA" result packet. + + + The result packet returned by watchdog for the "GET NODES LIST" + will contains the list of all configured watchdog nodes to do + health check on in the JSON format. + The JSON of the watchdog nodes contains the + "WatchdogNodes" Array of all watchdog nodes. + Each watchdog JSON node contains the + "ID", "NodeName", + "HostName", "DelegateIP", + "WdPort" and "PgpoolPort" + for each node. + + + + -- The example JSON data contained in "NODES LIST DATA" { "NodeCount":3, "WatchdogNodes": - [ - { - "ID":0, - "State":1, - "NodeName":"Linux_ubuntu_9999", - "HostName":"watchdog-host1", - "DelegateIP":"172.16.5.133", - "WdPort":9000, - "PgpoolPort":9999 - }, - { - "ID":1, - "State":1, - "NodeName":"Linux_ubuntu_9991", - "HostName":"watchdog-host2", - "DelegateIP":"172.16.5.133", - "WdPort":9000, - "PgpoolPort":9991 - }, - { - "ID":2, - "State":1, - "NodeName":"Linux_ubuntu_9992", - "HostName":"watchdog-host3", - "DelegateIP":"172.16.5.133", - "WdPort":9000, - "PgpoolPort":9992 - } - ] + [ + { + "ID":0, + "State":1, + "NodeName":"Linux_ubuntu_9999", + "HostName":"watchdog-host1", + "DelegateIP":"172.16.5.133", + "WdPort":9000, + "PgpoolPort":9999 + }, + { + "ID":1, + "State":1, + "NodeName":"Linux_ubuntu_9991", + "HostName":"watchdog-host2", + "DelegateIP":"172.16.5.133", + "WdPort":9000, + "PgpoolPort":9991 + }, + { + "ID":2, + "State":1, + "NodeName":"Linux_ubuntu_9992", + "HostName":"watchdog-host3", + "DelegateIP":"172.16.5.133", + "WdPort":9000, + "PgpoolPort":9992 + } + ] } - -- Note that ID 0 is always reserved for local watchdog node - - - - - After getting the configured watchdog nodes information from the - watchdog the external lifecheck system can proceed with the - health checking of watchdog nodes, and when it detects some status - change of any node it can inform that to watchdog using the - "NODE STATUS CHANGE" IPC messages of watchdog. - The data in the message should contain the JSON - with the node ID of the node whose status is changed - (The node ID must be same as returned by watchdog for that node - in WatchdogNodes list) and the new status of node. - - - - -- The example JSON to inform pgpool-II watchdog about health check - failed on node with ID 1 will look like - - { - "NodeID":1, - "NodeStatus":1, - "Message":"optional message string to log by watchdog for this event" - "IPCAuthKey":"wd_authkey configuration parameter value" - } - - -- NodeStatus values meanings are as follows - NODE STATUS DEAD = 1 - NODE STATUS ALIVE = 2 - - - - + -- Note that ID 0 is always reserved for local watchdog node + + + + + After getting the configured watchdog nodes information from the + watchdog the external lifecheck system can proceed with the + health checking of watchdog nodes, and when it detects some status + change of any node it can inform that to watchdog using the + "NODE STATUS CHANGE" IPC messages of watchdog. + The data in the message should contain the JSON + with the node ID of the node whose status is changed + (The node ID must be same as returned by watchdog for that node + in WatchdogNodes list) and the new status of node. + + + + -- The example JSON to inform pgpool-II watchdog about health check + failed on node with ID 1 will look like + + { + "NodeID":1, + "NodeStatus":1, + "Message":"optional message string to log by watchdog for this event" + "IPCAuthKey":"wd_authkey configuration parameter value" + } + + -- NodeStatus values meanings are as follows + NODE STATUS DEAD = 1 + NODE STATUS ALIVE = 2 + + + + -
- - Restrictions on watchdog + + + Restrictions on watchdog + + + WATCHDOG + - + + Watchdog restriction with query mode lifecheck + WATCHDOG - - Watchdog restriction with query mode lifecheck - - WATCHDOG - - - - In query mode, when all the DB nodes are detached from a - Pgpool-II due to PostgreSQL server - failure or pcp_detach_node issued, watchdog regards that the - Pgpool-II service is in the down - status and brings the virtual IP assigned to watchdog down. - Thus clients of Pgpool-II cannot - connect to Pgpool-II using the - virtual IP any more. This is neccessary to avoid split-brain, - that is, situations where there are multiple active - Pgpool-II. - - - - - Connecting to <productname>Pgpool-II</productname> whose watchdog status is down - - WATCHDOG - - - Don't connect to Pgpool-II in down - status using the real IP. Because a Pgpool-II - in down status can't receive information from other - Pgpool-II watchdogs so it's backend status - may be different from other the Pgpool-II. - - - - - <productname>Pgpool-II</productname> whose watchdog status is down requires restart - - WATCHDOG - - - Pgpool-II in down status can't become active - nor the standby Pgpool-II. - Recovery from down status requires the restart of Pgpool-II. - - - - - Watchdog promotion to active takes few seconds - - WATCHDOG - - - After the active Pgpool-II stops, - it will take a few seconds until the standby Pgpool-II - promote to new active, to make sure that the former virtual IP is - brought down before a down notification packet is sent to other - Pgpool-II. - - - - - - Architecure of the watchdog + + In query mode, when all the DB nodes are detached from a + Pgpool-II due to PostgreSQL server + failure or pcp_detach_node issued, watchdog regards that the + Pgpool-II service is in the down + status and brings the virtual IP assigned to watchdog down. + Thus clients of Pgpool-II cannot + connect to Pgpool-II using the + virtual IP any more. This is necessary to avoid split-brain, + that is, situations where there are multiple leader + Pgpool-II. + + + + Connecting to <productname>Pgpool-II</productname> whose watchdog status is down + + WATCHDOG + + + Don't connect to Pgpool-II in down + status using the real IP. Because a Pgpool-II + in down status can't receive information from other + Pgpool-II watchdogs so it's backend status + may be different from other the Pgpool-II. + + + + + <productname>Pgpool-II</productname> whose watchdog status is down requires restart + + WATCHDOG + + + Pgpool-II in down status can't become active + nor the standby Pgpool-II. + Recovery from down status requires the restart of Pgpool-II. + + + + + Watchdog promotion to active takes few seconds + + WATCHDOG + + + After the leader Pgpool-II stops, + it will take a few seconds until the standby Pgpool-II + promote to new leader, to make sure that the former virtual IP is + brought down before a down notification packet is sent to other + Pgpool-II. + + + + + + Architecture of the watchdog + + + Watchdog is a sub process of Pgpool-II, + which adds the high availability and resolves the single point of + failure by coordinating multiple Pgpool-II. + The watchdog process automatically starts (if enabled) when the + Pgpool-II starts up and consists of two + main components, Watchdog core and the lifecheck system. + + + + Watchdog Core + + Watchdog core referred as a "watchdog" is a + Pgpool-II child process that + manages all the watchdog related communications with the + Pgpool-II nodes present in the + cluster and also communicates with the Pgpool-II + parent and lifecheck processes. + + + The heart of a watchdog process is a state machine that starts + from its initial state (WD_LOADING) and transit + towards either standby (WD_STANDBY) or + leader/coordinator (WD_COORDINATOR) state. + Both standby and leader/coordinator states are stable states of the + watchdog state machine and the node stays in standby or + leader/coordinator state until some problem in local + Pgpool-II node is detected or a + remote Pgpool-II disconnects from the cluster. + + + The watchdog process performs the following tasks: + + + + + Manages and coordinates the local node watchdog state. + + + + + + Interacts with built-in or external lifecheck system + for the of local and remote Pgpool-II + node health checking. + + + + + + Interacts with Pgpool-II main + process and provides the mechanism to + Pgpool-II parent process for + executing the cluster commands over the watchdog channel. + + + + + + Communicates with all the participating Pgpool-II + nodes to coordinate the selection of + leader/coordinator node and to ensure the quorum in the cluster. + + + + + + Manages the Virtual-IP on the leader/coordinator node and + allow the users to provide custom scripts for + escalation and de-escalation. + + + + + + Verifies the consistency of Pgpool-II + configurations across the participating Pgpool-II + nodes in the watchdog cluster. + + + + + + Synchronize the status of all PostgreSQL backends at startup. + + + + + + Provides the distributed locking facility to + Pgpool-II main process + for synchronizing the different failover commands. + + + + + + + Communication with other nodes in the Cluster + + Watchdog uses TCP/IP sockets for all the communication with other nodes. + Each watchdog node can have two sockets opened with each node. One is the + outgoing (client) socket which this node creates and initiate the + connection to the remote node and the second socket is the one which + is listening socket for inbound connection initiated by remote + watchdog node. As soon as the socket connection to remote node succeeds + watchdog sends the ADD NODE (WD_ADD_NODE_MESSAGE) + message on that socket. And upon receiving the ADD NODE message the + watchdog node verifies the node information encapsulated in the message + with the Pgpool-II configurations for that node, and if the node passes + the verification test it is added to the cluster otherwise the connection + is dropped. + + + + + IPC and data format - Watchdog is a sub process of Pgpool-II, - which adds the high availability and resolves the single point of - failure by coordinating multiple Pgpool-II. - The watchdog process automatically starts (if enabled) when the - Pgpool-II starts up and consists of two - main components, Watchdog core and the lifecheck system. + Watchdog process exposes a UNIX domain socket + for IPC communications, which accepts and provides the data in + JSON format. All the internal Pgpool-II + processes, including Pgpool-II's + built-in lifecheck and Pgpool-II main process + uses this IPC socket interface to interact with the watchdog. + This IPC socket can also be used by any external/3rd party system + to interact with watchdog. + + See for details + on how to use watchdog IPC interface for integrating external/3rd party systems. + + + + + + Watchdog Lifecheck + + Watchdog lifecheck is the sub-component of watchdog that monitors the health + of Pgpool-II nodes participating in the watchdog + cluster. Pgpool-II watchdog provides three built-in + methods of remote node health checking, "heartbeat", "query" and "external" mode. + + + In "heartbeat" mode, The lifecheck process sends and receives the data over + UDP socket to check the availability of remote nodes and + for each node the parent lifecheck process spawns two child process one for + sending the heartbeat signal and another for receiving the heartbeat. + While in "query" mode, The lifecheck process uses the PostgreSQL libpq + interface for querying the remote Pgpool-II. + And in this mode the lifecheck process creates a new thread for each health + check query which gets destroyed as soon as the query finishes. + While in "external" mode, this mode disables the built in lifecheck of + Pgpool-II, and expects that the external system + will monitor local and remote node instead. + + + Apart from remote node health checking watchdog lifecheck can also check the + health of node it is installed on by monitoring the connection to upstream servers. + For monitoring the connectivity to the upstream server Pgpool-II + lifecheck uses execv() function to executes + 'ping -q -c3 hostname' command. + So a new child process gets spawned for executing each ping command. + This means for each health check cycle a child process gets created and + destroyed for each configured upstream server. + For example, if two upstream servers are configured in the lifecheck and it is + asked to health check at ten second intervals, then after each ten second + lifecheck will spawn two child processes, one for each upstream server, + and each process will live until the ping command is finished. + + - - Watchdog Core - - Watchdog core referred as a "watchdog" is a - Pgpool-II child process that - manages all the watchdog related communications with the - Pgpool-II nodes present in the - cluster and also communicates with the Pgpool-II - parent and lifecheck processes. - - - The heart of a watchdog process is a state machine that starts - from its initial state (WD_LOADING) and transit - towards either standby (WD_STANDBY) or - master/coordinator (WD_COORDINATOR) state. - Both standby and master/coordinator states are stable states of the - watchdog state machine and the node stays in standby or - master/coordinator state until some problem in local - Pgpool-II node is detected or a - remote Pgpool-II disconnects from the cluster. - - - The watchdog process performs the following tasks: - - - - - Manages and coordinates the local node watchdog state. - - - - - - Interacts with built-in or external lifecheck system - for the of local and remote Pgpool-II - node health checking. - - - - - - Interacts with Pgpool-II main - process and provides the mechanism to - Pgpool-II parent process for - executing the cluster commands over the watchdog channel. - - - - - - Communicates with all the participating Pgpool-II - nodes to coordinate the selection of - master/coordinator node and to ensure the quorum in the cluster. - - - - - - Manages the Virtual-IP on the active/coordinator node and - allow the users to provide custom scripts for - escalation and de-escalation. - - - - - - Verifies the consistency of Pgpool-II - configurations across the participating Pgpool-II - nodes in the watchdog cluster. - - - - - - Synchronize the status of all PostgreSQL backends at startup. - - - - - - Provides the distributed locking facility to - Pgpool-II main process - for synchronizing the different failover commands. - - - - - - - Communication with other nodes in the Cluster - - Watchdog uses TCP/IP sockets for all the communication with other nodes. - Each watchdog node can have two sockets opened with each node. One is the - outgoing (client) socket which this node creates and initiate the - connection to the remote node and the second socket is the one which - is listening socket for inbound connection initiated by remote - watchdog node. As soon as the socket connection to remote node succeeds - watchdog sends the ADD NODE (WD_ADD_NODE_MESSAGE) - message on that socket. And upon receiving the ADD NODE message the - watchdog node verifies the node information encapsulated in the message - with the Pgpool-II configurations for that node, and if the node passes - the verification test it is added to the cluster otherwise the connection - is dropped. - - - - - IPC and data format - - Watchdog process exposes a UNIX domain socket - for IPC communications, which accepts and provides the data in - JSON format. All the internal Pgpool-II - processes, including Pgpool-II's - built-in lifecheck and Pgpool-II main process - uses this IPC socket interface to interact with the watchdog. - This IPC socket can also be used by any external/3rd party system - to interact with watchdog. - - - See for details - on how to use watchdog IPC interface for integrating external/3rd party systems. - - - - - - Watchdog Lifecheck - - Watchdog lifecheck is the sub-component of watchdog that monitors the health - of Pgpool-II nodes participating in the watchdog - cluster. Pgpool-II watchdog provides two built-in - methods of remote node health checking, "heartbeat" and "query" mode. - - - In "heartbeat" mode, The lifecheck process sends and receives the data over - UDP socket to check the availability of remote nodes and - for each node the parent lifecheck process spawns two child process one for - sending the heartbeat signal and another for receiving the heartbeat. - While in "query" mode, The lifecheck process uses the PostgreSQL libpq - interface for querying the remote Pgpool-II. - And in this mode the lifecheck process creates a new thread for each health - check query which gets destroyed as soon as the query finishes. - - - Apart from remote node health checking watchdog lifecheck can also check the - health of node it is installed on by monitoring the connection to upstream servers. - For monitoring the connectivity to the upstream server Pgpool-II - lifecheck uses execv() function to executes - 'ping -q -c3 hostname' command. - So a new child process gets spawned for executing each ping command. - This means for each health check cycle a child process gets created and - destroyed for each configured upstream server. - For example, if two upstream servers are configured in the lifecheck and it is - asked to health check at ten second intervals, then after each ten second - lifecheck will spawn two child processes, one for each upstream server, - and each process will live until the ping command is finished. - - - - +
diff --git a/doc/src/sgml/biblio.sgml b/doc/src/sgml/biblio.sgml new file mode 100644 index 000000000..24558b719 --- /dev/null +++ b/doc/src/sgml/biblio.sgml @@ -0,0 +1,34 @@ + + + + Bibliography + + + Proceedings and Articles + + + + <ulink + url="http://www.vldb.org/pvldb/vol2/vldb09-694.pdf">Pangea: An + Eager Database Replication Middleware guaranteeing Snapshot + Isolation without modification of Database Servers</ulink> + + + Takeshi + Mishima + + + Hiroshi + Nakamura + + + + + VLDB Conference + Aug. 2009 +
Lyon, France
+
+
+ +
+
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index a8d1adbd4..791855743 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -1,832 +1,1265 @@ - Client Authentication - - - client authentication + Client Authentication + + + client authentication + + + + Since Pgpool-II is a middleware that works between + PostgreSQL servers and + a PostgreSQL database client, so when a + client application connects to + the Pgpool-II, Pgpool-II + in turn connects to the PostgreSQL servers + using the same credentials to serve the incoming client + connection. Thus, all the access privileges and restrictions defined + for the user in PostgreSQL gets + automatically applied to all Pgpool-II + clients, with an exceptions of the authentications + on PostgreSQL side that depends on the + client's IP addresses or host names. Reason being the connections + to the PostgreSQL server are made + by Pgpool-II on behalf of the connecting + clients and PostgreSQL server can only + see the IP address of the + Pgpool-II server and not that of the actual client. + Therefore, for the client host based authentications Pgpool-II has the + pool_hba mechanism similar to the pg_hba mechanism for + authenticating the incoming client connections. + + + The pool_passwd file manages passwords for + authentication used when clients connect + to Pgpool-II + (see for more details). The + passwords registered on pool_passwd must match + with the passwords registered + on PostgreSQL. Note that passwords + changed on PostgreSQL are not + automatically sync to the passwords + on pool_passwd. scram-shar-256 + authentication and MD5 + authentication require that the user name and the password + have been already registered on pool_passwd, + while clear text password + authentication + or does not + require that. Therefore, if you want to avoid maintaining + the pool_passwd, it would be worth to + check clear text password + authentication + or . + + + + The <filename>pool_hba.conf</filename> File + + + pool_hba.conf - Since Pgpool-II is a middleware that works between - PostgreSQL servers and - a PostgreSQL database client, so when a - client application connects to - the Pgpool-II, Pgpool-II - inturn connects to the PostgreSQL servers - using the same credentials to serve the incomming client - connection. Thus, all the access privileges and restrictions defined - for the user in PostgreSQL gets - automatically applied to all Pgpool-II - clients, with an exceptions of the authentications - on PostgreSQL side that depends on the - client's IP addresses or host names. Reason being the connections - to the PostgreSQL server are made - by Pgpool-II on behalf of the connecting - clients and PostgreSQL server can only - see the IP address of the - Pgpool-II server and not that of the actual client. - Therefore, for the client host based authentications Pgpool-II has the - pool_hba mechanism similar to the pg_hba mechanism for - authenticating the incomming client connections. + Just like the pg_hba.conf file for PostgreSQL, + Pgpool-II supports a similar client authentication + function using a configuration file called pool_hba.conf. + If Pgpool-II is installed from source code, it also includes the sample + pool_hba.conf.sample file in the default + configuration directory ("/usr/local/etc"). + By default, pool_hba authentication is disabled, and + setting enable_pool_hba + to on enables it. see + the configuration + parameter. - - The <filename>pool_hba.conf</filename> File + + + If number of PostgreSQL servers is + only one, or when running in raw mode + (see ), + pool_hba.conf is not necessary + thus enable_pool_hba may be being set to off. + In this case the client authentication method is completely + managed by PostgreSQL. Also number + of PostgreSQL servers is more than + one, or not running in raw + mode, enable_pool_hba may be being set to off + as long as the authentication method defined + by PostgreSQL + is trust. + + - - pool_hba.conf - + + The format of the pool_hba.conf file + follows very + closely PostgreSQL's pg_hba.conf + format. + + + The general format of the pool_hba.conf file is + a set of records, one per line. Blank lines are ignored, as is any + text after the # comment character. + Records cannot be continued across lines. + A record is made + up of a number of fields which are separated by spaces and/or tabs. + Fields can contain white space if the field value is double-quoted. + Quoting one of the keywords in a database, user, or address field (e.g., + all or replication) makes + the word lose its special meaning, and just match a database, user, or + host with that name. + - - Just like the pg_hba.conf file for PostgreSQL, - Pgpool-II supports a similar client authentication - function using a configuration file called pool_hba.conf. - Pgpool-II installation also includes the sample - pool_hba.conf.sample file in the default - configuration directory ("/usr/local/etc"). - By default, pool_hba authentication is disabled, and - setting enable_pool_hba - to on enables it. see - the configuration - parameter. - + + Each record specifies a connection type, a client IP address + range (if relevant for the connection type), a database name, a + user name, and the authentication method to be used for + connections matching these parameters. The first record with a + matching connection type, client address, requested database, + and user name is used to perform authentication. There is + no fall-through or + backup: if one record is chosen and the authentication + fails, subsequent records are not considered. If no record matches, + access is denied. + - - The format of the pool_hba.conf file - follows very - closely PostgreSQL's pg_hba.conf - format. - - - The general format of the pool_hba.conf file is - a set of records, one per line. Blank lines are ignored, as is any - text after the # comment character. - Records cannot be continued across lines. - A record is made - up of a number of fields which are separated by spaces and/or tabs. - Fields can contain white space if the field value is double-quoted. - Quoting one of the keywords in a database, user, or address field (e.g., - all or replication) makes - the word lose its special meaning, and just match a database, user, or - host with that name. - + + A record can have one of the following formats + + local database user auth-method auth-options + + 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 + + host database user address auth-method auth-options + hostssl database user address auth-method auth-options + hostnossl database user address auth-method auth-options + + The meaning of the fields is as follows: + + + + local + + + This record matches connection attempts using Unix-domain + sockets. Without a record of this type, Unix-domain socket + connections are disallowed. + + + - - Each record specifies a connection type, a client IP address - range (if relevant for the connection type), a database name, a - user name, and the authentication method to be used for - connections matching these parameters. The first record with a - matching connection type, client address, requested database, - and user name is used to perform authentication. There is - no fall-through or - backup: if one record is chosen and the authentication - fails, subsequent records are not considered. If no record matches, - access is denied. - + + host + + + This record matches connection attempts made using TCP/IP. + host records match either + SSL or non-SSL connection + attempts. + + + + Remote TCP/IP connections will not be possible unless + the server is started with an appropriate value for the + configuration parameter, + since the default behavior is to listen for TCP/IP connections + only on the local loopback address localhost. + + + + - - A record can have one of the following formats - - local database user auth-method auth-options - - 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 - - host database user address auth-method auth-options - hostssl database user address auth-method auth-options - hostnossl database user address auth-method auth-options - - The meaning of the fields is as follows: - - - - local - - - This record matches connection attempts using Unix-domain - sockets. Without a record of this type, Unix-domain socket - connections are disallowed. - - - + + hostssl + + + This record matches connection attempts made using TCP/IP, but only + when the connection is made with SSL encryption. + + + To make use of this option the Pgpool-II must be + built with SSL support. Furthermore, SSL must be enabled by setting the + configuration parameter. Otherwise, the hostssl record is ignored. + + + - - host - - - This record matches connection attempts made using TCP/IP. - host records match either - SSL or non-SSL connection - attempts. - - - - Remote TCP/IP connections will not be possible unless - the server is started with an appropriate value for the - configuration parameter, - since the default behavior is to listen for TCP/IP connections - only on the local loopback address localhost. - - - - + + hostnossl + + + This record type has the opposite behavior of hostssl; it only matches connection + attempts made over TCP/IP that do not use SSL. + + + - - hostssl - - - This record matches connection attempts made using TCP/IP, but only - when the connection is made with SSL encryption. - - - To make use of this option the Pgpool-II must be - built with SSL support. Furthermore, SSL must be enabled by setting the - configuration parameter. Otherwise, the hostssl record is ignored. - - - + + database + + + Specifies which database name(s) this record matches. The value + all specifies that it matches all databases. + + + "samegroup" for database field is not supported: + + + Since Pgpool-II does not know anything about + users in the PostgreSQL backend server, the database name is simply + compared against the entries in the database field of pool_hba.conf. + + + + + - - hostnossl - - - This record type has the opposite behavior of hostssl; it only matches connection - attempts made over TCP/IP that do not use SSL. - - - + + user + + + Specifies which database user name(s) this record + matches. The value all specifies that it + matches all users. Otherwise, this is the name of a specific + database user + + + group names following "+" for user field is not supported: + + + This is for the same reason as for the "samegroup" of database field. + A user name is simply checked against the entries in the user field of + pool_hba.conf. + + + + + - - database - - - Specifies which database name(s) this record matches. The value - all specifies that it matches all databases. - - - "samegroup" for database field is not supported: - - - Since Pgpool-II does not know anything about - users in the PostgreSQL backend server, the database name is simply - compared against the entries in the database field of pool_hba.conf. - - - - - + + address + + + Specifies the client machine address(es) that this record matches. + This field can contain either a host name, an IP address range, + or one of the special key words mentioned below. + - - user - - - Specifies which database user name(s) this record - matches. The value all specifies that it - matches all users. Otherwise, this is the name of a specific - database user - - - group names following "+" for user field is not supported: - - - This is for the same reason as for the "samegroup" of database field. - A user name is simply checked against the entries in the user field of - pool_hba.conf. - - - - - + + An IP address range is specified using standard numeric notation for + the range's starting address, then a slash (/) + and a CIDR mask length. + The mask length indicates the number of high-order bits of the client + IP address that must match. Bits to the right of this should be zero + in the given IP address. There must not be any white space between the + IP address, the /, and the CIDR mask length. + - - address - - - Specifies the client machine address(es) that this record matches. - This field can contain either a host name, an IP address range, - or one of the special key words mentioned below. - - - - An IP address range is specified using standard numeric notation for - the range's starting address, then a slash (/) - and a CIDR mask length. - The mask length indicates the number of high-order bits of the client - IP address that must match. Bits to the right of this should be zero - in the given IP address. There must not be any white space between the - IP address, the /, and the CIDR mask length. - - - - Typical examples of an IPv4 address range specified this way are - 172.20.143.89/32 for a single host, or - 172.20.143.0/24 for a small network, or - 10.6.0.0/16 for a larger one. - An IPv6 address range might look like ::1/128 for - a single host (in this case the IPv6 loopback address) or - fe80::7a31:c1ff:0000:0000/96 for a small network. - 0.0.0.0/0 represents all IPv4 addresses, and - ::0/0 represents all IPv6 addresses. To specify a - single host, use a mask length of 32 for IPv4 or 128 for IPv6. - In a network address, do not omit trailing zeroes. - - - - An entry given in IPv4 format will match only IPv4 connections, and - an entry given in IPv6 format will match only IPv6 connections, even - if the represented address is in the IPv4-in-IPv6 range. - Note that entries in IPv6 format will be rejected if the system's C - library does not have support for IPv6 addresses. - - - - You can also write all to match any IP address, - samehost to match any - of the server's own IP addresses, or samenet to match any address in - any subnet that the server is directly connected to. - - - - If a host name is specified (anything that is not an IP address range or - a special key word is treated as a host name), that name is compared with - the result of a reverse name resolution of the client's IP address - (e.g., reverse DNS lookup, if DNS is used). Host name comparisons are - case insensitive. If there is a match, then a forward name resolution - (e.g., forward DNS lookup) is performed on the host name to check whether - any of the addresses it resolves to are equal to the client's IP address. - If both directions match, then the entry is considered to match. - (The host name that is used in pool_hba.conf should be the one that - address-to-name resolution of the client's IP address returns, otherwise - the line won't be matched. Some host name databases allow associating an - IP address with multiple host names, but the operating system will only - return one host name when asked to resolve an IP address.) - - - - A host name specification that starts with a dot (.) matches - a suffix of the actual host name. So .example.com would match - foo.example.com (but not just example.com). - - - - When host names are specified in pool_hba.conf, you should - make sure that name resolution is reasonably fast. It can be of advantage to - set up a local name resolution cache such as nscd. - - - - This field only applies to host, hostssl, and hostnossl records. - - - Specifying the host name in address field is not supported prior to - Pgpool-II V3.7. - - - + + Typical examples of an IPv4 address range specified this way are + 172.20.143.89/32 for a single host, or + 172.20.143.0/24 for a small network, or + 10.6.0.0/16 for a larger one. + An IPv6 address range might look like ::1/128 for + a single host (in this case the IPv6 loopback address) or + fe80::7a31:c1ff:0000:0000/96 for a small network. + 0.0.0.0/0 represents all IPv4 addresses, and + ::0/0 represents all IPv6 addresses. To specify a + single host, use a mask length of 32 for IPv4 or 128 for IPv6. + In a network address, do not omit trailing zeroes. + - - IP-address - IP-mask - - - These two fields can be used as an alternative to the - IP-address/ - mask-length notation. - Instead of specifying the mask length, the actual mask - is specified in a separate column. For - example, 255.0.0.0 represents an - IPv4 CIDR mask length - of 8, - and 255.255.255.255 represents a - CIDR mask length of 32. - - - - This field only applies to host, hostssl, and hostnossl records. - + + An entry given in IPv4 format will match only IPv4 connections, and + an entry given in IPv6 format will match only IPv6 connections, even + if the represented address is in the IPv4-in-IPv6 range. + Note that entries in IPv6 format will be rejected if the system's C + library does not have support for IPv6 addresses. + - - + + You can also write all to match any IP address, + samehost to match any + of the server's own IP addresses, or samenet to match any address in + any subnet that the server is directly connected to. + - - auth-method - - - Specifies the authentication method to use when a connection matches - this record. The possible choices are summarized here; details - are in . - - - - trust - - - Allow the connection unconditionally. This method - allows anyone that can connect to the - Pgpool-II. - - - - - - reject - - - Reject the connection unconditionally. This is useful for - filtering out certain hosts, for example a - reject line could block a specific - host from connecting. - - - - - - md5 - - - Require the client to supply a double-MD5-hashed password for - authentication. - - - - To use md5 authentication, you need to register - the user name and password in file. - See for more details. - - - - - - - - scram-sha-256 - - - Perform SCRAM-SHA-256 authentication to verify the user's password. - - - To use scram-sha-256 authentication, you need to register - the user name and password in file. - See for more details. - - - - - - - - cert - - - Authenticate using SSL client certificates. - See for more details. - - - - - - pam - - - Authenticate using the Pluggable Authentication Modules - (PAM) service provided by the operating system. - See for details. - - - PAM authentication is supported using user information on the host - where Pgpool-II is running. - To enable PAM support the Pgpool-II - must be configured with "--with-pam" - - - To enable PAM authentication, you must create a - service-configuration file - for Pgpool-II in the system's PAM - configuration directory (that is usually located - at "/etc/pam.d"). A sample - service-configuration file is also installed - as "share/pgpool.pam" under the install - directory. - - - - - - - - + + If a host name is specified (anything that is not an IP address range or + a special key word is treated as a host name), that name is compared with + the result of a reverse name resolution of the client's IP address + (e.g., reverse DNS lookup, if DNS is used). Host name comparisons are + case insensitive. If there is a match, then a forward name resolution + (e.g., forward DNS lookup) is performed on the host name to check whether + any of the addresses it resolves to are equal to the client's IP address. + If both directions match, then the entry is considered to match. + (The host name that is used in pool_hba.conf should be the one that + address-to-name resolution of the client's IP address returns, otherwise + the line won't be matched. Some host name databases allow associating an + IP address with multiple host names, but the operating system will only + return one host name when asked to resolve an IP address.) + - - auth-options - - - After the auth-method field, - there can be field(s) of the - form name= - value - that specify options for the authentication method. - - - - - + + A host name specification that starts with a dot (.) matches + a suffix of the actual host name. So .example.com would match + foo.example.com (but not just example.com). + - - Since the pool_hba.conf records are examined - sequentially for each connection attempt, the order of the records - is significant. Typically, earlier records will have tight - connection match parameters and weaker authentication methods, while - later records will have looser match parameters and stronger - authentication methods. For example, one might wish to - use trust authentication for local TCP/IP - connections but require a password for remote TCP/IP connections. In - this case a record specifying - trust authentication for connections from 127.0.0.1 would - appear before a record specifying password authentication for a wider - range of allowed client IP addresses. - + + When host names are specified in pool_hba.conf, you should + make sure that name resolution is reasonably fast. It can be of advantage to + set up a local name resolution cache such as nscd. + - - All pool_hba authentication options described in this section are - about the authentication taking place between a client and the - Pgpool-II. A client still has to go - through the PostgreSQL's authentication - process and must have the CONNECT privilege for - the database on the backend PostgreSQL - server. + This field only applies to host, hostssl, and hostnossl records. - As far as pool_hba is concerned, it does not matter if a user name - and/or database name given by a client - (i.e. psql -U testuser testdb) - really exists in the backend. pool_hba only cares if a match in the - pool_hba.conf can be found or not. + Specifying the host name in address field is not supported prior to + Pgpool-II V3.7. - - - - Some examples of pool_hba.conf entries. - See the next section for details on the different authentication methods. - - - - Example <filename>pool_hba.conf</filename> Entries - - # Allow any user on the local system to connect to any database with - # any database user name using Unix-domain sockets (the default for local - # connections). - # - # TYPE DATABASE USER ADDRESS METHOD - local all all trust - - # The same using local loopback TCP/IP connections. - # - # TYPE DATABASE USER ADDRESS METHOD - host all all 127.0.0.1/32 trust - - # Allow any user from host 192.168.12.10 to connect to database - # "postgres" if the user's password is correctly supplied. - # - # TYPE DATABASE USER ADDRESS METHOD - host postgres all 192.168.12.10/32 md5 - - - - - - Authentication Methods - - The following subsections describe the authentication methods in more detail. - - - - Trust Authentication + + + + IP-address + IP-mask + - When trust authentication is specified, - Pgpool-II assumes that anyone who can - connect to the server is authorized to access connect with - whatever database user name they specify. + These two fields can be used as an alternative to the + IP-address/ + mask-length notation. + Instead of specifying the mask length, the actual mask + is specified in a separate column. For + example, 255.0.0.0 represents an + IPv4 CIDR mask length + of 8, + and 255.255.255.255 represents a + CIDR mask length of 32. - - - - MD5 Password Authentication - - - MD5 - - This authentication method is the password-based authentication - methods in which MD-5-hashed password is sent by client. - Since Pgpool-II does not has the - visibility of PostgreSQL's database - user password and client application only sends the MD5-hash of - the password, so md5 authentication - in Pgpool-II is supported using the - authentication file. + This field only applies to host, hostssl, and hostnossl records. - - - If Pgpool-II is operated in raw - mode or there's only 1 backend configured, you don't need to - setup . - - + + - - Authentication file format - - To use the md5 authentication - authentication file - must contain the user password in either plain text - md5 or AES encrypted format. - - - The file should contain lines in the following format: - - "username:plain_text_passwd" - - - "username:encrypted_passwd" - - - + + auth-method + + + Specifies the authentication method to use when a connection matches + this record. The possible choices are summarized here; details + are in . - - Setting md5 Authentication - - MD5 - + + + trust + + + Allow the connection unconditionally. This method + allows anyone that can connect to the + Pgpool-II. + + + - - here are the steps to enable md5 - authentication: - - - 1- Login as the database's operating system user and type - "pg_md5 --md5auth --username=username password" user name - and md5 encrypted password are registered - into . If pool_passwd does not exist yet, pg_md5 - command will automatically create it for you. - - - user name and password must be identical to those registered - in PostgreSQL server. - - - + + reject + + + Reject the connection unconditionally. This is useful for + filtering out certain hosts, for example a + reject line could block a specific + host from connecting. + + + - - 2- Add an appropriate md5 entry to pool_hba.conf. - See for more details. - - - 3- After changing md5 password (in both pool_passwd - and PostgreSQL of course), reload - the pgpool configurations. - - + + md5 + + + Require the client to supply a double-MD5-hashed password for + authentication. - + + + To use md5 + authentication, you need to register the + user name and password + in file. + See for more + details. If you don't want to manage + password by + using pool_passwd, + you could + use . + + + + + - - scram-sha-256 Authentication + + scram-sha-256 + + + Perform SCRAM-SHA-256 authentication to verify the user's password. + + + To use scram-sha-256 + authentication, you need to register the + user name and password + in file. + See for more + details. If you don't want to manage + password by + using pool_passwd, + you could + use . + + + + + - - SCRAM - + + cert + + + Authenticate using SSL client certificates. + See for more details. + + + + + pam + + + Authenticate using the Pluggable Authentication Modules + (PAM) service provided by the operating system. + See for details. + + + PAM authentication is supported using user information on the host + where Pgpool-II is running. + To enable PAM support the Pgpool-II + must be configured with "--with-pam" + + + To enable PAM authentication, you must create a + service-configuration file + for Pgpool-II in the system's PAM + configuration directory (that is usually located + at "/etc/pam.d"). A sample + service-configuration file is also installed + as "share/pgpool.pam" under the install + directory. + + + + + + ldap + + + Authenticate using LDAP server. + See for more details. + + + To enable LDAP support the Pgpool-II + must be configured with "--with-ldap" + + + + + + + + + + auth-options + - This authentication method also known as SCRAM is a - challenge-response based authentication that prevents the - password sniffing on untrusted connections. - Since Pgpool-II does not has the - visibility of PostgreSQL's database user - password, so SCRAM authentication is supported using the - authentication file. + After the auth-method field, + there can be field(s) of the + form name= + value + that specify options for the authentication method. + + + + - - Authentication file entry for SCRAM - - - To use the SCRAM authentication - authentication file - must contain the user password in either plain text - or AES encrypted format. - - - "username:plain_text_passwd" - - - "username:AES_encrypted_passwd" - - - - md5 type user passwords in - file can't be used for - scram authentication - - - - - - - Setting scram-sha-256 Authentication - - SCRAM - - - - Here are the steps to enable scram-sha-256 - authentication: - - - 1- Create file entry - for database user and password in plain text or AES - encrypted format. - The utility that comes with Pgpool-II - can be used to create the AES encrypted password - entries in the file. - - - User name and password must be identical to those registered - in the PostgreSQL server. - - - + + Since the pool_hba.conf records are examined + sequentially for each connection attempt, the order of the records + is significant. Typically, earlier records will have tight + connection match parameters and weaker authentication methods, while + later records will have looser match parameters and stronger + authentication methods. For example, one might wish to + use trust authentication for local TCP/IP + connections but require a password for remote TCP/IP connections. In + this case a record specifying + trust authentication for connections from 127.0.0.1 would + appear before a record specifying password authentication for a wider + range of allowed client IP addresses. + - - 2- Add an appropriate scram-sha-256 entry to pool_hba.conf. - See for more details. - - - 3- After changing SCRAM password (in both pool_passwd - and PostgreSQL of course), reload - the Pgpool-II configuration. - - + + + All pool_hba authentication options described in this section are + about the authentication taking place between a client and the + Pgpool-II. A client still has to go + through the PostgreSQL's authentication + process and must have the CONNECT privilege for + the database on the backend PostgreSQL + server. + + + As far as pool_hba is concerned, it does not matter if a user name + and/or database name given by a client + (i.e. psql -U testuser testdb) + really exists in the backend. pool_hba only cares if a match in the + pool_hba.conf can be found or not. + + - + + Some examples of pool_hba.conf entries. + See the next section for details on the different authentication methods. + - - Certificate Authentication + + Example <filename>pool_hba.conf</filename> Entries + + # Allow any user on the local system to connect to any database with + # any database user name using Unix-domain sockets (the default for local + # connections). + # + # TYPE DATABASE USER ADDRESS METHOD + local all all trust + + # The same using local loopback TCP/IP connections. + # + # TYPE DATABASE USER ADDRESS METHOD + host all all 127.0.0.1/32 trust + + # Allow any user from host 192.168.12.10 to connect to database + # "postgres" if the user's password is correctly supplied. + # + # TYPE DATABASE USER ADDRESS METHOD + host postgres all 192.168.12.10/32 md5 + + + + + + Authentication Methods + + The following subsections describe the authentication methods + specified by pool_hba.conf in more detail. + - - Certificate - + + Trust Authentication + + + When trust authentication is specified, + Pgpool-II assumes that anyone who can + connect to the server is authorized to access connect with + whatever database user name they specify. + + + + + Clear Text Password Authentication + + + The method password sends the password in + clear-text and is therefore vulnerable to password + sniffing attacks. It should always be avoided if + possible. If the connection is protected by SSL encryption then + password can be used safely, though. For this + sake, it is recommended to use hostssl in + pool_hba.conf so that clients are enforced to + use SSL encryption. + + + A benefit to use the method is, the password for authentication is + provided by client side and pool_passwd is + not consulted. So you can avoid maintaining + pool_passwd file. + + + You can avoid maintaining pool_passwd by + using as well + but it does not enforce to use SSL encryption because + pool_hba.conf cannot be used with the + parameter. + + + + + MD5 Password Authentication + + + MD5 + + + + This authentication method is the password-based authentication + methods in which MD-5-hashed password is sent by client. + Since Pgpool-II does not has the + visibility of PostgreSQL's database + user password and client application only sends the MD5-hash of + the password, so md5 authentication + in Pgpool-II is supported using the + authentication file. + + + + Authentication file format + + To use the md5 authentication + authentication file must contain + the user password in either plain text, AES + or md5 encrypted format. + + + The file should contain lines in the following format: + + "username:TEXT_plain_text_passwd" + + + "username:AES_encrypted_passwd" + + + "username:md5_encrypted_passwd" + + (Actually "_" after "TEXT", "AES" or "md5" does not exist.) + + - - This authentication method uses SSL client certificates - to perform authentication. It is therefore only available for SSL connections. - When using this authentication method, the Pgpool-II - will require that the client provide a valid certificate. - No password prompt will be sent to the client. - The cn (Common Name) attribute of the certificate will be - compared to the requested database user name, and if they match the login will - be allowed. - + + Setting md5 Authentication + + MD5 + + + here are the steps to enable md5 + authentication: + + + 1- Login as the database's operating system user and type + "pg_md5 --config-file=path_to_pgpool.conf --md5auth --username=username password" user name + and md5 encrypted password are registered + into . If pool_passwd does not exist yet, pg_md5 + command will automatically create it for you. - - The certificate authentication works between client and - Pgpool-II, for the - backend authentication you can use any other authentication method - + + user name and password must be identical to those registered + in PostgreSQL server. + + - + + 2- Add an appropriate md5 entry to pool_hba.conf. + See for more details. + If pool_hba.conf is not enabled, make sure + that md5 authentication is specified + in pg_hba.conf + of PostgreSQL. + + + 3- After changing md5 password (in both pool_passwd + and PostgreSQL of course), reload + the pgpool configurations. + + - - PAM Authentication + - - PAM - + + scram-sha-256 Authentication - - This authentication method uses PAM (Pluggable - Authentication Modules) as the authentication mechanism. The - default PAM service name is pgpool. - PAM authentication is supported using user information on - the host where Pgpool-II is executed. - For more - information about PAM, please read the - - Linux-PAM Page. - + + SCRAM + - - To enable PAM authentication, you need to create a service-configuration - file for Pgpool-II in the system's - PAM configuration directory (which is usually at "/etc/pam.d"). - A sample service-configuration file is installed as - "share/pgpool-II/pgpool.pam" under the install directory. - + + This authentication method also known as SCRAM is a + challenge-response based authentication that prevents the + password sniffing on untrusted connections. + Since Pgpool-II does not has the + visibility of PostgreSQL's database user + password, so SCRAM authentication is supported using the + authentication file. + + + + Authentication file entry for SCRAM + + To use the SCRAM authentication + authentication file + must contain the user password in either plain text + or AES encrypted format. + + + "username:TEXT_plain_text_passwd" + + + "username:AES_encrypted_passwd" + + (Actually "_" after "TEXT" or "AES" does not exist.) - - To enable PAM support the Pgpool-II - must be configured with "--with-pam" - + + md5 type user passwords in + file can't be used for + scram authentication + - - - - - Using different methods for frontend and backend authentication + + - - AUTH + + Setting scram-sha-256 Authentication + + SCRAM - Since Pgpool-IIV4.0 - it possible to use different authentication for client application - and backend PostgreSQL servers. - For example, a client application can use scram-sha-256 - to connect to Pgpool-II which - in turn can use trust or md5 - authentication to connect to PostgreSQL - backend for the same session. + Here are the steps to enable scram-sha-256 + authentication: + + + 1- Create file entry + for database user and password in plain text or AES + encrypted format. + The utility that comes with Pgpool-II + can be used to create the AES encrypted password + entries in the file. + + + User name and password must be identical to those registered + in the PostgreSQL server. + + + + + 2- Add an appropriate scram-sha-256 entry to pool_hba.conf. + See for more details. + If pool_hba.conf is not enabled, make sure that md5 authentication is specified in pg_hba.conf of PostgreSQL. + + + 3- After changing SCRAM password (in both pool_passwd + and PostgreSQL of course), reload + the Pgpool-II configuration. - + - - Using AES256 encrypted passwords in <xref linkend="guc-pool-passwd"> + - - AUTH - + + Certificate Authentication - - SCRAM authentication guards against the man-in-the-middle - type of attack, so Pgpool-II requires the user password - to authenticate with the PostgreSQL backend. - + + Certificate + + + This authentication method uses SSL client certificates + to perform authentication. It is therefore only available for SSL connections. + When using this authentication method, the Pgpool-II + will require that the client provide a valid certificate. + No password prompt will be sent to the client. + The cn (Common Name) attribute of the certificate will be + compared to the requested database user name, and if they match the login will + be allowed. + + + - However, storing the clear text passwords in the "pool_passwd" file - is not a good idea. + The certificate authentication works between only client and + Pgpool-II. The certificate + authentication does not work between + Pgpool-II and + PostgreSQL. For backend + authentication you can use any other authentication method. + + + + + + PAM Authentication + + + PAM + + + + This authentication method uses PAM (Pluggable + Authentication Modules) as the authentication mechanism. The + default PAM service name is pgpool. + PAM authentication is supported using user information on + the host where Pgpool-II is executed. + For more + information about PAM, please read the + + Linux-PAM Page. + + + + To enable PAM authentication, you need to create a service-configuration + file named for Pgpool-II in the system's + PAM configuration directory (which is usually at "/etc/pam.d"). + + + - You can instead store AES256 encrypted passwords, which will be used for authentication. - The password is first encrypted using the AES256 encryption with the user provided key - and then the encrypted password is base64 encoded and - an AES prefix is added to the encoded string. - - - You can use the utility to create the properly - formatted AES256 encrypted password. - - + To enable PAM support the Pgpool-II + must be configured with "--with-pam" + + + + + LDAP Authentication + + + LDAP + + + + This authentication method uses LDAP as the password certification method. + LDAP is used only to validate the user name/password pairs. Therefore the user must + already exist in the database before LDAP can be used for authentication. + + + + LDAP authentication can operate in two modes. In the first mode, which we + will call the simple bind mode, the server will bind to the distinguished + name constructed as + prefix username suffix. + Typically, the prefix parameter is used to specify + cn=, or DOMAIN\ + in an Active Directory environment. suffix is used + to specify the remaining part of the DN in a non-Active Directory environment. + + + + In the second mode, which we will call the search+bind mode, the server first + binds to the LDAP directory with a fixed user name and password, specified + with ldapbinddn and ldapbindpasswd, + and performs a search for the user trying to log in to the database. If no + user and password is configured, an anonymous bind will be attempted to the + directory. The search will be performed over the subtree at + ldapbasedn, and will try to do an exact match of + the attribute specified in ldapsearchattribute. + Once the user has been found in this search, the server disconnects and + re-binds to the directory as this user, using the password specified by the + client, to verify that the login is correct. This mode is the same as that + used by LDAP authentication schemes in other software, such as Apache + mod_authnz_ldap and pam_ldap. This + method allows for significantly more flexibility in where the user objects + are located in the directory, but will cause two separate connections to the + LDAP server to be made. + + + + The following configuration options are used in both modes: + + + ldapserver + + + Names or IP addresses of LDAP servers to connect to. Multiple servers + may be specified, separated by spaces. + + + + + ldapport + + + Port number on LDAP server to connect to. If no port is specified, the + LDAP library's default port setting will be used. + + + + + ldapscheme + + + Set to ldaps to use LDAPS. This is a non-standard + way of using LDAP over SSL, supported by some LDAP server implementations. + See also the ldaptls option for an alternative. + + + + + ldaptls + + + Set to 1 to make the connection between Pgpool-II and the LDAP server + use TLS encryption. This uses the StartTLS operation + per RFC 4513. See also the ldapscheme option for an alternative. + + + + + + + + Note that using ldapscheme or + ldaptls only encrypts the traffic between the + Pgpool-II server and the LDAP server. The connection between the + Pgpool-II server and the client will still be unencrypted + unless SSL is used there as well. + + + + The following options are used in simple bind mode only: + + + ldapprefix + + + String to prepend to the user name when forming the DN to bind as, + when doing simple bind authentication. + + + + + ldapsuffix + + + String to append to the user name when forming the DN to bind as, + when doing simple bind authentication. + + + + + + + + The following options are used in search+bind mode only: + + + ldapbasedn + + + Root DN to begin the search for the user in, when doing search+bind + authentication. + + + + + ldapbinddn + + + DN of user to bind to the directory with to perform the search when + doing search+bind authentication. + + + + + ldapbindpasswd + + + Password for user to bind to the directory with to perform the search + when doing search+bind authentication. + + + + + ldapsearchattribute + + + Attribute to match against the user name in the search when doing + search+bind authentication. If no attribute is specified, the + uid attribute will be used. + + + + + ldapsearchfilter + + + The search filter to use when doing search+bind authentication. + Occurrences of $username will be replaced with the + user name. This allows for more flexible search filters than + ldapsearchattribute. + + + + + ldapurl + + + An RFC 4516 LDAP URL. This is an alternative way to write some of the + other LDAP options in a more compact and standard form. The format is + +ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] + + scope must be one of base, + one, sub, typically the last. + (The default is base, which is normally not useful + in this application.) attribute can nominate + a single attribute, in which case it is used as a value for ldapsearchattribute. + If attribute is empty then filter + can be used as a value for ldapsearchfilter. + - - Creating encrypted password entries - - can be used to create AES - encrypted password entries in file. - requires the key for encrypting the password entries. - Later that same key will be required by Pgpool-II - to decrypt the passwords to use for authentication. - - - Pgpool-II must be built with SSL - (--with-openssl) support to use the encrypted password feature. - - + + The URL scheme ldaps chooses the LDAPS method for + making LDAP connections over SSL, equivalent to using ldapscheme=ldaps. + To use encrypted LDAP connections using the StartTLS + operation, use the normal URL scheme ldap and specify the + ldaptls option in addition to ldapurl. - - - - Providing decryption key to <productname>Pgpool-II</productname> - - - If you have AES encrypted passwords stored in the - file, then Pgpool-II - will require the decryption key to decrypt the passwords before using them, - Pgpool-II tries to read the decryption key at - startup from the .pgpoolkey file. - - - By default the Pgpool-II will look for the - .pgpoolkey file in the user's home directory or the file - referenced by environment variable PGPOOLKEYFILE. - You can also specify the key file using the (-k, --key-file=KEY_FILE) - command line argument to the command. - The permissions on .pgpoolkey must disallow any access to world or group. - Change the file permissions by the command chmod 0600 ~/.pgpoolkey. + + + For non-anonymous binds, ldapbinddn and + ldapbindpasswd must be specified as separate options. + + + + + backend_use_passwd + + + Set to 1 to make the password used for LDAP authentication use authentication + between Pgpool-II and backend. - + + + + + + + It is an error to mix configuration options for simple bind with options + for search+bind. + + + + When using search+bind mode, the search can be performed using a single + attribute specified with ldapsearchattribute, or using + a custom search filter specified with + ldapsearchfilter. + Specifying ldapsearchattribute=foo is equivalent to + specifying ldapsearchfilter="(foo=$username)". If neither + option is specified the default is + ldapsearchattribute=uid. + + + + If Pgpool-II 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: + +host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" + + When a connection to the database server as database + user foo is requested, Pgpool-II will attempt to + bind to the LDAP server using the DN cn=foo, dc=example, + dc=net and the password provided by the client. If that connection + succeeds, the database access is granted. + + + + Here is an example for a search+bind configuration: + +host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid + + When a connection to the database server as database + user foo is requested, Pgpool-II will attempt to + bind anonymously (since ldapbinddn was not specified) to + the LDAP server, perform a search for (uid=foo) + under the specified base DN. If an entry is found, it will then attempt to + bind using that found information and the password supplied by the client. + If that second connection succeeds, the database access is granted. + + + + Here is the same search+bind configuration written as a URL: + +host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" + + Some other software that supports authentication against LDAP uses the + same URL format, so it will be easier to share the configuration. + + + + Here is an example for a search+bind configuration that uses + ldapsearchfilter instead of + ldapsearchattribute to allow authentication by + user ID or email address: + +host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))" + + + + + 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 + parts of a DN, it is often necessary to use double-quoted parameter + values when configuring LDAP options, as shown in the examples. + + + + + + To enable LDAP support the Pgpool-II + must be configured with "--with-ldap" + + + + + GSSAPI Authentication + + GSSAPI + + + + GSSAPI is an industry-standard protocol for secure authentication + defined in RFC 2743. Currently + Pgpool-II does not support GSSAPI. + Clients should not use GSSAPI authentication, or should use + "prefer GSSAPI authentication if possible" option (this is the + default setting of PostgreSQL clients). + If latter is chosen, Pgpool-II requests + non-GSSAPI authentication to client, and the clients will fall + back to non-GSSAPI authentication method. Thus, usually users do + not need to worry about that Pgpool-II + does not accept GSSAPI authentication. + + + + + + Using different methods for frontend and backend authentication + + + AUTH + + + + Since Pgpool-IIV4.0 + it possible to use different authentication for client application + and backend PostgreSQL servers. + For example, a client application can use scram-sha-256 + to connect to Pgpool-II which + in turn can use trust or md5 + authentication to connect to PostgreSQL + backend for the same session. + + + - + + Using AES256 encrypted passwords in <xref linkend="guc-pool-passwd"> + + + AUTH + + + + SCRAM authentication guards against the man-in-the-middle + type of attack, so Pgpool-II requires the user password + to authenticate with the PostgreSQL backend. + + + + However, storing the clear text passwords in the "pool_passwd" file + is not a good idea. + + + You can instead store AES256 AES256 encrypted passwords, which will be used for authentication. + The password is first encrypted using the AES256 encryption with the user provided key + and then the encrypted password is base64 encoded and + an AES prefix is added to the encoded string. + + + You can use the utility to create the properly + formatted AES256 encrypted password. + + + + + + Creating encrypted password entries + + can be used to create AES + encrypted password entries in file. + requires the key for encrypting the password entries. + Later that same key will be required by Pgpool-II + to decrypt the passwords to use for authentication. + + + Pgpool-II must be built with SSL + (--with-openssl) support to use the encrypted password feature. + + + + + + + Providing decryption key to <productname>Pgpool-II</productname> + + + If you have AES encrypted passwords stored in the + file, then Pgpool-II + will require the decryption key to decrypt the passwords before using them, + Pgpool-II tries to read the decryption key at + startup from the .pgpoolkey file. + pgpoolkey + PGPOOLKEYFILE + .pgpoolkey is a plain text file which + contains the decryption key string. + + + By default the Pgpool-II will look for the + .pgpoolkey file in the user's home directory or the file + referenced by environment variable PGPOOLKEYFILE. + You can also specify the key file using the (-k, --key-file=KEY_FILE) + command line argument to the command. + The permissions on .pgpoolkey must disallow any access to world or group. + Change the file permissions by the command chmod 0600 ~/.pgpoolkey. + + + + diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index e9e573eaa..542217d09 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,152 +1,195 @@ - Server Configuration - - - configuration - of the server - - - - There are many configuration parameters that affect the behavior of - Pgpool-II. In the first section of this chapter we - describe how to interact with configuration parameters. The subsequent sections - discuss each parameter in detail. - - - - Setting Parameters - - - Parameter Names and Values - - - All parameter names are case-insensitive. Every parameter takes a - value of one of five types: boolean, string, integer, floating point, - or enumerated (enum). The type determines the syntax for setting the - parameter: - - - - - - Boolean: - Values can be written as - on, - off, - true, - false, - yes, - no, - 1, - 0 - (all case-insensitive) or any unambiguous prefix of one of these. - - + Server Configuration + + + configuration + of the server + + + + There are many configuration parameters that affect the behavior of + Pgpool-II. In the first section of this chapter we + describe how to interact with configuration parameters. The subsequent sections + discuss each parameter in detail. + + + + Setting Parameters + + + Parameter Names and Values + + + All parameter names are case-insensitive. Every parameter takes a + value of one of five types: boolean, string, integer, floating point, + or enumerated (enum). The type determines the syntax for setting the + parameter: + + + + + + Boolean: + Values can be written as + on, + off, + true, + false, + yes, + no, + 1, + 0 + (all case-insensitive) or any unambiguous prefix of one of these. + + - - - String: - 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. - - + + + String: + 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. + + + + + + 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 with Unit: + The numeric parameters that describe the quantities of + memory or time have an implicit unit. + The unit might be kilobytes, megabytes, milliseconds, + seconds, or minutes. + For example: + + + search_primary_node_timeout = 6min + memqcache_total_size = 64MB + + An unadorned numeric value for one of these settings will use + the parameter's default unit. + - Numeric (integer and floating point): - A decimal point is permitted only for floating-point parameters. - Do not use thousands separators. Quotes are not required. + The unit name is case-sensitive, and there can be whitespace between the numeric value and the unit. - + Valid memory units are kB (kilobytes), MB (megabytes), GB (gigabytes), and TB (terabytes). + Valid time units are ms (milliseconds), s (seconds), min (minutes), h (hours), and d (days). - - + + + + Enumerated: Enumerated-type parameters are written in the same way as string parameters, but are restricted to have one of a limited set of values. Enum parameter values are case-insensitive. - - - - + + + + - - Parameter Interaction via the Configuration File + + Parameter Interaction via the Configuration File - + The most fundamental way to set these parameters is to edit the file pgpool.confpgpool.conf, - which is located in $prefix/etc/pgpool.conf. - An example of what this file might look like is: + which is located in $prefix/etc/pgpool.conf, if it + installed from source code. An example of what this file might look like is: + + # This is a comment + listen_addresses = 'localhost' + port = 9999 + serialize_accept = off + reset_query_list = 'ABORT; DISCARD ALL' + + + One parameter is specified per line. The equal sign between name and + value is optional. Whitespace is insignificant (except within a quoted + parameter value) and blank lines are + ignored. Hash marks (#) designate the remainder + of the line as a comment. Parameter values that are not simple + identifiers or numbers must be single-quoted. To embed a single + quote in a parameter value, write either two quotes (preferred) + or backslash-quote. + + + + Parameters set in this way provide default values for the cluster. + The settings seen by active sessions will be these values unless they + are overridden. The following sections describe ways in which the + administrator or user can override these defaults. + + + + + SIGHUP + + The configuration file is reread whenever the main server process + receives a SIGHUP signal; this signal is most easily + sent by running pgpool reload from the command line. The main + pgpool process also propagates this signal to all its child + processes, so that next sessions also adopt the new values. + Some parameters can only be set at server start; any changes to their + entries in the configuration file will be ignored until the server is restarted. + Invalid parameter settings in the configuration file are likewise + ignored (but logged) during SIGHUP processing. + + + + + Managing Configuration File Contents + + + Pgpool-II provides a feature for breaking down + pgpool.conf files into sub-files. This feature is + especially useful when managing multiple servers or dividing by features. + include directive can be used like this: + - # This is a comment - listen_addresses = 'localhost' - port = 9999 - serialize_accept = off - reset_query_list = 'ABORT; DISCARD ALL' + include = 'filename' - One parameter is specified per line. The equal sign between name and - value is optional. Whitespace is insignificant (except within a quoted - parameter value) and blank lines are - ignored. Hash marks (#) designate the remainder - of the line as a comment. Parameter values that are not simple - identifiers or numbers must be single-quoted. To embed a single - quote in a parameter value, write either two quotes (preferred) - or backslash-quote. - - - - Parameters set in this way provide default values for the cluster. - The settings seen by active sessions will be these values unless they - are overridden. The following sections describe ways in which the - administrator or user can override these defaults. - - - - - SIGHUP - - The configuration file is reread whenever the main server process - receives a SIGHUP signal; this signal is most easily - sent by running pgpool reload from the command line. The main - pgpool process also propagates this signal to all its child - processes, so that existing sessions also adopt the new values. - Some parameters can only be set at server start; any changes to their - entries in the configuration file will be ignored until the server is restarted. - Invalid parameter settings in the configuration file are likewise - ignored (but logged) during SIGHUP processing. - + If the file name is not an absolute path, it is taken as relative + to the directory containing the referencing configuration file. + Inclusions can be nested. + - - Parameter Interaction via SQL Clients + + Parameter Interaction via SQL Clients - - Pgpool-II also provides two SQL style - commands to interact with session-local configuration settings. - + + Pgpool-II also provides two SQL style + commands to interact with session-local configuration settings. + - + - - The command allows inspection of the - current value of all parameters. - + + The command allows inspection of the + current value of all parameters. + - - The command allows modification of the - current value of those parameters that can be set locally to a - session; it has no effect on other sessions. - + + The command allows modification of the + current value of those parameters that can be set locally to a + session; it has no effect on other sessions. + - + - +
diff --git a/doc/src/sgml/connection-pooling.sgml b/doc/src/sgml/connection-pooling.sgml index b61d893bb..982ab1870 100644 --- a/doc/src/sgml/connection-pooling.sgml +++ b/doc/src/sgml/connection-pooling.sgml @@ -1,719 +1,1089 @@ - Connection Pooling - - - Pgpool-II maintains established - connections to the PostgreSQL servers, and reuses them whenever a - new connection with the same properties (i.e. user name, database, - protocol version) comes in. It reduces the connection overhead, - and improves system's overall throughput. - - - - Connection Pooling Settings - - - - - connection_cache (boolean) - - connection_cache configuration parameter - - - - - Caches connections to backends when set to on. Default is on. - However, connections to template0, template1, - postgres and regression databases are not cached even if - connection_cache is on. - - - You need to restart Pgpool-II - if you change this value. - - - - - - max_pool (integer) - - max_pool configuration parameter - - - - - The maximum number of cached connections - in each Pgpool-II child - process. Pgpool-II reuses the - cached connection if an incoming connection is connecting - to the same database with the same user name. If not, - Pgpool-II creates a new - connection to the backend. If the number of cached - connections exceeds max_pool, the oldest connection will - be discarded, and uses that slot for the new connection. - - - Default value is 4. Please be aware that the number of - connections from Pgpool-II processes to the backends may reach - num_init_children * max_pool in total. - - - This parameter can only be set at server start. - - - - - - listen_backlog_multiplier (integer) - - listen_backlog_multiplier configuration parameter - - - - - Specifies the length of connection queue from frontend to - Pgpool-II. The queue length (actually - "backlog" parameter of listen() - system call) is defined as - listen_backlog_multiplier * . - - - - Some systems have the upper limit of the backlog parameter of - listen() system call. - See for more details. - - - - Default is 2. - - - This parameter can only be set at server start. - - - - - - serialize_accept (boolean) - - serialize_accept configuration parameter - - - - - When set to on, Pgpool-II enables the serialization - on incoming client connections. - Without serialization the OS kernel wakes up all of the - Pgpool-II children processes to execute accept() and one of them - actually gets the incoming connection. The problem here is, because so my child - process wake up at a same time, heavy context switching occurs and the - performance is affected. - - - This phenomena is a well known classic problem called - "the thundering herd problem". This can be solved by the - serialization of the accept() calls, so that only one - Pgpool-II process gets woken up - for incoming connection to execute the accept() - . - - - - But serialization has its own overheads, and it is recomended - to be used only with the larger values of . - For the small number of , - the serialize accept can degrade the performance because of - serializing overhead. - - - - - It is recomended to do a benchmark before deciding wether to use - serialize_accept or not, because the corelation - of and serialize_accept - can be different on different environments. - - - - - Using pgbench to decide if serialize_accept should be used - - To run the pgbench use the following - command. - -pgbench -n -S -p 9999 -c 32 -C -S -T 300 test - - Here, -C tells pgbench to connect - to database each time a transaction gets executed. -c 32 - specifies the number of the concurrent sessions to Pgpool-II. - You should change this according to your system's requirement. - After pgbench finishes, check the number from - "including connections establishing". - - - - - - When is enabled, serialize_accept - has no effect. Make sure that you set to 0 if you intend - to turn on the serialize_accept. - And if you are worried about Pgpool-II process memory leaks - or whatever potential issue, you could use instead. - This is purely an implementation limitation and may be removed in the future. - - - - - Default is off. - - - This parameter can only be set at server start. - - - - - - child_life_time (integer) - - child_life_time configuration parameter - - - - - Specifies the time in seconds to terminate a Pgpool-II - child process if it remains idle. The new child process - is immediately spawned by Pgpool-II when it - is terminated because of child_life_time. - child_life_time is a measure to prevent the - memory leaks and other unexpected errors in Pgpool-II - children. - - - - child_life_time does not apply to - processes that have not accepted any connection yet. - - - - - becomes ineffective when - child_life_time is enabled. - - - - Default is 300 (5 minutes) and setting it to 0 disables the feature. - - - This parameter can only be set at server start. - - - - - - client_idle_limit (integer) - - client_idle_limit configuration parameter - - - - - Specifies the time in seconds to disconnect a client if it remains idle - since the last query. - This is useful for preventing the Pgpool-II - children from being occupied by a lazy clients or broken TCP/IP - connection between client and Pgpool-II. - - - - client_idle_limit is ignored in - the second stage of online recovery. - - - - The default is 0, which turns off the feature. - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - child_max_connections (integer) - - child_max_connections configuration parameter - - - - - Specifies the lifetime of a Pgpool-II - child process in terms of the number of client connections it can receive. - Pgpool-II will terminate the child process - after it has served child_max_connections client - connections and will immediately spawn a new child process to take its place. - - - child_max_connections is useful on a very busy server, - where and - never gets triggered. It is also useful to prevent the PostgreSQL servers from getting - too big. - - - The default is 0, which turns off the feature. - - - This parameter can only be set at server start. - - - - - - connection_life_time (integer) - - connection_life_time configuration parameter - - - - - Specifies the time in seconds to terminate the cached connections - to the PostgreSQL backend. This serves as the cached connection expiration time. - - - The default is 0, which means the cached connections will not be disconnected. - - - This parameter can only be set at server start. - - - - - - reset_query_list (string) - - reset_query_list configuration parameter - - - - - Specifies the SQL commands to be sent to reset the backend connection - when exiting the user session. Multiple commands can be specified by delimiting each - by ";". - - - - The available commands differ among PostgreSQL versions. - Below are some recommended settings for reset_query_list - on different PostgreSQL versions. - Note, however, that ABORT command should be always included. - - - - Recommended setting for <varname>reset_query_list</varname> - on different PostgreSQL versions - - - - PostgreSQL version - reset_query_list - - - - - - 7.1 or earlier - 'ABORT' - - - - 7.2 to 8.2 - 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' - - - - 8.3 or later - 'ABORT; DISCARD ALL' - - - - -
- - - - "ABORT" is not issued when not in a transaction block for 7.4 or later - PostgreSQL versions. - - - - Default is 'ABORT; DISCARD ALL'. - - - This parameter can be changed by reloading the Pgpool-II configurations. - -
-
- -
-
+ Connection Pooling + + + Pgpool-II maintains established + connections to the PostgreSQL servers, and reuses them whenever a + new connection with the same properties (i.e. user name, database, + protocol version) comes in. It reduces the connection overhead, + and improves system's overall throughput. + + + + Connection Pooling Settings + + + + + connection_cache (boolean) + + connection_cache configuration parameter + + + + + Caches connections to backends when set to on. Default is on. + However, connections to template0, template1, + postgres and regression databases are not cached even if + connection_cache is on. + + + You need to restart Pgpool-II + if you change this value. + + + + + + max_pool (integer) + + max_pool configuration parameter + + + + + The maximum number of cached connections + in each Pgpool-II child + process. Pgpool-II reuses the + cached connection if an incoming connection is connecting + to the same database with the same user name and the same + run-time parameters. If not, + Pgpool-II creates a new + connection to the backend. If the number of cached + connections exceeds max_pool, the oldest connection will + be discarded, and uses that slot for the new connection. + + + Default value is 4. Please be aware that the number of + connections from Pgpool-II processes to the backends may reach + num_init_children * max_pool in total. + + + This parameter can only be set at server start. + + + + + + listen_backlog_multiplier (integer) + + listen_backlog_multiplier configuration parameter + + + + + Specifies the length of connection queue from frontend to + Pgpool-II. The queue length (actually + "backlog" parameter of listen() + system call) is defined as + listen_backlog_multiplier * . + + + + Some systems have the upper limit of the backlog parameter of + listen() system call. + See for more details. + + + + Default is 2. + + + This parameter can only be set at server start. + + + + + + serialize_accept (boolean) + + serialize_accept configuration parameter + + + + + When set to on, Pgpool-II enables the serialization + on incoming client connections. + Without serialization the OS kernel wakes up all of the + Pgpool-II children processes to execute accept() and one of them + actually gets the incoming connection. The problem here is, because so my child + process wake up at a same time, heavy context switching occurs and the + performance is affected. + + + This phenomena is a well known classic problem called + "the thundering herd problem". This can be solved by the + serialization of the accept() calls, so that only one + Pgpool-II process gets woken up + for incoming connection to execute the accept() + . + + + + But serialization has its own overheads, and it is recommended + to be used only with the larger values of . + For the small number of , + the serialize accept can degrade the performance because of + serializing overhead. + + + + + It is recommended to do a benchmark before deciding whether to use + serialize_accept or not, because the correlation + of and serialize_accept + can be different on different environments. + + + + + Using pgbench to decide if serialize_accept should be used + + To run the pgbench use the following + command. + + pgbench -n -S -p 9999 -c 32 -C -S -T 300 test + + Here, -C tells pgbench to connect + to database each time a transaction gets executed. -c 32 + specifies the number of the concurrent sessions to Pgpool-II. + You should change this according to your system's requirement. + After pgbench finishes, check the number from + "including connections establishing". + + + + + + When is enabled, serialize_accept + has no effect. Make sure that you set to 0 if you intend + to turn on the serialize_accept. + And if you are worried about Pgpool-II process memory leaks + or whatever potential issue, you could use instead. + This is purely an implementation limitation and may be removed in the future. + + + + + Default is off. + + + This parameter can only be set at server start. + + + + + + child_life_time (integer) + + child_life_time configuration parameter + + + + + Specifies the time in seconds to terminate + a Pgpool-II + child process if it remains idle because no client is connecting to it. + The new child process + is immediately spawned by Pgpool-II when it + is terminated because of child_life_time. + child_life_time is a measure to prevent the + memory leaks and other unexpected errors in Pgpool-II + + children. + + + + child_life_time does not apply to + processes that have not accepted any connection yet. + + + + + becomes ineffective when + child_life_time is enabled. + + + + Default is 300 (5 minutes) and setting it to 0 disables the feature. + + + This parameter can only be set at server start. + + + + + + client_idle_limit (integer) + + client_idle_limit configuration parameter + + + + + Specifies the time in seconds to disconnect a client if it remains idle + since the last query. + This is useful for preventing the Pgpool-II + children from being occupied by a lazy clients or broken TCP/IP + connection between client and Pgpool-II. + + + + client_idle_limit is ignored in + the second stage of online recovery. + + + + The default is 0, which turns off the feature. + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + child_max_connections (integer) + + child_max_connections configuration parameter + + + + + Specifies the lifetime of a Pgpool-II + child process in terms of the number of client connections it can receive. + Pgpool-II will terminate the child process + after it has served child_max_connections client + connections and will immediately spawn a new child process to take its place. + + + child_max_connections is useful on a very busy server, + where and + never gets triggered. It is also useful to prevent the PostgreSQL servers from getting + too big. + + + The default is 0, which turns off the feature. + + + This parameter can only be set at server start. + + + + + + connection_life_time (integer) + + connection_life_time configuration parameter + + + + + Specifies the time in seconds to terminate the cached connections + to the PostgreSQL backend. This serves as the cached connection expiration time. + + + If a client connects to the process which holds the cached + connections, a calculation on + the connection_life_time is not performed + until the client disconnects. Thus it is possible that the cached + connections are kept for longer time than this value. To avoid + this, it is recommended to set shorter value + to . + + + The default is 0, which means the cached connections will not be + disconnected. + + + This parameter can only be set at server start. + + + + + + reset_query_list (string) + + reset_query_list configuration parameter + + + + + Specifies the SQL commands to be sent to reset the backend connection + when exiting the user session. Multiple commands can be specified by delimiting each + by ";". + + + + The available commands differ among PostgreSQL versions. + Below are some recommended settings for reset_query_list + on different PostgreSQL versions. + Note, however, that ABORT command should be always included. + + + + Recommended setting for <varname>reset_query_list</varname> + on different PostgreSQL versions + + + + PostgreSQL version + reset_query_list + + + + + + 7.1 or earlier + 'ABORT' + + + + 7.2 to 8.2 + 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' + + + + 8.3 or later + 'ABORT; DISCARD ALL' + + + + +
+ + + + "ABORT" is not issued when not in a transaction block for 7.4 or later + PostgreSQL versions. + + + + Default is 'ABORT; DISCARD ALL'. + + + This parameter can be changed by reloading the Pgpool-II configurations. + +
+
+ +
+
- Error Reporting and Logging - - - Where To Log - - - - - log_destination (string) - - log_destination configuration parameter - - - - - Pgpool-II supports two destinations - for logging the Pgpool-II messages. - The supported log destinations are stderr - and syslog. You can also set this parameter to a list - of desired log destinations separated by commas if you want the log messages - on the multiple destinations. - -#for example to log on both syslog and stderr -log_destination = 'syslog,stderr' - - The default is to log to stderr only. - - - - On some systems you will need to alter the configuration of your - system's syslog daemon in order to make use of the - syslog option - for log_destination. Pgpool-II - can log to syslog facilities LOCAL0 through LOCAL7 - (see ), but the default - syslog - configuration on most platforms will discard all such messages. - You will need to add something like: - -local0.* /var/log/pgpool.log - - to the syslog daemon's configuration file to make it work. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - syslog_facility (enum) - - syslog_facility configuration parameter - - - - - See also the documentation of your system's syslog daemon. - When logging to syslog is enabled, - this parameter determines the syslog - "facility" to be used. - You can choose from LOCAL0, LOCAL1, - LOCAL2, LOCAL3, LOCAL4, - LOCAL5, LOCAL6, LOCAL7; - the default is LOCAL0. - See also the documentation of your system's syslog daemon. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - syslog_ident (string) - - syslog_ident configuration parameter - - - - - When logging to syslog is enabled, this parameter determines - the program name used to identify Pgpool-II - messages in syslog logs. The default is pgpool. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - - - - When To Log - - - - - client_min_messages (enum) - - client_min_messages configuration parameter - - - - - Controls which minimum 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 default is NOTICE. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - log_min_messages (enum) - - log_min_messages configuration parameter - - - - - The default is WARNING. - Controls which minimum message levels are emitted to log. - 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. - The default is WARNING. - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - - - - What To Log - - - - - log_statement (boolean) - - log_statement configuration parameter - - - - - Setting to on, prints all SQL statements to the log. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - log_per_node_statement (boolean) - - log_per_node_statement configuration parameter - - - - - Similar to , except that it print the - logs for each DB node separately. It can be useful to make sure that - replication or load-balancing is working. - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - log_client_messages (boolean) - - log_client_messages configuration parameter - - - - - Setting to on, prints client messages to the log. - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - log_hostname (boolean) - - log_hostname configuration parameter - - - - - Setting to on, prints the hostname instead of IP address - in the ps command result, and connection logs - (when is on). - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - log_connections (boolean) - - log_connections configuration parameter - - - - - Setting to on, prints all client connections from to the log. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - log_error_verbosity (enum) - - log_error_verbosity configuration parameter - - - - - Controls the amount of detail emitted for each message that is logged. - Valid values are TERSE, DEFAULT, and VERBOSE, - each adding more fields - to displayed messages. TERSE excludes the logging of DETAIL, - HINT, - and CONTEXT error information. - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - log_line_prefix (string) - - log_line_prefix configuration parameter - - - - - This is a printf-style string that is output at the beginning of - each log line. - % characters begin escape sequences that are replaced - with information outlined below. - All unrecognized escapes are ignored. Other characters are copied straight to - the log line. Default is '%t: pid %p: ', which prints timestamp and process id, - which keeps backward compatibily with prePgpool-II - V3.4. - - - - log_line_prefix escape options - - - - - Escape - Effect - - - - - - %a - Client application name - - - - %p - Process ID (PID) - - - - %P - Process name - - - - %t - Time stamp - - - - %d - Database name - - - - %u - User name - - - - %l - Log line number for each process - - - - %% - '%' character - - - - -
- - This parameter can be changed by reloading the Pgpool-II configurations. - -
-
- -
-
+ Error Reporting and Logging + + + Where To Log + + + + + log_destination (string) + + log_destination configuration parameter + + + + + Pgpool-II supports two destinations + for logging the Pgpool-II messages. + The supported log destinations are stderr + and syslog. You can also set this parameter to a list + of desired log destinations separated by commas if you want the log messages + on the multiple destinations. + + #for example to log on both syslog and stderr + log_destination = 'syslog,stderr' + + The default is to log to stderr only. + + + + On some systems you will need to alter the configuration of your + system's syslog daemon in order to make use of the + syslog option + for log_destination. Pgpool-II + can log to syslog facilities LOCAL0 through LOCAL7 + (see ), but the default + syslog + configuration on most platforms will discard all such messages. + You will need to add something like: + + local0.* /var/log/pgpool.log + + to the syslog daemon's configuration file to make it work. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + logging_collector (boolean) + + logging_collector configuration parameter + + + + + This parameter enables the logging collector, which is a background process that captures + log messages sent to stderr and redirects them into log files. + + + + It is possible to log to stderr without using the logging collector; the log messages will + just go to wherever the server's stderr is directed. However, that method is only suitable + for low log volumes, since it provides no convenient way to rotate log files. + + + + This parameter can only be set at the Pgpool-II start. + + + logging_collector is not available prior to + Pgpool-II V4.2. + + + + + + log_directory (string) + + log_directory configuration parameter + + + + + When is enabled, this parameter determines + the directory in which log files will be created. + + The default is /tmp/pgpool_logs. + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + log_filename (string) + + log_filename configuration parameter + + + + + When is enabled, this parameter sets the + file names of the created log files. The value is treated as a + strftime pattern, so %-escapes can be used to specify time-varying + file names. + The supported %-escapes are similar to those listed in the Open Group's + strftimespecification. + + + If you specify a file name without escapes, you should plan to use a log rotation + utility to avoid eventually filling the entire disk. + + + The default is pgpool-%Y-%m-%d_%H%M%S.log. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_file_mode (integer) + + log_file_mode configuration parameter + + + + + This parameter sets the permissions for log files when + is enabled. The parameter value is expected to be a numeric mode specified in the format + accepted by the chmod and umask system calls. + + + + + To use the customary octal format the number must start with a 0 (zero). + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_rotation_age (integer) + + log_rotation_age configuration parameter + + + + + When is enabled, this parameter determines + the maximum amount of time to use an individual log file, after which a new log + file will be created. If this value is specified without units, + it is taken as minutes. The default is 24 hours. + + + Set to zero to disable time-based creation of new log files. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_rotation_size (integer) + + log_rotation_size configuration parameter + + + + + When is enabled, this parameter determines + the maximum size of an individual log file. After this many kilobytes have been + emitted into a log file, a new log file will be created. + + + Set to zero to disable size-based creation of new log files. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_truncate_on_rotation (boolean) + + log_truncate_on_rotation configuration parameter + + + + + When is enabled, + this parameter will cause Pgpool-II to truncate (overwrite), + rather than append to, any existing log file of the same name. + However, truncation will occur only when a new file is being opened due to + time-based rotation, not during the startup or size-based rotation. + When off, pre-existing files will be appended to in all cases. + For example, using this setting in combination with a + like pgpool-%H.log would result in generating twenty-four hourly log + files and then cyclically overwriting them. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + syslog_facility (enum) + + syslog_facility configuration parameter + + + + + See also the documentation of your system's syslog daemon. + When logging to syslog is enabled, + this parameter determines the syslog + "facility" to be used. + You can choose from LOCAL0, LOCAL1, + LOCAL2, LOCAL3, LOCAL4, + LOCAL5, LOCAL6, LOCAL7; + the default is LOCAL0. + See also the documentation of your system's syslog daemon. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + syslog_ident (string) + + syslog_ident configuration parameter + + + + + When logging to syslog is enabled, this parameter determines + the program name used to identify Pgpool-II + messages in syslog logs. The default is pgpool. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + + + When To Log + + + + + client_min_messages (enum) + + client_min_messages configuration parameter + + + + + Controls which minimum 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 default is NOTICE. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + log_min_messages (enum) + + log_min_messages configuration parameter + + + + + The default is WARNING. + Controls which minimum message levels are emitted to log. + 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. + The default is WARNING. + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + + + + What To Log + + + + + log_statement (boolean) + + log_statement configuration parameter + + + + + Setting to on, prints all SQL statements to the log. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + log_per_node_statement (boolean) + + log_per_node_statement configuration parameter + + + + + Similar to , except that it print the + logs for each DB node separately. It can be useful to make sure that + replication or load-balancing is working. + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + notice_per_node_statement (boolean) + + notice_per_node_statement configuration parameter + + + + + Similar to , except + that it prints the statement logs for each DB node separately as + a NOTICE message. With the + default setting (that + is NOTICE), the log message will be printed on client's terminal + as well. This is convenient for clients because it does not need + to access Pgpool-II log file. Note + that + unlike , + does not print internal queries, (e.g., system catalog inquiry). + This is because this feature is designed to be used for testing + as well. As internal queries tend to be non-deterministic, + printing them in testing is not helpful. For the same reason, + backend process id is not printed. + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + log_client_messages (boolean) + + log_client_messages configuration parameter + + + + + Setting to on, prints client messages to the log. + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + log_backend_messages (enum) + + log_backend_messages configuration parameter + + + + + Setting to terse + or verbose, prints backend messages to the + log. With terse the number of same kind of + messages are recorded and is printed when different kind of + messages is sent. Below is an example. + + LOG: last DataRow message from backend 0 repeated 10 times + + Thus the log will not be printed if the process corresponding to + the session is killed. If you want to print the log even in this + case, use verbose option. Note that with the + option each repeated message is printed and lots of log lines + are printed. The default is none, which + disables printing log messages from backend. + + + This parameter can be changed by reloading + the Pgpool-II configurations. You can also + use command to alter the value + of this parameter for a current session. + + + + + + log_hostname (boolean) + + log_hostname configuration parameter + + + + + Setting to on, prints the hostname instead of IP address + in the ps command result, and connection logs + (when is on). + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_connections (boolean) + + log_connections configuration parameter + + + + + Setting to on, prints all client connections from to the log. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_disconnections (boolean) + + log_disconnections configuration parameter + + + + + Setting to on, prints all client connection terminations to the log. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_pcp_processes (boolean) + + log_pcp_processes configuration parameter + + + + + Setting to on, enable logging about normal PCP Process + fork and exit status. Default is off. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_error_verbosity (enum) + + log_error_verbosity configuration parameter + + + + + Controls the amount of detail emitted for each message that is logged. + Valid values are TERSE, DEFAULT, and VERBOSE, + each adding more fields + to displayed messages. TERSE excludes the logging of DETAIL, + HINT, QUERY + and CONTEXT error information. + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + log_line_prefix (string) + + log_line_prefix configuration parameter + + + + + This is a printf-style string that is output at the beginning of + each log line. + % characters begin escape sequences that are replaced + with information outlined below. + All unrecognized escapes are ignored. Other characters are copied straight to + the log line. Default is '%m: %a pid %p: ', which prints timestamp, application name and process id. + + + + log_line_prefix escape options + + + + + Escape + Effect + + + + + + %a + + Application name. The initial value for child (session + process) is "child". If Clients set application name + (either in the startup message or by using SET command), + application name will be changed accordingly. In other types + of process, application name is a hard coded string. see + . + + + + + %p + Process ID (PID) + + + + %P + Process name + + + + %t + Time stamp without milliseconds + + + + %m + Time stamp with milliseconds + + + + %d + Database name + + + + %u + User name + + + + %l + Log line number for each process + + + + %% + '%' character + + + + +
+ + + application names in various process + + + + + Process type + application name + + + + + + + main + main + + + + child + child + + + + streaming replication delay check worker + sr_check_worker + + + + watchdog heart beat sender + heart_beat_sender + + + + watchdog heart beat receiver + heart_beat_receiver + + + + watchdog + watchdog + + + + watchdog life check + life_check + + + + follow primary child + follow_child + + + + watchdog utility + watchdog_utility + + + + pcp main + pcp_main + + + + pcp child + pcp_child + + + + health check process + health_check%d (%d is replaced with backend node id) + + + + logger process + logger (Note that the application name "logger" will not be output to the log file managed by logger process) + + + + +
+ + + This parameter can be changed by reloading the Pgpool-II configurations. + +
+
+ +
+
diff --git a/doc/src/sgml/connection-settings.sgml b/doc/src/sgml/connection-settings.sgml index 3178c308e..1aa2e1034 100644 --- a/doc/src/sgml/connection-settings.sgml +++ b/doc/src/sgml/connection-settings.sgml @@ -1,1174 +1,1531 @@ - Connections and Authentication - - - Connection Settings - - - - - listen_addresses (string) - - listen_addresses configuration parameter - - - - - Specifies the hostname or IP address, on - which Pgpool-II will accept - TCP/IP connections. '*' accepts all - incoming connections. '' disables - TCP/IP connections. Default - is 'localhost'. Connections via UNIX - domain socket are always accepted. - - - This parameter can only be set at server start. - - - - - - port (integer) - - port configuration parameter - - - - - The port number used - by Pgpool-II to listen for - connections. Default is 9999. - - - This parameter can only be set at server start. - - - - - - socket_dir (string) - - socket_dir configuration parameter - - - - - The directory where the UNIX domain socket accepting connections for - Pgpool-II will be - created. Default is /tmp. Be aware that - this socket might be deleted by a cron job. We recommend - to set this value to /var/run or such - directory. - - - This parameter can only be set at server start. - - - - - - pcp_listen_addresses (string) - - pcp_listen_addresses configuration parameter - - - - - Specifies the hostname or IP address, on which pcp process - will accept TCP/IP connections. * - accepts all incoming connections. "" - disables TCP/IP connections. Default - is *. Connections via UNIX domain - socket are always accepted. - - - This parameter can only be set at server start. - - - - - - pcp_port (integer) - - pcp_port configuration parameter - - - - - The port number used by PCP - process to listen for connections. Default is 9898. - - - This parameter can only be set at server start. - - - - - - pcp_socket_dir (string) - - pcp_socket_dir configuration parameter - - - - - The directory where the UNIX domain socket accepting - connections for PCP process will be created. Default - is /tmp. Be aware that this socket - might be deleted by a cron job. We recommend to set this - value to /var/run or such directory. - - - This parameter can only be set at server start. - - - - - - num_init_children (integer) - - num_init_children configuration parameter - - + Connections and Authentication + + + Connection Settings + + + + + listen_addresses (string) + + listen_addresses configuration parameter + + + + + Specifies the TCP/IP address(es) on which the server is + to listen for connections from client applications. + The value takes the form of a comma-separated list of host names + and/or numeric IP addresses. The special entry * + corresponds to all available IP interfaces. The entry + 0.0.0.0 allows listening for all IPv4 addresses and + :: allows listening for all IPv6 addresses. + If the list is empty, the server does not listen on any IP interface + at all, in which case only Unix-domain sockets can be used to connect + to it. + The default value + is localhost, which + allows only local TCP/IP loopback connections to + be made. While client authentication + () allows fine-grained + control over who can access the + server, listen_addresses controls which + interfaces accept connection attempts, which can help prevent + repeated malicious connection requests on insecure network + interfaces. This parameter can only be set at server start. + + + This parameter can only be set at server start. + + + + + + port (integer) + + port configuration parameter + + + + + The port number used + by Pgpool-II to listen for + connections. Default is 9999. + + + This parameter can only be set at server start. + + + + + + unix_socket_directories (string) + + unix_socket_directories configuration parameter + + + + + The directory where the UNIX domain socket(s) accepting connections for + Pgpool-II will be created. Multiple sockets + can be created by listing multiple directories separated by commas. + Leading and trailing spaces in each setting value will be automatically + removed. Default is /tmp. Be aware that this sockets + might be deleted by a cron job. We recommend to set this value to + /var/run or such directory. + + + This parameter can only be set at server start. + + + + + + unix_socket_group (string) + + unix_socket_group configuration parameter + + + + + Sets the owning group of the Unix-domain socket(s). (The owning user of + the sockets is always the user that starts the server.) In combination + with the parameter unix_socket_permissions this can be + used as an additional access control mechanism for Unix-domain connections. + By default this is the empty string, which uses the default group of the + server user. + + + This parameter can only be set at server start. + + + + + + unix_socket_permissions (integer) + + unix_socket_permissions configuration parameter + + + + + Sets the access permissions of the Unix-domain socket(s). Unix-domain + sockets use the usual Unix file system permission set. The parameter value + is expected to be a numeric mode specified in the format accepted by the + chmod and umask system calls. (To use the customary octal format the number + must start with a 0 (zero).) + + + The default permissions are 0777, meaning anyone can + connect. Reasonable alternatives are 0770 (only user + and group, see also unix_socket_group) and + 0700 (only user). (Note that for a Unix-domain socket, + only write permission matters, so there is no point in setting or revoking + read or execute permissions.) + + + This parameter can only be set at server start. + + + + + + pcp_listen_addresses (string) + + pcp_listen_addresses configuration parameter + + + + + Specifies the TCP/IP address(es) on which the pcp server is + to listen for connections from client applications. + The value takes the form of a comma-separated list of host names + and/or numeric IP addresses. The special entry * + corresponds to all available IP interfaces. The entry + 0.0.0.0 allows listening for all IPv4 addresses and + :: allows listening for all IPv6 addresses. + If the list is empty, the server does not listen on any IP interface + at all, in which case only Unix-domain sockets can be used to connect + to it. + The default value + is localhost, which + allows only local TCP/IP loopback connections to + be made. While client authentication + () allows fine-grained + control over who can access the + server, pcp_listen_addresses controls which + interfaces accept connection attempts, which can help prevent + repeated malicious connection requests on insecure network + interfaces. This parameter can only be set at server start. + + + + + + pcp_port (integer) + + pcp_port configuration parameter + + + + + The port number used by PCP + process to listen for connections. Default is 9898. + + + This parameter can only be set at server start. + + + + + + pcp_socket_dir (string) + + pcp_socket_dir configuration parameter + + + + + The directory where the UNIX domain socket accepting + connections for PCP process will be created. Multiple sockets + can be created by listing multiple directories separated by commas. + Leading and trailing spaces in each setting value will be + automatically removed. + Default is /tmp. Be aware that this socket + might be deleted by a cron job. We recommend to set this + value to /var/run or such directory. + + + This parameter can only be set at server start. + + + + + + num_init_children (integer) + + num_init_children configuration parameter + + + + + The number of + preforked Pgpool-II server + processes. Default is 32. num_init_children is also the + concurrent connections limit + to Pgpool-II from clients. If + more than num_init_children clients try to connect to + Pgpool-II, they are + blocked (not rejected with an error, + like PostgreSQL) until a + connection to any Pgpool-II + process is closed + unless is set + to 1 or more. Up to + * + num_init_children can be queued. + + + The queue is inside the kernel called "listen queue". The + length of the listen queue is called "backlog". There is + an upper limit of the backlog in some systems, and if + num_init_children* + exceeds the number, you need to set the backlog higher. + Otherwise, following problems may occur in heavy loaded systems: + - - The number of - preforked Pgpool-II server - processes. Default is 32. num_init_children is also the - concurrent connections limit - to Pgpool-II from clients. If - more than num_init_children clients try to connect to - Pgpool-II, they are - blocked (not rejected with an error, - like PostgreSQL) until a - connection to any Pgpool-II - process is closed - unless is set - to 1 or more. Up to - * - num_init_children can be queued. - - - The queue is inside the kernel called "listen queue". The - length of the listen queue is called "backlog". There is - an upper limit of the backlog in some systems, and if - num_init_children* - exceeds the number, you need to set the backlog higher. - Otherwise, following problems may occur in heavy loaded systems: - 1) connecting to Pgpool-II fails - 2) connecting to Pgpool-II is - getting slow because of retries in the kernel. You can - check if the listen queue is actually overflowed by using - "netstat -s" command. If you find something like: - - 535 times the listen queue of a socket overflowed - - then the listen queue is definitely overflowed. You - should increase the backlog in this case (you will be - required a super user privilege). - - # sysctl net.core.somaxconn - net.core.somaxconn = 128 - # sysctl -w net.core.somaxconn = 256 - - You could add following to /etc/sysctl.conf instead. - - net.core.somaxconn = 256 - - - - Number of connections to - each PostgreSQL is roughly - max_pool*num_init_children. - - - - However, canceling a query creates another - connection to the backend; thus, a query cannot be canceled if - all the connections are in use. If you want to ensure that queries can - be canceled, set this value to twice the expected connections. - - - In addition, PostgreSQL allows concurrent - connections for non superusers up to max_connections - - superuser_reserved_connections. - - - In summary, max_pool, num_init_children, max_connections, - superuser_reserved_connections must satisfy the following formula: - - max_pool*num_init_children <= (max_connections - superuser_reserved_connections) (no query canceling needed) - max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections) (query canceling needed) - - - - This parameter can only be set at server start. - + + connecting to Pgpool-II fails + - - - - reserved_connections (integer) - - reserverd_connections configuration parameter - - - - When this parameter is set to 1 or greater, incoming - connections from clients are not accepted with error - message "Sorry, too many clients already", rather than - blocked if the number of current connections from clients - is more than ( - - reserved_connections). For example, - if reserved_connections = 1 - and = 32, then the - 32th connection from a client will be refused. This - behavior is similar - to PostgreSQL and good for - systems on which the number of connections from clients is - large and each session may take long time. In this case - length of the listen queue could be very long and may - cause the system unstable. In this situation setting this - parameter to non 0 is a good idea to prevent the listen - queue becomes very long. - - - If this parameter is set to 0, no connection from clients - will be refused. The default value is 0. - This parameter can only be set at server start. - + + connecting to Pgpool-II is + getting slow because of retries in the kernel. + - - - - - - Authentication Settings - - - - enable_pool_hba (boolean) - - enable_pool_hba configuration parameter - - - - - If true, Pgpool-II will use the - pool_hba.conf for the client - authentication. See - for details on how to configure - pool_hba.conf for client authentication. - Default is false. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - - - - pool_passwd (string) - - pool_passwd configuration parameter - - - - - Specify the password file name for authentication. - Default value is "pool_passwd". - Specifying '' (empty) disables the use - of password file. - - - Passwords can be stored in the pool_passwd file using three formats. - AES256 encrypted format, plain text format and md5 format. - Pgpool-II identifies the password format type - by it's prefix, so each password entry in the pool_passwd must be prefixed - as per the password format. - - - To store the password in the plain text format use TEXT prefix. - For example. to store clear text password string "mypassword" - in the pool_passwd, prepend the password string with TEXT prefix. - e.g. TEXTmypassword - + + You can check if the listen queue is actually overflowed by using + "netstat -s" command. If you find something like: + + 535 times the listen queue of a socket overflowed + + then the listen queue is definitely overflowed. You + should increase the backlog in this case (you will be + required a super user privilege). + + # sysctl net.core.somaxconn + net.core.somaxconn = 128 + # sysctl -w net.core.somaxconn = 256 + + You could add following to /etc/sysctl.conf instead. + + net.core.somaxconn = 256 + + + + Number of connections to + each PostgreSQL is roughly + max_pool*num_init_children. + + + + However, canceling a query creates another + connection to the backend; thus, a query cannot be canceled if + all the connections are in use. If you want to ensure that queries can + be canceled, set this value to twice the expected connections. + + + In addition, PostgreSQL allows concurrent + connections for non superusers up to max_connections - + superuser_reserved_connections. + + + In summary, max_pool, num_init_children, max_connections, + superuser_reserved_connections must satisfy the following formula: + + max_pool*num_init_children <= (max_connections - superuser_reserved_connections) (no query canceling needed) + max_pool*num_init_children*2 <= (max_connections - superuser_reserved_connections) (query canceling needed) + + + + This parameter can only be set at server start. + + + + + + reserved_connections (integer) + + reserved_connections configuration parameter + + + + + When this parameter is set to 1 or greater, incoming + connections from clients are not accepted with error + message "Sorry, too many clients already", rather than + blocked if the number of current connections from clients + is more than ( - + reserved_connections). For example, + if reserved_connections = 1 + and = 32, then the + 32th connection from a client will be refused. This + behavior is similar + to PostgreSQL and good for + systems on which the number of connections from clients is + large and each session may take long time. In this case + length of the listen queue could be very long and may + cause the system unstable. In this situation setting this + parameter to non 0 is a good idea to prevent the listen + queue becomes very long. + + + If this parameter is set to 0, no connection from clients + will be refused. The default value is 0. + This parameter can only be set at server start. + + + + + + + + Authentication Settings + + + + enable_pool_hba (boolean) + + enable_pool_hba configuration parameter + + + + + If true, Pgpool-II will use the + pool_hba.conf for the client + authentication. See + for details on how to configure + pool_hba.conf for client authentication. + Default is false. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + + + + pool_passwd (string) + + pool_passwd configuration parameter + + + + + Specify the path (absolute or relative) to password file for + authentication. Default value is "pool_passwd". + A relative path will be interpreted with respect to the directory + where configuration file is placed. + Specifying '' (empty) disables the use + of password file. + + + Passwords can be stored in the pool_passwd file using three formats. + AES256 encrypted format, plain text format and md5 format. + Pgpool-II identifies the password format type + by it's prefix, so each password entry in the pool_passwd must be prefixed + as per the password format. + + + To store the password in the plain text format use TEXT prefix. + For example. to store clear text password string "mypassword" + in the pool_passwd, prepend the password string with TEXT prefix. + e.g. TEXTmypassword + + + similarly md5 hashed passwords must be prefixed with md5 and + AES256 encrypted password types can be stored using AES prefix. + see for more details on using + AES256 encrypted passwords. + + + + In the absence of a valid prefix, Pgpool-II will + be considered the string as a plain text password. + + + This parameter can only be set at server start. + + + + + + allow_clear_text_frontend_auth (boolean) + + allow_clear_text_frontend_auth configuration parameter + + + + + If PostgreSQL backend servers require + md5 or SCRAM authentication for some + user's authentication but the password for that user is not present in the + "pool_passwd" file, then enabling + allow_clear_text_frontend_auth will allow the + Pgpool-II to use clear-text-password + authentication with frontend clients to get the password in plain text form + from the client and use it for backend authentication. + + + Default is false. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + - similarly md5 hashed passwords must be prefixed with md5 and - AES256 encrypted password types can be stored using AES prefix. - see for more details on using - AES256 encrypted passwords. + allow_clear_text_frontend_auth only works when is not enabled + + + + + + authentication_timeout (integer) + + authentication_timeout configuration parameter + + + + + Specify the timeout in seconds + for Pgpool-II + authentication. Specifying 0 disables the time out. + Default value is 60. + + + This parameter can only be set at server start. + + + + + + + + - - In the absence of a valid prefix, Pgpool-II will - be considered the string as a plain text password. + + Process Management + + + + + + process_management_mode (enum) + + process_management_mode configuration parameter + + + + + Specify the idle process management method for + Pgpool-II child processes. + Valid options: + + Possible Process Management Modes + + + + + static + + All children are pre-forked at startup. + Number of child processes is fixed (). + + + + + dynamic + child processes are spawned on demand up to . + Number of idle child processes at any time depends on + min_spare_children and max_spare_children + + + + + +
+
+ + Default is static, that is compatible with pre V4.4. + + + + process_management_mode is not available prior to + Pgpool-II V4.4. + + + + See for more details. + + +
+
+ + + process_management_strategy (enum) + + process_management_strategy configuration parameter + + + + + Specify the process management strategy to satisfy spare (idle) processes count + Valid options: + + Possible Process Management Strategies + + + + + lazy + With this strategy the scale-down is performed gradually + and only gets triggered when excessive spare processes count + remains high for more than 5 mins + + + + + gentle + With this strategy the scale-down is performed gradually + and only gets triggered when excessive spare processes count + remains high for more than 2 mins + + + + + aggressive + With this strategy the scale-down is performed aggressively + and gets triggered more frequently in case of higher spare processes. + This mode uses faster and slightly less smart process selection criteria + to identify the child processes that can be serviced to satisfy + max_spare_children + + + + + +
+
+ + Default is gentle. + + + process_management_strategy is not available prior to + Pgpool-II V4.4. - - This parameter can only be set at server start. - -
-
- - - allow_clear_text_frontend_auth (boolean) - - allow_clear_text_frontend_auth configuration parameter - - - - - If PostgreSQL backend servers require - md5 or SCRAM authentication for some - user's authentication but the password for that user is not present in the - "pool_passwd" file, then enabling - allow_clear_text_frontend_auth will allow the - Pgpool-II to use clear-text-password - authentication with frontend clients to get the password in plain text form - from the client and use it for backend authentication. - - - Default is false. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - - allow_clear_text_frontend_auth only works when is not enabled - - - - - - - authentication_timeout (integer) - - authentication_timeout configuration parameter - - - - - Specify the timeout in seconds - for Pgpool-II - authentication. Specifying 0 disables the time out. - Default value is 60. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - + + + + + + min_spare_children (integer) + + min_spare_children configuration parameter + + + + + Specify the minimum number of spare (idle) child processes to keep. + If the idle process count falls below min_spare_children, + Pgpool-II will spawn new child processes unless it hits the total allowed child process ceiling (num_init_children). + Default value is 5. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + This parameter is only applicable for dynamic process management mode. + + + + + + max_spare_children (integer) + + max_spare_children configuration parameter + + + + + Specify the maximum number of spare (idle) child processes to keep. + If the idle process count increases from max_spare_children, Pgpool-II will kill the excessive child processes. + Selection criteria is to select the processes with minimum number of pooled connections. + Default value is 10. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + This parameter is only applicable for dynamic process management mode. + + +
- +
- Running mode - - - Master slave mode - - - This mode is used to couple Pgpool-II - with another master/slave replication software - (like Slony-I and Streaming replication), - that is responsible for doing the actual data replication. - - - + Clustering mode + + + + backend_clustering_mode (enum) + + backend_clustering_mode configuration parameter + + + + + Clustering mode is the method to sync + PostgreSQL servers. To set the clustering + mode, backend_clustering_mode can be used. In + this section we discuss how to set the clustering mode. See for more details. + + + + + + + + Streaming replication mode + + + This mode is most popular and recommended clustering mode. In this + mode PostgreSQL is responsible to + replicate each servers. To enable this mode, use + streaming_replication for + backend_clustering_mode. + +backend_clustering_mode = streaming_replication + + In this mode you can have up to 127 streaming replication standby servers. + Also it is possible not to have standby server at all. + + + The drawback of this mode is, it is necessary to consider the + replication delay while distributing read queries. The visibility + consistency among nodes is not guaranteed either. To mitigate these + problems lots of additional parameters are prepared but it may make + the administration task harder. Also it may take sometime to + perform failover when the primary server goes down and one of + standbys is promoted. If you want to avoid these problems, consider + snapshot isolation + mode. + + + See for + additional parameters for streaming replication mode. + + + + + Native replication mode + + + This mode makes the Pgpool-II to + replicate data between PostgreSQL + backends. To enable this mode, use native_replication for + backend_clustering_mode. + +backend_clustering_mode = native_replication + + In this mode you can have up to 127 standby replication servers. + Also it is possible not to have standby server at all. + + + + Load balancing (see ) can + also be used with replication mode to distribute the load to the + attached backend nodes. + + + + The drawback of this mode is, visibility consistency among nodes is + not guaranteed. This could bring inconsistency among nodes and read + inconsistent data. If you want to avoid these problems, consider + snapshot isolation + mode. + + + + Following options affect the behavior of + Pgpool-II in the replication mode. + + + + + + replication_stop_on_mismatch (boolean) + + replication_stop_on_mismatch configuration parameter + + + + + When set to on, and all nodes do not reply with the same + packet kind to the query that was sent to + all PostgreSQL backend nodes, + then the backend node whose reply differs from the + majority is degenerated by + the Pgpool-II. + If replication_stop_on_mismatch is set + to off and a similar situation happens then + the Pgpool-II only terminates + the current user session but does not degenerate a backend + node. + + + - The number of slave nodes are not limited to 1 and - Pgpool-II can have up to 127 slave nodes. - master/slave mode can also work just master node without any slave nodes. + Pgpool-II does not examine + the data returned by the backends and takes the decision + only by comparing the result packet types. - - - - Load balancing (see ) can - also be used with master/slave mode to distribute the read load on the - standby backend nodes. - - - Following options are required to be specified for master/slave mode. - - - - - - master_slave_mode (boolean) - - master_slave_mode configuration parameter - - - - - Setting to on enables the master/slave mode. - Default is off. - - - - and - are mutually exclusive and only one can be enabled at a time. - - - - This parameter can only be set at server start. - - - - - - master_slave_sub_mode (enum) - - master_slave_sub_mode configuration parameter - - - - - Specifies the external replication system used for data - replication between - PostgreSQL nodes. - Below table contains the list of valid values for the parameter. - - - - master slave sub mode options - - - - Value - Description - - - - - - 'slony' - Suitable for Slony-I - - - - 'stream' - Suitable - for PostgreSQL's built-in - replication system (Streaming Replication) - - - - 'logical' - Suitable - for PostgreSQL's built-in - replication system (Logical Replication) - - - - -
- - - Default is 'slony'. - - - This parameter can only be set at server start. - -
-
- -
-
- - - Replication mode - - - This mode makes the Pgpool-II to - replicate data between PostgreSQL - backends. - - - - Load balancing - (see ) can also - be used with replication mode to distribute the load to the - attached backend nodes. - +
+ + + A typical use case of enabling + the replication_stop_on_mismatch is to + guard against the data inconsistency among the backend + nodes. For example, you may want to degenerate a backend + node if an UPDATE statement fails on one backend node + while passes on others. + + + Default is off. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + + + + failover_if_affected_tuples_mismatch (boolean) + + failover_if_affected_tuples_mismatch configuration parameter + + + + + When set to on, and all nodes do not reply with the same + number of affected tuples to the INSERT/UPDATE/DELETE + query, then the backend node whose reply differs from the + majority is degenerated by + the Pgpool-II. + If failover_if_affected_tuples_mismatch + is set to off and a similar situation happens then + the Pgpool-II only terminates + the current user session but does not degenerate a backend + node. + + + + + In case of a tie, when two or more groups have the same + number of nodes, then the group containing the primary + node (backend node having the youngest node id) gets the + precedence. + + + + + Default is off. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + replicate_select (boolean) + + replicate_select configuration parameter + + + + + When set to on, Pgpool-II enables the + SELECT query replication mode. i.e. The SELECT queries are sent + to all backend nodes. + + + + replicate_select with <xref linkend="guc-load-balance-mode"> affects on SELECT routing + + + + + + + + + + + replicate_select is true + Y + N + + + + load_balance_mode is true + ANY + Y + N + + + + SELECT is inside a transaction block + ANY + Y + N + ANY + + + + + Transaction isolation level is SERIALIZABLE and + the transaction has issued a write query + + ANY + Y + N + ANY + ANY + + + + + results(R:replication, M: send only to main, L: load balance) + + R + M + L + L + M + + + + +
+ + + Default is off. + + + This parameter can be changed by reloading the Pgpool-II configurations. + +
+
+ + + insert_lock (boolean) + + insert_lock configuration parameter + + + + + When set to on, Pgpool-II will + automatically lock the table + on PostgreSQL before an INSERT + statement is issued for that. + + + + When replicating a table with SERIAL data type, the SERIAL + column value may get different values on the different + backends. The workaround to this problem is to explicitly + lock the table before issuing the INSERT. + + + So for automatically locking the + table Pgpool-II do the + following transformation: + + INSERT INTO ... + + to + + BEGIN; + LOCK TABLE ... + INSERT INTO ... + COMMIT; + + + + + This approach severely degrades the transactions' + parallelism + + + + + Pgpool-II V2.2 + or later, automatically detects whether the table has a + SERIAL columns or not, so it never locks the table if it + doesn't have the SERIAL columns. + + + + Pgpool-II V3.0 until + Pgpool-II V3.0.4 + uses a row lock against the sequence relation, rather than + table lock. This is intended to minimize lock conflict + with VACUUM (including autovacuum). + However this can lead to another problem. After + transaction wraparound happens, row locking against the + sequence relation causes PostgreSQL internal error (more + precisely, access error on pg_clog, which keeps + transaction status). To prevent + this, PostgreSQL core + developers decided to disallow row locking against + sequences and this broke + the Pgpool-II, of course (the + "fixed" version of PostgreSQL was released as 9.0.5, + 8.4.9, 8.3.16 and 8.2.22). + + + + Pgpool-II V3.0.5 + or later uses a row lock + against pgpool_catalog.insert_lock + table because new PostgreSQL disallows a row lock against + the sequence relation. So creating insert_lock table in + all databases which are accessed via + Pgpool-II beforehand is + required. See + for more details. If does not exist insert_lock + table, Pgpool-II locks the + insert target table. This behavior is same + as Pgpool-II V2.2 + and V2.3 series. + + + If you want to use insert_lock which is + compatible with older releases, you can specify lock + method by configure script. + See for more details. + + + + For fine (per statement) control: + + + + + + set insert_lock to true, and add /*NO INSERT LOCK*/ at + the beginning of an INSERT statement for which you do + not want to acquire the table lock. + + + + + set insert_lock to false, and add /*INSERT LOCK*/ at + the beginning of an INSERT statement for which you + want to acquire the table lock. + + + + + + + If insert_lock is enabled, the regression tests for + PostgreSQL 8.0 gets fail in transactions, privileges, + rules, and alter_table. + + + The reason for this is + that Pgpool-II tries to LOCK + the VIEW for the rule test, and it produces the below + error message: + + ! ERROR: current transaction is aborted, commands ignored until + end of transaction block + + For example, the transactions test tries an INSERT into + a table which does not exist, + and Pgpool-II + causes PostgreSQL to acquire + the lock for the table. Of cause this results in an + error. The transaction will be aborted, and the + following INSERT statement produces the above error + message. + + + + Default is on. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + + + + lobj_lock_table (string) + + lobj_lock_table configuration parameter + + + + + Specifies a table name used for large object replication control. + If it is specified, Pgpool-II will lock + the table specified by lobj_lock_table and generate + a large object id by looking into pg_largeobject + system catalog and then call lo_create to create + the large object. + This procedure guarantees that Pgpool-II + will get the same large object id in all DB nodes in replication mode. + + + + PostgreSQL 8.0 and older does + not have lo_create, so this feature + does not work with PostgreSQL 8.0 and older versions. + + + + A call to the libpq + function lo_creat() triggers this + feature. Also large object creation + through Java API + (JDBC driver), PHP + API (pg_lo_create, or similar API in + PHP library such as PDO), and this same API in various + programming languages are known to use a similar protocol, + and thus should work. + + + + This feature does not works with following operations on large objects. + + + + + All APIs using lo_create, lo_import_with_oid. + + + + + lo_import function in backend called in SELECT. + + + + + lo_create function in backend called in SELECT. + + + + + + + All PostgreSQL users must + have a write access + on lobj_lock_table and it can be + created in any schema. + + + + + Example to create a large object lock table: + + CREATE TABLE public.my_lock_table (); + GRANT ALL ON public.my_lock_table TO PUBLIC; + + + + Default is ''(empty), which disables the feature. + + + + + +
+ + + Snapshot isolation mode + + + This mode is similar to the native replication mode except it adds + the visibility consistency among nodes. The implementation is based + on a research paper . + To enable this mode, use snapshot_isolation for + backend_clustering_mode. + +backend_clustering_mode = snapshot_isolation + + For example, you can avoid following inconsistency among nodes caused by the + visibility inconsistency. Here S1 and S2 denotes sessions, while N1 + and N2 denotes the PostgreSQL server 1 and 2 respectively. + +S1/N1: BEGIN; +S1/N2: BEGIN; +S1/N1: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N2: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N1: COMMIT; +S2/N1: BEGIN; +S2/N2: BEGIN; +S2/N2: DELETE FROM t1 WHERE i = 1; -- delete 1 row since S1/N2 is not committed yet +S2/N1: DELETE FROM t1 WHERE i = 1; -- delete no row since S1/N1 is committed and i is not 1 anymore +S1/N2: COMMIT; +S2/N1: COMMIT; +S2/N2: COMMIT; + + In the snapshot isolation mode, the result will be either one of + them below and it never damages the data consistency among database + nodes. + +S1/N1: BEGIN; +S1/N2: BEGIN; +S1/N1: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N2: UPDATE t1 SET i = i + 1; -- i = 1 +S2/N1: BEGIN; +S2/N2: BEGIN; +S1/N1: COMMIT; +S1/N2: COMMIT; +S2/N1: DELETE FROM t1 WHERE i = 1; -- delete no row since S1/N1 is committed and i is not 1 anymore +S2/N2: DELETE FROM t1 WHERE i = 1; -- delete no row since S1/N2 is committed and i is not 1 anymore +S2/N1: COMMIT; +S2/N2: COMMIT; + + + +S1/N1: BEGIN; +S1/N2: BEGIN; +S1/N1: UPDATE t1 SET i = i + 1; -- i = 1 +S1/N2: UPDATE t1 SET i = i + 1; -- i = 1 +S2/N1: BEGIN; +S2/N2: BEGIN; +S2/N1: DELETE FROM t1 WHERE i = 1; -- delete 1 row since S1/N1 is not committed yet +S2/N2: DELETE FROM t1 WHERE i = 1; -- delete 1 row since S1/N2 is not committed yet +S1/N1: COMMIT; +S1/N2: COMMIT; +S2/N1: COMMIT; +S2/N2: COMMIT; + + + + + - Following options affect the behavior of - Pgpool-II in the replication mode. + It is necessary to set the transaction isolation level to + REPEATABLE READ. That means you need to set it in + postgresql.conf like this: + +default_transaction_isolation = 'repeatable read' + - - - - - replication_mode (boolean) - - replication_mode configuration parameter - - - - - Setting to on enables the replication mode. - Default is off. - - - - - and are - mutually exclusive and only one can be enabled at a - time. - - - - This parameter can only be set at server start. - - - - - - replication_stop_on_mismatch (boolean) - - replication_stop_on_mismatch configuration parameter - - - - - When set to on, and all nodes do not reply with the same - packet kind to the query that was sent to - all PostgreSQL backend nodes, - then the backend node whose reply differs from the - majority is degenerated by - the Pgpool-II. - If replication_stop_on_mismatch is set - to off and a similar situation happens then - the Pgpool-II only terminates - the current user session but does not degenerate a backend - node. - - - - - Pgpool-II does not examine - the data returned by the backends and takes the decision - only by comparing the result packet types. - - - - - A typical use case of enabling - the replication_stop_on_mismatch is to - guard against the data inconsistency among the backend - nodes. For example, you may want to degenerate a backend - node if an UPDATE statement fails on one backend node - while passes on others. - - - Default is off. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - - - - failover_if_affected_tuples_mismatch (boolean) - - failover_if_affected_tuples_mismatch configuration parameter - - - - - When set to on, and all nodes do not reply with the same - number of affected tuples to the INSERT/UPDATE/DELETE - query, then the backend node whose reply differs from the - majority is degenerated by - the Pgpool-II. - If failover_if_affected_tuples_mismatch - is set to off and a similar situation happens then - the Pgpool-II only terminates - the current user session but does not degenerate a backend - node. - - - - - In case of a tie, when two or more groups have the same - number of nodes, then the group containing the master - node (backend node having the youngest node id) gets the - precedence. - - - - - Default is off. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - replicate_select (boolean) - - replicate_select configuration parameter - - - - - When set to on, Pgpool-II enables the - SELECT query replication mode. i.e. The SELECT queries are sent - to all backend nodes. - - - - replicate_select with <xref linkend="guc-load-balance-mode"> affects on SELECT routing - - - - - - - - - - - replicate_select is true - Y - N - - - - load_balance_mode is true - ANY - Y - N - - - - SELECT is inside a transaction block - ANY - Y - N - ANY - - - - - Transaction isolation level is SERIALIZABLE and - the transaction has issued a write query - - ANY - Y - N - ANY - ANY - - - - - results(R:replication, M: send only to master, L: load balance) - - R - M - L - L - M - - - - -
- - - Default is off. - - - This parameter can be changed by reloading the Pgpool-II configurations. - -
-
- - - insert_lock (boolean) - - insert_lock configuration parameter - - - - - When set to on, Pgpool-II will - automatically lock the table - on PostgreSQL before an INSERT - statement is issued for that. - - - - When replicating a table with SERIAL data type, the SERIAL - column value may get different values on the different - backends. The workaround to this problem is to explicitly - lock the table before issuing the INSERT. - - - So for automatically locking the - table Pgpool-II do the - following transformation: - - INSERT INTO ... - - to - - BEGIN; - LOCK TABLE ... - INSERT INTO ... - COMMIT; - - - - - This approach severely degrades the transactions' - parallelism - - - - - Pgpool-II V2.2 - or later, automatically detects whether the table has a - SERIAL columns or not, so it never locks the table if it - desn't have the SERIAL columns. - - - - Pgpool-II V3.0 until - Pgpool-II V3.0.4 - uses a row lock against the sequence relation, rather than - table lock. This is intended to minimize lock conflict - with VACUUM (including autovacuum). - However this can lead to another problem. After - transaction wraparound happens, row locking against the - sequence relation causes PostgreSQL internal error (more - precisely, access error on pg_clog, which keeps - transaction status). To prevent - this, PostgreSQL core - developers decided to disallow row locking against - sequences and this broke - the Pgpool-II, of course (the - "fixed" version of PostgreSQL was released as 9.0.5, - 8.4.9, 8.3.16 and 8.2.22). - - - - Pgpool-II V3.0.5 - or later uses a row lock - against pgpool_catalog.insert_lock - table because new PostgreSQL disallows a row lock against - the sequence relation. So creating insert_lock table in - all databases which are accessed via - Pgpool-II beforehand is - required. See - for more details. If does not exist insert_lock - table, Pgpool-II locks the - insert target table. This behavior is same - as Pgpool-II V2.2 - and V2.3 series. - - - If you want to use insert_lock which is - compatible with older releases, you can specify lock - method by configure script. - See for more details. - - - - For fine (per statement) control: - - - - - - set insert_lock to true, and add /*NO INSERT LOCK*/ at - the beginning of an INSERT statement for which you do - not want to acquire the table lock. - - - - - set insert_lock to false, and add /*INSERT LOCK*/ at - the beginning of an INSERT statement for which you - want to acquire the table lock. - - - - - - - If insert_lock is enabled, the regression tests for - PostgreSQL 8.0 gets fail in transactions, privileges, - rules, and alter_table. - - - The reason for this is - that Pgpool-II tries to LOCK - the VIEW for the rule test, and it produces the below - error message: - - ! ERROR: current transaction is aborted, commands ignored until - end of transaction block - - For example, the transactions test tries an INSERT into - a table which does not exist, - and Pgpool-II - causes PostgreSQL to acquire - the lock for the table. Of cause this results in an - error. The transaction will be aborted, and the - following INSERT statement produces the above error - message. - - - - Default is off. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - - - - lobj_lock_table (string) - - lobj_lock_table configuration parameter - - - - - Specifies a table name used for large object replication control. - If it is specified, Pgpool-II will lock - the table specified by lobj_lock_table and generate - a large object id by looking into pg_largeobject - system catalog and then call lo_create to create - the large object. - This procedure guarantees that Pgpool-II - will get the same large object id in all DB nodes in replication mode. - - - - PostgreSQL 8.0 and older does - not have lo_create, so this feature - does not work with PostgreSQL 8.0 and older versions. - - - - A call to the libpq - function lo_creat() triggers this - feature. Also large object creation - through Java API - (JDBC driver), PHP - API (pg_lo_create, or similar API in - PHP library such as PDO), and this same API in various - programming languages are known to use a similar protocol, - and thus should work. - - - - This feature does not works with following operations on large objects. - - - - - All APIs using lo_create, lo_import_with_oid. - - - - - lo_import function in backend called in SELECT. - - - - - lo_create function in backend called in SELECT. - - - - - - - All PostgreSQL users must - have a write access - on lobj_lock_table and it can be - created in any schema. - - - - - Example to create a large object lock table: - - CREATE TABLE public.my_lock_table (); - GRANT ALL ON public.my_lock_table TO PUBLIC; - - - - Default is ''(empty), which disables the feature. - - - - -
-
+ + + + + + + Logical replication mode + + + In this mode + PostgreSQL is responsible to replicate + each servers. To enable this mode, use logical_replication for + backend_clustering_mode. + +backend_clustering_mode = logical_replication + + In this mode you can have up to 127 logical replication standby servers. + Also it is possible not to have standby server at all. + + + + The drawback of this mode is, it is necessary to consider the + replication delay while distributing read queries. The visibility + consistency among nodes is not guaranteed either. Also certain + kind of objects such as DDL and large objects are not replicated. + + + + + + Raw mode + + In this mode, Pgpool-II does not care about the database synchronization. + It's user's responsibility to make the whole system does a meaningful thing. + Load balancing is not possible in the mode. + To enable this mode, use raw for backend_clustering_mode. + +backend_clustering_mode = raw + + +
- Backend Settings - - - Backend Connection Settings - - - - - backend_hostname (string) - - backend_hostname configuration parameter - - - - - - backend_hostname specifies the - PostgreSQL backend to be - connected to. It is used - by Pgpool-II to communicate - with the server. - - - - For TCP/IP communication, this parameter can take a - hostname or an IP address. If this begins with a - slash(/), it specifies Unix-domain - communication rather than TCP/IP; the value is the name of - the directory in which the socket file is stored. The - default behavior when backend_hostname is empty - ('') is to connect to a Unix-domain - socket in /tmp. - - - - Multiple backends can be specified by adding a number at the - end of the parameter name (e.g.backend_hostname0). This - number is referred to as "DB node ID", and it starts from - 0. The backend which was given the DB node ID of 0 will be - called "master node". When multiple backends are defined, the - service can be continued even if the master node is down (not - true in some modes). In this case, the youngest DB node ID - alive will be the new master node. - - - - Please note that the DB node which has id 0 has no special - meaning if operated in streaming replication mode. Rather, - you should care about if the DB node is the "primary node" or - not. See , - , - - for more details. - - - - If you plan to use only - one PostgreSQL server, specify - it by backend_hostname0. - - - - New nodes can be added by adding parameter rows and - reloading a configuration file. However, the existing - values cannot be updated, so you must - restart Pgpool-II in that case. - - - - - - - - backend_port (integer) - - backend_port configuration parameter - - - - - - backend_port specifies the port number - of the backends. Multiple backends can be specified by - adding a number at the end of the parameter name - (e.g. backend_port0). If you plan to use only one - PostgreSQL server, specify it by backend_port0. - - - New backend ports can be added by adding parameter rows - and reloading a configuration file. However, the existing - values cannot be updated, so you must - restart Pgpool-II in that case. - - - - - - backend_weight (floating point) - - backend_weight configuration parameter - - - - - - backend_weight specifies the load balance - ratio of the backends. It may be set to any interger or - floating point value greater than or equeal zero. - Multiple backends can be specified by - adding a number at the end of the parameter name - (e.g. backend_weight0). If you plan to use only one - PostgreSQL server, specify it by backend_weight0. - - - New backend_weight can be added in this parameter by - reloading a configuration file. However, this will take - effect only for new established client sessions. - Pgpool-II V2.2.6, V2.3 - or later allows alllow updating the values by reloading a - configuration file. This is useful if you want to prevent - any query sent to slaves to perform some administrative - work in master/slave mode. - - - - - - - - - Backend Data Settings - - - - - backend_data_directory (string) - - backend_data_directory configuration parameter - - - - - - backend_data_directory specifies the - database cluster directory of the backend. Multiple backends can be - specified by adding a number at the end of the parameter - name (e.g. backend_data_directory0). If you plan to use - only one PostgreSQL server, specify it by - backend_data_directory0. - - - New backend data_directory can be added by adding parameter rows and reloading a - configuration file. However, the existing values cannot be updated, so - you must restart Pgpool-II in - that case. - - - - - - backend_flag (string) - - backend_flag configuration parameter - - - - - - backend_flag controls various backend - behavior. Multiple backends can be specified by adding a - number at the end of the parameter name - (e.g. backend_flag0). If you plan to use only one - PostgreSQL server, specify it by backend_flag0. - - - New backend flags can be added by adding parameter rows and reloading a - configuration file. Currently followings are allowed. Multiple flags can - be specified by using "|". - - - - Backend flags - - - - Flag - Description - - - - - - ALLOW_TO_FAILOVER - Allow to failover or detaching backend. This - is the default. You cannot specify with - DISALLOW_TO_FAILOVER at a same time. - - - DISALLOW_TO_FAILOVER - Disllow to failover or detaching backend - This is useful when you protect backend by - using HA (High Availability) softwares such as - Heartbeat - or Pacemaker. You cannot specify with - ALLOW_TO_FAILOVER at a same time. - - - - - ALWAYS_MASTER - This is only useful in streaming replication - mode. See about - streaming replication mode. If this flag is set to - one of - backends, Pgpool-II will - not find the primary node by inspecting - backend. Instead, always regard the node which the - flag is set as the primary node. This is useful for - systems including Amazon Aurora for - PostgreSQL Compatibility which has - fixed master server name. See - for an example settings. - - - - - -
- - This parameter can be changed by reloading - the Pgpool-II configurations. - - -
-
- -
- -
+ Backend Settings + + + Backend Connection Settings + + + + + backend_hostname (string) + + backend_hostname configuration parameter + + + + + + backend_hostname specifies the + PostgreSQL backend to be + connected to. It is used + by Pgpool-II to communicate + with the server. + + + + For TCP/IP communication, this parameter can take a + hostname or an IP address. If this begins with a + slash(/), it specifies Unix-domain + communication rather than TCP/IP; the value is the name of + the directory in which the socket file is stored. The + default behavior when backend_hostname is empty + ('') is to connect to a Unix-domain + socket in /tmp. + + + + Multiple backends can be specified by adding a number at the + end of the parameter name (e.g.backend_hostname0). This + number is referred to as "DB node ID", and it starts from + 0. The backend which was given the DB node ID of 0 will be + called "main node". When multiple backends are defined, the + service can be continued even if the main node is down (not + true in some modes). In this case, the youngest DB node ID + alive will be the new main node. + + + + Please note that the DB node which has id 0 has no special + meaning if operated in streaming replication mode. Rather, + you should care about if the DB node is the "primary node" or + not. See , + , + + for more details. + + + + In a replication configuration, the host specified in + primary_conninfo on the standby side must match the value of + backend_hostname that Pgpool-II uses + to identify the primary node. + For example, if the primary node is backend0 (with hostname host0) + and the standby node is backend1 with backend_application_name + set to server1, then the postgresql.conf + on backend1 should be configured as follows: + +primary_conninfo = 'host=host0 port=5432 user=postgres application_name=''server1''' + + In this case, backend_hostname corresponding to backend0 + should also be set to host0. + If these values do not match, Pgpool-II may fail to + identify the primary node correctly, and features such as streaming replication + checks may not work as expected. + + + + If you plan to use only + one PostgreSQL server, specify + it by backend_hostname0. + + + + New nodes can be added by adding parameter rows and + reloading a configuration file. However, the existing + values cannot be updated, so you must + restart Pgpool-II in that case. + + + + + + + + backend_port (integer) + + backend_port configuration parameter + + + + + + backend_port specifies the port number + of the backends. Multiple backends can be specified by + adding a number at the end of the parameter name + (e.g. backend_port0). If you plan to use only one + PostgreSQL server, specify it by backend_port0. + + + New backend ports can be added by adding parameter rows + and reloading a configuration file. However, the existing + values cannot be updated, so you must + restart Pgpool-II in that case. + + + + + + backend_weight (floating point) + + backend_weight configuration parameter + + + + + + backend_weight specifies the load balance + ratio of the backends. It may be set to any integer or + floating point value greater than or equal to zero. + Multiple backends can be specified by + adding a number at the end of the parameter name + (e.g. backend_weight0). If you plan to use only one + PostgreSQL server, specify it by backend_weight0. + + + New backend_weight can be added in this parameter by + reloading a configuration file. However, this will take + effect only for new established client sessions. + Pgpool-II V2.2.6, V2.3 + or later allows updating the values by reloading a + configuration file. This is useful if you want to prevent + any query sent to standbys to perform some administrative + work in streaming replication mode, logical replication mode and slony mode. + + + + + + + + + Backend Data Settings + + + + + backend_data_directory (string) + + backend_data_directory configuration parameter + + + + + + backend_data_directory specifies the + database cluster directory of the backend. Multiple backends can be + specified by adding a number at the end of the parameter + name (e.g. backend_data_directory0). If you plan to use + only one PostgreSQL server, specify it by + backend_data_directory0. This parameter is used by online recovery. + If you do not use online recovery, you do not need to set it. + + + New backend data_directory can be added by adding parameter rows and reloading a + configuration file. However, the existing values cannot be updated, so + you must restart Pgpool-II in + that case. + + + + + + backend_flag (string) + + backend_flag configuration parameter + + + + + + backend_flag controls various backend + behavior. Multiple backends can be specified by adding a + number at the end of the parameter name + (e.g. backend_flag0). If you plan to use only one + PostgreSQL server, specify it by backend_flag0. + + + New backend flags can be added by adding parameter rows and reloading a + configuration file. Currently followings are allowed. Multiple flags can + be specified by using "|". + + + + Backend flags + + + + Flag + Description + + + + + + ALLOW_TO_FAILOVER + Allow to failover or detaching backend. This + is the default. You cannot specify with + DISALLOW_TO_FAILOVER at a same time. + + + DISALLOW_TO_FAILOVER + Disallow to failover or detaching backend + This is useful when you protect backend by + using HA (High Availability) softwares such as + Heartbeat + or Pacemaker. You cannot specify with + ALLOW_TO_FAILOVER at a same time. + + + + + ALWAYS_PRIMARY + This is only useful in streaming replication + mode. See about + streaming replication mode. If this flag is set to + one of + backends, Pgpool-II will + not find the primary node by inspecting + backend. Instead, always regard the node which the + flag is set as the primary node. This is useful for + systems including Amazon Aurora for + PostgreSQL Compatibility which has + fixed primary server name. See + for an example settings. + + + + + +
+ + This parameter can be changed by reloading + the Pgpool-II configurations. + + +
+
+ + + backend_application_name (string) + + backend_application_name configuration parameter + + + + + + backend_application_name specifies the + application name of walreceiver, which receives WAL log + from primary node. Thus in other than streaming + replication mode, this parameter does not need to be set. + Also this parameter is required to if you want to show + "replication_state" and "replication_sync_state" column + in and commands. + Moreover requires + this parameter too. + + + For example, suppose the primary node is backend0 (its host name + is "host0"), the standby node in question is backend1 and the + backend_application_name for backend1 is "server1", then + primary_conninfo parameter of + postgresql.conf should look like: + +primary_conninfo = 'host=host0 port=5432 user=postgres application_name='server1'' + + The should + generate the parameter. See for a + complete example of the command. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + + +
+ +
diff --git a/doc/src/sgml/errcodes-table.sgml b/doc/src/sgml/errcodes-table.sgml index 1c518cf64..5d6a6860c 100644 --- a/doc/src/sgml/errcodes-table.sgml +++ b/doc/src/sgml/errcodes-table.sgml @@ -2,1370 +2,1370 @@ -Class 00 — Successful Completion + Class 00 — Successful Completion -00000 -successful_completion + 00000 + successful_completion -Class 01 — Warning + Class 01 — Warning -01000 -warning + 01000 + warning -0100C -dynamic_result_sets_returned + 0100C + dynamic_result_sets_returned -01008 -implicit_zero_bit_padding + 01008 + implicit_zero_bit_padding -01003 -null_value_eliminated_in_set_function + 01003 + null_value_eliminated_in_set_function -01007 -privilege_not_granted + 01007 + privilege_not_granted -01006 -privilege_not_revoked + 01006 + privilege_not_revoked -01004 -string_data_right_truncation + 01004 + string_data_right_truncation -01P01 -deprecated_feature + 01P01 + deprecated_feature -Class 02 — No Data (this is also a warning class per the SQL standard) + Class 02 — No Data (this is also a warning class per the SQL standard) -02000 -no_data + 02000 + no_data -02001 -no_additional_dynamic_result_sets_returned + 02001 + no_additional_dynamic_result_sets_returned -Class 03 — SQL Statement Not Yet Complete + Class 03 — SQL Statement Not Yet Complete -03000 -sql_statement_not_yet_complete + 03000 + sql_statement_not_yet_complete -Class 08 — Connection Exception + Class 08 — Connection Exception -08000 -connection_exception + 08000 + connection_exception -08003 -connection_does_not_exist + 08003 + connection_does_not_exist -08006 -connection_failure + 08006 + connection_failure -08001 -sqlclient_unable_to_establish_sqlconnection + 08001 + sqlclient_unable_to_establish_sqlconnection -08004 -sqlserver_rejected_establishment_of_sqlconnection + 08004 + sqlserver_rejected_establishment_of_sqlconnection -08007 -transaction_resolution_unknown + 08007 + transaction_resolution_unknown -08P01 -protocol_violation + 08P01 + protocol_violation -Class 09 — Triggered Action Exception + Class 09 — Triggered Action Exception -09000 -triggered_action_exception + 09000 + triggered_action_exception -Class 0A — Feature Not Supported + Class 0A — Feature Not Supported -0A000 -feature_not_supported + 0A000 + feature_not_supported -Class 0B — Invalid Transaction Initiation + Class 0B — Invalid Transaction Initiation -0B000 -invalid_transaction_initiation + 0B000 + invalid_transaction_initiation -Class 0F — Locator Exception + Class 0F — Locator Exception -0F000 -locator_exception + 0F000 + locator_exception -0F001 -invalid_locator_specification + 0F001 + invalid_locator_specification -Class 0L — Invalid Grantor + Class 0L — Invalid Grantor -0L000 -invalid_grantor + 0L000 + invalid_grantor -0LP01 -invalid_grant_operation + 0LP01 + invalid_grant_operation -Class 0P — Invalid Role Specification + Class 0P — Invalid Role Specification -0P000 -invalid_role_specification + 0P000 + invalid_role_specification -Class 0Z — Diagnostics Exception + Class 0Z — Diagnostics Exception -0Z000 -diagnostics_exception + 0Z000 + diagnostics_exception -0Z002 -stacked_diagnostics_accessed_without_active_handler + 0Z002 + stacked_diagnostics_accessed_without_active_handler -Class 20 — Case Not Found + Class 20 — Case Not Found -20000 -case_not_found + 20000 + case_not_found -Class 21 — Cardinality Violation + Class 21 — Cardinality Violation -21000 -cardinality_violation + 21000 + cardinality_violation -Class 22 — Data Exception + Class 22 — Data Exception -22000 -data_exception + 22000 + data_exception -2202E -array_subscript_error + 2202E + array_subscript_error -22021 -character_not_in_repertoire + 22021 + character_not_in_repertoire -22008 -datetime_field_overflow + 22008 + datetime_field_overflow -22012 -division_by_zero + 22012 + division_by_zero -22005 -error_in_assignment + 22005 + error_in_assignment -2200B -escape_character_conflict + 2200B + escape_character_conflict -22022 -indicator_overflow + 22022 + indicator_overflow -22015 -interval_field_overflow + 22015 + interval_field_overflow -2201E -invalid_argument_for_logarithm + 2201E + invalid_argument_for_logarithm -22014 -invalid_argument_for_ntile_function + 22014 + invalid_argument_for_ntile_function -22016 -invalid_argument_for_nth_value_function + 22016 + invalid_argument_for_nth_value_function -2201F -invalid_argument_for_power_function + 2201F + invalid_argument_for_power_function -2201G -invalid_argument_for_width_bucket_function + 2201G + invalid_argument_for_width_bucket_function -22018 -invalid_character_value_for_cast + 22018 + invalid_character_value_for_cast -22007 -invalid_datetime_format + 22007 + invalid_datetime_format -22019 -invalid_escape_character + 22019 + invalid_escape_character -2200D -invalid_escape_octet + 2200D + invalid_escape_octet -22025 -invalid_escape_sequence + 22025 + invalid_escape_sequence -22P06 -nonstandard_use_of_escape_character + 22P06 + nonstandard_use_of_escape_character -22010 -invalid_indicator_parameter_value + 22010 + invalid_indicator_parameter_value -22023 -invalid_parameter_value + 22023 + invalid_parameter_value -2201B -invalid_regular_expression + 2201B + invalid_regular_expression -2201W -invalid_row_count_in_limit_clause + 2201W + invalid_row_count_in_limit_clause -2201X -invalid_row_count_in_result_offset_clause + 2201X + invalid_row_count_in_result_offset_clause -22009 -invalid_time_zone_displacement_value + 22009 + invalid_time_zone_displacement_value -2200C -invalid_use_of_escape_character + 2200C + invalid_use_of_escape_character -2200G -most_specific_type_mismatch + 2200G + most_specific_type_mismatch -22004 -null_value_not_allowed + 22004 + null_value_not_allowed -22002 -null_value_no_indicator_parameter + 22002 + null_value_no_indicator_parameter -22003 -numeric_value_out_of_range + 22003 + numeric_value_out_of_range -22026 -string_data_length_mismatch + 22026 + string_data_length_mismatch -22001 -string_data_right_truncation + 22001 + string_data_right_truncation -22011 -substring_error + 22011 + substring_error -22027 -trim_error + 22027 + trim_error -22024 -unterminated_c_string + 22024 + unterminated_c_string -2200F -zero_length_character_string + 2200F + zero_length_character_string -22P01 -floating_point_exception + 22P01 + floating_point_exception -22P02 -invalid_text_representation + 22P02 + invalid_text_representation -22P03 -invalid_binary_representation + 22P03 + invalid_binary_representation -22P04 -bad_copy_file_format + 22P04 + bad_copy_file_format -22P05 -untranslatable_character + 22P05 + untranslatable_character -2200L -not_an_xml_document + 2200L + not_an_xml_document -2200M -invalid_xml_document + 2200M + invalid_xml_document -2200N -invalid_xml_content + 2200N + invalid_xml_content -2200S -invalid_xml_comment + 2200S + invalid_xml_comment -2200T -invalid_xml_processing_instruction + 2200T + invalid_xml_processing_instruction -Class 23 — Integrity Constraint Violation + Class 23 — Integrity Constraint Violation -23000 -integrity_constraint_violation + 23000 + integrity_constraint_violation -23001 -restrict_violation + 23001 + restrict_violation -23502 -not_null_violation + 23502 + not_null_violation -23503 -foreign_key_violation + 23503 + foreign_key_violation -23505 -unique_violation + 23505 + unique_violation -23514 -check_violation + 23514 + check_violation -23P01 -exclusion_violation + 23P01 + exclusion_violation -Class 24 — Invalid Cursor State + Class 24 — Invalid Cursor State -24000 -invalid_cursor_state + 24000 + invalid_cursor_state -Class 25 — Invalid Transaction State + Class 25 — Invalid Transaction State -25000 -invalid_transaction_state + 25000 + invalid_transaction_state -25001 -active_sql_transaction + 25001 + active_sql_transaction -25002 -branch_transaction_already_active + 25002 + branch_transaction_already_active -25008 -held_cursor_requires_same_isolation_level + 25008 + held_cursor_requires_same_isolation_level -25003 -inappropriate_access_mode_for_branch_transaction + 25003 + inappropriate_access_mode_for_branch_transaction -25004 -inappropriate_isolation_level_for_branch_transaction + 25004 + inappropriate_isolation_level_for_branch_transaction -25005 -no_active_sql_transaction_for_branch_transaction + 25005 + no_active_sql_transaction_for_branch_transaction -25006 -read_only_sql_transaction + 25006 + read_only_sql_transaction -25007 -schema_and_data_statement_mixing_not_supported + 25007 + schema_and_data_statement_mixing_not_supported -25P01 -no_active_sql_transaction + 25P01 + no_active_sql_transaction -25P02 -in_failed_sql_transaction + 25P02 + in_failed_sql_transaction -Class 26 — Invalid SQL Statement Name + Class 26 — Invalid SQL Statement Name -26000 -invalid_sql_statement_name + 26000 + invalid_sql_statement_name -Class 27 — Triggered Data Change Violation + Class 27 — Triggered Data Change Violation -27000 -triggered_data_change_violation + 27000 + triggered_data_change_violation -Class 28 — Invalid Authorization Specification + Class 28 — Invalid Authorization Specification -28000 -invalid_authorization_specification + 28000 + invalid_authorization_specification -28P01 -invalid_password + 28P01 + invalid_password -Class 2B — Dependent Privilege Descriptors Still Exist + Class 2B — Dependent Privilege Descriptors Still Exist -2B000 -dependent_privilege_descriptors_still_exist + 2B000 + dependent_privilege_descriptors_still_exist -2BP01 -dependent_objects_still_exist + 2BP01 + dependent_objects_still_exist -Class 2D — Invalid Transaction Termination + Class 2D — Invalid Transaction Termination -2D000 -invalid_transaction_termination + 2D000 + invalid_transaction_termination -Class 2F — SQL Routine Exception + Class 2F — SQL Routine Exception -2F000 -sql_routine_exception + 2F000 + sql_routine_exception -2F005 -function_executed_no_return_statement + 2F005 + function_executed_no_return_statement -2F002 -modifying_sql_data_not_permitted + 2F002 + modifying_sql_data_not_permitted -2F003 -prohibited_sql_statement_attempted + 2F003 + prohibited_sql_statement_attempted -2F004 -reading_sql_data_not_permitted + 2F004 + reading_sql_data_not_permitted -Class 34 — Invalid Cursor Name + Class 34 — Invalid Cursor Name -34000 -invalid_cursor_name + 34000 + invalid_cursor_name -Class 38 — External Routine Exception + Class 38 — External Routine Exception -38000 -external_routine_exception + 38000 + external_routine_exception -38001 -containing_sql_not_permitted + 38001 + containing_sql_not_permitted -38002 -modifying_sql_data_not_permitted + 38002 + modifying_sql_data_not_permitted -38003 -prohibited_sql_statement_attempted + 38003 + prohibited_sql_statement_attempted -38004 -reading_sql_data_not_permitted + 38004 + reading_sql_data_not_permitted -Class 39 — External Routine Invocation Exception + Class 39 — External Routine Invocation Exception -39000 -external_routine_invocation_exception + 39000 + external_routine_invocation_exception -39001 -invalid_sqlstate_returned + 39001 + invalid_sqlstate_returned -39004 -null_value_not_allowed + 39004 + null_value_not_allowed -39P01 -trigger_protocol_violated + 39P01 + trigger_protocol_violated -39P02 -srf_protocol_violated + 39P02 + srf_protocol_violated -Class 3B — Savepoint Exception + Class 3B — Savepoint Exception -3B000 -savepoint_exception + 3B000 + savepoint_exception -3B001 -invalid_savepoint_specification + 3B001 + invalid_savepoint_specification -Class 3D — Invalid Catalog Name + Class 3D — Invalid Catalog Name -3D000 -invalid_catalog_name + 3D000 + invalid_catalog_name -Class 3F — Invalid Schema Name + Class 3F — Invalid Schema Name -3F000 -invalid_schema_name + 3F000 + invalid_schema_name -Class 40 — Transaction Rollback + Class 40 — Transaction Rollback -40000 -transaction_rollback + 40000 + transaction_rollback -40002 -transaction_integrity_constraint_violation + 40002 + transaction_integrity_constraint_violation -40001 -serialization_failure + 40001 + serialization_failure -40003 -statement_completion_unknown + 40003 + statement_completion_unknown -40P01 -deadlock_detected + 40P01 + deadlock_detected -Class 42 — Syntax Error or Access Rule Violation + Class 42 — Syntax Error or Access Rule Violation -42000 -syntax_error_or_access_rule_violation + 42000 + syntax_error_or_access_rule_violation -42601 -syntax_error + 42601 + syntax_error -42501 -insufficient_privilege + 42501 + insufficient_privilege -42846 -cannot_coerce + 42846 + cannot_coerce -42803 -grouping_error + 42803 + grouping_error -42P20 -windowing_error + 42P20 + windowing_error -42P19 -invalid_recursion + 42P19 + invalid_recursion -42830 -invalid_foreign_key + 42830 + invalid_foreign_key -42602 -invalid_name + 42602 + invalid_name -42622 -name_too_long + 42622 + name_too_long -42939 -reserved_name + 42939 + reserved_name -42804 -datatype_mismatch + 42804 + datatype_mismatch -42P18 -indeterminate_datatype + 42P18 + indeterminate_datatype -42P21 -collation_mismatch + 42P21 + collation_mismatch -42P22 -indeterminate_collation + 42P22 + indeterminate_collation -42809 -wrong_object_type + 42809 + wrong_object_type -42703 -undefined_column + 42703 + undefined_column -42883 -undefined_function + 42883 + undefined_function -42P01 -undefined_table + 42P01 + undefined_table -42P02 -undefined_parameter + 42P02 + undefined_parameter -42704 -undefined_object + 42704 + undefined_object -42701 -duplicate_column + 42701 + duplicate_column -42P03 -duplicate_cursor + 42P03 + duplicate_cursor -42P04 -duplicate_database + 42P04 + duplicate_database -42723 -duplicate_function + 42723 + duplicate_function -42P05 -duplicate_prepared_statement + 42P05 + duplicate_prepared_statement -42P06 -duplicate_schema + 42P06 + duplicate_schema -42P07 -duplicate_table + 42P07 + duplicate_table -42712 -duplicate_alias + 42712 + duplicate_alias -42710 -duplicate_object + 42710 + duplicate_object -42702 -ambiguous_column + 42702 + ambiguous_column -42725 -ambiguous_function + 42725 + ambiguous_function -42P08 -ambiguous_parameter + 42P08 + ambiguous_parameter -42P09 -ambiguous_alias + 42P09 + ambiguous_alias -42P10 -invalid_column_reference + 42P10 + invalid_column_reference -42611 -invalid_column_definition + 42611 + invalid_column_definition -42P11 -invalid_cursor_definition + 42P11 + invalid_cursor_definition -42P12 -invalid_database_definition + 42P12 + invalid_database_definition -42P13 -invalid_function_definition + 42P13 + invalid_function_definition -42P14 -invalid_prepared_statement_definition + 42P14 + invalid_prepared_statement_definition -42P15 -invalid_schema_definition + 42P15 + invalid_schema_definition -42P16 -invalid_table_definition + 42P16 + invalid_table_definition -42P17 -invalid_object_definition + 42P17 + invalid_object_definition -Class 44 — WITH CHECK OPTION Violation + Class 44 — WITH CHECK OPTION Violation -44000 -with_check_option_violation + 44000 + with_check_option_violation -Class 53 — Insufficient Resources + Class 53 — Insufficient Resources -53000 -insufficient_resources + 53000 + insufficient_resources -53100 -disk_full + 53100 + disk_full -53200 -out_of_memory + 53200 + out_of_memory -53300 -too_many_connections + 53300 + too_many_connections -53400 -configuration_limit_exceeded + 53400 + configuration_limit_exceeded -Class 54 — Program Limit Exceeded + Class 54 — Program Limit Exceeded -54000 -program_limit_exceeded + 54000 + program_limit_exceeded -54001 -statement_too_complex + 54001 + statement_too_complex -54011 -too_many_columns + 54011 + too_many_columns -54023 -too_many_arguments + 54023 + too_many_arguments -Class 55 — Object Not In Prerequisite State + Class 55 — Object Not In Prerequisite State -55000 -object_not_in_prerequisite_state + 55000 + object_not_in_prerequisite_state -55006 -object_in_use + 55006 + object_in_use -55P02 -cant_change_runtime_param + 55P02 + cant_change_runtime_param -55P03 -lock_not_available + 55P03 + lock_not_available -Class 57 — Operator Intervention + Class 57 — Operator Intervention -57000 -operator_intervention + 57000 + operator_intervention -57014 -query_canceled + 57014 + query_canceled -57P01 -admin_shutdown + 57P01 + admin_shutdown -57P02 -crash_shutdown + 57P02 + crash_shutdown -57P03 -cannot_connect_now + 57P03 + cannot_connect_now -57P04 -database_dropped + 57P04 + database_dropped -Class 58 — System Error (errors external to PostgreSQL itself) + Class 58 — System Error (errors external to PostgreSQL itself) -58000 -system_error + 58000 + system_error -58030 -io_error + 58030 + io_error -58P01 -undefined_file + 58P01 + undefined_file -58P02 -duplicate_file + 58P02 + duplicate_file -Class F0 — Configuration File Error + Class F0 — Configuration File Error -F0000 -config_file_error + F0000 + config_file_error -F0001 -lock_file_exists + F0001 + lock_file_exists -Class HV — Foreign Data Wrapper Error (SQL/MED) + Class HV — Foreign Data Wrapper Error (SQL/MED) -HV000 -fdw_error + HV000 + fdw_error -HV005 -fdw_column_name_not_found + HV005 + fdw_column_name_not_found -HV002 -fdw_dynamic_parameter_value_needed + HV002 + fdw_dynamic_parameter_value_needed -HV010 -fdw_function_sequence_error + HV010 + fdw_function_sequence_error -HV021 -fdw_inconsistent_descriptor_information + HV021 + fdw_inconsistent_descriptor_information -HV024 -fdw_invalid_attribute_value + HV024 + fdw_invalid_attribute_value -HV007 -fdw_invalid_column_name + HV007 + fdw_invalid_column_name -HV008 -fdw_invalid_column_number + HV008 + fdw_invalid_column_number -HV004 -fdw_invalid_data_type + HV004 + fdw_invalid_data_type -HV006 -fdw_invalid_data_type_descriptors + HV006 + fdw_invalid_data_type_descriptors -HV091 -fdw_invalid_descriptor_field_identifier + HV091 + fdw_invalid_descriptor_field_identifier -HV00B -fdw_invalid_handle + HV00B + fdw_invalid_handle -HV00C -fdw_invalid_option_index + HV00C + fdw_invalid_option_index -HV00D -fdw_invalid_option_name + HV00D + fdw_invalid_option_name -HV090 -fdw_invalid_string_length_or_buffer_length + HV090 + fdw_invalid_string_length_or_buffer_length -HV00A -fdw_invalid_string_format + HV00A + fdw_invalid_string_format -HV009 -fdw_invalid_use_of_null_pointer + HV009 + fdw_invalid_use_of_null_pointer -HV014 -fdw_too_many_handles + HV014 + fdw_too_many_handles -HV001 -fdw_out_of_memory + HV001 + fdw_out_of_memory -HV00P -fdw_no_schemas + HV00P + fdw_no_schemas -HV00J -fdw_option_name_not_found + HV00J + fdw_option_name_not_found -HV00K -fdw_reply_handle + HV00K + fdw_reply_handle -HV00Q -fdw_schema_not_found + HV00Q + fdw_schema_not_found -HV00R -fdw_table_not_found + HV00R + fdw_table_not_found -HV00L -fdw_unable_to_create_execution + HV00L + fdw_unable_to_create_execution -HV00M -fdw_unable_to_create_reply + HV00M + fdw_unable_to_create_reply -HV00N -fdw_unable_to_establish_connection + HV00N + fdw_unable_to_establish_connection -Class P0 — PL/pgSQL Error + Class P0 — PL/pgSQL Error -P0000 -plpgsql_error + P0000 + plpgsql_error -P0001 -raise_exception + P0001 + raise_exception -P0002 -no_data_found + P0002 + no_data_found -P0003 -too_many_rows + P0003 + too_many_rows -Class XX — Internal Error + Class XX — Internal Error -XX000 -internal_error + XX000 + internal_error -XX001 -data_corrupted + XX001 + data_corrupted -XX002 -index_corrupted + XX002 + index_corrupted diff --git a/doc/src/sgml/example-AWS.sgml b/doc/src/sgml/example-AWS.sgml new file mode 100644 index 000000000..497616e50 --- /dev/null +++ b/doc/src/sgml/example-AWS.sgml @@ -0,0 +1,532 @@ + + + + AWS Configuration Example + + + This tutorial shows an example of setting a virtual IP + when using watchdog on AWS. + + + There are several methods to set up a virtual IP on AWS. This example describes the following methods: + + + + + Assigning Elastic IP + + + + + + Updating route table + + + + + + Assigning Elastic IP + + This section explains how to use an Elastic IP address as a virtual IP and associate it with the leader Pgpool-II (watchdog) instance. + + + + AWS Setup + + When using this method, it is assumed that the Pgpool-II + EC2 instance is placed in a public subnet and clients connect to + Pgpool-II via Internet. + This method supports multiple availability zones. + + + In this example, we will use three nodes Pgpool-II + (watchdog) cluster. So we will create three EC2 instances and one Elastic IP address. + + + Complete the following steps to setup AWS: + + + + + + + Launch three EC2 instances. + + + + + + Configure the security group for the Pgpool-II instances. + + + + + Allow inbound traffic on ports used by Pgpool-II and watchdog. + + + + + Since Pgpool-II (watchdog) will ping the virtual IP to check connectivity, + allow inbound ICMP traffic from the Elastic IP (Source). + + + + + + + + Install Pgpool-II on each instance. + + + + + + AWS CLI is + a tool to manage your AWS services on EC2 instances. + Install AWS CLI on each Pgpool-II instance. + + + + Furthermore, run aws configure as Pgpool-II startup user + to create the config and credentials files so that Pgpool-II + startup user can run AWS CLI. + If Pgpool-II is installed using RPM packages, + Pgpool-II is running as postgres + user by default. + + + + + + Allocate an Elastic IP address. + In this example, we will use "35.163.178.3". + + + + + + + <productname>Pgpool-II</productname> configurations + + This section explains how to configure Pgpool-II. + Mostly the Pgpool-II configurations for this + example will be same as in the , except + using / + to assign/remove an Elastic IP address to/from the leader + Pgpool-II instance. + + + Specify the Elastic IP address to . + + +use_watchdog = on +delegate_ip = '35.163.178.3' + + + + Specify the script used to assign/remove Elastic IP address to + and . + is the script executed by the watchdog to + assign the Elastic IP to the instance when watchdog becomes the leader node. + is the script executed by watchdog to + remove the Elastic IP from the instance when watchdog resign from the leader node. + + + +if_up_cmd = '<path to script> up $_IP_$ <path to awscli>' +if_down_cmd = '<path to script> down $_IP_$ <path to awscli>' + + + + + + <path to script>: Specify the path to the script used to assign or remove Elastic IP address. + + + + + + <path to awscli>: Specify the path to AWS CLI command. + + + + + + In this example, we use the following settings. Replace them with your own settings. + + + +if_up_cmd = '/etc/pgpool-II/aws_eip_if_cmd.sh up $_IP_$ /usr/local/bin/aws' +if_down_cmd = '/etc/pgpool-II/aws_eip_if_cmd.sh down $_IP_$ /usr/local/bin/aws' + + + + Because arping isn't required on AWS, set it to 'true' to always return a successful exit status. + + +arping_cmd = 'true' + + + + + + Elastic IP assigning/removing script + + Create the script executed by if_up_cmd/if_down_cmd on each Pgpool-II instance. + + + In this example, we use the sample script aws_eip_if_cmd.sh. Modify it if necessary. + + +(run the following command on each Pgpool-II instance) +# cp -p /etc/pgpool-II/sample_scripts/aws_eip_if_cmd.sh.sample /etc/pgpool-II/aws_eip_if_cmd.sh + + + + + Try it out + + Start Pgpool-II on each Pgpool-II + instance. + Try to connect to Pgpool-II using the Elastic IP address. + + +[user@someserver]$ psql -h 35.163.178.3 -p 9999 -U postgres -c "show pool_nodes" + + + Stop the leader Pgpool-II. + Then the Elastic IP address is reassigned to the new leader Pgpool-II. + Verify that you can connect to Pgpool-II + using Elastic IP address even if the leader Pgpool-II + has switched over. + + +[user@someserver]$ psql -h 35.163.178.3 -p 9999 -U postgres -c "show pool_nodes" + + + + + + Updating Route Table + + This section describes how to control routing for the leader Pgpool-II (watchdog) + by updating the route table entry. + + + In this method, a private IP address is used as a virtual IP and assigned to the + leader Pgpool-II instance. If a failover occurs, reassign the virtual IP, + and route traffic with a destination address of the virtual IP to the new leader + Pgpool-II instance by updating route tables. + + + + AWS Setup + + When using this method, it is assumed that the Pgpool-II + EC2 instance is placed in a private subnet and the client application connects to + Pgpool-II within the same VPC. + This method supports multiple Availability Zones. + + + In this example, we will use three nodes + Pgpool-II (watchdog) cluster. So we will create three + EC2 instances across multiple Availability Zones. + + + Complete the following steps to setup AWS: + + + + + + + Create a VPC with one public subnet and three private subnets, + and each private subnet is in a different Availability Zone. + For detailed information, please refer to the + documentation. + + + + + + create two route tables associated with the public subnet and the private subnet + respectively. Please refer to this documentation + for detailed information. + + + + + + Launch one application EC2 instance in the public subnet and + three Pgpool-II EC2 instances in different private subnets. + + + + + + Configure a security group allowing traffic from the VPC CIDR block range + on the ports used by Pgpool-II and watchdog. + + + + + + Install Pgpool-II on each Pgpool-II EC2 instance. + + + + + + AWS CLI is + a tool to manage your AWS services on EC2 instances. + Install AWS CLI on each Pgpool-II instance. + + + + Furthermore, run aws configure as Pgpool-II startup user + to create the config and credentials files so that Pgpool-II + startup user can run AWS CLI. + If Pgpool-II is installed using RPM packages, + Pgpool-II is running as postgres + user by default. + + + + + + Assigning or removing a virtual IP address requires root privileges. + If you start Pgpool-II as a non-root user, + configure the sudoers file and allow this user to run sudo without being + asked for the password. + If Pgpool-II is installed using RPM packages, + the settings for postgres user are automatically added to sudoers. + + + + + + Choose an IPv4 address to be used as the virtual IP. + Because the secondary IP address cannot be reassigned across multiple subnets, + you need to choose a private IP address which should not belong to + the IP addresses range for VPC. + In this example, we use "20.0.0.50". + + + + + + + <productname>Pgpool-II</productname> configurations + + This section explains how to configure Pgpool-II. + Mostly the Pgpool-II configurations for this + example will be same as in the , except + using and + to assign the virtual IP and update route tables. + + + Specify the virtual IP to . + + + +use_watchdog = on +delegate_ip = '20.0.0.50' + + + + Specify the script used to update route table to + and . + is the script executed by watchdog to + assign the virtual IP and update route tables when watchdog becomes the leader node. + is the script executed by watchdog to + remove the virtual IP and update route tables when watchdog resign from the leader node. + + +if_up_cmd = '<path to script> up $_IP_$ <interface> <route table ID> <path to awscli>' +if_down_cmd = '<path to script> down $_IP_$ <interface> <route table ID> <path to awscli>' + + + + + + + <path to script>: Specify the path to the script used to assign the virtual IP and update route tables. + + + + + + <interface>: Specify the network interface to assign the virtual IP. + + + + + + <route table ID>: Specify the route table IDs (e.g. client application or + Pgpool-II instance) to be updated. + You can specify multiple comma separated route table IDs. + + + + + + <path to awscli>: Specify the path to AWS CLI command. + + + + + + + In this example, we use the following settings. Replace them with your own settings. + Specify the route table IDs associated with the public subnet where the application + EC2 instance is located and the private subnet where the Pgpool-II + EC2 instances are located. + + + +if_up_cmd = '/etc/pgpool-II/aws_rtb_if_cmd.sh up $_IP_$ eth0 rtb-012345abcd,rtb-67890abcd /usr/local/bin/aws' +if_down_cmd = '/etc/pgpool-II/aws_rtb_if_cmd.sh down $_IP_$ eth0 rtb-012345abcd,rtb-67890abcd /usr/local/bin/aws' + + + + Because arping isn't required on AWS, set it to 'true' to always return a successful exit status. + + +arping_cmd = 'true' + + + + + Route table updating script + + Create the script executed by if_up_cmd/if_down_cmd on each + Pgpool-II instance. + + + In this example, we use the sample script aws_rtb_if_cmd.sh. Modify it if necessary. + + +(run the following command on each Pgpool-II instance) +# cp -p /etc/pgpool-II/sample_scripts/aws_rtb_if_cmd.sh.sample /etc/pgpool-II/aws_rtb_if_cmd.sh + + + + + Disabling source/destination check + + AWS EC2 instance checks the source or the destination of any received + traffics by default. You must disable source/destination check on each + Pgpool-II instance to route the traffic for virtual IP + to the target instance. + + + Disable "source/destination check" in the network interface settings of all + Pgpool-II instances. + It can be configured through the AWS Management Console + or using AWS CLI. When using the AWS CLI, execute the following command. + Set LOCAL_INTERFACE to the network interface where the virtual IP will be added. + In the example, we use eth0. + + + +$ sudo su - postgres +$ TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") +$ LOCAL_INTERFACE=eth0 +$ MAC_ADDR=$(ip -br link show dev ${LOCAL_INTERFACE} | tr -s ' ' | cut -d ' ' -f3) +$ EC2_NETWORK_INTERFACE_ID=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC_ADDR}/interface-id) +$ aws ec2 modify-network-interface-attribute --network-interface-id ${EC2_NETWORK_INTERFACE_ID} --no-source-dest-check + + + + + Try it out + + Start Pgpool-II on each Pgpool-II + instance. + Try to connect to Pgpool-II using the virtual IP + from the application instance. + + +[user@application instance]$ psql -h 20.0.0.50 -p 9999 -U postgres -c "show pool_nodes" + + + Stop the leader Pgpool-II. + Then the virtual IP is reassigned to the new leader Pgpool-II. + Verify that you can connect to Pgpool-II + using Elastic IP address from application instance even if the leader + Pgpool-II has switched over. + + +[user@application instance]$ psql -h 20.0.0.50 -p 9999 -U postgres -c "show pool_nodes" + + + + + + AWS Command References + + + + <ulink url="http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html">Configure AWS CLI</ulink> + + + AWS Documentation: Configuring the AWS Command Line Interface + + + + + + <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/associate-address.html">associate-address</ulink> + + + AWS Documentation: associate-address reference + + + + + + <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/disassociate-address.html">disassociate-address</ulink> + + + AWS Documentation: disassociate-address reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/create-route.html">create-route</ulink> + + + AWS Documentation: create-route reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/replace-route.html">replace-route</ulink> + + + AWS Documentation: replace-route reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-route.html">delete-route</ulink> + + + AWS Documentation: delete-route reference + + + + + + <ulink url="https://docs.aws.amazon.com/cli/latest/reference/ec2/modify-network-interface-attribute.html">modify-network-interface-attribute</ulink> + + + AWS Documentation: modify-network-interface-attribute + + + + + diff --git a/doc/src/sgml/example-Aurora.sgml b/doc/src/sgml/example-Aurora.sgml new file mode 100644 index 000000000..540132f32 --- /dev/null +++ b/doc/src/sgml/example-Aurora.sgml @@ -0,0 +1,109 @@ + + Aurora Configuration Example + + + Amazon Aurora for PostgreSQL + Compatibility (Aurora) is a managed service for + PostgreSQL. From user's point of + view, Aurora can be regarded as a + streaming replication cluster with some exceptions. First, + fail over and online recovery are managed + by Aurora. So you don't need to + set , , + and recovery related parameters. In this section we explain + how to set up Pgpool-II for Aurora. + + + + Setting pgpool.conf for Aurora + + + + + Create pgpool.conf + from pgpool.conf.sample. + Make sure your pgpool.conf includes following line: + +backend_clustering_mode = streaming_replication + + + + + + Set to 0 to + disable streaming replication delay checking. This + is because Aurora does + not provide necessary functions to check the + replication delay. + + +sr_check_period = 0 + + + + + Enable to on so + that md5 authentication is enabled + (Aurora always use md5 + authentication). + + +enable_pool_hba = on + + + + + Create pool_password. See + for more details. + + + + + Set 0 for the Aurora cluster endpoint. + Set 1 for the Aurora reader endpoint. + Set appropriate as usual. + You don't need to set . + + +backend_hostname0 = 'cluster endpoint' +backend_hostname1 = 'reader endpoint' + + + + + Set ALWAYS_PRIMARY flag to + the + for 0. + + + + + Because failover is managed by Aurora, set DISALLOW_TO_FAILOVER flag to + the + for 0 and 1. + + +backend_flag0 = 'ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER' +backend_flag1 = 'DISALLOW_TO_FAILOVER' + + + + + Set to 0 to disable health checking. + + +health_check_period = 0 + + + + + Disable + to avoid failover when connecting to the backend or + detecting errors on backend side while executing + queries for the same reasons above. + + + + + + diff --git a/doc/src/sgml/example-basic.sgml b/doc/src/sgml/example-basic.sgml new file mode 100644 index 000000000..a58e47212 --- /dev/null +++ b/doc/src/sgml/example-basic.sgml @@ -0,0 +1,351 @@ + + + Basic Configuration Example + + + Let's Begin! + + First, we must learn how to install and configure Pgpool-II and database nodes before using replication. + + + + Installing <productname>Pgpool-II</productname> + + Installing Pgpool-II is very easy. + In the directory which you have extracted the source tar ball, + execute the following commands. + + $ ./configure + $ make + $ make install + + configure script collects your system information + and use it for the compilation procedure. You can pass command + line arguments to configure script to change the default behavior, + such as the installation directory. Pgpool-II + will be installed to /usr/local directory by default. + + + make command compiles the source code, and + make install will install the executables. + You must have write permission on the installation directory. + In this tutorial, we will install Pgpool-II + in the default /usr/local directory. + + + + Pgpool-II requires libpq + library in PostgreSQL 7.4 or later (version 3 protocol). + + + + If the configure script displays the following error message, the + libpq library may not be installed, or it is not of version 3 + + configure: error: libpq is not installed or libpq is old + + If the library is version 3, but the above message is still displayed, your + libpq library is probably not recognized by the + configure script. + The configure script searches for libpq + library under /usr/local/pgsql. If you have installed the + PostgreSQL in a directory other than /usr/local/pgsql, use + --with-pgsql, or --with-pgsql-includedir + and --with-pgsql-libdir command line options when you + execute configure. + + + + + Configuration Files + + Pgpool-II configuration parameters are saved in the + pgpool.conf file. The file is in "parameter = value" + per line format. When you install Pgpool-II, + pgpool.conf.sample is automatically created. + We recommend copying and renaming it to pgpool.conf, and edit + it as you like. + + $ cp /usr/local/etc/pgpool.conf.sample /usr/local/etc/pgpool.conf + + Pgpool-II only accepts connections from the localhost + using port 9999 by the default. If you wish to receive connections from other hosts, + set to '*'. + + listen_addresses = 'localhost' + port = 9999 + + We will use the default parameters in this tutorial. + + + + + Configuring <acronym>PCP</acronym> Commands + + Pgpool-II has an interface for administrative + purpose to retrieve information on database nodes, shutdown + Pgpool-II, etc. via network. To use + PCP commands, user authentication is required. + This authentication is different from PostgreSQL's user authentication. + A user name and password need to be defined in the pcp.conf + file. In the file, a user name and password are listed as a pair on each line, + and they are separated by a colon (:). Passwords are encrypted in + md5 hash format. + + + postgres:e8a48653851e28c69d0506508fb27fc5 + + + When you install Pgpool-II, pcp.conf.sample + is automatically created. We recommend copying and renaming it + to pcp.conf, and edit it. + + $ cp /usr/local/etc/pcp.conf.sample /usr/local/etc/pcp.conf + + To encrypt your password into md5 hash format, use the pg_md5 + command, which is installed as one of Pgpool-II's + executables. pg_md5 takes text as a command line argument, + and displays its md5-hashed text. + For example, give "postgres" as the command line argument, + and pg_md5 displays md5-hashed text on its standard output. + + $ /usr/local/bin/pg_md5 postgres + e8a48653851e28c69d0506508fb27fc5 + + PCP commands are executed via network, so the port number must be configured + with parameter in pgpool.conf file. + We will use the default 9898 for in this tutorial. + + pcp_port = 9898 + + + + + + Preparing Database Nodes + + Now, we need to set up backend PostgreSQL servers for Pgpool-II + . These servers can be placed within the same host as + Pgpool-II, or on separate machines. If you decide + to place the servers on the same host, different port numbers must be assigned + for each server. If the servers are placed on separate machines, + they must be configured properly so that they can accept network + connections from Pgpool-II. + In this example, we create 3 PostgreSQL servers and + specify the PostgreSQL information in the following parameters. + + + backend_hostname0 = 'localhost' + backend_port0 = 5432 + backend_weight0 = 1 + backend_hostname1 = 'localhost' + backend_port1 = 5433 + backend_weight1 = 1 + backend_hostname2 = 'localhost' + backend_port2 = 5434 + backend_weight2 = 1 + + + For , , + , set the node's hostname, port number, + and ratio for load balancing. At the end of each parameter string, + node ID must be specified by adding positive integers starting with 0 (i.e. 0, 1, 2..). + + + + parameters for all nodes are + set to 1, meaning that SELECT queries are equally distributed among + three servers. + + + + + + Starting/Stopping <productname>Pgpool-II</productname> + + To fire up Pgpool-II, execute the following + command on a terminal. + + + $ pgpool + + + The above command, however, prints no log messages because + Pgpool-II detaches the terminal. If you want to show + Pgpool-II log messages, you pass -n + option to pgpool command so Pgpool-II + is executed as non-daemon process, and the terminal will not be detached. + + $ pgpool -n & + + + The log messages are printed on the terminal, so it is recommended to use the following options. + + $ pgpool -n -d > /tmp/pgpool.log 2>&1 & + + + The -d option enables debug messages to be generated. + The above command keeps appending log messages to /tmp/pgpool.log + . If you need to rotate log files, pass the logs to a external + command which has log rotation function. + For example, you can use + rotatelogs from Apache2: + + $ pgpool -n 2>&1 | /usr/local/apache2/bin/rotatelogs \ + -l -f /var/log/pgpool/pgpool.log.%A 86400 & + + + This will generate a log file named "pgpool.log.Thursday" + then rotate it 00:00 at midnight. Rotatelogs adds logs to a file if it already + exists. To delete old log files before rotation, you could use cron: + + 55 23 * * * /usr/bin/find /var/log/pgpool -type f -mtime +5 -exec /bin/rm -f '{}' \; + + + Please note that rotatelogs may exist as /usr/sbin/rotatelogs2 + in some distributions. -f option generates a log file as soon as + rotatelogs starts and is available in apache2 2.2.9 or greater. + Also cronolog can be used. + + $ pgpool -n 2>&1 | /usr/sbin/cronolog \ + --hardlink=/var/log/pgsql/pgpool.log \ + '/var/log/pgsql/%Y-%m-%d-pgpool.log' & + + + To stop Pgpool-II execute the following command. + + $ pgpool stop + + + If any client is still connected, Pgpool-II + waits for it to disconnect, and then terminates itself. Run the following + command instead if you want to shutdown Pgpool-II + forcibly. + + $ pgpool -m fast stop + + + + + + + + Your First Replication + + Replication (see ) enables + the same data to be copied to multiple database nodes. + In this section, we'll use three database nodes, which we have already set + up in , and takes you step by step to + create a database replication system. + Sample data to be replicated will be generated by the + + pgbench benchmark program. + + + + Configuring Replication + + To enable the database replication function, set + to on in pgpool.conf file. + + replication_mode = true + + When is on, Pgpool-II + will send a copy of a received query to all the database nodes. + In addition, when is set to true, + Pgpool-II will distribute SELECT queries + among the database nodes. + + load_balance_mode = true + + In this section, we will enable both + and . + + + + + Checking Replication + + To reflect the above changes in pgpool.conf, + Pgpool-II must be restarted. + Please refer to "Starting/Stopping Pgpool-II" + . + After configuring pgpool.conf and restarting the + Pgpool-II, let's try the actual replication + and see if everything is working. + First, we need to create a database to be replicated. We will name it + "bench_replication". This database needs to be created + on all the nodes. Use the + + createdb commands through + Pgpool-II, and the database will be created + on all the nodes. + + $ createdb -p 9999 bench_replication + + Then, we'll execute + pgbench with -i option. + -i option initializes the database with pre-defined tables and data. + + $ pgbench -i -p 9999 bench_replication + + The following table is the summary of tables and data, which will be created by + + pgbench -i. If, on all the nodes, the listed tables and + data are created, replication is working correctly. + + + + data summary + + + + Table Name + Number of Rows + + + + + + pgbench_branches + 1 + + + + pgbench_tellers + 10 + + + + pgbench_accounts + 100000 + + + + pgbench_history + 0 + + + + +
+ + + Let's use a simple shell script to check the above on all the nodes. + The following script will display the number of rows in pgbench_branches, + pgbench_tellers, pgbench_accounts, and pgbench_history tables on all the nodes (5432, 5433, 5434). + + $ for port in 5432 5433 5434; do + > echo $port + > for table_name in pgbench_branches pgbench_tellers pgbench_accounts pgbench_history; do + > echo $table_name + > psql -c "SELECT count(*) FROM $table_name" -p $port bench_replication + > done + > done + + + +
+
+ +
diff --git a/doc/src/sgml/example-cluster.sgml b/doc/src/sgml/example-cluster.sgml new file mode 100644 index 000000000..49d9e3d6b --- /dev/null +++ b/doc/src/sgml/example-cluster.sgml @@ -0,0 +1,1492 @@ + + <productname>Pgpool-II</productname> + Watchdog Setup Example + + This section shows an example of streaming replication configuration using + Pgpool-II. In this example, we use 3 + Pgpool-II servers to manage PostgreSQL + servers to create a robust cluster system and avoid the single point of failure or split brain. + + + PostgreSQL 18 is used in this configuration example. + + + Requirements + + We assume that all the Pgpool-II servers and the PostgreSQL servers are in the same subnet. + + + + + Cluster System Configuration + + We use three servers with Rocky Linux 10 installed and + the hostnames of the three servers are server1 + server2 and server3 respectively. + We install PostgreSQL and Pgpool-II on each server. + + +
+ Cluster System Configuration + + + + + +
+
+ + + The roles of Leader, Standby, Primary, + Standby are not fixed and may be changed by further operations. + + + + Hostname and IP address + + + + Hostname + IP Address + Virtual IP + + + + + server1 + 192.168.100.51 + 192.168.100.50 + + + server2 + 192.168.100.52 + + + server3 + 192.168.100.53 + + + +
+ + + PostgreSQL version and Configuration + + + + Item + Value + Detail + + + + + PostgreSQL Version + 18.0 + - + + + port + 5432 + - + + + $PGDATA + /var/lib/pgsql/18/data + - + + + Archive mode + off + - + + + Replication Slots + Enabled + In this configuration example, replication slots are + automatically created or deleted in the scripts which are executed + during failover or online recovery. + These scripts use the hostname specified in backend_hostnameX as + the replication slot name. + See for + more information about the scripts. + + + Async/Sync Replication + Async + - + + + +
+ + + Pgpool-II version and Configuration + + + + Item + Value + Detail + + + + + Pgpool-II Version + 4.6.1 + - + + + port + 9999 + Pgpool-II accepts connections + + + 9898 + PCP process accepts connections + + + 9000 + watchdog accepts connections + + + 9694 + UDP port for receiving Watchdog's heartbeat signal + + + Config file + /etc/pgpool-II/pgpool.conf + Pgpool-II config file + + + User running Pgpool-II + postgres (Pgpool-II 4.1 or later) + Pgpool-II 4.0 or before, the default user running Pgpool-II is root + + + Running mode + streaming replication mode + - + + + Watchdog + on + Life check method: heartbeat + + + +
+ + + Various sample scripts included in rpm package + + + + Feature + Script + Detail + + + + + Failover + /etc/pgpool-II/sample_scripts/failover.sh.sample + Run by to perform failover + + + /etc/pgpool-II/sample_scripts/follow_primary.sh.sample + Run by to synchronize the Standby with the new Primary after failover. + + + Online recovery + /etc/pgpool-II/sample_scripts/recovery_1st_stage.sample + Run by to recovery a Standby node + + + /etc/pgpool-II/sample_scripts/pgpool_remote_start.sample + Run after to start the Standby node + + + Watchdog + /etc/pgpool-II/sample_scripts/escalation.sh.sample + Optional Configuration. Run by to switch the Leader/Standby Pgpool-II safely + + + +
+ + The above scripts are included in the RPM package and can be customized as needed. + +
+ + + Installation + + In this example, we install Pgpool-II and PostgreSQL RPM packages with YUM. + + + + Install PostgreSQL from PostgreSQL YUM repository. + + +[all servers]# dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm +[all servers]# dnf -qy module disable postgresql +[all servers]# dnf install -y postgresql18-server + + + Since Pgpool-II related packages are also included in PostgreSQL YUM repository, + add the "exclude" settings to /etc/yum.repos.d/pgdg-redhat-all.repo + so that Pgpool-II is not installed from PostgreSQL YUM repository. + + +[all servers]# vi /etc/yum.repos.d/pgdg-redhat-all.repo + + + The following is a setting example of /etc/yum.repos.d/pgdg-redhat-all.repo. + + +[pgdg-common] +... +exclude=pgpool* + +[pgdg18] +... +exclude=pgpool* + +[pgdg17] +... +exclude=pgpool* + +[pgdg16] +... +exclude=pgpool* + +[pgdg15] +... +exclude=pgpool* + +[pgdg14] +... +exclude=pgpool* + +[pgdg13] +... +exclude=pgpool* + + + + Install Pgpool-II from + Pgpool-II YUM repository. + To install the required libmemcached library for Pgpool-II, + you need to enable crb repository. + If you're using Rocky Linux 8, + use powertools repository instead of + crb repository. + + +[all servers]# dnf install -y https://www.pgpool.net/yum/rpms/4.6/redhat/rhel-9-x86_64/pgpool-II-release-4.6-1.noarch.rpm +[all servers]# dnf install -y --enablerepo=crb pgpool-II-pg18-* + + + + + Before Starting + + Before you start the configuration process, please check the following prerequisites. + + + + Setting up SSH public key authentication + + To use the automated failover and online recovery of Pgpool-II, + it is required to configure SSH public key authentication + (passwordless SSH login) to all backend servers using + postgres user (the default user Pgpool-II is running as. + Pgpool-II 4.0 or before, the default user is root). + + + Execute the following command on all servers to generate a key pair using + the RSA algorithm. In this example, we assume that the generated key file + name is id_rsa_pgpool. + + +[all servers]# su - postgres +[all servers]$ mkdir ~/.ssh && chmod 700 ~/.ssh +[all servers]$ ssh-keygen -t rsa -f ~/.ssh/id_rsa_pgpool + + + Then add the public key id_rsa_pgpool.pub to + /var/lib/pgsql/.ssh/authorized_keys file + on each server. + + + After setting SSH, make sure that you can run + ssh postgres@serverX -i ~/.ssh/id_rsa_pgpool command + as postgres user to login to each server + without entering a password. + + + + + If you failed to login using SSH public key authentication, please check the following: + + + + Ensure the public key authentication option PubkeyAuthentication are allowed in /etc/ssh/sshd_config: + + + + +PubkeyAuthentication yes + + + + + If SELinux is enabled, SSH public key authentication (passwordless SSH) may fail. + You need to run the following command on all servers. + + + + +[all servers]# su - postgres +[all servers]$ restorecon -Rv ~/.ssh + + + + + + + Setting up firewall + + When connect to Pgpool-II and PostgreSQL servers, the target port must be accessible by enabling firewall management softwares. Following is an example for Rocky Linux 10/RHEL 10. + + +[all servers]# firewall-cmd --permanent --zone=public --add-service=postgresql +[all servers]# firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp --add-port=9000/tcp --add-port=9694/udp +[all servers]# firewall-cmd --reload + + + + + Setting up PostgreSQL primary + + Set up the PostgreSQL primary server on server1. + + + + First, initialize the database cluster. + In PostgreSQL 18, the default directory + for creating the database cluster is /var/lib/pgsql/18/data, + and this is specified in the environment variable PGDATA + in the ~/.bash_profile of the postgres + user. Modify it if you want to change the default path. + + + Run initdb to initialize the database cluster. + Specify options + such as --encoding and --locale + if you need to configure the database encoding and locale settings. + + +[root@server1 ~]# su - postgres +[postgres@server1 ~]$ /usr/pgsql-18/bin/initdb + + + + Then edit the configuration file $PGDATA/postgresql.conf + on server1 as follows. Enable wal_log_hints + to use pg_rewind. + + +[postgres@server1 ~]$ vi $PGDATA/postgresql.conf +listen_addresses = '*' +wal_log_hints = on + + + Start PostgreSQL on server1. + + +[postgres@server1 ~]$ /usr/pgsql-18/bin/pg_ctl start + + + + + Setting up PostgreSQL standby + + There are multiple methods to setup a standby server, such as: + + + + use Pgpool-II's online recovery feature + () to automatically + setup a standby server. + + + + + use pg_basebackup to backup the data directory of the primary from the standby. + + + + + + + + If you manually set up standby without using online recovery, please note the following: + + + + You must manually create the replication slots. + + + + + + + Do not specify the -R option when running pg_basebackup. + Write primary_conninfo, recovery_target_timeline, and primary_slot_name in $PGDATA/myrecovery.conf, not in postgresql.auto.conf, and add the following to postgresql.conf. + + + + +include_if_exists = 'myrecovery.conf' + + + + + + In this example, we use Pgpool-II's + online recovery to setup the standby server + in section + after the configuration of Pgpool-II + is completed. + + + + + Setting up PostgreSQL users + + A PostgreSQL user is required to use Pgpool-II's + health check and replication delay check features. + Because of the security reasons, we create a dedicated user named + pgpool for streaming replication delay check and + health check. + And create a dedicated user named repl for replication. + Because online recovery feature requires superuser privilege, + we use postgres user here. + + + Since Pgpool-II 4.0, + scram-sha-256 authentication is supported. + This configuration example uses scram-sha-256 + authentication method. + First, set password_encryption = 'scram-sha-256' + and then created the users. + + + + Users + + + + User Name + Password + Detail + + + + + repl + repl + PostgreSQL replication user + + + pgpool + pgpool + Pgpool-II health check () and replication delay check () user + + + postgres + postgres + User running online recovery + + + +
+ + +[postgres@server1 ~]$ psql +postgres=# SET password_encryption = 'scram-sha-256'; +postgres=# CREATE ROLE pgpool WITH LOGIN; +postgres=# CREATE ROLE repl WITH REPLICATION LOGIN; +postgres=# \password pgpool +postgres=# \password repl +postgres=# \password postgres + + + + To show replication_state and + replication_sync_state column in + command result, role + pgpool needs to be PostgreSQL superuser or in + pg_monitor group (Pgpool-II 4.1 or later). + Grant pg_monitor + to pgpool: + + +postgres=# GRANT pg_monitor TO pgpool; +postgres=# \q + + + + If you plan to use (Pgpool-II 4.0 or later), + role "pgpool" needs to be PostgreSQL superuser + or in pg_monitor group to use this feature. + + + + In this example, assuming that all the Pgpool-II servers and the + PostgreSQL servers are in the same subnet and edit pg_hba.conf to + enable scram-sha-256 authentication method. + + +[postgres@server1 ~]$ vi $PGDATA/pg_hba.conf +(Add the following entries) +host all pgpool samenet scram-sha-256 +host all postgres samenet scram-sha-256 +host replication repl samenet scram-sha-256 + +
+ + + Creating .pgpass + + To allow repl user without specifying password for streaming + replication and online recovery, and execute pg_rewind + using postgres, we + Create the .pgpass file in postgres + user's home directory and change the permission to 600 + on each PostgreSQL server. + This file allows repl user and postgres + user without providing a password for streaming replication and failover. + + +[postgres@server1 ~]$ vi ~/.pgpass +server1:5432:replication:repl:<repl user password> +server2:5432:replication:repl:<repl user password> +server3:5432:replication:repl:<repl user password> +server1:5432:postgres:postgres:<postgres user password> +server2:5432:postgres:postgres:<postgres user password> +server3:5432:postgres:postgres:<postgres user password> + +[postgres@server1 ~]$ chmod 600 ~/.pgpass + + + Copy it to the home directory of postgres user + on server2 and server3. + + +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpass postgres@server2: +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpass postgres@server3: + + +
+ + + PCP connection authentication + + To use PCP commands PCP user names and md5 encrypted passwords must be + declared in pcp.conf in format + "username:encrypted password". + + + In this example, we set PCP username to "pgpool" + and password to "pgpool_password". + Use to create the encrypted password entry for + pgpool user as below: + + +[postgres@server1 ~]$ echo 'pgpool:'`pg_md5 pgpool_password` >> /etc/pgpool-II/pcp.conf + +[postgres@server1 ~]$ cat /etc/pgpool-II/pcp.conf +# USERID:MD5PASSWD +pgpool:4aa0cb9673e84b06d4c8a848c80eb5d0 + + + Since follow_primary.sh script mentioned + later must execute PCP command without entering a password, + create .pcppass in + postgres user's home directory + (the home directory of the user Pgpool-II is running as). + The format of .pcppass is + "hostname:port:username:password". + + + In this example, we assume that the PCP user is pgpool + and the password is pgpool_password. + + +[postgres@server1 ~]$ echo 'localhost:9898:pgpool:pgpool_password' > ~/.pcppass +[postgres@server1 ~]$ chmod 600 ~/.pcppass + + + Copy to server2 and server3. + + +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pcppass postgres@server2: +[postgres@server1 ~]$ scp -i ~/.ssh/id_rsa_pgpool -p ~/.pcppass postgres@server3: +[postgres@server1 ~]$ exit + + + + + Create pgpool_node_id + + From Pgpool-II 4.2, now all configuration parameters are identical on all hosts. + If watchdog feature is enabled, to distinguish which host is which, + a pgpool_node_id file is required. + You need to create a pgpool_node_id file and specify the pgpool (watchdog) node number + (e.g. 0, 1, 2 ...) to identify pgpool (watchdog) host. + + + + + server1 + + +[root@server1 ~]# echo 0 > /etc/pgpool-II/pgpool_node_id +[root@server1 ~]# cat /etc/pgpool-II/pgpool_node_id +0 + + + + + server2 + + +[root@server2 ~]# echo 1 > /etc/pgpool-II/pgpool_node_id +[root@server2 ~]# cat /etc/pgpool-II/pgpool_node_id +1 + + + + + server3 + + +[root@server3 ~]# echo 2 > /etc/pgpool-II/pgpool_node_id +[root@server3 ~]# cat /etc/pgpool-II/pgpool_node_id +2 + + + + + + + <productname>Pgpool-II</productname> Configuration + + When installing Pgpool-II using YUM, the + Pgpool-II configuration file pgpool.conf + is installed in /etc/pgpool-II. + + + Since from Pgpool-II 4.2, all configuration parameters are + identical on all hosts, you can edit pgpool.conf on any pgpool node + and copy the edited pgpool.conf file to the other pgpool nodes. + + + + Clustering mode + + Pgpool-II has several clustering modes. To set the clustering + mode, can be used. In this configuration + example, streaming replication mode is used. + + +[root@server1 ~]# vi /etc/pgpool-II/pgpool.conf +backend_clustering_mode = streaming_replication + + + + + listen_addresses + + To allow Pgpool-II and PCP to accept all incoming connections, set the following + parameters to '*'. + + +listen_addresses = '*' +pcp_listen_addresses = '*' + + + + + port + + Specify the port number Pgpool-II listen on. + + +port = 9999 + + + + + Streaming Replication Check + + Specify replication delay check user and password in + and . In this example, we leave + empty, and create the entry in + . See + for how to create the entry in . + From Pgpool-II 4.0, if these parameters are left blank, + Pgpool-II will first try to get the password for that + specific user from file before using the empty password. + + +sr_check_user = 'pgpool' +sr_check_password = '' + + + + + Health Check + + Enable health check so that Pgpool-II performs failover. Also, if the network is unstable, + the health check fails even though the backend is running properly, failover or degenerate operation may occur. + In order to prevent such incorrect detection of health check, we set health_check_max_retries = 3. + Specify and in + the same way like and . + + +health_check_period = 5 +health_check_timeout = 30 +health_check_user = 'pgpool' +health_check_password = '' +health_check_max_retries = 3 + + + + + Backend Settings + + Specify the PostgreSQL backend information. + Multiple backends can be specified by adding a number at the end of the parameter name. + + +backend_hostname0 = 'server1' +backend_port0 = 5432 +backend_weight0 = 1 +backend_data_directory0 = '/var/lib/pgsql/18/data' +backend_flag0 = 'ALLOW_TO_FAILOVER' + +backend_hostname1 = 'server2' +backend_port1 = 5432 +backend_weight1 = 1 +backend_data_directory1 = '/var/lib/pgsql/18/data' +backend_flag1 = 'ALLOW_TO_FAILOVER' + +backend_hostname2 = 'server3' +backend_port2 = 5432 +backend_weight2 = 1 +backend_data_directory2 = '/var/lib/pgsql/18/data' +backend_flag2 = 'ALLOW_TO_FAILOVER' + + + To show replication_state and + replication_sync_state column in + command result, + parameter is required. + Here we specify each backend's hostname in these parameters + (Pgpool-II 4.1 or later). + Make sure that the value set in backend_application_nameX + matches the value set in application_name + of primary_conninfo. + + +backend_application_name0 = 'server1' +backend_application_name1 = 'server2' +backend_application_name2 = 'server3' + + + + + Failover configuration + + Specify the script that will be executed when failover occurs in + . When using three or more + PostgreSQL servers, it's required to specify + to synchronize the standby + with the new primary. In case of two PostgreSQL servers, the setting of + is not required. + + + + When performing a switchover using + with option added in Pgpool-II 4.3, + if you want to turn the former primary into standby automatically, + is required to be set + even if there are two PostgreSQL servers. + + + + Pgpool-II replaces the following special characters with the backend specific + information while executing the scripts. + See and for more details about each character. + + +failover_command = '/etc/pgpool-II/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S' +follow_primary_command = '/etc/pgpool-II/follow_primary.sh %d %h %p %D %m %H %M %P %r %R' + + + + %N and %S are added in Pgpool-II 4.1. + Please note that these characters cannot be specified if using Pgpool-II 4.0 or earlier. + + + + Sample scripts failover.sh + and follow_primary.sh + are installed in /etc/pgpool-II/. Create failover scripts using these sample files. + + +[root@server1 ~]# cp -p /etc/pgpool-II/sample_scripts/failover.sh.sample /etc/pgpool-II/failover.sh +[root@server1 ~]# cp -p /etc/pgpool-II/sample_scripts/follow_primary.sh.sample /etc/pgpool-II/follow_primary.sh +[root@server1 ~]# chown postgres:postgres /etc/pgpool-II/{failover.sh,follow_primary.sh} + + + Basically, it should work if you change PGHOME according to + PostgreSQL installation directory. + + +[root@server1 ~]# vi /etc/pgpool-II/failover.sh +... +PGHOME=/usr/pgsql-18 +... + +[root@server1 ~]# vi /etc/pgpool-II/follow_primary.sh +... +PGHOME=/usr/pgsql-18 +... + + + + Make sure the entry of the PCP user specified in PCP_USER in + follow_primary.sh is created in pcp.conf. + In this example, we have created in + + +[root@server1 ~]# cat /etc/pgpool-II/follow_primary.sh +... +PCP_USER=pgpool +... + + + + The follow_primary.sh script does not support tablespaces. + If you are using tablespaces, you need to modify the script to support tablespaces. + + + + + + Pgpool-II Online Recovery Configurations + + Next, configure the required parameters to perform online recovery + (). + Because Superuser privilege in PostgreSQL + is required for performing online recovery, we specify postgres + user in . In this example, we leave + empty, and create the entry in + . See + for how to create the entry in . + + +recovery_user = 'postgres' +recovery_password = '' +recovery_1st_stage_command = 'recovery_1st_stage' + + + Then, we create recovery_1st_stage and pgpool_remote_start + in database cluster directory of PostgreSQL + primary server (server1). + + + The sample scripts of online recovery recovery_1st_stage + and pgpool_remote_start + are installed in /etc/pgpool-II/. Copy these files to the data directory of the primary server (server1). + + +[root@server1 ~]# su - postgres -c "cp -p /etc/pgpool-II/sample_scripts/recovery_1st_stage.sample \$PGDATA/recovery_1st_stage" +[root@server1 ~]# su - postgres -c "cp -p /etc/pgpool-II/sample_scripts/pgpool_remote_start.sample \$PGDATA/pgpool_remote_start" + + + Basically, it should work if you change PGHOME according to PostgreSQL installation directory. + + +[root@server1 ~]# vi /var/lib/pgsql/18/data/recovery_1st_stage +... +PGHOME=/usr/pgsql-18 +... + +[root@server1 ~]# vi /var/lib/pgsql/18/data/pgpool_remote_start +... +PGHOME=/usr/pgsql-18 +... + + + + In addition, to perform online recovery, the functions + pgpool_recovery, pgpool_remote_start + and pgpool_switch_xlog must be created in advance + in the database specified by + (the default is 'postgres'). + Execute the following command to create these functions in + postgres on server1. + If a value other than the default is configured for + , replace postgres + with the configured value. + + +[root@server1 ~]# psql -U postgres postgres -c "CREATE EXTENSION pgpool_recovery" + + + + The recovery_1st_stage script does not support tablespaces. + If you are using tablespaces, you need to modify the script to support tablespaces. + + + + + + Client Authentication Configuration + + Because in the section Before Starting, + we already set PostgreSQL authentication method to + scram-sha-256, it is necessary to set a client authentication by + Pgpool-II to connect to backend nodes. + When installing with RPM, the Pgpool-II configuration file + pool_hba.conf is in /etc/pgpool-II. + By default, pool_hba authentication is disabled, set enable_pool_hba = on + to enable it. + + +enable_pool_hba = on + + + The format of pool_hba.conf file follows + PostgreSQL's pg_hba.conf format very closely. + Set pgpool and postgres user's + authentication method to scram-sha-256. In this example, + it is assumed that the application connecting to Pgpool-II + is in the same subnet. + + +[root@server1 ~]# vi /etc/pgpool-II/pool_hba.conf +(Add the following entries) +host all pgpool samenet scram-sha-256 +host all postgres samenet scram-sha-256 + + + + Please note that in Pgpool-II 4.0 only AES encrypted password or clear text password + can be specified in , , + , in pgpool.conf. + + + + The default password file name for authentication is . + To use scram-sha-256 authentication, the decryption key to + decrypt the passwords is required. We create the .pgpoolkey + file in postgres user's home directory + (the user Pgpool-II is running as. Pgpool-II 4.0 or before, + Pgpool-II is running as root by default) + +[root@server1 ~]# su - postgres -c "echo 'some string' > ~/.pgpoolkey" +[root@server1 ~]# su - postgres -c "chmod 600 ~/.pgpoolkey" +[root@server1 ~]# su - postgres -c "scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpoolkey postgres@server2:" +[root@server1 ~]# su - postgres -c "scp -i ~/.ssh/id_rsa_pgpool -p ~/.pgpoolkey postgres@server3:" + + + + Execute command pg_enc -m -k /path/to/.pgpoolkey -u username -p to register user + name and AES encrypted password in file pool_passwd. + If pool_passwd doesn't exist yet, it will be created in the same directory as + pgpool.conf. + + +[root@server1 ~]# pg_enc -m -k /var/lib/pgsql/.pgpoolkey -u pgpool -p +db password: (Enter the password for pgpool user) +trying to read key from file /var/lib/pgsql/.pgpoolkey + +[root@server1 ~]# pg_enc -m -k /var/lib/pgsql/.pgpoolkey -u postgres -p +db password: (Enter the password for postgres user) +trying to read key from file /var/lib/pgsql/.pgpoolkey + +[root@server1 ~]# cat /etc/pgpool-II/pool_passwd +pgpool:AESheq2ZMZjynddMWk5sKP/Rw== +postgres:AESHs/pWL5rtXy2IwuzroHfqg== + + + + + Watchdog Configuration + + Enable watchdog functionality on server1, server2, server3. + + +use_watchdog = on + + + Set virtual IP address to . + Ensure that the IP address isn't used yet. + + +delegate_ip = '192.168.100.50' + + + + To bring up/down the virtual IP and send the ARP requests, + we set , and . + Set the netmask and network interface name according to your network environment. + The network interface used in this example is enp0s8. + Since root privilege is required to execute if_up/down_cmd or + arping_cmd command, use setuid on these command or allow + postgres user (the user Pgpool-II is running as) to run + sudo command without a password. + + + + If Pgpool-II is installed using RPM, the postgres + user has been configured to run ip/arping via sudo without + a password. + +postgres ALL=NOPASSWD: /sbin/ip +postgres ALL=NOPASSWD: /usr/sbin/arping + + + + + Here we configure the following parameters to run if_up/down_cmd or arping_cmd with sudo. + + +if_up_cmd = '/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev enp0s8 label enp0s8:0' +if_down_cmd = '/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev enp0s8' +arping_cmd = '/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I enp0s8' + + + + If "Defaults requiretty" is set in the /etc/sudoers, + please ensure that the user that Pgpool-II is running as can execute the if_up_cmd, if_down_cmd and arping_cmd command without a tty. + + + + Set and according to the + command path. + If if_up/down_cmd or arping_cmd starts with "/", these parameters will be ignored. + + +if_cmd_path = '/sbin' +arping_path = '/usr/sbin' + + + Specify all Pgpool-II nodes information for configuring watchdog. + Specify pgpool_portX using the port number specified in port in + . + + +hostname0 = 'server1' +wd_port0 = 9000 +pgpool_port0 = 9999 + +hostname1 = 'server2' +wd_port1 = 9000 +pgpool_port1 = 9999 + +hostname2 = 'server3' +wd_port2 = 9000 +pgpool_port2 = 9999 + + + Configure the method of lifecheck + and the lifecheck interval . + Here, we use heartbeat method to perform watchdog lifecheck. + + +wd_lifecheck_method = 'heartbeat' +wd_interval = 10 + + + Specify all Pgpool-II nodes information for sending and receiving heartbeat signal. + + +heartbeat_hostname0 = 'server1' +heartbeat_port0 = 9694 +heartbeat_device0 = '' +heartbeat_hostname1 = 'server2' +heartbeat_port1 = 9694 +heartbeat_device1 = '' +heartbeat_hostname2 = 'server3' +heartbeat_port2 = 9694 +heartbeat_device2 = '' + + + If is set to heartbeat, + specify the time to detect a fault and + the interval to send heartbeat signals . + + +wd_heartbeat_keepalive = 2 +wd_heartbeat_deadtime = 30 + + + + This setting is optional. + When Watchdog process is abnormally terminated, + the virtual IP may be "up" on both of the old and new active pgpool nodes. + To prevent this, configure + to bring down the virtual IP on other Pgpool-II nodes before + bringing up the virtual IP on the new leader Pgpool-II node. + + +wd_escalation_command = '/etc/pgpool-II/escalation.sh' + + + The sample script escalation.sh is installed in /etc/pgpool-II/. + + +[root@server1 ~]# cp -p /etc/pgpool-II/sample_scripts/escalation.sh.sample /etc/pgpool-II/escalation.sh +[root@server1 ~]# chown postgres:postgres /etc/pgpool-II/escalation.sh + + + + Basically, it should work if you change the following variables according to your environment. + PGPOOLS is a list of hostnames where Pgpool-II is running. + VIP is the virtual IP address that is set to . + DEVICE is the network interface for the virtual IP. + + +[root@server1 ~]# vi /etc/pgpool-II/escalation.sh +... +PGPOOLS=(server1 server2 server3) +VIP=192.168.100.50 +DEVICE=enp0s8 +CIDR_NETMASK=24 +... + + + + + If you have even number of watchdog nodes, you need to turn on parameter. + + + + + If use_watchdog = on, please make sure the pgpool + node number is specified in pgpool_node_id file. + See for details. + + + + + + Logging + + Since Pgpool-II 4.2, + the logging collector process has been implemented. + When installed using the RPM packages, the logging + collector process () + is enabled by default. Log files are output to + /var/log/pgpool_log by default. + Configure the logging related configuration parameters + as needed to meet your requirements. + + +log_destination = 'stderr' +logging_collector = on +log_directory = '/var/log/pgpool' +log_filename = 'pgpool-%a.log' +log_truncate_on_rotation = on +log_rotation_age = 1d + + + + The configurations of Pgpool-II on server1 are completed. + Finally, copy the configuration files to server2 + and server3. + + +[root@server1 ~]# scp -p /etc/pgpool-II/{*.conf,*.sh,pool_passwd} server2:/etc/pgpool-II/ +[root@server1 ~]# ssh server2 "chown postgres:postgres /etc/pgpool-II/{*.conf,*.sh,pool_passwd}" +[root@server1 ~]# scp -p /etc/pgpool-II/{*.conf,*.sh,pool_passwd} server3:/etc/pgpool-II/ +[root@server1 ~]# ssh server3 "chown postgres:postgres /etc/pgpool-II/{*.conf,*.sh,pool_passwd}" + + + + + + How to use + + Let's start to use Pgpool-II. + + + Starting/Stopping Pgpool-II + + + + Starting Pgpool-II + + + First, let's start Pgpool-II. + + + Before starting Pgpool-II, + the PostgreSQL primary server must be already running. + If PostgreSQL primary server is not running, start it first + using the following command. + + +[root@server1 ~]# su - postgres -c "/usr/pgsql-18/bin/pg_ctl start" + + + Start Pgpool-II on server1, + server2, server3 by using the following command. + + +[all servers]# systemctl start pgpool.service + + + + + Stopping Pgpool-II + + + When stopping PostgreSQL, + Pgpool-II must be stopped first. + + +[all servers]# systemctl stop pgpool.service + + + + + + + Setting up PostgreSQL standby server + + First, we should set up PostgreSQL standby server by + using Pgpool-II online recovery functionality. + + + Connect to Pgpool-II via virtual IP to check the status of backend nodes. + As shown in the result, primary server is running on server1, + standby servers on server2 and server3 + are in "down" status. + + +[any server]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | primary | primary | 0 | true | 0 | | | 2023-11-10 15:30:14 + 1 | server2 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false | 0 | | | 2023-11-10 15:30:14 + 2 | server3 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false | 0 | | | 2023-11-10 15:30:14 +(3 rows) + + + Before running command, + ensure that recovery_1st_stage and + pgpool_remote_start scripts exist in the + data directory of PostgreSQL + primary server (server1). + + +[any server]# pcp_recovery_node -h 192.168.100.50 -p 9898 -U pgpool -n 1 -W +Password: +pcp_recovery_node -- Command Successful + +[any server]# pcp_recovery_node -h 192.168.100.50 -p 9898 -U pgpool -n 2 -W +Password: +pcp_recovery_node -- Command Successful + + + After executing pcp_recovery_node command, + verify that PostgreSQL standby servers + are running on server2 and server3. + + +[any server]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 15:30:14 + 1 | server2 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 16:32:33 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | false | 0 | streaming | async | 2023-11-10 16:33:08 +(3 rows) + + + + + Switching leader/standby watchdog + + Confirm the watchdog status by using pcp_watchdog_info. The Pgpool-II server which is started first runs as LEADER. + + +[any server]# pcp_watchdog_info -h 192.168.100.50 -p 9898 -U pgpool -W +Password: +3 3 YES server1:9999 Linux server1 server1 + +server1:9999 Linux server1 server1 9999 9000 4 LEADER 0 MEMBER # The Pgpool-II server started first becomes "LEADER". +server2:9999 Linux server2 server2 9999 9000 7 STANDBY 0 MEMBER # running as STANDBY +server3:9999 Linux server3 server3 9999 9000 7 STANDBY 0 MEMBER # running as STANDBY + + + If the LEADER Pgpool-II + on server1 goes down, standby + Pgpool-II on server2 or + server3 will become the new LEADER. + + + To verify this behavior, you may stop Pgpool-II + service or shutdown the whole system. Here, we stop + Pgpool-II service. + + +[root@server1 ~]# systemctl stop pgpool.service + +[root@server1 ~]# pcp_watchdog_info -p 9898 -h 192.168.100.50 -U pgpool -W +Password: +3 3 YES server2:9999 Linux server2 server2 + +server2:9999 Linux server2 server2 9999 9000 4 LEADER 0 MEMBER # server2 becomes LEADER +server1:9999 Linux server1 server1 9999 9000 10 SHUTDOWN 0 MEMBER # server1 is stopped +server3:9999 Linux server3 server3 9999 9000 7 STANDBY 0 MEMBER # server3 is running as a STANDBY + + + Restart the stopped Pgpool-II + on server1 and verify that it is running + as a STANDBY. + + +[root@server1 ~]# systemctl start pgpool.service + +[root@server1 ~]# pcp_watchdog_info -p 9898 -h 192.168.100.50 -U pgpool -W +Password: +3 3 YES server2:9999 Linux server2 server2 + +server2:9999 Linux server2 server2 9999 9000 4 LEADER 0 MEMBER +server1:9999 Linux server1 server1 9999 9000 7 STANDBY 0 MEMBER +server3:9999 Linux server3 server3 9999 9000 7 STANDBY 0 MEMBER + + + + + Failover + + First, use psql to connect to + PostgreSQL via virtual IP, + and verify the backend information. + + +[any server]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 15:30:14 + 1 | server2 | 5432 | up | up | 0.333333 | standby | standby | 0 | false | 0 | streaming | async | 2023-11-10 16:32:33 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 16:33:08 +(3 rows) + + + Next, stop the primary PostgreSQL server + on server1 and verify that failover is performed + automatically. + + +[root@server1 ~]# su - postgres -c "/usr/pgsql-18/bin/pg_ctl -m immediate stop" + + + After stopping PostgreSQL on + server1, failover occurs. + PostgreSQL on + server2 becomes the new primary and + the standby server on server3 + is configured as a standby of the new primary. + + +[any server]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false | 0 | | | 2023-11-10 17:05:40 + 1 | server2 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 17:05:40 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 17:05:51 +(3 rows) + + + server3 is running as a standby of new primary server2. + + + +[any server]# psql -h server3 -p 5432 -U pgpool postgres -c "select pg_is_in_recovery()" +pg_is_in_recovery +------------------- +t + +[any server]# psql -h server2 -p 5432 -U pgpool postgres -c "select pg_is_in_recovery()" +pg_is_in_recovery +------------------- +f + +[any server]# psql -h server2 -p 5432 -U pgpool postgres -c "select * from pg_stat_replication" -x +-[ RECORD 1 ]----+------------------------------ +pid | 7198 +usesysid | 16385 +usename | repl +application_name | server3 +client_addr | 192.168.100.53 +client_hostname | +client_port | 40916 +backend_start | 2023-11-10 17:10:03.067241+00 +backend_xmin | +state | streaming +sent_lsn | 0/12000260 +write_lsn | 0/12000260 +flush_lsn | 0/12000260 +replay_lsn | 0/12000260 +write_lag | +flush_lag | +replay_lag | +sync_priority | 0 +sync_state | async +reply_time | 2023-11-10 17:17:23.886477+00 + + + + + Online Recovery + + Here, we use Pgpool-II online recovery + feature to restore the former primary on server1 + as a standby. + + +[any server]# pcp_recovery_node -h 192.168.100.50 -p 9898 -U pgpool -n 0 -W +Password: +pcp_recovery_node -- Command Successful + + + Then verify that PostgreSQL on server1 is + running as a standby. + + +[any server]# psql -h 192.168.100.50 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: +node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | standby | standby | 0 | true | 0 | streaming | async | 2023-11-10 17:22:03 + 1 | server2 | 5432 | up | up | 0.333333 | primary | primary | 0 | false | 0 | | | 2023-11-10 17:05:40 + 2 | server3 | 5432 | up | up | 0.333333 | standby | standby | 0 | false | 0 | streaming | async | 2023-11-10 17:05:51 +(3 rows) + + + +
diff --git a/doc/src/sgml/example-replication-si-mode.sgml b/doc/src/sgml/example-replication-si-mode.sgml new file mode 100644 index 000000000..993ff068a --- /dev/null +++ b/doc/src/sgml/example-replication-si-mode.sgml @@ -0,0 +1,917 @@ + + Replication Mode and Snapshot Isolation Mode Configuration Example + + This section shows an example of how to configure Pgpool-II + replication mode and snapshot isolation mode. + + + In streaming replication mode described in , + replication is performed by PostgreSQL's streaming replication functionality. + However, in native replication mode, Pgpool-II + performs replication by routing write queries to all + PostgreSQL servers. + + + Snapshot isolation mode is similar to native replication mode except it adds + the visibility consistency among nodes. + + + PostgreSQL 18 is used in this configuration example. + + + + Cluster Structure + + In this example, we use one Pgpool-II and + three PostgreSQL servers to describe how to configure and use Pgpool-II's + replication. + + + In this example we use 3 servers with Rocky Linux 10 installed. + Let these servers be server1, + server2, server3. + We install PostgreSQL on all servers and + Pgpool-II on server1. + + + In this example we use the minimum settings to configure replication. + In a production environment, it is recommended to enable Watchdog + to avoid single points of failure. + For more details about Watchdog configurations, please refer to . + + + + Hostname and IP address + + + + Hostname + IP Address + Virtual IP + + + + + server1 + 192.168.137.101 + PostgreSQL node0, Pgpool-II + + + server2 + 192.168.137.102 + PostgreSQL node1 + + + server3 + 192.168.137.103 + PostgreSQL node2 + + + +
+ + + PostgreSQL version and Configuration + + + + Item + Value + Detail + + + + + PostgreSQL Version + 18.0 + - + + + port + 5432 + - + + + $PGDATA + /var/lib/pgsql/18/data + - + + + Archive mode + on + /var/lib/pgsql/archivedir + + + +
+ + + Pgpool-II version and Configuration + + + + Item + Value + Detail + + + + + Pgpool-II Version + 4.3.0 + - + + + port + 9999 + Pgpool-II accepts connections + + + 9898 + PCP process accepts connections + + + Config file + /etc/pgpool-II/pgpool.conf + Pgpool-II config file + + + Pgpool-II start user + postgres (Pgpool-II 4.1 or later) + Pgpool-II 4.0 or before, the default startup user is root + + + Clustering mode + native replication mode + - + + + snapshot isolation mode + - + + + +
+
+ + + Installation + + In this example, we install Pgpool-II and PostgreSQL RPM packages with YUM. + + + Install PostgreSQL from PostgreSQL YUM repository. + + +[all servers]# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm +[all servers]# yum install -y postgresql18-server + + + + Since Pgpool-II related packages are also included in PostgreSQL YUM repository, + add the "exclude" settings to /etc/yum.repos.d/pgdg-redhat-all.repo + so that Pgpool-II is not installed from PostgreSQL YUM repository. + + +[all servers]# vi /etc/yum.repos.d/pgdg-redhat-all.repo + + + The following is a setting example of /etc/yum.repos.d/pgdg-redhat-all.repo. + + +[pgdg-common] +... +exclude=pgpool* + +[pgdg18] +... +exclude=pgpool* + +[pgdg17] +... +exclude=pgpool* + +[pgdg16] +... +exclude=pgpool* + +[pgdg15] +... +exclude=pgpool* + +[pgdg14] +... +exclude=pgpool* + +[pgdg13] +... +exclude=pgpool* +... +exclude=pgpool* + + + Install Pgpool-II using Pgpool-II YUM repository. + + +[all servers]# yum install -y https://www.pgpool.net/yum/rpms/4.6/redhat/rhel-10-x86_64/pgpool-II-release-4.6-1.noarch.rpm +[all servers]# yum install -y pgpool-II-pg18-* + + + + + Before Starting + + Before you start the configuration process, please check the following prerequisites. + + + + Configure passwordless SSH login + + To use the online recovery of Pgpool-II, + the settings that allow passwordless SSH to all + servers are required. + Execute the following command on all servers to set up passwordless + SSH. + The generated key file name is id_rsa_pgpool. + + +[all servers]# su - postgres +[all servers]$ mkdir ~/.ssh && chmod 700 ~/.ssh +[all servers]$ ssh-keygen -t rsa -f ~/.ssh/id_rsa_pgpool + + + Then add the public key id_rsa_pgpool.pub to + /var/lib/pgsql/.ssh/authorized_keys file + on each server. + + + After setting SSH, make sure that you can run + ssh postgres@serverX -i ~/.ssh/id_rsa_pgpool command + as postgres user to login to each server + without entering a password. + + + + + If you failed to login using SSH public key authentication, please check the following: + + + + Ensure the public key authentication option PubkeyAuthentication are allowed in /etc/ssh/sshd_config: + + + + +PubkeyAuthentication yes + + + + + If SELinux is enabled, SSH public key authentication (passwordless SSH) may fail. + You need to run the following command on all servers. + + + + +[all servers]# su - postgres +[all servers]$ restorecon -Rv ~/.ssh + + + + + + + Create .pgpass + + To allow repl user to execute online recovery scripts + without specifying password, we create the .pgpass file + in postgres user's home directory and change the + permission to 600 on each server. + + +[all servers]# su - postgres +[all servers]$ vi ~/.pgpass +server1:5432:replication:repl:<repl user password> +server2:5432:replication:repl:<repl user password> +server3:5432:replication:repl:<repl user password> +server1:5432:postgres:postgres:<postgres user password> +server2:5432:postgres:postgres:<postgres user password> +server3:5432:postgres:postgres:<postgres user password> +[all servers]$ chmod 600 ~/.pgpass + + + + + Configure firewall + + When connect to Pgpool-II and PostgreSQL servers, the target port must be accessible by enabling firewall management softwares. Following is an example for Rocky Linux 10. + + +[all servers]# firewall-cmd --permanent --zone=public --add-service=postgresql +[all servers]# firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp +[all servers]# firewall-cmd --reload + + + If Watchdog is enabled, you also need to open port 9000 and 9694. + + +[all servers]# firewall-cmd --permanent --zone=public --add-port=9000/tcp --add-port=9694/udp + + + + + + <productname>PostgreSQL</productname> Configuration + + This section describes how to create and configure a PostgreSQL server. + + + In this example, we use WAL archiving. + First, we create the directory /var/lib/pgsql/archivedir + to store WAL segments on all servers. + + +[all servers]# su - postgres +[all servers]$ mkdir /var/lib/pgsql/archivedir + + + Create only one PostgreSQL server on server1. + The other two PostgreSQL servers are created by using Pgpool-II's online + recovery functionality in . + + + Run the following command to create a PostgreSQL database cluster on server1. + + +[server1]# su - postgres +[server1]$ /usr/pgsql-18/bin/initdb -E UTF8 --no-locale + + + Then edit $PGDATA/postgresql.conf on server1. + + +[server1]$ vi $PGDATA/postgresql.conf +listen_addresses = '*' +archive_mode = on +archive_command = 'cp "%p" "/var/lib/pgsql/archivedir/%f"' + + + + Assuming that all the Pgpool-II servers and the + PostgreSQL servers are in the same subnet and edit pg_hba.conf to + enable scram-sha-256 authentication method. + + +[server1]$ vi $PGDATA/pg_hba.conf +host all all samenet scram-sha-256 +host replication all samenet scram-sha-256 + + + + Run the following command to start PostgreSQL server. + + +[server1]$ /usr/pgsql-18/bin/pg_ctl start + + + + Create PostgreSQL users. + + + PostgreSQL users + + + + User Name + Password + Detail + + + + + repl + repl + PostgreSQL replication user + + + pgpool + pgpool + + User performing health check () + + + + postgres + postgres + User performing online recovery + + + +
+ + +[server1]$ psql -U postgres -p 5432 +postgres=# SET password_encryption = 'scram-sha-256'; +postgres=# CREATE ROLE pgpool WITH LOGIN; +postgres=# CREATE ROLE repl WITH REPLICATION LOGIN; +postgres=# \password pgpool +postgres=# \password repl +postgres=# \password postgres + + + + Settings for snapshot isolation mode + + Snapshot isolation mode is only available when PostgreSQL's transaction isolation + level is "repeatable read". + If you want to use snapshot isolation mode, set + default_transaction_isolation ='repeatable read' in + postgresql.conf. + + +[server1]$ vi $PGDATA/postgresql.conf +default_transaction_isolation = 'repeatable read' + + +
+ + + Configure <productname>Pgpool-II</productname> + + When installing Pgpool-II using RPM, the + Pgpool-II configuration sample files are in + /etc/pgpool-II. + + + + Clustering mode + + First, specify Pgpool-II clustering mode in . + + + + + Native replication mode + + +backend_clustering_mode = native_replication + + + + + Snapshot isolation mode + + +backend_clustering_mode = snapshot_isolation + + + + + + + listen_addresses + + To allow Pgpool-II to accept all incoming connections, we set listen_addresses = '*'. + + +listen_addresses = '*' + + + + + Health Check + + Enable health check to allow Pgpool-II to detect PostgreSQL failure. + Also, if the network is unstable, the health check fails even though the backend is running + properly, failover or degenerate operation may occur. + In order to prevent such incorrect detection of health check, we set health_check_max_retries = 3. + Specify and . + In this example, we leave empty, and create the entry + in . + See for how to create the entry in . + From Pgpool-II 4.0, if these parameters are left blank, + Pgpool-II will first try to get the password for that + specific user from file before using the empty password. + + +health_check_period = 5 +health_check_timeout = 30 +health_check_user = 'pgpool' +health_check_password = '' +health_check_max_retries = 3 + + + + + Backend Settings + + Specify the PostgreSQL backend information. + Multiple backends can be specified by adding a number at the end of the parameter name. + + +# - Backend Connection Settings - + +backend_hostname0 = 'server1' +backend_port0 = 5432 +backend_weight0 = 1 +backend_data_directory0 = '/var/lib/pgsql/18/data' +backend_flag0 = 'ALLOW_TO_FAILOVER' + +backend_hostname1 = 'server2' +backend_port1 = 5432 +backend_weight1 = 1 +backend_data_directory1 = '/var/lib/pgsql/18/data' +backend_flag1 = 'ALLOW_TO_FAILOVER' + +backend_hostname2 = 'server3' +backend_port2 = 5432 +backend_weight2 = 1 +backend_data_directory2 = '/var/lib/pgsql/18/data' +backend_flag2 = 'ALLOW_TO_FAILOVER' + + + + + Online Recovery + + Next, in order to perform online recovery we specify the + PostgreSQL user name and online recovery command + recovery_1st_stage_command and recovery_2nd_stage_command. + Because Superuser privilege in PostgreSQL + is required for performing online recovery, we specify postgres user in . + +recovery_user = 'postgres' +recovery_password = '' + +recovery_1st_stage_command = 'recovery_1st_stage' +recovery_2nd_stage_command = 'recovery_2nd_stage' + + The sample scripts + replication_mode_recovery_1st_stage.sample, + replication_mode_recovery_2nd_stage.sample + and + pgpool_remote_start.sample + are installed in /etc/pgpool-II/. + Create the scripts used by online recovery command from sample scripts and copy these files to the database cluster directory. + + +[server1]# cp -p /etc/pgpool-II/sample_scripts/replication_mode_recovery_1st_stage.sample /var/lib/pgsql/18/data/recovery_1st_stage +[server1]# cp -p /etc/pgpool-II/sample_scripts/replication_mode_recovery_2nd_stage.sample /var/lib/pgsql/18/data/recovery_2nd_stage +[server1]# cp -p /etc/pgpool-II/sample_scripts/pgpool_remote_start.sample /var/lib/pgsql/18/data/pgpool_remote_start +[server1]# chown postgres:postgres /var/lib/pgsql/18/data/{recovery_1st_stage,recovery_2nd_stage,pgpool_remote_start} + + + Basically, it should work if you change PGHOME according to PostgreSQL installation directory. + + +[server1]# vi /var/lib/pgsql/18/data/recovery_1st_stage +... +PGHOME=/usr/pgsql-18 +... + +[server1]# vi /var/lib/pgsql/18/data/recovery_2nd_stage +... +PGHOME=/usr/pgsql-18 +... + +[server1]# vi /var/lib/pgsql/18/data/pgpool_remote_start +... +PGHOME=/usr/pgsql-18 +... + + + + In addition, to perform online recovery, the functions + pgpool_recovery, pgpool_remote_start + and pgpool_switch_xlog must be created in advance + in the database specified by + (the default is 'postgres'). + Execute the following command to create these functions in + postgres on server1. + If a value other than the default is configured for + , replace postgres + with the configured value. + + +[server1]# psql -U postgres postgres -c "CREATE EXTENSION pgpool_recovery" + + + + The recovery_1st_stage script does not support tablespaces. + If you are using tablespaces, you need to modify the script to support tablespaces. + + + + + + Client Authentication Configuration + + Enable client authentication between client and Pgpool-II. + When installing with RPM, the Pgpool-II configuration file + pool_hba.conf is in /etc/pgpool-II. + By default, pool_hba authentication is disabled, set enable_pool_hba = on + to enable it. + + +enable_pool_hba = on + + + The format of pool_hba.conf file follows very closely PostgreSQL's + pg_hba.conf format. Set pgpool and postgres user's authentication method to scram-sha-256. + + +[server1]# vi /etc/pgpool-II/pool_hba.conf +host all pgpool 0.0.0.0/0 scram-sha-256 +host all postgres 0.0.0.0/0 scram-sha-256 + + + + Please note that in Pgpool-II 4.0 only AES encrypted password or clear text password + can be specified in , , + , in pgpool.conf. + + + + The default password file name for authentication is . + To use scram-sha-256 authentication, the decryption key to decrypt the passwords + is required. We create the .pgpoolkey file in Pgpool-II + start user postgres's (Pgpool-II 4.1 or later) home directory. + (Pgpool-II 4.0 or before, by default Pgpool-II + is started as root) + +[server1]# su - postgres +[server1]$ echo 'some string' > ~/.pgpoolkey +[server1]$ chmod 600 ~/.pgpoolkey + + + + Execute command pg_enc -m -k /path/to/.pgpoolkey -u username -p to register user + name and AES encrypted password in file pool_passwd. + If pool_passwd doesn't exist yet, it will be created in the same directory as + pgpool.conf. + + +[server1]# su - postgres +[server1]$ pg_enc -m -k ~/.pgpoolkey -u pgpool -p +db password: [pgpool user's password] +[server1]$ pg_enc -m -k ~/.pgpoolkey -u postgres -p +db password: [postgres user's password] + +[server1]$ cat /etc/pgpool-II/pool_passwd +pgpool:AESheq2ZMZjynddMWk5sKP/Rw== +postgres:AESHs/pWL5rtXy2IwuzroHfqg== + + + + + PCP password + + Since user authentication is required to use the PCP command, + we need to specify user name and md5 encrypted password in pcp.conf + in format "username:encrypted password". + + + We use to create the encrypted password entry for pgpool user as below: + + +[server1]# echo 'pgpool:'`pg_md5 PCP password` >> /etc/pgpool-II/pcp.conf + + + + + Logging + + Since Pgpool-II 4.2, the logging collector process has been implemented. + In the example, we enable logging collector. + + +log_destination = 'stderr' +logging_collector = on +log_directory = '/var/log/pgpool' +log_filename = 'pgpool-%Y-%m-%d_%H%M%S.log' +log_truncate_on_rotation = on +log_rotation_age = 1d +log_rotation_size = 10MB + + + Create the log directory on server1. + + +[server1]# mkdir /var/log/pgpool_log/ +[server1]# chown postgres:postgres /var/log/pgpool_log/ + + + + + + Starting/Stopping Pgpool-II + + Before starting Pgpool-II, please start + PostgreSQL servers first. + Also, when stopping PostgreSQL, + it is necessary to stop Pgpool-II first. + Run the following command to start or stop Pgpool-II. + + + + + Starting Pgpool-II + + +# systemctl start pgpool.service + + + + + Stopping Pgpool-II + + +# systemctl stop pgpool.service + + + + + + + How to use + + Once the configuration is completed, let's start to use Pgpool-II. + + + First, let's start Pgpool-II. + + +[server1]# systemctl start pgpool.service + + + + Create PostgreSQL servers using online recovery + + Then, we create PostgreSQL node1 and node2 using online recovery. + Ensure that recovery_1st_stage, + recovery_2nd_stage and pgpool_remote_start + scripts used by pcp_recovery_node command are in the database + cluster directory on server1. + + +[server1]# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 1 +Password: +pcp_recovery_node -- Command Successful + +[server1]# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 2 +Password: +pcp_recovery_node -- Command Successful + + + If pcp_recovery_node has run successfully, + verify that the PostgreSQL node0 is started as the main node, + and node1 and node2 are started as replicas. + + +# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change + ---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | main | main | 0 | true | 0 | | | 2021-12-02 16:48:21 + 1 | server2 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 + 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 +(3 rows) + + + + + Verify replication + + Next, let's verify the replication functionality using a benchmark tool pgbench. + + +[server1]# /usr/pgsql-18/bin/createdb test -U postgres -p 9999 +[server1]# /usr/pgsql-18/bin/pgbench -h server1 -U postgres -i -p 9999 test + + + To check if the replication works correctly, directly connect to each PostgreSQL + server to see if they return identical results. + + +[server1]# /usr/pgsql-18/bin/psql -h server1 -U postgres -p 5432 test +test=# \d + List of relations + Schema | Name | Type | Owner +--------+------------------+-------+---------- + public | pgbench_accounts | table | postgres + public | pgbench_branches | table | postgres + public | pgbench_history | table | postgres + public | pgbench_tellers | table | postgres +(4 rows) + +[server1]# /usr/pgsql-18/bin/psql -h server2 -U postgres -p 5432 test +test=# \d + List of relations + Schema | Name | Type | Owner +--------+------------------+-------+---------- + public | pgbench_accounts | table | postgres + public | pgbench_branches | table | postgres + public | pgbench_history | table | postgres + public | pgbench_tellers | table | postgres +(4 rows) + +[server1]# /usr/pgsql-18/bin/psql -h server3 -U postgres -p 5432 test +test=# \d + List of relations + Schema | Name | Type | Owner +--------+------------------+-------+---------- + public | pgbench_accounts | table | postgres + public | pgbench_branches | table | postgres + public | pgbench_history | table | postgres + public | pgbench_tellers | table | postgres +(4 rows) + + + server1, server2 and server3 return identical results. + + + Next, let's run pgbench for a while and check to results. + + +[server1]# /usr/pgsql-18/bin/pgbench -h server1 -U postgres -p 9999 -T 10 test + + + All PostgreSQL servers return identical results. + + +[server1]# /usr/pgsql-18/bin/psql -h server1 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" +Password for user postgres: + sum +-------- + -99710 +(1 row) + +[server1]# /usr/pgsql-18/bin/psql -h server2 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" +Password for user postgres: + sum +-------- + -99710 +(1 row) + +[server1]# /usr/pgsql-18/bin/psql -h server3 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" +Password for user postgres: + sum +-------- + -99710 +(1 row) + + + + + PostgreSQL failure + + Next, stop the PostgreSQL main node on server1 + and verify the switchover of the main node. + + +[server1]# su - postgres -c "/usr/pgsql-18/bin/pg_ctl -m i stop" + + + After stopping PostgreSQL on server1, + switchover occurs and PostgreSQL on + server2 becomes the new main node. + + +[server1]# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | down | down | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:57:45 + 1 | server2 | 5432 | up | up | 0.333333 | main | main | 1 | true | 0 | | | 2021-12-02 16:48:21 + 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 +(3 rows) + + + + + Online Recovery + + Here, we use Pgpool-II online recovery functionality to + restore the PostgreSQL node0 on server1. + + +# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 0 +Password: +pcp_recovery_node -- Command Successful + + + Then verify that server1 is started as the main node. + + +# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" +Password for user pgpool: + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | server1 | 5432 | up | up | 0.333333 | main | main | 0 | true | 0 | | | 2021-12-02 16:57:45 + 1 | server2 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 + 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 +(3 rows) + + + +
diff --git a/doc/src/sgml/examples.sgml b/doc/src/sgml/examples.sgml index c842e4450..d142d29b4 100644 --- a/doc/src/sgml/examples.sgml +++ b/doc/src/sgml/examples.sgml @@ -1,1945 +1,20 @@ - Examples - - - - Various examples - - - - - - Configuration Examples - - - Basic Configuration Example - - - Let's Begin! - - First, we must learn how to install and configure Pgpool-II and database nodes before using replication. - - - - Installing <productname>Pgpool-II</productname> - - Installing Pgpool-II is very easy. - In the directory which you have extracted the source tar ball, - execute the following commands. - -$ ./configure -$ make -$ make install - - configure script collects your system information - and use it for the compilation procedure. You can pass command - line arguments to configure script to change the default behavior, - such as the installation directory. Pgpool-II - will be installed to /usr/local directory by default. - - - make command compiles the source code, and - make install will install the executables. - You must have write permission on the installation directory. - In this tutorial, we will install Pgpool-II - in the default /usr/local directory. - - - - Pgpool-II requires libpq - library in PostgreSQL 7.4 or later (version 3 protocol). - - - - If the configure script displays the following error message, the - libpq library may not be installed, or it is not of version 3 - -configure: error: libpq is not installed or libpq is old - - If the library is version 3, but the above message is still displayed, your - libpq library is probably not recognized by the - configure script. - The configure script searches for libpq - library under /usr/local/pgsql. If you have installed the - PostgreSQL in a directory other than /usr/local/pgsql, use - --with-pgsql, or --with-pgsql-includedir - and --with-pgsql-libdir command line options when you - execute configure. - - - - - Configuration Files - - Pgpool-II configuration parameters are saved in the - pgpool.conf file. The file is in "parameter = value" - per line format. When you install Pgpool-II, - pgpool.conf.sample is automatically created. - We recommend copying and renaming it to pgpool.conf, and edit - it as you like. - -$ cp /usr/local/etc/pgpool.conf.sample /usr/local/etc/pgpool.conf - - Pgpool-II only accepts connections from the localhost - using port 9999. If you wish to receive conenctions from other hosts, - set to '*'. - -listen_addresses = 'localhost' -port = 9999 - - We will use the default parameters in this tutorial. - - - - - Configuring <acronym>PCP</acronym> Commands - - Pgpool-II has an interface for administrative - purpose to retrieve information on database nodes, shutdown - Pgpool-II, etc. via network. To use - PCP commands, user authentication is required. - This authentication is different from PostgreSQL's user authentication. - A user name and password need to be defined in the pcp.conf - file. In the file, a user name and password are listed as a pair on each line, - and they are separated by a colon (:). Passwords are encrypted in - md5 hash format. - - -postgres:e8a48653851e28c69d0506508fb27fc5 - - - When you install Pgpool-II, pcp.conf.sample - is automatically created. We recommend copying and renaming it - to pcp.conf, and edit it. - -$ cp /usr/local/etc/pcp.conf.sample /usr/local/etc/pcp.conf - - To encrypt your password into md5 hash format, use the pg_md5 - command, which is installed as one of Pgpool-II's - executables. pg_md5 takes text as a command line argument, - and displays its md5-hashed text. - For example, give "postgres" as the command line argument, - and pg_md5 displays md5-hashed text on its standard output. - -$ /usr/bin/pg_md5 postgres -e8a48653851e28c69d0506508fb27fc5 - - PCP commands are executed via network, so the port number must be configured - with parameter in pgpool.conf file. - We will use the default 9898 for in this tutorial. - -pcp_port = 9898 - - - - - - - Preparing Database Nodes - - Now, we need to set up backend PostgreSQL servers for Pgpool-II - . These servers can be placed within the same host as - Pgpool-II, or on separate machines. If you decide - to place the servers on the same host, different port numbers must be assigned - for each server. If the servers are placed on separate machines, - they must be configured properly so that they can accept network - connections from Pgpool-II. - - -backend_hostname0 = 'localhost' -backend_port0 = 5432 -backend_weight0 = 1 -backend_hostname1 = 'localhost' -backend_port1 = 5433 -backend_weight1 = 1 -backend_hostname2 = 'localhost' -backend_port2 = 5434 -backend_weight2 = 1 - - - For , , - , set the node's hostname, port number, - and ratio for load balancing. At the end of each parameter string, - node ID must be specified by adding positive integers starting with 0 (i.e. 0, 1, 2..). - - - - parameters for all nodes are - set to 1, meaning that SELECT queries are equally distributed among - three servers. - - - - - - Starting/Stopping <productname>Pgpool-II</productname> - - To fire up Pgpool-II, execute the following - command on a terminal. - - -$ pgpool - - - The above command, however, prints no log messages because - Pgpool-II detaches the terminal. If you want to show - Pgpool-II log messages, you pass -n - option to pgpool command so Pgpool-II - is executed as non-daemon process, and the terminal will not be detached. - -$ pgpool -n & - - - The log messages are printed on the terminal, so it is recommended to use the following options. - -$ pgpool -n -d > /tmp/pgpool.log 2>&1 & - - - The -d option enables debug messages to be generated. - The above command keeps appending log messages to /tmp/pgpool.log - . If you need to rotate log files, pass the logs to a external - command which has log rotation function. - For example, you can use - rotatelogs from Apache2: - -$ pgpool -n 2>&1 | /usr/local/apache2/bin/rotatelogs \ --l -f /var/log/pgpool/pgpool.log.%A 86400 & - - - This will generate a log file named "pgpool.log.Thursday" - then rotate it 00:00 at midnight. Rotatelogs adds logs to a file if it already - exists. To delete old log files before rotation, you could use cron: - -55 23 * * * /usr/bin/find /var/log/pgpool -type f -mtime +5 -exec /bin/rm -f '{}' \; - - - Please note that rotatelogs may exist as /usr/sbin/rotatelogs2 - in some distributions. -f option generates a log file as soon as - rotatelogs starts and is available in apache2 2.2.9 or greater. - Also cronolog can be used. - -$ pgpool -n 2>&1 | /usr/sbin/cronolog \ ---hardlink=/var/log/pgsql/pgpool.log \ -'/var/log/pgsql/%Y-%m-%d-pgpool.log' & - - - To stop Pgpool-II execute the following command. - -$ pgpool stop - - - If any client is still connected, Pgpool-II - waits for it to disconnect, and then terminates itself. Run the following - command instead if you want to shutdown Pgpool-II - forcibly. - -$ pgpool -m fast stop - - - - - - - - Your First Replication - - Replication (see ) enables - the same data to be copied to multiple database nodes. - In this section, we'll use three database nodes, which we have already set - up in , and takes you step by step to - create a database replication system. - Sample data to be replicated will be generated by the - - pgbench benchmark program. - - - - Configuring Replication - - To enable the database replication function, set - to on in pgpool.conf file. - -replication_mode = true - - When is on, Pgpool-II - will send a copy of a received query to all the database nodes. - In addition, when is set to true, - Pgpool-II will distribute SELECT queries - among the database nodes. - -load_balance_mode = true - - In this section, we will enable both - and . - - - - - Checking Replication - - To reflect the changes in pgpool.conf, - Pgpool-II must be restarted. - Please refer to "Starting/Stopping Pgpool-II" - . - After configuring pgpool.conf and restarting the - Pgpool-II, let's try the actual replication - and see if everything is working. - First, we need to create a database to be replicated. We will name it - "bench_replication". This database needs to be created - on all the nodes. Use the - - createdb commands through - Pgpool-II, and the database will be created - on all the nodes. - -$ createdb -p 9999 bench_replication - - Then, we'll execute - pgbench with -i option. - -i option initializes the database with pre-defined tables and data. - -$ pgbench -i -p 9999 bench_replication - - The following table is the summary of tables and data, which will be created by - - pgbench -i. If, on all the nodes, the listed tables and - data are created, replication is working correctly. - - - - data summary - - - - Table Name - Number of Rows - - - - - - pgbench_branches - 1 - - - - pgbench_tellers - 10 - - - - pgbench_accounts - 100000 - - - - pgbench_history - 0 - - - - -
- - - Let's use a simple shell script to check the above on all the nodes. - The following script will display the number of rows in pgbench_branches, - pgbench_tellers, pgbench_accounts, and pgbench_history tables on all the nodes (5432, 5433, 5434). - -$ for port in 5432 5433 5434; do -> echo $port -> for table_name in pgbench_branches pgbench_tellers pgbench_accounts pgbench_history; do -> echo $table_name -> psql -c "SELECT count(*) FROM $table_name" -p $port bench_replication -> done -> done - - - -
-
- -
- - - Watchdog Configuration Example - - - This tutrial explains the simple way to try "Watchdog". - What you need is 2 Linux boxes on which - Pgpool-II is installed and a PostgreSQL - on the same machine or in the other one. It is enough - that 1 node for backend exists. - You can use watchdog with - Pgpool-II in any mode: replication mode, - master/slave mode and raw mode. - - - This example uses use "osspc16" as an Active node and - "osspc20" as a Standby node. "Someserver" means one of them. - - - - Common configurations - - Set the following parameters in both of active and standby nodes. - - - - Enabling watchdog - - First of all, set to on. - -use_watchdog = on -# Activates watchdog - - - - - - Configure Up stream servers - - Specify the up stream servers (e.g. application servers). - Leaving it blank is also fine. - -trusted_servers = '' - # trusted server list which are used - # to confirm network connection - # (hostA,hostB,hostC,...) - - - - - - Watchdog Communication - - Specify the TCP port number for watchdog communication. - -wd_port = 9000 - # port number for watchdog service - - - - - - Virtual IP - - Specify the IP address to be used as a virtual IP address - in the . - -delegate_IP = '133.137.177.143' -# delegate IP address - - - - - Make sure the IP address configured as a Virtual IP should be - free and is not used by any other machine. - - - - - - - Individual Server Configurations - - Next, set the following parameters for each - Pgpool-II. - Specify , - and - with the values of - other Pgpool-II server values. - - - - Active (osspc16) Server configurations - - -other_pgpool_hostname0 = 'osspc20' - # Host name or IP address to connect to for other pgpool 0 -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 -other_wd_port0 = 9000 - # Port number for other watchdog 0 - - - - - - Standby (osspc20) Server configurations - - -other_pgpool_hostname0 = 'osspc16' - # Host name or IP address to connect to for other pgpool 0 -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 -other_wd_port0 = 9000 - # Port number for other watchdog 0 - - - - - - - Starting <productname>Pgpool-II</productname> - - Start Pgpool-II on each servers from - root user with "-n" switch - and redirect log messages into pgpool.log file. - - - - Starting pgpool in Active server (osspc16) - - First start the Pgpool-II on Active server. - -[user@osspc16]$ su - -[root@osspc16]# {installed_dir}/bin/pgpool -n -f {installed_dir}/etc/pgpool.conf > pgpool.log 2>&1 - - Log messages will show that Pgpool-II - has the virtual IP address and starts watchdog process. - -LOG: I am announcing my self as master/coordinator watchdog node -LOG: I am the cluster leader node -DETAIL: our declare coordinator message is accepted by all nodes -LOG: I am the cluster leader node. Starting escalation process -LOG: escalation process started with PID:59449 -LOG: watchdog process is initialized -LOG: watchdog: escalation started -LOG: I am the master watchdog node - DETAIL: using the local backend node status - - - - - - Starting pgpool in Standby server (osspc20) - - Now start the Pgpool-II on Standby server. - -[user@osspc20]$ su - -[root@osspc20]# {installed_dir}/bin/pgpool -n -f {installed_dir}/etc/pgpool.conf > pgpool.log 2>&1 - - Log messages will show that Pgpool-II - has joind the watchdog cluster as standby watchdog. - -LOG: watchdog cluster configured with 1 remote nodes -LOG: watchdog remote node:0 on Linux_osspc16_9000:9000 -LOG: interface monitoring is disabled in watchdog -LOG: IPC socket path: "/tmp/.s.PGPOOLWD_CMD.9000" -LOG: watchdog node state changed from [DEAD] to [LOADING] -LOG: new outbound connection to Linux_osspc16_9000:9000 -LOG: watchdog node state changed from [LOADING] to [INITIALIZING] -LOG: watchdog node state changed from [INITIALIZING] to [STANDBY] - -LOG: successfully joined the watchdog cluster as standby node -DETAIL: our join coordinator request is accepted by cluster leader node "Linux_osspc16_9000" -LOG: watchdog process is initialized - - - - - - - - Try it out - - Confirm to ping to the virtual IP address. - -[user@someserver]$ ping 133.137.177.142 -PING 133.137.177.143 (133.137.177.143) 56(84) bytes of data. -64 bytes from 133.137.177.143: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 133.137.177.143: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 133.137.177.143: icmp_seq=3 ttl=64 time=0.412 ms - - Confirm if the Active server which started at first has the virtual IP address. - -[root@osspc16]# ifconfig -eth0 ... - -eth0:0 inet addr:133.137.177.143 ... - -lo ... - - Confirm if the Standby server which started not at first doesn't have the virtual IP address. - -[root@osspc20]# ifconfig -eth0 ... - -lo ... - - - Try to connect PostgreSQL by "psql -h delegate_IP -p port". - -[user@someserver]$ psql -h 133.137.177.142 -p 9999 -l - - - - - - Switching virtual IP - - Confirm how the Standby server works when the Active server can't provide its service. - Stop Pgpool-II on the Active server. - -[root@osspc16]# {installed_dir}/bin/pgpool stop - - - Then, the Standby server starts to use the virtual IP address. Log shows: - - - -LOG: remote node "Linux_osspc16_9000" is shutting down -LOG: watchdog cluster has lost the coordinator node - -LOG: watchdog node state changed from [STANDBY] to [JOINING] -LOG: watchdog node state changed from [JOINING] to [INITIALIZING] -LOG: I am the only alive node in the watchdog cluster -HINT: skipping stand for coordinator state -LOG: watchdog node state changed from [INITIALIZING] to [MASTER] -LOG: I am announcing my self as master/coordinator watchdog node -LOG: I am the cluster leader node -DETAIL: our declare coordinator message is accepted by all nodes - -LOG: I am the cluster leader node. Starting escalation process -LOG: watchdog: escalation started - -LOG: watchdog escalation process with pid: 59551 exit with SUCCESS. - - - Confirm to ping to the virtual IP address. - -[user@someserver]$ ping 133.137.177.142 -PING 133.137.177.143 (133.137.177.143) 56(84) bytes of data. -64 bytes from 133.137.177.143: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 133.137.177.143: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 133.137.177.143: icmp_seq=3 ttl=64 time=0.412 ms - - - Confirm that the Active server doesn't use the virtual IP address any more. - -[root@osspc16]# ifconfig -eth0 ... - -lo ... - - - Confirm that the Standby server uses the virtual IP address. - -[root@osspc20]# ifconfig -eth0 ... - -eth0:0 inet addr:133.137.177.143 ... - -lo ... - - - Try to connect PostgreSQL by "psql -h delegate_IP -p port". - -[user@someserver]$ psql -h 133.137.177.142 -p 9999 -l - - - - - - - More - - - Lifecheck - - There are the parameters about watchdog's monitoring. - Specify the interval to check , - the count to retry , - the qyery to check and - finaly the type of lifecheck . - -wd_lifecheck_method = 'query' - # Method of watchdog lifecheck ('heartbeat' or 'query' or 'external') - # (change requires restart) -wd_interval = 10 - # lifecheck interval (sec) > 0 -wd_life_point = 3 - # lifecheck retry times -wd_lifecheck_query = 'SELECT 1' - # lifecheck query to pgpool from watchdog - - - - - - - Switching virtual IP address - - There are the parameters for switching the virtual IP address. - Specify switching commands , - , the path to them - , the command executed after - switching to send ARP request - and the path to it . - -ifconfig_path = '/sbin' -# ifconfig command path -if_up_cmd = 'ifconfig eth0:0 inet $_IP_$ netmask 255.255.255.0' -# startup delegate IP command -if_down_cmd = 'ifconfig eth0:0 down' -# shutdown delegate IP command - -arping_path = '/usr/sbin' # arping command path - -arping_cmd = 'arping -U $_IP_$ -w 1' - - You can also use the custom scripts to bring up and bring down the - virtual IP using and - configurations. - - - - - - - - <productname>Pgpool-II</productname> + Watchdog Setup Example - -This section shows an example of streaming replication configuration using Pgpool-II. In this example, we use 3 Pgpool-II servers to manage PostgreSQL servers to create a robust cluster system and avoid the single point of failure or split brain. - - - Requirements - -We assume that all the Pgpool-II servers and the PostgreSQL servers are in the same subnet. - - - - - Cluster System Configuration - -We use 2 PostgreSQL servers and 3 Pgpool-II servers with CentOS7. Let these servers be osspc16, osspc17, osspc18, osspc19 and osspc20. - - -
- Cluster System Configuration - - - - - -
-
- - - The roles of Active, Standy, Primary, Standby are not fixed and may be changed by further operations. - - -
- - - Installation - -In this example, we install Pgpool-II and PostgreSQL by using RPM packages. - - - - <productname>Pgpool-II</productname>, <productname>PostgreSQL</productname> version informations and Configuration - - - - Server - Version - Host Name - Port - $PGDATA Directory - - - - - - PostgreSQL server (primary) - PostgreSQL 9.6.1 - osspc19 - 5432 - /var/lib/pgsql/9.6/data - - - PostgreSQL server (standby) - PostgreSQL 9.6.1 - osspc20 - 5432 - /var/lib/pgsql/9.6/data - - - Pgpool-II server - Pgpool-II 3.6.1 - osspc16 - 9999 - - - - - - Pgpool-II server - Pgpool-II 3.6.1 - osspc17 - 9999 - - - - - - Pgpool-II server - Pgpool-II 3.6.1 - osspc18 - 9999 - - - - - - -
- - Install Pgpool-II by using Pgpool-II YUM repository. - - -# yum install http://www.pgpool.net/yum/rpms/3.6/redhat/rhel-7-x86_64/pgpool-II-release-3.6-1.noarch.rpm -# yum install pgpool-II-pg96 -# yum install pgpool-II-pg96-debuginfo -# yum install pgpool-II-pg96-devel -# yum install pgpool-II-pg96-extensions - - - - Install PostgreSQL by using PostgreSQL YUM repository. - - -# yum install https://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm -# yum install postgresql96 postgresql96-devel postgresql96-server - -
- - - Before Starting - - Before you start the configuration process, please check the following prerequisites. - - - - - -Set up PostgreSQL streaming replication on the primary server. In this example, we use WAL archiving. - - -First, we create the directory /var/lib/pgsql/archivedir to store WAL segments on both PostgreSQL servers (osspc19 and osspc20). - - -[PostgreSQL server]$ mkdir /var/lib/pgsql/archivedir - - - -Then we edit the configuration file $PGDATA/postgresql.conf on osspc19 (primary) as follows. - - -listen_addresses = '*' -wal_level = hot_standby -max_wal_senders = 2 - -archive_mode = on -archive_command = 'cp "%p" "/var/lib/pgsql/archivedir/%f"' - - -We use the online recovery functionality of Pgpool-II to setup standby server after the primary server is started. - - - - - -Because of the security reasons, we create a user repl solely used for replication purpose, and a user pgpool for streaming replication delay check and health check of Pgpool-II. Assuming that all the Pgpool-II servers and the PostgreSQL servers are in the network of 133.137.174.0/24, and edit pg_hba.conf to enable md5 authentication method. - - -host all pgpool 133.137.174.0/24 md5 -host all all 0.0.0.0/0 md5 - -host replication repl 133.137.174.0/24 md5 - - - - - -To use the failover and online recovery of Pgpool-II, the settings that allow SSH without passowrd to other servers (osspc16 - osspc20) are necessary. - - - - - - -To allow repl user without specifying password for streaming replication and online recovery, we create the .pgpass file in postgres user's home directory and change the permisson to 600 on both postgreSQL servers osspc19 and osspc20. - - -[osspc19]$ cat /var/lib/pgsql/.pgpass -osspc20:5432:replication:repl:<password of repl user> - - - -[osspc20]$ cat /var/lib/pgsql/.pgpass -osspc19:5432:replication:repl:<passowrd of repl user> - - - -$ chmod 600 /var/lib/pgsql/.pgpass - - - - - - -When Pgpool-II connects to other Pgpool-II servers or PostgreSQL servers, the target port must be accessible by enabling firewall management softwares. Following is an example for CentOS/RHEL7. - - -[PostgreSQL server]# firewall-cmd --permanent --zone=public --add-service=postgresql -[PostgreSQL server]# firewall-cmd --reload - - - - - -The following commands are to enable Pgpool-II and PostgreSQL start on system boot. - - -[Pgpool-II server]# systemctl enable pgpool.service - - -[PostgreSQL server]# systemctl enable postgresql.service - - - - - - - <productname>Pgpool-II</productname> Configuration - - Common Settings - -Here are the common settings on osspc16, osspc17 and osspc18. - - -When installing Pgpool-II from RPM, all the Pgpool-II configuration files are in /etc/pgpool-II. In this example, we copy the sample configuration file for streaming replicaton mode. - - -# cp /etc/pgpool-II/pgpool.conf.sample-stream /etc/pgpool-II/pgpool.conf - - -To allow Pgpool-II to accept all incoming connections, we set listen_addresses = '*'. - - -listen_addresses = '*' - - -Specifiy replication delay check user and password. - - -sr_check_user = 'pgpool' -sr_check_password = 'pgpool' - - -Enable health check so that pgpool-II performs failover. Also, if the network is unstable, the health check fails even though the backend is running properly, failover or degenerate operation may occur. In order to prevent such incorrect detection of health check, we set health_check_max_retries = 10. - - -health_check_period = 5 - # Health check period - # Disabled (0) by default -health_check_timeout = 20 - # Health check timeout - # 0 means no timeout -health_check_user = 'pgpool' -health_check_password = 'pgpool' - -health_check_max_retries = 10 - - -Specify the backend informations with osspc19 and osspc20. - - -# - Backend Connection Settings - - -backend_hostname0 = 'osspc19' - # Host name or IP address to connect to for backend 0 -backend_port0 = 5432 - # Port number for backend 0 -backend_weight0 = 1 - # Weight for backend 0 (only in load balancing mode) -backend_data_directory0 = '/var/lib/pgsql/9.6/data' - # Data directory for backend 0 -backend_flag0 = 'ALLOW_TO_FAILOVER' - # Controls various backend behavior - # ALLOW_TO_FAILOVER or DISALLOW_TO_FAILOVER -backend_hostname1 = 'osspc20' -backend_port1 = 5432 -backend_weight1 = 1 -backend_data_directory1 = '/var/lib/pgsql/9.6/data' -backend_flag1 = 'ALLOW_TO_FAILOVER' - - - - - Failover configuration - -Specify failover_command to execute failover.sh script. The special characters %d %P %H %R in failover_command are replcaed with DB node ID of the detached node, Old primary node ID, Hostname of the new master node, Database cluster directory of the new master node. - - -failover_command = '/etc/pgpool-II/failover.sh %d %P %H %R' - - -Create /etc/pgpool-II/failover.sh, and set the file permisson to 755. - - -# vi /etc/pgpool-II/failover.sh -# chmod 755 /etc/pgpool-II/failover.sh - - - - - -/etc/pgpool-II/failover.sh - - -#! /bin/sh -x -# Execute command by failover. -# special values: %d = node id -# %h = host name -# %p = port number -# %D = database cluster path -# %m = new master node id -# %M = old master node id -# %H = new master node host name -# %P = old primary node id -# %R = new master database cluster path -# %r = new master port number -# %% = '%' character - -falling_node=$1 # %d -old_primary=$2 # %P -new_primary=$3 # %H -pgdata=$4 # %R - -pghome=/usr/pgsql-9.6 -log=/var/log/pgpool/failover.log - -date >> $log -echo "failed_node_id=$falling_node new_primary=$new_primary" >> $log - -if [ $falling_node = $old_primary ]; then - if [ $UID -eq 0 ] - then - su postgres -c "ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata" - else - ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata - fi - exit 0; -fi; -exit 0; - - - - - - - - Pgpool-II Online Recovery Configurations - -Next, in order to perform online recovery with Pgpool-II we specify the PostgreSQL user name and online recovery command recovery_1st_stage. Then, we create recovery_1st_stage and pgpool_remote_start in database cluster directory of PostgreSQL primary server, and set the file permissions to 755. - - -recovery_user = 'postgres' - # Online recovery user -recovery_password = 'postgres' - # Online recovery password - -recovery_1st_stage_command = 'recovery_1st_stage' - - -$ vi /var/lib/pgsql/9.6/data/recovery_1st_stage -$ vi /var/lib/pgsql/9.6/data/pgpool_remote_start -$ chmod 755 /var/lib/pgsql/9.6/data/recovery_1st_stage -$ chmod 755 /var/lib/pgsql/9.6/data/pgpool_remote_start - - - - - -/var/lib/pgsql/9.6/data/recovery_1st_stage - - -#!/bin/bash -x -# Recovery script for streaming replication. - -pgdata=$1 -remote_host=$2 -remote_pgdata=$3 -port=$4 - -pghome=/usr/pgsql-9.6 -archivedir=/var/lib/pgsql/archivedir -hostname=$(hostname) - -ssh -T postgres@$remote_host " -rm -rf $remote_pgdata -$pghome/bin/pg_basebackup -h $hostname -U repl -D $remote_pgdata -x -c fast -rm -rf $archivedir/* - -cd $remote_pgdata -cp postgresql.conf postgresql.conf.bak -sed -e 's/#*hot_standby = off/hot_standby = on/' postgresql.conf.bak > postgresql.conf -rm -f postgresql.conf.bak -cat > recovery.conf << EOT -standby_mode = 'on' -primary_conninfo = 'host="$hostname" port=$port user=repl' -restore_command = 'scp $hostname:$archivedir/%f %p' -EOT -" - - - - - -/var/lib/pgsql/9.6/data/pgpool_remote_start - - -#! /bin/sh -x - -pghome=/usr/pgsql-9.6 -remote_host=$1 -remote_pgdata=$2 - -# Start recovery target PostgreSQL server -ssh -T $remote_host $pghome/bin/pg_ctl -w -D $remote_pgdata start > /dev/null 2>&1 < /dev/null & - - - - - - In order to use the online recovery functionality, the functions of pgpool_recovery, pgpool_remote_start, pgpool_switch_xlog are required, so we need install pgpool_recovery on template1 of PostgreSQL server osspc19. - - -# su - postgres -$ psql template1 -=# CREATE EXTENSION pgpool_recovery; - - - - - Client Authentication Configuration - -Because in the section Before Starting, we already set PostgreSQL authentication method to md5, it is necessary to set a client authentication by Pgpool-II to connect to backend nodes. When installing from RPM, the Pgpool-II configuration file pool_hba.conf is in /etc/pgpool-II. By default, pool_hba authentication is disabled, and set enable_pool_hba = on to enable it. - - -enable_pool_hba = on - - -The format of pool_hba.conf file follows very closely PostgreSQL's pg_hba.conf format. Set pgpool and postgres user's authentication method to md5. - - -host all pgpool 0.0.0.0/0 md5 -host all postgres 0.0.0.0/0 md5 - - -To use md5 authentication, we need to register the user name and password in file pool_passwd. Execute command pg_md5 --md5auth --username=<user name> <password> to regist user name and MD5-hashed password in file pool_passwd. If pool_passwd doesn't exist yet, it will be created in the same directory as pgpool.conf. - - -# pg_md5 --md5auth --username=pgpool <password of pgpool user> -# pg_md5 --md5auth --username=postgres <password of postgres user> - - - - - Watchdog Configuration - - Enable watchdog functionality on osspc16, osspc17, osspc18. - - -use_watchdog = on - - - Specify virtual IP address that accepts connections from clients on osspc16, osspc17, osspc18. Ensure that the IP address set to virtual IP isn't used yet. - - -delegate_IP = '133.137.174.153' - - - Specify the hostname and port number of each Pgpool-II server. - - - - - osspc16 - - -wd_hostname = 'osspc16' -wd_port = 9000 - - - - - osspc17 - - -wd_hostname = 'osspc17' -wd_port = 9000 - - - - - osspc18 - - -wd_hostname = 'osspc18' -wd_port = 9000 - - - - - - Specify the hostname, Pgpool-II port number, and watchdog port number of monitored Pgpool-II servers on each Pgpool-II server. - - - - - osspc16 - - -# - Other pgpool Connection Settings - - -other_pgpool_hostname0 = 'osspc17' - # Host name or IP address to connect to for other pgpool 0 - # (change requires restart) -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 - # (change requires restart) -other_wd_port0 = 9000 - # Port number for other watchdog 0 - # (change requires restart) -other_pgpool_hostname1 = 'osspc18' -other_pgpool_port1 = 9999 -other_wd_port1 = 9000 - - - - - osspc17 - - -# - Other pgpool Connection Settings - - -other_pgpool_hostname0 = 'osspc16' - # Host name or IP address to connect to for other pgpool 0 - # (change requires restart) -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 - # (change requires restart) -other_wd_port0 = 9000 - # Port number for other watchdog 0 - # (change requires restart) -other_pgpool_hostname1 = 'osspc18' -other_pgpool_port1 = 9999 -other_wd_port1 = 9000 - - - - - osspc18 - - -# - Other pgpool Connection Settings - - -other_pgpool_hostname0 = 'osspc16' - # Host name or IP address to connect to for other pgpool 0 - # (change requires restart) -other_pgpool_port0 = 9999 - # Port number for other pgpool 0 - # (change requires restart) -other_wd_port0 = 9000 - # Port number for other watchdog 0 - # (change requires restart) -other_pgpool_hostname1 = 'osspc17' -other_pgpool_port1 = 9999 -other_wd_port1 = 9000 - - - - - - Specify the hostname and port number of destination for sending heartbeat signal on osspc16, osspc17, osspc18. - - - - - osspc16 - - -heartbeat_destination0 = 'osspc17' - # Host name or IP address of destination 0 - # for sending heartbeat signal. - # (change requires restart) -heartbeat_destination_port0 = 9694 - # Port number of destination 0 for sending - # heartbeat signal. Usually this is the - # same as wd_heartbeat_port. - # (change requires restart) -heartbeat_device0 = '' - # Name of NIC device (such like 'eth0') - # used for sending/receiving heartbeat - # signal to/from destination 0. - # This works only when this is not empty - # and pgpool has root privilege. - # (change requires restart) - -heartbeat_destination1 = 'osspc18' -heartbeat_destination_port1 = 9694 -heartbeat_device1 = '' - - - - - - osspc17 - - -heartbeat_destination0 = 'osspc16' - # Host name or IP address of destination 0 - # for sending heartbeat signal. - # (change requires restart) -heartbeat_destination_port0 = 9694 - # Port number of destination 0 for sending - # heartbeat signal. Usually this is the - # same as wd_heartbeat_port. - # (change requires restart) -heartbeat_device0 = '' - # Name of NIC device (such like 'eth0') - # used for sending/receiving heartbeat - # signal to/from destination 0. - # This works only when this is not empty - # and pgpool has root privilege. - # (change requires restart) - -heartbeat_destination1 = 'osspc18' -heartbeat_destination_port1 = 9694 -heartbeat_device1 = '' - - - - - - osspc18 - - -heartbeat_destination0 = 'osspc16' - # Host name or IP address of destination 0 - # for sending heartbeat signal. - # (change requires restart) -heartbeat_destination_port0 = 9694 - # Port number of destination 0 for sending - # heartbeat signal. Usually this is the - # same as wd_heartbeat_port. - # (change requires restart) -heartbeat_device0 = '' - # Name of NIC device (such like 'eth0') - # used for sending/receiving heartbeat - # signal to/from destination 0. - # This works only when this is not empty - # and pgpool has root privilege. - # (change requires restart) - -heartbeat_destination1 = 'osspc17' -heartbeat_destination_port1 = 9694 -heartbeat_device1 = '' - - - - - - - PCP Command Configuration - - Because user authentication is required to use the PCP command, we specify user name and md5 encrypted password in pcp.conf. Here we create the encrypted password for user postgres, and add <username: encrypted password≷ in /etc/pgpool-II/pcp.conf. - - -# pg_md5 -p -Password: (input password) -(paste the md5 encrypted password to pcp.conf) - -# vi /etc/pgpool-II/pcp.conf -(add password entry) -user name:md5 encrypted password - - -The settings of Pgpool-II is completed. - - - - - - Starting/Stopping Pgpool-II - - Next we start Pgpool-II. Before starting Pgpool-II, please start PostgreSQL servers first. Also, when stopping PostgreSQL, it is necessary to stop Pgpool-II first. - - - - -Starting Pgpool-II - - - In section Before Starting, we already set the auto-start of Pgpool-II. To start Pgpool-II, restart the whole system or execute the following command. - - -# systemctl start pgpool.service - - - - - Stopping Pgpool-II - - -# systemctl stop pgpool.service - - - - - - - Log - - Use journalctl command to see Pgpool-II logs. - - -# journalctl -a | grep pgpool - - - - - How to use - - Let's start to use Pgpool-II. First, let's start Pgpool-II on osspc16, osspc17, osspc18 by using the following command. - - -# systemctl start pgpool.service - - - - Set up PostgreSQL standby server - -First, we should set up PostgreSQL standby server by using Pgpool-II online recovery functionality. Ensure that recovery_1st_stage and pgpool_remote_start scripts used by pcp_recovery_node command are in database cluster directory of PostgreSQL primary server (osspc19). - - -# pcp_recovery_node -h 133.137.174.153 -p 9898 -U postgres -n 1 - - - After executing pcp_recovery_node command, vertify that osspc20 is started as a PostgreSQL standby server. - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | up | 0.500000 | primary | 0 | true | 0 - 1 | osspc20 | 5432 | up | 0.500000 | standby | 0 | false | 0 - - - - - Switching active/standby watchdog - - Confirm the watchdog status by using pcp_watchdog_info. The Pgpool-II server which is started first run as MASTER. - - -# pcp_watchdog_info -h 133.137.174.153 -p 9898 -U postgres -Password: -3 YES osspc16:9999 Linux osspc16 osspc16 - -osspc16:9999 Linux osspc16 osspc16 9999 9000 4 MASTER #The Pgpool-II server started first becames "MASTER". -osspc17:9999 Linux osspc17 osspc17 9999 9000 7 STANDBY #run as standby -osspc18:9999 Linux osspc18 osspc18 9999 9000 7 STANDBY #run as standby - - -Stop active server osspc16, then osspc17 or osspc18 will be promoted to active server. To stop osspc16, we can stop Pgpool-II service or shutdown the whole system. Here, we stop Pgpool-II service. - - -[root@osspc16 ~]# systemctl stop pgpool.service -[root@osspc16 ~]# pcp_watchdog_info -h 133.137.174.153 -p 9898 -U postgres -Password: -3 YES osspc17:9999 Linux osspc17 osspc17 - -osspc17:9999 Linux osspc17 osspc17 9999 9000 4 MASTER #osspc17 is promoted to MASTER -osspc16:9999 Linux osspc16 osspc16 9999 9000 10 SHUTDOWN #osspc16 is stopped -osspc18:9999 Linux osspc18 osspc18 9999 9000 7 STANDBY #osspc18 runs as STANDBY - - -Start Pgpool-II (osspc16) which we have stopped again, and vertify that osspc16 runs as a standby. - - -[root@osspc16 ~]# systemctl start pgpool.service -[root@osspc16 ~]# pcp_watchdog_info -h 133.137.174.153 -p 9898 -U postgres -Password: -3 YES osspc17:9999 Linux osspc17 osspc17 - -osspc17:9999 Linux osspc17 osspc17 9999 9000 4 MASTER -osspc16:9999 Linux osspc16 osspc16 9999 9000 7 STANDBY -osspc18:9999 Linux osspc18 osspc18 9999 9000 7 STANDBY - - - - - Failover - -First, use psql to connect to PostgreSQL via virtual IP, and verify the backend informations. - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | up | 0.500000 | primary | 0 | true | 0 - 1 | osspc20 | 5432 | up | 0.500000 | standby | 0 | false | 0 - - -Next, stop primary PostgreSQL server osspc19, and verify automatic failover. - - -$ pg_ctl -D /var/lib/pgsql/9.6/data -m immediate stop - - -After stopping PostgreSQL on osspc19, failover occurs and PostgreSQL on osspc20 becomes new primary DB. - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | down | 0.500000 | standby | 0 | false | 0 - 1 | osspc20 | 5432 | up | 0.500000 | primary | 0 | true | 0 - - - - - Online Recovery - -Here, we use Pgpool-II online recovery functionality to restore osspc19 (old primary server) as a standby. Before restoring the old primary server, please ensure that recovery_1st_stage and pgpool_remote_start scripts exist in database cluster directory of current primary server osspc20. - - -# pcp_recovery_node -h 133.137.174.153 -p 9898 -U postgres -n 0 - - -Then verify that osspc19 is started as a standby. - - -# psql -h 133.137.174.153 -p 9999 -U pgpool postgres - -postgres=> show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+------+--------+-----------+---------+------------+-------------------+------------------- - 0 | osspc19 | 5432 | up | 0.500000 | standby | 0 | false | 0 - 1 | osspc20 | 5432 | up | 0.500000 | primary | 0 | true | 0 - - - - -
- - - AWS Configuration Example - - - This tutrial explains the simple way to try "Watchdog" - on AWS and using - the - Elastic IP Address as the Virtual IP for the high availability solution. - - - You can use watchdog with - Pgpool-II in any mode: replication mode, - master/slave mode and raw mode. - - - - - - AWS Setup - - For this example, we will use two node - Pgpool-II watchdog cluster. So we will set up two - Linux Amazon EC2 instances and one Elastic IP address. - So for this example, do the following steps: - - - - - - Launch two Linux Amazon EC2 instances. For this example, we name these - instances as "instance-1" and "instance-2" - - - - - - Configure the security group for the instances and allow inbound traffic - on ports used by pgpool-II and watchdog. - - - - - - Install the Pgpool-II on both instances. - - - - - - Allocate an Elastic IP address. - For this example, we will use "35.163.178.3" as an Elastic IP address" - - - - - - - - - <productname>Pgpool-II</productname> configurations - - Mostly the Pgpool-II configurations for this - example will be same as in the , except the - which we will not set in this example instead - we will use and - to switch the - Elastic IP address to the maste/Active Pgpool-II node. - - - - <productname>Pgpool-II</productname> configurations on Instance-1 - - - -use_watchdog = on -delegate_IP = '' -wd_hostname = 'instance-1-private-ip' -other_pgpool_hostname0 = 'instance-2-private-ip' -other_pgpool_port0 = 9999 -other_wd_port0 = 9000 -wd_escalation_command = '$path_to_script/aws-escalation.sh' -wd_de_escalation_command = '$path_to_script/aws-de-escalation.sh' - - - - - - - <productname>Pgpool-II</productname> configurations on Instance-2 - - - -use_watchdog = on -delegate_IP = '' -wd_hostname = 'instance-2-private-ip' -other_pgpool_hostname0 = 'instance-1-private-ip' -other_pgpool_port0 = 9999 -other_wd_port0 = 9000 -wd_escalation_command = '$path_to_script/aws-escalation.sh' -wd_de_escalation_command = '$path_to_script/aws-de-escalation.sh' - - - - - - - - escalation and de-escalation Scripts - - Create the aws-escalation.sh and aws-de-escalation.sh scripts on both - instances and point the and - to the respective scripts. - - - - - You may need to configure the AWS CLI first on all AWS instances - to enable the execution of commands used by wd-escalation.sh and wd-de-escalation.sh. - See configure AWS CLI - - - - - escalation script - - - This script will be executed by the watchdog - to assign the Elastic IP on the instance when the watchdog becomes the active/master node. - Change the INSTANCE_ID and ELASTIC_IP values as per your AWS setup values. - - - aws-escalation.sh: - -#! /bin/sh - -ELASTIC_IP=35.163.178.3 - # replace it with the Elastic IP address you - # allocated from the aws console -INSTANCE_ID=i-0a9b64e449b17ed4b - # replace it with the instance id of the Instance - # this script is installed on - -echo "Assigning Elastic IP $ELASTIC_IP to the instance $INSTANCE_ID" -# bring up the Elastic IP -aws ec2 associate-address --instance-id $INSTANCE_ID --public-ip $ELASTIC_IP - -exit 0 - - - - - - - de-escalation script - - - This script will be executed by watchdog - to remove the Elastic IP from the instance when the watchdog resign from the active/master node. - - - aws-de-escalation.sh: - -#! /bin/sh - -ELASTIC_IP=35.163.178.3 - # replace it with the Elastic IP address you - # allocated from the aws console - -echo "disassociating the Elastic IP $ELASTIC_IP from the instance" -# bring down the Elastic IP -aws ec2 disassociate-address --public-ip $ELASTIC_IP -exit 0 - - - - - - AWS Command References - - - - <ulink url="http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html">Configure AWS CLI</ulink> - - - AWS Documentation: Configuring the AWS Command Line Interface - - - - - - <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/associate-address.html">associate-address</ulink> - - - AWS Documentation: associate-address reference - - - - - - <ulink url="http://docs.aws.amazon.com/cli/latest/reference/ec2/disassociate-address.html">disassociate-address</ulink> - - - AWS Documentation: disassociate-address reference - - - - - - - - Try it out - - Start Pgpool-II on each server with "-n" switch - and redirect log messages to the pgpool.log file. - The log message of master/active Pgpool-II node - will show the message of Elastic IP assignment. - -LOG: I am the cluster leader node. Starting escalation process -LOG: escalation process started with PID:23543 -LOG: watchdog: escalation started - - Assigning Elastic IP 35.163.178.3 to the instance i-0a9b64e449b17ed4b - { - "AssociationId": "eipassoc-39853c42" - } - -LOG: watchdog escalation successful -LOG: watchdog escalation process with pid: 23543 exit with SUCCESS. - - - - - Confirm to ping to the Elastic IP address. - -[user@someserver]$ ping 35.163.178.3 -PING 35.163.178.3 (35.163.178.3) 56(84) bytes of data. -64 bytes from 35.163.178.3: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 35.163.178.3: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 35.163.178.3: icmp_seq=3 ttl=64 time=0.412 ms - - - - - Try to connect PostgreSQL by "psql -h ELASTIC_IP -p port". - -[user@someserver]$ psql -h 35.163.178.3 -p 9999 -l - - - - - - Switching Elastic IP - - To confirm if the Standby server acquires the Elastic IP when the - Active server becomes unavailable, Stop the Pgpool-II - on the Active server. Then, the Standby server should start using the Elastic IP address, - And the Pgpool-II log will show the below messages. - - - -LOG: remote node "172.31.2.94:9999 [Linux ip-172-31-2-94]" is shutting down -LOG: watchdog cluster has lost the coordinator node - -LOG: watchdog node state changed from [STANDBY] to [JOINING] -LOG: watchdog node state changed from [JOINING] to [INITIALIZING] -LOG: I am the only alive node in the watchdog cluster -HINT: skipping stand for coordinator state -LOG: watchdog node state changed from [INITIALIZING] to [MASTER] -LOG: I am announcing my self as master/coordinator watchdog node -LOG: I am the cluster leader node -DETAIL: our declare coordinator message is accepted by all nodes -LOG: I am the cluster leader node. Starting escalation process -LOG: escalation process started with PID:23543 -LOG: watchdog: escalation started - - Assigning Elastic IP 35.163.178.3 to the instance i-0dd3e60734a6ebe14 - { - "AssociationId": "eipassoc-39853c42" - } - -LOG: watchdog escalation successful -LOG: watchdog escalation process with pid: 61581 exit with SUCCESS. - - Confirm to ping to the Elastic IP address again. - -[user@someserver]$ ping 35.163.178.3 -PING 35.163.178.3 (35.163.178.3) 56(84) bytes of data. -64 bytes from 35.163.178.3: icmp_seq=1 ttl=64 time=0.328 ms -64 bytes from 35.163.178.3: icmp_seq=2 ttl=64 time=0.264 ms -64 bytes from 35.163.178.3: icmp_seq=3 ttl=64 time=0.412 ms - - - - Try to connect PostgreSQL by "psql -h ELASTIC_IP -p port". - -[user@someserver]$ psql -h 35.163.178.3 -p 9999 -l - - - - - - - Aurora Configuration Example - - - Amazon Aurora for PostgreSQL - Compatibility (Aurora) is a managed service for - PostgreSQL. From user's point of - view, Aurora can be regarded as a - streaming replication cluster with some exceptions. First, - fail over and online recovery are managed - by Aurora. So you don't need to - set , , - and recovery related parameters. In this section we explain - how to set up Pgpool-II for Aurora. - - - - Setting pgpool.conf for Aurora - - - - - Create pgpool.conf - from pgpool.conf.sample-stream. - - - - - Set to 0 to - disable streaming replication delay checking. This - is because Aurora does - not provide neccessary functions to check the - replication delay. - - - - - Enable to on so - that md5 authentication is enabled - (Aurora always use md5 - authentication). - - - - - Create pool_password. See - for more details. - - - - - Set 0 for the - Aurora writer node. Set - other for the - Aurora reader node. Set - appropreate as - usual. You don't need to - set - - - - - Set ALWAYS_MASTER flag to - the - for 0. - - - - - Enable health checking. - Set to 5. - Set , , - and - to appropriate values. - Enable health check retry. - Aurora shutdowns all DB nodes while switching - over or failover. If the retry is not performed, - Pgpool-II thinks that all DB nodes are in down status - so that it is required to restart Pgpool-II. - Set to 20. - Set to 1 to avoid the problem. - - - - - Disable - to avoid failover when connecting to the backend or - detecting errors on backend side while executing - queries for the same reasons above. - - - - - - - -
+ Examples + + + + Various examples + + + + + Configuration Examples + &example-basic; + &example-cluster; + &example-replication-si-mode; + &example-AWS; + &example-Aurora; +
diff --git a/doc/src/sgml/failover.sgml b/doc/src/sgml/failover.sgml index 204abe5a7..ea620e435 100644 --- a/doc/src/sgml/failover.sgml +++ b/doc/src/sgml/failover.sgml @@ -3,462 +3,798 @@ Failover and Failback + + Failover means automatically detaching + PostgreSQLbackend node which is not + accessible by Pgpool-II. This happens + automatically regardless the configuration parameter settings and is + so called automatic failover + process. Pgpool-II confirms the + inaccessibility of PostgreSQL backend node + by using following methods: + + + + + Regular health check process + (see for more + details). The heath check process tries to connect + from Pgpool-II + to PostgreSQL node to confirm + its healthiness. If it fails to connect, it is possible + that there's something wrong with network connection + between Pgpool-II + and PostgreSQL, + and/or PostgreSQL does not work + properly. Pgpool-II does not + distinguish each case and just decides that the + particular PostgreSQL node is + not available if health check fails. + + + + + + An error occurs while connecting + to PostgreSQL, or network level + errors occur while communicating with it. + Pgpool-II will just disconnect + the session to client + if is off in + that case However. + + + + + + In the case When clients already connect + to Pgpool-II + and PostgreSQL is shutdown + (please note that if no client connects + to Pgpool-II at all, shutting + down of PostgreSQL does not + trigger a failover). + + + In addition, in the streaming replication mode, shutting down + of PostgreSQL does not trigger a + failover, if the node is a standby node and is not the load + balance node even + if is on. + + + + + + + + If is configured and a + failover happens, gets + executed. should be provided + by user. From 4.1 an example script for failover command is provided + as failover.sh.sample which can be a good + starting point for you. + + + The major role of failover command is choosing new primary server + from existing standby servers and promoting it for example. Another + example would be let the administrator know that a failover happens + by sending a mail. + + + + While a failover could happen when a failure occurs, it is + possible to trigger it by hand. This is called a switch + over. For instance, switching over + a PostgreSQL to take its backup would + be possible. Note that switching over just sets the status to + down and never bringing PostgreSQL + down. A switch over can be triggered by + using command. + + + + A PostgreSQL node detached by failover or + switch over will never return to the previous state (attached state) + automatically in the default setting. Restarting + Pgpool-II with -D option or running makes it to the attached state again. It + is recommended to confirm the replication_state of is "streaming" before doing that. The + state indicates that the standby server is properly connected to the + primary server through streaming replication and both databases are + in sync. + + + From 4.1 a new parameter can be + used to do above automatically. See for more details. + + Failover and Failback Settings - - failover_command (string) - - failover_command configuration parameter - - - - - Specifies a user command to run when a PostgreSQL backend node gets detached. - Pgpool-II replaces the following special characters - with the backend specific information. - - - - failover command options - - - - Special character - Description - - - - - - %d - DB node ID of the detached node - - - %h - Hostname of the detached node - - - %p - Port number of the detached node - - - %D - Database cluster directory of the detached node - - - %M - Old master node ID - - - %m - New master node ID - - - %H - Hostname of the new master node - - - %P - Old primary node ID - - - %r - Port number of the new master node - - - %R - Database cluster directory of the new master node - - - %% - '%' character - - - - -
- - - - The "master node" referes to a node which has the - "youngest (or the smallest) node id" among live the - database nodes. In streaming - replication mode, this may be different from - primary node. In , - %m is the new master node chosen - by Pgpool-II. It is the node - being assigned the youngest (smallest) node id which is - alive. For example if you have 3 nodes, namely node 0, 1, - 2. Suppose node 1 the primary and all of them are healthy - (no down node). If node 1 fails, failover_command is - called with %m = 0. - - - - - - When a failover is performed, - basically Pgpool-II kills all - its child processes, which will in turn terminate all the - active sessions to - Pgpool-II. After that Pgpool-II - invokes the failover_command and after the command completion - Pgpool-II starts new child processes - which makes it ready again to accept client connections. - - - However from Pgpool-II 3.6, in - the steaming replication mode, client sessions will not be - disconnected when a failover occurs any more if the - session does not use the failed standby server. If the - primary server goes down, still all sessions will be - disconnected. Health check timeout case will also cause - the full session disconnection. Other health check error, - including retry over case does not trigger full session - disconnection. - - - - - - You can run psql (or whatever command) - against backend to retrieve some information in the - script, but you cannot run psql against - Pgpool-II itself, since the - script is called from Pgpool-II - and it needs to run - while Pgpool-II is working on - failover. - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - -
-
- - - failback_command (string) - - failback_command configuration parameter - - - - - Specifies a user command to run when a PostgreSQL backend node gets attached to - Pgpool-II. Pgpool-II - replaces the following special characters with the backend specific information. - before excuting the command. - - - - failback command options - - - - Special character - Description - - - - - - %d - DB node ID of the attached node - - - %h - Hostname of the attached node - - - %p - Port number of the attached node - - - %D - Database cluster directory of the attached node - - - %M - Old master node ID - - - %m - New master node ID - - - %H - Hostname of the new master node - - - %P - Old primary node ID - - - %r - Port number of the new master node - - - %R - Database cluster directory of the new master node - - - %% - '%' character - - - - -
- - - - You can run psql (or whatever command) - against backend to retrieve some information in the - script, but you cannot run psql against - Pgpool-II itself, since the - script is called from Pgpool-II - and it needs to run - while Pgpool-II is working on - failover. - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - -
-
- - - follow_master_command (string) - - follow_master_command configuration parameter - - - - - - Specifies a user command to run after failover on the primary node failover. - This works only in Master Replication mode with streaming replication. - Pgpool-II replaces the following special characters - with the backend specific information before excuting the command. - - - - follow master command options - - - - Special character - Description - - - - - - %d - DB node ID of the detached node - - - %h - Hostname of the detached node - - - %p - Port number of the detached node - - - %D - Database cluster directory of the detached node - - - %M - Old master node ID - - - %m - New primary node ID - - - %H - Hostname of the new primary node - - - %P - Old primary node ID - - - %r - Port number of the new primary node - - - %R - Database cluster directory of the new primary node - - - %% - '%' character - - - - -
- - - - If follow_master_command is not empty, then after failover - on the primary node gets completed in Master Slave mode with streaming replication, - Pgpool-II degenerates all nodes excepted the new primary - and starts new child processes to be ready again to accept connections from the clients. - After this, Pgpool-II executes the command configured - in the follow_master_command for each degenerated backend nodes. - - - - Typically follow_master_command command is used to recover - the slave from the new primary by calling the pcp_recovery_node command. - - - This parameter can be changed by reloading the Pgpool-II configurations. - -
-
- - - failover_on_backend_error (boolean) - - failover_on_backend_error configuration parameter - - - - - When set to on, Pgpool-II considers the reading/writing - errors on the PostgreSQL backend connection as the backend node failure and trigger the - failover on that node after disconnecting the current session. - When this is set to off, Pgpool-II only report an error - and disconnect the session in case of such errors. - - - - It is recommended to turn on the backend health checking - (see ) - when failover_on_backend_error is set to off. - Note, however, that Pgpool-II still triggers the - failover when it detects the administrative shutdown of - PostgreSQL backend server. - If you want to avoid a fail over even in this case, you need to specify DISALLOW_TO_FAILOVER on . - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - Prior to Pgpool-II V4.0, - this configuration parameter name was fail_over_on_backend_error. - - - - - - - search_primary_node_timeout (integer) - - search_primary_node_timeout configuration parameter - - - - - Specifies the maximum amount of time in seconds to search for the - primary node when a failover scenario occurs. - Pgpool-II will give up looking for the primary - node if it is not found with-in this configured time. - Default is 300 and Setting this parameter to 0 means keep trying forever. - - - This parameter is only applicable in the streaming replication mode. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - detach_false_primary (boolean) - - detach_false_primary configuration parameter - - - - - If set to on, detach false primary node. The default is - off. This parameter is only valid in streaming replication - mode and for PostgreSQL 9.6 or - after since this feature - uses pg_stat_wal_receiver. - If PostgreSQL 9.5.x or older - version is used, no error is raised, just the feature is - ignored. - - - If there's no primary node, no checking will be performed. - - - If there's no standby node, and there's only one primary - node, no checking will be performed. - - - If there's no standby node, and there's multiple primary - nodes, leave the primary node which has the youngest node - id and detach rest of primary nodes. - - - If there are one or more primaries and one or more standbys, - check the connectivity between primary and standby nodes by - using pg_stat_wal_receiver - if PostgreSQL 9.6 or after. In - this case if a primary node connects to all standby nodes, - the primary is regarded as "true" primary. Other primaries - are regarded as "false" primary and the false primaries will - be detached if detach_false_primary is - true. If no "true" primary is found, nothing will happen. - - - When Pgpool-II starts, the - checking of false primaries are performed only once in - the Pgpool-II main - process. If is greater - than 0, the false primaries checking will be performed at - the same timing of streaming replication delay checking. - - - This parameter is only applicable in the streaming replication mode. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - -
- Detecting false primaries - - - - - -
-
- -
-
+ + failover_command (string) + + failover_command configuration parameter + + + + + Specifies a user command to run when a PostgreSQL backend node gets detached. + Pgpool-II replaces the following special characters + with the backend specific information. + + + + failover command options + + + + Special character + Description + + + + + + %d + DB node ID of the detached node + + + %h + Hostname of the detached node + + + %p + Port number of the detached node + + + %D + Database cluster directory of the detached node + + + %m + New main node ID + + + %H + Hostname of the new main node + + + %M + Old main node ID + + + %P + Old primary node ID + + + %r + Port number of the new main node + + + %R + Database cluster directory of the new main node + + + %N + Hostname of the old primary node (Pgpool-II 4.1 or after) + + + %S + Port number of the old primary node (Pgpool-II 4.1 or after) + + + %% + '%' character + + + + +
+ + + + The "main node" refers to a node which has the + "youngest (or the smallest) node id" among live the + database nodes. In streaming + replication mode, this may be different from + primary node. In , + %m is the new main node chosen + by Pgpool-II. It is the node + being assigned the youngest (smallest) node id which is + alive. For example if you have 3 nodes, namely node 0, 1, + 2. Suppose node 1 the primary and all of them are healthy + (no down node). If node 1 fails, failover_command is + called with %m = 0. And, if all standby nodes are down and primary node + failover happens, failover_command is called with %m = -1 and %H,%R,$r = "". + + + + + + When a failover is performed, + basically Pgpool-II kills all + its child processes, which will in turn terminate all the + active sessions to + Pgpool-II. After that Pgpool-II + invokes the failover_command and after the command completion + Pgpool-II starts new child processes + which makes it ready again to accept client connections. + + + However from Pgpool-II 3.6, in the + steaming replication mode, client sessions will not be + disconnected any more when a failover occurs if the session + does not use the failed standby server. Please note that if a + query is sent while failover is processing, the session will be + disconnected. If the primary server goes down, still all + sessions will be disconnected. Health check timeout case will + also cause the full session disconnection. Other health check + error, including retry over case does not trigger full session + disconnection. + + + + + + You can run psql (or whatever command) + against backend to retrieve some information in the + script, but you cannot run psql against + Pgpool-II itself, since the + script is called from Pgpool-II + and it needs to run + while Pgpool-II is working on + failover. + + + + + A complete failover_command example can be found + in . + + + + This parameter can be changed by reloading the Pgpool-II configurations. + +
+
+ + + failback_command (string) + + failback_command configuration parameter + + + + + Specifies a user command to run when a PostgreSQL backend node gets attached to + Pgpool-II. Pgpool-II + replaces the following special characters with the backend specific information. + before executing the command. + + + + failback command options + + + + Special character + Description + + + + + + %d + DB node ID of the attached node + + + %h + Hostname of the attached node + + + %p + Port number of the attached node + + + %D + Database cluster directory of the attached node + + + %m + New main node ID + + + %H + Hostname of the new main node + + + %M + Old main node ID + + + %P + Old primary node ID + + + %r + Port number of the new main node + + + %R + Database cluster directory of the new main node + + + %N + Hostname of the old primary node (Pgpool-II 4.1 or after) + + + %S + Port number of the old primary node (Pgpool-II 4.1 or after) + + + %% + '%' character + + + + +
+ + + + You can run psql (or whatever command) + against backend to retrieve some information in the + script, but you cannot run psql against + Pgpool-II itself, since the + script is called from Pgpool-II + and it needs to run + while Pgpool-II is working on + failback. + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + +
+
+ + + follow_primary_command (string) + + follow_primary_command configuration parameter + + + + + + Specifies a user command to run after failover on the + primary node failover. In case of standby node failover, the + command will not be executed. This command also runs if a + node promote request is issued by + command. This works only + in streaming replication mode. + + + + Since the command is executed within a child process forked + off by Pgpool-II after failover + is completed, execution of follow primary command does not + block the service + of Pgpool-II. Here is a pseud + code to illustrate how the command is executed: + +for each backend node +{ + if (the node is not the new primary) + set down node status to shared memory status + memorize that follow primary command is needed to execute +} +if (we need to executed follow primary command) +{ + fork a child process + (within the child process) + + for each backend node + { + if (the node status in shared memory is down) + execute follow primary command + } +} + + + + + Pgpool-II replaces the following special characters + with the backend specific information before executing the command. + + + + follow primary command options + + + + Special character + Description + + + + + + %d + DB node ID of the detached node + + + %h + Hostname of the detached node + + + %p + Port number of the detached node + + + %D + Database cluster directory of the detached node + + + %m + New primary node ID + + + %H + Hostname of the new primary node + + + %M + Old main node ID + + + %P + Old primary node ID + + + %r + Port number of the new primary node + + + %R + Database cluster directory of the new primary node + + + %N + Hostname of the old primary node (Pgpool-II 4.1 or after) + + + %S + Port number of the old primary node (Pgpool-II 4.1 or after) + + + %% + '%' character + + + + +
+ + + + If follow_primary_command is not empty, then after failover + on the primary node gets completed in Native Replication mode with streaming replication, + Pgpool-II degenerates all nodes except the new primary + and starts new child processes to be ready again to accept connections from the clients. + After this, Pgpool-II executes the command configured + in the follow_primary_command for each degenerated backend nodes. + + + + Typically follow_primary_command command + is used to recover the standby from the new primary by calling + the pcp_recovery_node command. In + the follow_primary_command, it is + recommended to check whether + target PostgreSQL node is running + or not using pg_ctl since already stopped node usually has a + reason to be stopped: for example, it's broken by hardware + problems or administrator is maintaining the node. If the + node is stopped, skip the node. If the node is running, stop + the node first and recovery it. + Although it is possible to recover by directly + executing pg_basebackup or other commands + instead of , you need to + execute to + notice Pgpool-II that the standby + server is ready to use. Otherwise the standby server remains in + down status. (Since + internally executes , you don't + need to execute after + recovering. + A complete follow_primary_command example can + be found in . + + + This parameter can be changed by reloading the Pgpool-II configurations. + +
+
+ + + failover_on_backend_shutdown (boolean) + + failover_on_backend_shutdown configuration parameter + + + + + When set to on, Pgpool-II detects a + backend shutdown event by checking particular error code + 57P01 and 57P02 on a + session established between the client and backend. If it + detects those error codes, a failover is triggered on that node. + When this is set to off, Pgpool-II + only report an error and disconnect the session in case of such + errors. The default is off. + + + If no client is connected, + Pgpool-II will not detect the event + even if the parameter is on. + + + In addition, in the streaming replication mode, shutting down + of PostgreSQL does not trigger a + failover, if the node is a standby node and is not the load + balance node even + if is on. In + order to find which node is the load balance node, you can + use + or . + + + + Please note that 57P01 is not only sent at a + shutdown event, but also sent when the backend currently + connected is killed by pg_terminate_backend + or SIGTERM signal. This is annoying because it results in + unwanted failover. To avoid this, turn off this parameter. + + + + + It is recommended to turn on the backend health checking + (see ) + when failover_on_backend_shutdown is set to off. + + + + + This parameter is available + in Pgpool-II 4.3 or later. This + parameter can be changed by reloading + the Pgpool-II configurations. + + + + + + failover_on_backend_error (boolean) + + failover_on_backend_error configuration parameter + + + + + When set to on, Pgpool-II considers the reading/writing + errors on the PostgreSQL backend connection as the backend node failure and trigger the + failover on that node after disconnecting the current session. + When this is set to off, Pgpool-II only report an error + and disconnect the session in case of such errors. + + + + It is recommended to turn on the backend health checking + (see ) + when failover_on_backend_error is set to off. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + Prior to Pgpool-II V4.0, + this configuration parameter name was fail_over_on_backend_error. + + + + + + + search_primary_node_timeout (integer) + + search_primary_node_timeout configuration parameter + + + + + Specifies the maximum amount of time in seconds to search for the + primary node when a failover scenario occurs. + Pgpool-II will give up looking for the primary + node if it is not found with-in this configured time. + Default is 300 and Setting this parameter to 0 means keep trying forever. + + + This parameter is only applicable in the streaming replication mode. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + detach_false_primary (boolean) + + detach_false_primary configuration parameter + + + + + If set to on, detach false primary node. The default is + off. This parameter is only valid in streaming replication + mode and for PostgreSQL 9.6 or + after since this feature + uses pg_stat_wal_receiver. + If PostgreSQL 9.5.x or older + version is used, no error is raised, just the feature is + ignored. + + + If there's no primary node, no checking will be performed. + + + If there's no standby node, and there's only one primary + node, no checking will be performed. + + + If there's no standby node, and there's multiple primary + nodes, leave the primary node which has the youngest node + id and detach rest of primary nodes. + + + If there are one or more primaries and one or more standbys, + check the connectivity between primary and standby nodes by + using pg_stat_wal_receiver + if PostgreSQL 9.6 or after. In + this case if a primary node connects to all standby nodes, + the primary is regarded as "true" primary. Other primaries + are regarded as "false" primary and the false primaries will + be detached if detach_false_primary is + true. If no "true" primary is found, nothing will happen. + + + When Pgpool-II starts, the + checking of false primaries are performed only once in + the Pgpool-II main + process. If is greater + than 0, the false primaries checking will be performed at + the same timing of streaming replication delay checking. + + + + + must + be PostgreSQL super user or + in "pg_monitor" group to use this feature. To + make in pg_monitor + group, execute following SQL command + by PostgreSQL super user + (replace "sr_check_user" with the setting + of ): + + GRANT pg_monitor TO sr_check_user; + + For PostgreSQL 9.6, there's + no pg_monitor group + and must + be PostgreSQL super user. + + + + + + if watchdog is enabled, detaching false primary is only done by + leader watchdog node. Even + if is on, + detaching the false primary being performed is solely by the + judgment of the leader watchdog. No majority consensus is + required. + + + + + This parameter is only applicable in the streaming replication mode. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + +
+ Detecting false primaries + + + + + +
+
+ +
+
+ + + auto_failback (boolean) + + auto_failback configuration parameter + + + + + When set to on, standby node be automatically failback, if the node status + is down but streaming replication works normally. This is useful when + standby node is degenerated by pgpool because of the temporary network failure. + + + + To use this feature, streaming replication check (see for more details) + must be enabled, and PostgreSQL 9.1 or later + is required as backend nodes. This feature uses pg_stat_replication + on primary node. The automatic failback is performed on standby node only. + Note that failback_command will be executed as well if failback_command is not empty. + If you plan to detach standby node for maintenance, set this parameter to off beforehand. + Otherwise it's possible that standby node is reattached against your intention. + + + The default is off. This parameter can be changed by reloading the Pgpool-II configurations. + + + + + may not work, when replication slot is used. + There is possibility that the streaming replication is stopped, because + is executed and replication slot is deleted by + the command. + + + + + + + auto_failback_interval (integer) + + auto_failback_interval configuration parameter + + + + + Specifies the minimum amount of time in seconds for execution interval of auto failback. + Next auto failback won't execute until that specified time have passed + after previous auto failback. When Pgpool-II frequently detect + backend down because of network error for example, you may avoid repeating + failover and failback by setting this parameter to large enough value. + The default is 60. Setting this parameter to 0 means that auto failback don't wait. + + +
@@ -468,13 +804,13 @@ Failover in the raw Mode - Failover can be performed in raw mode if multiple backend servers are defined. - Pgpool-II usually accesses the backend specified by - backend_hostname0 during normal operation. If the - backend_hostname0 fails for some reason, - Pgpool-II tries to access the backend specified by - backend_hostname1. If that fails, Pgpool-II - tries the backend_hostname2, 3 and so on. + Failover can be performed in raw mode if multiple backend servers are defined. + Pgpool-II usually accesses the backend specified by + backend_hostname0 during normal operation. If the + backend_hostname0 fails for some reason, + Pgpool-II tries to access the backend specified by + backend_hostname1. If that fails, Pgpool-II + tries the backend_hostname2, 3 and so on. diff --git a/doc/src/sgml/features-supported.sgml b/doc/src/sgml/features-supported.sgml deleted file mode 100644 index c879328a9..000000000 --- a/doc/src/sgml/features-supported.sgml +++ /dev/null @@ -1,2174 +0,0 @@ - - - B012 - - Embedded C - - - - B021 - - Direct SQL - - - - E011 - Core - Numeric data types - - - - E011-01 - Core - INTEGER and SMALLINT data types - - - - E011-02 - Core - REAL, DOUBLE PRECISION, and FLOAT data types - - - - E011-03 - Core - DECIMAL and NUMERIC data types - - - - E011-04 - Core - Arithmetic operators - - - - E011-05 - Core - Numeric comparison - - - - E011-06 - Core - Implicit casting among the numeric data types - - - - E021 - Core - Character data types - - - - E021-01 - Core - CHARACTER data type - - - - E021-02 - Core - CHARACTER VARYING data type - - - - E021-03 - Core - Character literals - - - - E021-04 - Core - CHARACTER_LENGTH function - trims trailing spaces from CHARACTER values before counting - - - E021-05 - Core - OCTET_LENGTH function - - - - E021-06 - Core - SUBSTRING function - - - - E021-07 - Core - Character concatenation - - - - E021-08 - Core - UPPER and LOWER functions - - - - E021-09 - Core - TRIM function - - - - E021-10 - Core - Implicit casting among the character string types - - - - E021-11 - Core - POSITION function - - - - E021-12 - Core - Character comparison - - - - E031 - Core - Identifiers - - - - E031-01 - Core - Delimited identifiers - - - - E031-02 - Core - Lower case identifiers - - - - E031-03 - Core - Trailing underscore - - - - E051 - Core - Basic query specification - - - - E051-01 - Core - SELECT DISTINCT - - - - E051-02 - Core - GROUP BY clause - - - - E051-04 - Core - GROUP BY can contain columns not in <select list> - - - - E051-05 - Core - Select list items can be renamed - - - - E051-06 - Core - HAVING clause - - - - E051-07 - Core - Qualified * in select list - - - - E051-08 - Core - Correlation names in the FROM clause - - - - E051-09 - Core - Rename columns in the FROM clause - - - - E061 - Core - Basic predicates and search conditions - - - - E061-01 - Core - Comparison predicate - - - - E061-02 - Core - BETWEEN predicate - - - - E061-03 - Core - IN predicate with list of values - - - - E061-04 - Core - LIKE predicate - - - - E061-05 - Core - LIKE predicate ESCAPE clause - - - - E061-06 - Core - NULL predicate - - - - E061-07 - Core - Quantified comparison predicate - - - - E061-08 - Core - EXISTS predicate - - - - E061-09 - Core - Subqueries in comparison predicate - - - - E061-11 - Core - Subqueries in IN predicate - - - - E061-12 - Core - Subqueries in quantified comparison predicate - - - - E061-13 - Core - Correlated subqueries - - - - E061-14 - Core - Search condition - - - - E071 - Core - Basic query expressions - - - - E071-01 - Core - UNION DISTINCT table operator - - - - E071-02 - Core - UNION ALL table operator - - - - E071-03 - Core - EXCEPT DISTINCT table operator - - - - E071-05 - Core - Columns combined via table operators need not have exactly the same data type - - - - E071-06 - Core - Table operators in subqueries - - - - E081 - Core - Basic Privileges - - - - E081-01 - Core - SELECT privilege - - - - E081-02 - Core - DELETE privilege - - - - E081-03 - Core - INSERT privilege at the table level - - - - E081-04 - Core - UPDATE privilege at the table level - - - - E081-05 - Core - UPDATE privilege at the column level - - - - E081-06 - Core - REFERENCES privilege at the table level - - - - E081-07 - Core - REFERENCES privilege at the column level - - - - E081-08 - Core - WITH GRANT OPTION - - - - E081-09 - Core - USAGE privilege - - - - E081-10 - Core - EXECUTE privilege - - - - E091 - Core - Set functions - - - - E091-01 - Core - AVG - - - - E091-02 - Core - COUNT - - - - E091-03 - Core - MAX - - - - E091-04 - Core - MIN - - - - E091-05 - Core - SUM - - - - E091-06 - Core - ALL quantifier - - - - E091-07 - Core - DISTINCT quantifier - - - - E101 - Core - Basic data manipulation - - - - E101-01 - Core - INSERT statement - - - - E101-03 - Core - Searched UPDATE statement - - - - E101-04 - Core - Searched DELETE statement - - - - E111 - Core - Single row SELECT statement - - - - E121 - Core - Basic cursor support - - - - E121-01 - Core - DECLARE CURSOR - - - - E121-02 - Core - ORDER BY columns need not be in select list - - - - E121-03 - Core - Value expressions in ORDER BY clause - - - - E121-04 - Core - OPEN statement - - - - E121-06 - Core - Positioned UPDATE statement - - - - E121-07 - Core - Positioned DELETE statement - - - - E121-08 - Core - CLOSE statement - - - - E121-10 - Core - FETCH statement implicit NEXT - - - - E121-17 - Core - WITH HOLD cursors - - - - E131 - Core - Null value support (nulls in lieu of values) - - - - E141 - Core - Basic integrity constraints - - - - E141-01 - Core - NOT NULL constraints - - - - E141-02 - Core - UNIQUE constraints of NOT NULL columns - - - - E141-03 - Core - PRIMARY KEY constraints - - - - E141-04 - Core - Basic FOREIGN KEY constraint with the NO ACTION default for both referential delete action and referential update action - - - - E141-06 - Core - CHECK constraints - - - - E141-07 - Core - Column defaults - - - - E141-08 - Core - NOT NULL inferred on PRIMARY KEY - - - - E141-10 - Core - Names in a foreign key can be specified in any order - - - - E151 - Core - Transaction support - - - - E151-01 - Core - COMMIT statement - - - - E151-02 - Core - ROLLBACK statement - - - - E152 - Core - Basic SET TRANSACTION statement - - - - E152-01 - Core - SET TRANSACTION statement: ISOLATION LEVEL SERIALIZABLE clause - - - - E152-02 - Core - SET TRANSACTION statement: READ ONLY and READ WRITE clauses - - - - E153 - Core - Updatable queries with subqueries - - - - E161 - Core - SQL comments using leading double minus - - - - E171 - Core - SQLSTATE support - - - - F021 - Core - Basic information schema - - - - F021-01 - Core - COLUMNS view - - - - F021-02 - Core - TABLES view - - - - F021-03 - Core - VIEWS view - - - - F021-04 - Core - TABLE_CONSTRAINTS view - - - - F021-05 - Core - REFERENTIAL_CONSTRAINTS view - - - - F021-06 - Core - CHECK_CONSTRAINTS view - - - - F031 - Core - Basic schema manipulation - - - - F031-01 - Core - CREATE TABLE statement to create persistent base tables - - - - F031-02 - Core - CREATE VIEW statement - - - - F031-03 - Core - GRANT statement - - - - F031-04 - Core - ALTER TABLE statement: ADD COLUMN clause - - - - F031-13 - Core - DROP TABLE statement: RESTRICT clause - - - - F031-16 - Core - DROP VIEW statement: RESTRICT clause - - - - F031-19 - Core - REVOKE statement: RESTRICT clause - - - - F032 - - CASCADE drop behavior - - - - F033 - - ALTER TABLE statement: DROP COLUMN clause - - - - F034 - - Extended REVOKE statement - - - - F034-01 - - REVOKE statement performed by other than the owner of a schema object - - - - F034-02 - - REVOKE statement: GRANT OPTION FOR clause - - - - F034-03 - - REVOKE statement to revoke a privilege that the grantee has WITH GRANT OPTION - - - - F041 - Core - Basic joined table - - - - F041-01 - Core - Inner join (but not necessarily the INNER keyword) - - - - F041-02 - Core - INNER keyword - - - - F041-03 - Core - LEFT OUTER JOIN - - - - F041-04 - Core - RIGHT OUTER JOIN - - - - F041-05 - Core - Outer joins can be nested - - - - F041-07 - Core - The inner table in a left or right outer join can also be used in an inner join - - - - F041-08 - Core - All comparison operators are supported (rather than just =) - - - - F051 - Core - Basic date and time - - - - F051-01 - Core - DATE data type (including support of DATE literal) - - - - F051-02 - Core - TIME data type (including support of TIME literal) with fractional seconds precision of at least 0 - - - - F051-03 - Core - TIMESTAMP data type (including support of TIMESTAMP literal) with fractional seconds precision of at least 0 and 6 - - - - F051-04 - Core - Comparison predicate on DATE, TIME, and TIMESTAMP data types - - - - F051-05 - Core - Explicit CAST between datetime types and character string types - - - - F051-06 - Core - CURRENT_DATE - - - - F051-07 - Core - LOCALTIME - - - - F051-08 - Core - LOCALTIMESTAMP - - - - F052 - Enhanced datetime facilities - Intervals and datetime arithmetic - - - - F053 - - OVERLAPS predicate - - - - F081 - Core - UNION and EXCEPT in views - - - - F111 - - Isolation levels other than SERIALIZABLE - - - - F111-01 - - READ UNCOMMITTED isolation level - - - - F111-02 - - READ COMMITTED isolation level - - - - F111-03 - - REPEATABLE READ isolation level - - - - F131 - Core - Grouped operations - - - - F131-01 - Core - WHERE, GROUP BY, and HAVING clauses supported in queries with grouped views - - - - F131-02 - Core - Multiple tables supported in queries with grouped views - - - - F131-03 - Core - Set functions supported in queries with grouped views - - - - F131-04 - Core - Subqueries with GROUP BY and HAVING clauses and grouped views - - - - F131-05 - Core - Single row SELECT with GROUP BY and HAVING clauses and grouped views - - - - F171 - - Multiple schemas per user - - - - F191 - Enhanced integrity management - Referential delete actions - - - - F200 - - TRUNCATE TABLE statement - - - - F201 - Core - CAST function - - - - F221 - Core - Explicit defaults - - - - F222 - - INSERT statement: DEFAULT VALUES clause - - - - F231 - - Privilege tables - - - - F231-01 - - TABLE_PRIVILEGES view - - - - F231-02 - - COLUMN_PRIVILEGES view - - - - F231-03 - - USAGE_PRIVILEGES view - - - - F251 - - Domain support - - - - F261 - Core - CASE expression - - - - F261-01 - Core - Simple CASE - - - - F261-02 - Core - Searched CASE - - - - F261-03 - Core - NULLIF - - - - F261-04 - Core - COALESCE - - - - F262 - - Extended CASE expression - - - - F271 - - Compound character literals - - - - F281 - - LIKE enhancements - - - - F302 - - INTERSECT table operator - - - - F302-01 - - INTERSECT DISTINCT table operator - - - - F302-02 - - INTERSECT ALL table operator - - - - F304 - - EXCEPT ALL table operator - - - - F311-01 - Core - CREATE SCHEMA - - - - F311-02 - Core - CREATE TABLE for persistent base tables - - - - F311-03 - Core - CREATE VIEW - - - - F311-04 - Core - CREATE VIEW: WITH CHECK OPTION - - - - F311-05 - Core - GRANT statement - - - - F321 - - User authorization - - - - F361 - - Subprogram support - - - - F381 - - Extended schema manipulation - - - - F381-01 - - ALTER TABLE statement: ALTER COLUMN clause - - - - F381-02 - - ALTER TABLE statement: ADD CONSTRAINT clause - - - - F381-03 - - ALTER TABLE statement: DROP CONSTRAINT clause - - - - F382 - - Alter column data type - - - - F383 - - Set column not null clause - - - - F391 - - Long identifiers - - - - F392 - - Unicode escapes in identifiers - - - - F393 - - Unicode escapes in literals - - - - F401 - - Extended joined table - - - - F401-01 - - NATURAL JOIN - - - - F401-02 - - FULL OUTER JOIN - - - - F401-04 - - CROSS JOIN - - - - F402 - - Named column joins for LOBs, arrays, and multisets - - - - F411 - Enhanced datetime facilities - Time zone specification - differences regarding literal interpretation - - - F421 - - National character - - - - F431 - - Read-only scrollable cursors - - - - F431-01 - - FETCH with explicit NEXT - - - - F431-02 - - FETCH FIRST - - - - F431-03 - - FETCH LAST - - - - F431-04 - - FETCH PRIOR - - - - F431-05 - - FETCH ABSOLUTE - - - - F431-06 - - FETCH RELATIVE - - - - F441 - - Extended set function support - - - - F442 - - Mixed column references in set functions - - - - F471 - Core - Scalar subquery values - - - - F481 - Core - Expanded NULL predicate - - - - F491 - Enhanced integrity management - Constraint management - - - - F501 - Core - Features and conformance views - - - - F501-01 - Core - SQL_FEATURES view - - - - F501-02 - Core - SQL_SIZING view - - - - F501-03 - Core - SQL_LANGUAGES view - - - - F502 - - Enhanced documentation tables - - - - F502-01 - - SQL_SIZING_PROFILES view - - - - F502-02 - - SQL_IMPLEMENTATION_INFO view - - - - F502-03 - - SQL_PACKAGES view - - - - F531 - - Temporary tables - - - - F555 - Enhanced datetime facilities - Enhanced seconds precision - - - - F561 - - Full value expressions - - - - F571 - - Truth value tests - - - - F591 - - Derived tables - - - - F611 - - Indicator data types - - - - F641 - - Row and table constructors - - - - F651 - - Catalog name qualifiers - - - - F661 - - Simple tables - - - - F672 - - Retrospective check constraints - - - - F690 - - Collation support - but no character set support - - - F692 - - Extended collation support - - - - F701 - Enhanced integrity management - Referential update actions - - - - F711 - - ALTER domain - - - - F731 - - INSERT column privileges - - - - F751 - - View CHECK enhancements - - - - F761 - - Session management - - - - F762 - - CURRENT_CATALOG - - - - F763 - - CURRENT_SCHEMA - - - - F771 - - Connection management - - - - F781 - - Self-referencing operations - - - - F791 - - Insensitive cursors - - - - F801 - - Full set function - - - - F850 - - Top-level <order by clause> in <query expression> - - - - F851 - - <order by clause> in subqueries - - - - F852 - - Top-level <order by clause> in views - - - - F855 - - Nested <order by clause> in <query expression> - - - - F856 - - Nested <fetch first clause> in <query expression> - - - - F857 - - Top-level <fetch first clause> in <query expression> - - - - F858 - - <fetch first clause> in subqueries - - - - F859 - - Top-level <fetch first clause> in views - - - - F860 - - <fetch first row count> in <fetch first clause> - - - - F861 - - Top-level <result offset clause> in <query expression> - - - - F862 - - <result offset clause> in subqueries - - - - F863 - - Nested <result offset clause> in <query expression> - - - - F864 - - Top-level <result offset clause> in views - - - - F865 - - <offset row count> in <result offset clause> - - - - S071 - Enhanced object support - SQL paths in function and type name resolution - - - - S092 - - Arrays of user-defined types - - - - S095 - - Array constructors by query - - - - S096 - - Optional array bounds - - - - S098 - - ARRAY_AGG - - - - S111 - Enhanced object support - ONLY in query expressions - - - - S201 - - SQL-invoked routines on arrays - - - - S201-01 - - Array parameters - - - - S201-02 - - Array as result type of functions - - - - S211 - Enhanced object support - User-defined cast functions - - - - T031 - - BOOLEAN data type - - - - T071 - - BIGINT data type - - - - T121 - - WITH (excluding RECURSIVE) in query expression - - - - T122 - - WITH (excluding RECURSIVE) in subquery - - - - T131 - - Recursive query - - - - T132 - - Recursive query in subquery - - - - T141 - - SIMILAR predicate - - - - T151 - - DISTINCT predicate - - - - T152 - - DISTINCT predicate with negation - - - - T171 - - LIKE clause in table definition - - - - T172 - - AS subquery clause in table definition - - - - T173 - - Extended LIKE clause in table definition - - - - T191 - Enhanced integrity management - Referential action RESTRICT - - - - T201 - Enhanced integrity management - Comparable data types for referential constraints - - - - T211-01 - Active database, Enhanced integrity management - Triggers activated on UPDATE, INSERT, or DELETE of one base table - - - - T211-02 - Active database, Enhanced integrity management - BEFORE triggers - - - - T211-03 - Active database, Enhanced integrity management - AFTER triggers - - - - T211-04 - Active database, Enhanced integrity management - FOR EACH ROW triggers - - - - T211-05 - Active database, Enhanced integrity management - Ability to specify a search condition that must be true before the trigger is invoked - - - - T211-07 - Active database, Enhanced integrity management - TRIGGER privilege - - - - T212 - Enhanced integrity management - Enhanced trigger capability - - - - T213 - - INSTEAD OF triggers - - - - T231 - - Sensitive cursors - - - - T241 - - START TRANSACTION statement - - - - T271 - - Savepoints - - - - T281 - - SELECT privilege with column granularity - - - - T312 - - OVERLAY function - - - - T321-01 - Core - User-defined functions with no overloading - - - - T321-03 - Core - Function invocation - - - - T321-06 - Core - ROUTINES view - - - - T321-07 - Core - PARAMETERS view - - - - T323 - - Explicit security for external routines - - - - T325 - - Qualified SQL parameter references - - - - T331 - - Basic roles - - - - T341 - - Overloading of SQL-invoked functions and procedures - - - - T351 - - Bracketed SQL comments (/*...*/ comments) - - - - T441 - - ABS and MOD functions - - - - T461 - - Symmetric BETWEEN predicate - - - - T491 - - LATERAL derived table - - - - T501 - - Enhanced EXISTS predicate - - - - T551 - - Optional key words for default syntax - - - - T581 - - Regular expression substring function - - - - T591 - - UNIQUE constraints of possibly null columns - - - - T614 - - NTILE function - - - - T615 - - LEAD and LAG functions - - - - T617 - - FIRST_VALUE and LAST_VALUE function - - - - T621 - - Enhanced numeric functions - - - - T631 - Core - IN predicate with one list element - - - - T651 - - SQL-schema statements in SQL routines - - - - T655 - - Cyclically dependent routines - - - - X010 - - XML type - - - - X011 - - Arrays of XML type - - - - X016 - - Persistent XML values - - - - X020 - - XMLConcat - - - - X031 - - XMLElement - - - - X032 - - XMLForest - - - - X034 - - XMLAgg - - - - X035 - - XMLAgg: ORDER BY option - - - - X036 - - XMLComment - - - - X037 - - XMLPI - - - - X040 - - Basic table mapping - - - - X041 - - Basic table mapping: nulls absent - - - - X042 - - Basic table mapping: null as nil - - - - X043 - - Basic table mapping: table as forest - - - - X044 - - Basic table mapping: table as element - - - - X045 - - Basic table mapping: with target namespace - - - - X046 - - Basic table mapping: data mapping - - - - X047 - - Basic table mapping: metadata mapping - - - - X048 - - Basic table mapping: base64 encoding of binary strings - - - - X049 - - Basic table mapping: hex encoding of binary strings - - - - X050 - - Advanced table mapping - - - - X051 - - Advanced table mapping: nulls absent - - - - X052 - - Advanced table mapping: null as nil - - - - X053 - - Advanced table mapping: table as forest - - - - X054 - - Advanced table mapping: table as element - - - - X055 - - Advanced table mapping: target namespace - - - - X056 - - Advanced table mapping: data mapping - - - - X057 - - Advanced table mapping: metadata mapping - - - - X058 - - Advanced table mapping: base64 encoding of binary strings - - - - X059 - - Advanced table mapping: hex encoding of binary strings - - - - X060 - - XMLParse: Character string input and CONTENT option - - - - X061 - - XMLParse: Character string input and DOCUMENT option - - - - X070 - - XMLSerialize: Character string serialization and CONTENT option - - - - X071 - - XMLSerialize: Character string serialization and DOCUMENT option - - - - X072 - - XMLSerialize: Character string serialization - - - - X090 - - XML document predicate - - - - X120 - - XML parameters in SQL routines - - - - X121 - - XML parameters in external routines - - - - X400 - - Name and identifier mapping - - - - X410 - - Alter column data type: XML type - - - diff --git a/doc/src/sgml/features-unsupported.sgml b/doc/src/sgml/features-unsupported.sgml deleted file mode 100644 index 4d42fbbff..000000000 --- a/doc/src/sgml/features-unsupported.sgml +++ /dev/null @@ -1,1862 +0,0 @@ - - - B011 - - Embedded Ada - - - - B013 - - Embedded COBOL - - - - B014 - - Embedded Fortran - - - - B015 - - Embedded MUMPS - - - - B016 - - Embedded Pascal - - - - B017 - - Embedded PL/I - - - - B031 - - Basic dynamic SQL - - - - B032 - - Extended dynamic SQL - - - - B032-01 - - <describe input statement> - - - - B033 - - Untyped SQL-invoked function arguments - - - - B034 - - Dynamic specification of cursor attributes - - - - B035 - - Non-extended descriptor names - - - - B041 - - Extensions to embedded SQL exception declarations - - - - B051 - - Enhanced execution rights - - - - B111 - - Module language Ada - - - - B112 - - Module language C - - - - B113 - - Module language COBOL - - - - B114 - - Module language Fortran - - - - B115 - - Module language MUMPS - - - - B116 - - Module language Pascal - - - - B117 - - Module language PL/I - - - - B121 - - Routine language Ada - - - - B122 - - Routine language C - - - - B123 - - Routine language COBOL - - - - B124 - - Routine language Fortran - - - - B125 - - Routine language MUMPS - - - - B126 - - Routine language Pascal - - - - B127 - - Routine language PL/I - - - - B128 - - Routine language SQL - - - - B211 - - Module language Ada: VARCHAR and NUMERIC support - - - - B221 - - Routine language Ada: VARCHAR and NUMERIC support - - - - E182 - Core - Module language - - - - F054 - - TIMESTAMP in DATE type precedence list - - - - F121 - - Basic diagnostics management - - - - F121-01 - - GET DIAGNOSTICS statement - - - - F121-02 - - SET TRANSACTION statement: DIAGNOSTICS SIZE clause - - - - F122 - - Enhanced diagnostics management - - - - F123 - - All diagnostics - - - - F181 - Core - Multiple module support - - - - F202 - - TRUNCATE TABLE: identity column restart option - - - - F263 - - Comma-separated predicates in simple CASE expression - - - - F291 - - UNIQUE predicate - - - - F301 - - CORRESPONDING in query expressions - - - - F311 - Core - Schema definition statement - - - - F312 - - MERGE statement - - - - F313 - - Enhanced MERGE statement - - - - F314 - - MERGE statement with DELETE branch - - - - F341 - - Usage tables - no ROUTINE_*_USAGE tables - - - F384 - - Drop identity property clause - - - - F385 - - Drop column generation expression clause - - - - F386 - - Set identity column generation clause - - - - F394 - - Optional normal form specification - - - - F403 - - Partitioned joined tables - - - - F451 - - Character set definition - - - - F461 - - Named character sets - - - - F492 - - Optional table constraint enforcement - - - - F521 - Enhanced integrity management - Assertions - - - - F671 - Enhanced integrity management - Subqueries in CHECK - intentionally omitted - - - F693 - - SQL-session and client module collations - - - - F695 - - Translation support - - - - F696 - - Additional translation documentation - - - - F721 - - Deferrable constraints - foreign and unique keys only - - - F741 - - Referential MATCH types - no partial match yet - - - F812 - Core - Basic flagging - - - - F813 - - Extended flagging - - - - F821 - - Local table references - - - - F831 - - Full cursor update - - - - F831-01 - - Updatable scrollable cursors - - - - F831-02 - - Updatable ordered cursors - - - - F841 - - LIKE_REGEX predicate - - - - F842 - - OCCURENCES_REGEX function - - - - F843 - - POSITION_REGEX function - - - - F844 - - SUBSTRING_REGEX function - - - - F845 - - TRANSLATE_REGEX function - - - - F846 - - Octet support in regular expression operators - - - - F847 - - Nonconstant regular expressions - - - - F866 - - FETCH FIRST clause: PERCENT option - - - - F867 - - FETCH FIRST clause: WITH TIES option - - - - S011 - Core - Distinct data types - - - - S011-01 - Core - USER_DEFINED_TYPES view - - - - S023 - Basic object support - Basic structured types - - - - S024 - Enhanced object support - Enhanced structured types - - - - S025 - - Final structured types - - - - S026 - - Self-referencing structured types - - - - S027 - - Create method by specific method name - - - - S028 - - Permutable UDT options list - - - - S041 - Basic object support - Basic reference types - - - - S043 - Enhanced object support - Enhanced reference types - - - - S051 - Basic object support - Create table of type - partially supported - - - S081 - Enhanced object support - Subtables - - - - S091 - - Basic array support - partially supported - - - S091-01 - - Arrays of built-in data types - - - - S091-02 - - Arrays of distinct types - - - - S091-03 - - Array expressions - - - - S094 - - Arrays of reference types - - - - S097 - - Array element assignment - - - - S151 - Basic object support - Type predicate - - - - S161 - Enhanced object support - Subtype treatment - - - - S162 - - Subtype treatment for references - - - - S202 - - SQL-invoked routines on multisets - - - - S231 - Enhanced object support - Structured type locators - - - - S232 - - Array locators - - - - S233 - - Multiset locators - - - - S241 - - Transform functions - - - - S242 - - Alter transform statement - - - - S251 - - User-defined orderings - - - - S261 - - Specific type method - - - - S271 - - Basic multiset support - - - - S272 - - Multisets of user-defined types - - - - S274 - - Multisets of reference types - - - - S275 - - Advanced multiset support - - - - S281 - - Nested collection types - - - - S291 - - Unique constraint on entire row - - - - S301 - - Enhanced UNNEST - - - - S401 - - Distinct types based on array types - - - - S402 - - Distinct types based on distinct types - - - - S403 - - ARRAY_MAX_CARDINALITY - - - - S404 - - TRIM_ARRAY - - - - T011 - - Timestamp in Information Schema - - - - T021 - - BINARY and VARBINARY data types - - - - T022 - - Advanced support for BINARY and VARBINARY data types - - - - T023 - - Compound binary literal - - - - T024 - - Spaces in binary literals - - - - T041 - Basic object support - Basic LOB data type support - - - - T041-01 - Basic object support - BLOB data type - - - - T041-02 - Basic object support - CLOB data type - - - - T041-03 - Basic object support - POSITION, LENGTH, LOWER, TRIM, UPPER, and SUBSTRING functions for LOB data types - - - - T041-04 - Basic object support - Concatenation of LOB data types - - - - T041-05 - Basic object support - LOB locator: non-holdable - - - - T042 - - Extended LOB data type support - - - - T043 - - Multiplier T - - - - T044 - - Multiplier P - - - - T051 - - Row types - - - - T052 - - MAX and MIN for row types - - - - T053 - - Explicit aliases for all-fields reference - - - - T061 - - UCS support - - - - T101 - - Enhanced nullability determination - - - - T111 - - Updatable joins, unions, and columns - - - - T174 - - Identity columns - - - - T175 - - Generated columns - - - - T176 - - Sequence generator support - - - - T177 - - Sequence generator support: simple restart option - - - - T178 - - Identity columns: simple restart option - - - - T180 - - System-versioned tables - - - - T181 - - Application-time period tables - - - - T211 - Active database, Enhanced integrity management - Basic trigger capability - - - - T211-06 - Active database, Enhanced integrity management - Support for run-time rules for the interaction of triggers and constraints - - - - T211-08 - Active database, Enhanced integrity management - Multiple triggers for the same event are executed in the order in which they were created in the catalog - intentionally omitted - - - T251 - - SET TRANSACTION statement: LOCAL option - - - - T261 - - Chained transactions - - - - T272 - - Enhanced savepoint management - - - - T285 - - Enhanced derived column names - - - - T301 - - Functional dependencies - partially supported - - - T321 - Core - Basic SQL-invoked routines - - - - T321-02 - Core - User-defined stored procedures with no overloading - - - - T321-04 - Core - CALL statement - - - - T321-05 - Core - RETURN statement - - - - T322 - PSM - Declared data type attributes - - - - T324 - - Explicit security for SQL routines - - - - T326 - - Table functions - - - - T332 - - Extended roles - mostly supported - - - T431 - OLAP - Extended grouping capabilities - - - - T432 - - Nested and concatenated GROUPING SETS - - - - T433 - - Multiargument GROUPING function - - - - T434 - - GROUP BY DISTINCT - - - - T471 - - Result sets return value - - - - T472 - - DESCRIBE CURSOR - - - - T495 - - Combined data change and retrieval - different syntax - - - T502 - - Period predicates - - - - T511 - - Transaction counts - - - - T521 - - Named arguments in CALL statement - - - - T522 - - Default values for IN parameters of SQL-invoked procedures - - - - T541 - - Updatable table references - - - - T561 - - Holdable locators - - - - T571 - - Array-returning external SQL-invoked functions - - - - T572 - - Multiset-returning external SQL-invoked functions - - - - T601 - - Local cursor references - - - - T611 - OLAP - Elementary OLAP operations - most forms supported - - - T612 - - Advanced OLAP operations - some forms supported - - - T613 - - Sampling - - - - T616 - - Null treatment option for LEAD and LAG functions - - - - T618 - - NTH_VALUE function - function exists, but some options missing - - - T619 - - Nested window functions - - - - T620 - - WINDOW clause: GROUPS option - - - - T641 - - Multiple column assignment - only some syntax variants supported - - - T652 - - SQL-dynamic statements in SQL routines - - - - T653 - - SQL-schema statements in external routines - - - - T654 - - SQL-dynamic statements in external routines - - - - M001 - - Datalinks - - - - M002 - - Datalinks via SQL/CLI - - - - M003 - - Datalinks via Embedded SQL - - - - M004 - - Foreign data support - partially supported - - - M005 - - Foreign schema support - - - - M006 - - GetSQLString routine - - - - M007 - - TransmitRequest - - - - M009 - - GetOpts and GetStatistics routines - - - - M010 - - Foreign data wrapper support - different API - - - M011 - - Datalinks via Ada - - - - M012 - - Datalinks via C - - - - M013 - - Datalinks via COBOL - - - - M014 - - Datalinks via Fortran - - - - M015 - - Datalinks via M - - - - M016 - - Datalinks via Pascal - - - - M017 - - Datalinks via PL/I - - - - M018 - - Foreign data wrapper interface routines in Ada - - - - M019 - - Foreign data wrapper interface routines in C - different API - - - M020 - - Foreign data wrapper interface routines in COBOL - - - - M021 - - Foreign data wrapper interface routines in Fortran - - - - M022 - - Foreign data wrapper interface routines in MUMPS - - - - M023 - - Foreign data wrapper interface routines in Pascal - - - - M024 - - Foreign data wrapper interface routines in PL/I - - - - M030 - - SQL-server foreign data support - - - - M031 - - Foreign data wrapper general routines - - - - X012 - - Multisets of XML type - - - - X013 - - Distinct types of XML type - - - - X014 - - Attributes of XML type - - - - X015 - - Fields of XML type - - - - X025 - - XMLCast - - - - X030 - - XMLDocument - - - - X038 - - XMLText - - - - X065 - - XMLParse: BLOB input and CONTENT option - - - - X066 - - XMLParse: BLOB input and DOCUMENT option - - - - X068 - - XMLSerialize: BOM - - - - X069 - - XMLSerialize: INDENT - - - - X073 - - XMLSerialize: BLOB serialization and CONTENT option - - - - X074 - - XMLSerialize: BLOB serialization and DOCUMENT option - - - - X075 - - XMLSerialize: BLOB serialization - - - - X076 - - XMLSerialize: VERSION - - - - X077 - - XMLSerialize: explicit ENCODING option - - - - X078 - - XMLSerialize: explicit XML declaration - - - - X080 - - Namespaces in XML publishing - - - - X081 - - Query-level XML namespace declarations - - - - X082 - - XML namespace declarations in DML - - - - X083 - - XML namespace declarations in DDL - - - - X084 - - XML namespace declarations in compound statements - - - - X085 - - Predefined namespace prefixes - - - - X086 - - XML namespace declarations in XMLTable - - - - X091 - - XML content predicate - - - - X096 - - XMLExists - - - - X100 - - Host language support for XML: CONTENT option - - - - X101 - - Host language support for XML: DOCUMENT option - - - - X110 - - Host language support for XML: VARCHAR mapping - - - - X111 - - Host language support for XML: CLOB mapping - - - - X112 - - Host language support for XML: BLOB mapping - - - - X113 - - Host language support for XML: STRIP WHITESPACE option - - - - X114 - - Host language support for XML: PRESERVE WHITESPACE option - - - - X131 - - Query-level XMLBINARY clause - - - - X132 - - XMLBINARY clause in DML - - - - X133 - - XMLBINARY clause in DDL - - - - X134 - - XMLBINARY clause in compound statements - - - - X135 - - XMLBINARY clause in subqueries - - - - X141 - - IS VALID predicate: data-driven case - - - - X142 - - IS VALID predicate: ACCORDING TO clause - - - - X143 - - IS VALID predicate: ELEMENT clause - - - - X144 - - IS VALID predicate: schema location - - - - X145 - - IS VALID predicate outside check constraints - - - - X151 - - IS VALID predicate with DOCUMENT option - - - - X152 - - IS VALID predicate with CONTENT option - - - - X153 - - IS VALID predicate with SEQUENCE option - - - - X155 - - IS VALID predicate: NAMESPACE without ELEMENT clause - - - - X157 - - IS VALID predicate: NO NAMESPACE with ELEMENT clause - - - - X160 - - Basic Information Schema for registered XML Schemas - - - - X161 - - Advanced Information Schema for registered XML Schemas - - - - X170 - - XML null handling options - - - - X171 - - NIL ON NO CONTENT option - - - - X181 - - XML(DOCUMENT(UNTYPED)) type - - - - X182 - - XML(DOCUMENT(ANY)) type - - - - X190 - - XML(SEQUENCE) type - - - - X191 - - XML(DOCUMENT(XMLSCHEMA)) type - - - - X192 - - XML(CONTENT(XMLSCHEMA)) type - - - - X200 - - XMLQuery - - - - X201 - - XMLQuery: RETURNING CONTENT - - - - X202 - - XMLQuery: RETURNING SEQUENCE - - - - X203 - - XMLQuery: passing a context item - - - - X204 - - XMLQuery: initializing an XQuery variable - - - - X205 - - XMLQuery: EMPTY ON EMPTY option - - - - X206 - - XMLQuery: NULL ON EMPTY option - - - - X211 - - XML 1.1 support - - - - X221 - - XML passing mechanism BY VALUE - - - - X222 - - XML passing mechanism BY REF - - - - X231 - - XML(CONTENT(UNTYPED)) type - - - - X232 - - XML(CONTENT(ANY)) type - - - - X241 - - RETURNING CONTENT in XML publishing - - - - X242 - - RETURNING SEQUENCE in XML publishing - - - - X251 - - Persistent XML values of XML(DOCUMENT(UNTYPED)) type - - - - X252 - - Persistent XML values of XML(DOCUMENT(ANY)) type - - - - X253 - - Persistent XML values of XML(CONTENT(UNTYPED)) type - - - - X254 - - Persistent XML values of XML(CONTENT(ANY)) type - - - - X255 - - Persistent XML values of XML(SEQUENCE) type - - - - X256 - - Persistent XML values of XML(DOCUMENT(XMLSCHEMA)) type - - - - X257 - - Persistent XML values of XML(CONTENT(XMLSCHEMA)) type - - - - X260 - - XML type: ELEMENT clause - - - - X261 - - XML type: NAMESPACE without ELEMENT clause - - - - X263 - - XML type: NO NAMESPACE with ELEMENT clause - - - - X264 - - XML type: schema location - - - - X271 - - XMLValidate: data-driven case - - - - X272 - - XMLValidate: ACCORDING TO clause - - - - X273 - - XMLValidate: ELEMENT clause - - - - X274 - - XMLValidate: schema location - - - - X281 - - XMLValidate: with DOCUMENT option - - - - X282 - - XMLValidate with CONTENT option - - - - X283 - - XMLValidate with SEQUENCE option - - - - X284 - - XMLValidate NAMESPACE without ELEMENT clause - - - - X286 - - XMLValidate: NO NAMESPACE with ELEMENT clause - - - - X300 - - XMLTable - - - - X301 - - XMLTable: derived column list option - - - - X302 - - XMLTable: ordinality column option - - - - X303 - - XMLTable: column default option - - - - X304 - - XMLTable: passing a context item - - - - X305 - - XMLTable: initializing an XQuery variable - - - diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index a7efd6a7a..2247e15d0 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -13,36 +13,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -60,127 +35,31 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + %allfiles; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + @@ -191,14 +70,8 @@ - - - - - - - + - Health Check - - - Pgpool-II periodically connects to the configured - PostgreSQL backends to detect any error on the servers or networks. - This error check procedure is called "health check". - If an error is detected, Pgpool-II performs failover - or degeneration depending on the configurations. - - - Health check requires one extra connection to each backend node, - so max_connections in the postgresql.conf - needs to be adjusted accordingly. - - - + Health Check + + + Pgpool-II periodically connects to the configured + PostgreSQL backends to detect any error on the servers or networks. + This error check procedure is called "health check". + + + If SSL is enabled, health check + process may use SSL connection. + + + If an error is detected, Pgpool-II performs failover + or degeneration depending on the configurations. + + + Health check requires one extra connection to each backend node, + so max_connections in the postgresql.conf + needs to be adjusted accordingly. + + + - - Following parameter names can also have numeric suffix at the end - of each name. The suffix corresponds to backend id, which is - defined in backend information, such - as . - example, health_check_timeout0 is applied to - backend 0's health_check_timeout value. - - - If there's no parameter with suffix, the value for the backend - is taken from the parameter name which does not have a suffix. In - this sense, parameter names without suffix work like "global - variables". - + + The health check process collects various statistics data such as + number of health check count in total. To inspect the statistics + data, use + command. Please note that the data is stored in the shared memory + area and it will be initialized upon + Pgpool-II starting up. + - + + Following parameter names can also have numeric suffix at the end + of each name. The suffix corresponds to backend id, which is + defined in backend information, such + as . + For example, health_check_timeout0 is applied to + backend 0's health_check_timeout value. + + + If there's no parameter with suffix, the value for the backend + is taken from the parameter name which does not have a suffix. In + this sense, parameter names without suffix work like "global + variables". + - - health_check_timeout (integer) - - health_check_timeout configuration parameter - - - + + + + health_check_timeout (integer) + + health_check_timeout configuration parameter + + + - Specifies the timeout in seconds to give up connecting to the backend - PostgreSQL if the TCP connect does not succeed within this time. + Specifies the timeout in seconds to give up connecting to the backend + PostgreSQL if the TCP connect does not succeed within this time. - This parameter serves to prevent the health check from waiting for a - long time when the network cable is unplugged. - Default value is 20. Setting it to 0, disables the timeout (waits until TCP/IP timeout). + This parameter serves to prevent the health check from waiting for a + long time when the network cable is unplugged. + Default value is 20. Setting it to 0, disables the timeout (waits until TCP/IP timeout). - This parameter can be changed by reloading the Pgpool-II configurations. + This parameter can be changed by reloading the Pgpool-II configurations. - - + + - - health_check_period (integer) - - health_check_period configuration parameter - - - + + health_check_period (integer) + + health_check_period configuration parameter + + + - Specifies the interval between the health checks in seconds. - Default is 0, which means health check is disabled. + Specifies the interval between the health checks in seconds. + Default is 0, which means health check is disabled. This parameter can be changed by reloading the Pgpool-II configurations. - - + + - - health_check_user (string) - - health_check_user configuration parameter - - - - - Specifies the PostgreSQL user name to perform health check. - The same user must exist in all the PostgreSQL backends. - Otherwise, health check causes an error. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - health_check_password (string) - - health_check_password configuration parameter - - - - - Specifies the password for the PostgreSQL user name configured in - to perform health check. - The user and password must be same in all the PostgreSQL backends. - Otherwise, health check results in an error. - - - If health_check_password is left blank Pgpool-II - will first try to get the password for from - file before using the empty password. - - - You can also specify AES256-CBC encrypted password in health_check_password field. - To specify the AES encrypted password, password string must be prefixed with - AES after encrypting (using aes-256-cbc algorithm) and - encoding to base64. - - - To specify the unencrypted clear text password, prefix the password string with - TEXT. For example if you want to set mypass as - a password, you should specify TEXTmypass in the password field. - In the absence of a valid prefix, Pgpool-II will considered - the string as a plain text password. - - - You can also use utility to create the correctly formatted - AES encrypted password strings. - - - Pgpool-II will require a valid decryption key at the - startup to use the encrypted passwords. - see for more details on providing the - decryption key to Pgpool-II - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - + + health_check_user (string) + + health_check_user configuration parameter + + + + + Specifies the PostgreSQL user name to perform health check. + Default is ''(empty). + The same user must exist in all the PostgreSQL backends. + Otherwise, health check causes an error. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + health_check_password (string) + + health_check_password configuration parameter + + + + + Specifies the password for the PostgreSQL user name configured in + to perform health check. + The user and password must be same in all the PostgreSQL backends. + Otherwise, health check results in an error. + + + If health_check_password is left blank Pgpool-II + will first try to get the password for from + file before using the empty password. + + + Pgpool-II accepts following forms + of password in either health_check_password + or file: + + + + AES256-CBC encrypted password + + + Most secure and recommended way to store password. The + password string must be prefixed + with AES. + You can use utility to create the correctly formatted + AES encrypted password strings. + Pgpool-II will require a valid decryption key at the + startup to use the encrypted passwords. + see for more details on providing the + decryption key to Pgpool-II + + + + + + MD5 hashed password + + + Not so secure as AES256, but still better than clear + text password. The password string must be prefixed + with MD5. Note that the backend + must set up MD5 authentication as well. You can + use utility to create the + correctly formatted + MD5 hashed password strings. + + + + + + Plain text password + + + Not encrypted, clear text password. You should avoid + to use this if possible. The password string must be + prefixed with TEXT. For example if + you want to set mypass as a + password, you should + specify TEXTmypass in the password + field. In the absence of a valid + prefix, Pgpool-II will + considered the string as a plain text password. + + + + + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + - health_check_database (string) - - health_check_database configuration parameter - - - - - Specifies the PostgreSQL database name to perform health check. - The default is ''(empty), which tries "postgres" - database first, then "template1" database until it succeeds - - - health_check_database was introduced in - Pgpool-II V3.5. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - + health_check_database (string) + + health_check_database configuration parameter + + + + + Specifies the PostgreSQL database name to perform health check. + The default is ''(empty), which tries "postgres" + database first, then "template1" database until it succeeds + + + health_check_database was introduced in + Pgpool-II V3.5. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + - health_check_max_retries (integer) - - health_check_max_retries configuration parameter - - - + health_check_max_retries (integer) + + health_check_max_retries configuration parameter + + + + + Specifies the maximum number of retries to do before giving up and + initiating failover when health check fails. + - Specifies the maximum number of retries to do before giving up and - initiating failover when health check fails. - - - This setting can be useful in spotty networks, when it is expected that - health checks will fail occasionally even when the master node is fine. - - - - - It is advised that must be disabled, - if you want to enable health_check_max_retries. - - - Default is 0, which means do not retry. + This setting can be useful in spotty networks, when it is expected that + health checks will fail occasionally even when the primary node is fine. + + - This parameter can be changed by reloading the Pgpool-II configurations. + It is advised that must be disabled, + if you want to enable health_check_max_retries. - + + Default is 0, which means do not retry. +
+ + This parameter can be changed by reloading the Pgpool-II configurations. + + - health_check_retry_delay (integer) - - health_check_retry_delay configuration parameter - - - - - Specifies the amount of time in seconds to sleep between failed - health check retries (not used unless is > 0). - If 0, then retries are immediate without delay. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - + health_check_retry_delay (integer) + + health_check_retry_delay configuration parameter + + + + + Specifies the amount of time in seconds to sleep between failed + health check retries (not used unless is > 0). + If 0, then retries are immediate without delay. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + - - connect_timeout (integer) - - connect_timeout configuration parameter - - - - - Specifies the amount of time in milliseconds before giving up connecting - to backend using connect() system call. - Default is 10000 ms (10 second). The flaky network user may want to increase the value. - 0 means no timeout. - - - connect_timeout value is not only used for a health check, - but also for creating ordinary connection pools. - - - + + connect_timeout (integer) + + connect_timeout configuration parameter + + + + + Specifies the amount of time in milliseconds before giving up connecting + to backend using connect() system call. + Default is 10000 ms (10 second). The flaky network user may want to increase the value. + 0 means no timeout. + - This parameter can be changed by reloading the Pgpool-II configurations. + connect_timeout value is not only used for a health check, + but also for creating ordinary connection pools. - - + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + - +
diff --git a/doc/src/sgml/history.sgml b/doc/src/sgml/history.sgml index 5ce15421e..e3d068eb9 100644 --- a/doc/src/sgml/history.sgml +++ b/doc/src/sgml/history.sgml @@ -8,31 +8,31 @@ of Pgpool-II - Pgpool-II started its life as a personal - project by Tatsuo Ishii. In the project it was just a simple - connection pooling software. So the - name Pgpool came from the fact. The - first version was in public in 2003. + Pgpool-II started its life as a personal + project by Tatsuo Ishii. In the project it was just a simple + connection pooling software. So the + name Pgpool came from the fact. The + first version was in public in 2003. - In 2004, Pgpool 1.0 was released with - the native replication feature (SQL statement based - replication). In the same year 2.0 was released with load - balancing, and support for version 3 frontend/backend protocol. In - 2005, automated fail over and master slave mode support were added. + In 2004, Pgpool 1.0 was released with + the native replication feature (SQL statement based + replication). In the same year 2.0 was released with load + balancing, and support for version 3 frontend/backend protocol. In + 2005, automated fail over and master slave mode support were added. - In 2006, Pgpool - became Pgpool-II. The first release 1.0 - eliminated many of restrictions - in Pgpool, for example the number - of PostgreSQL servers was up to 2 in - Pgpool. Also many new features such as - parallel query mode and PCP commands (PCP stands for "Pgpool - Control Protocol") were added. Probably the most important change - made between Pgpool - and Pgpool-II was that the project was - changed from a personal project to a group project owned by the - Pgpool Developement Group. + In 2006, Pgpool + became Pgpool-II. The first release 1.0 + eliminated many of restrictions + in Pgpool, for example the number + of PostgreSQL servers was up to 2 in + Pgpool. Also many new features such as + parallel query mode and PCP commands (PCP stands for "Pgpool + Control Protocol") were added. Probably the most important change + made between Pgpool + and Pgpool-II was that the project was + changed from a personal project to a group project owned by the + Pgpool Development Group.
diff --git a/doc/src/sgml/installation-rpm.sgml b/doc/src/sgml/installation-rpm.sgml index 763f5fa08..582c53f7a 100644 --- a/doc/src/sgml/installation-rpm.sgml +++ b/doc/src/sgml/installation-rpm.sgml @@ -1,128 +1,207 @@ - Installation from RPM + Installation from RPM + + This chapter describes the installation of Pgpool-II from RPM. + If you are going to install from the source code, please check . + + + Pgpool-II community provides RPM packages for RHEL10/9/8 + and the operating system which is compatible with RHEL. + You can download package files from + official Pgpool-II repository. + + + Pgpool-II official repository contains the following packages: + + + Pgpool-II RPM Packages + + + + Package + Description + + + + + pgpool-II-pgXX + Libraries and binaries required to run Pgpool-II + + + pgpool-II-pgXX-extensions + This package must be installed on all PostgreSQL servers to use online recovery functionality + + + pgpool-II-pgXX-debuginfo + Debug symbols for debugging + + + pgpool-II-pgXX-debugsource + Only for RHEL10/9/8. Debug symbols for debugging + + + pgpool-II-pgXX-extensions-debuginfo + Only for RHEL10/9/8. Debug symbols for debugging + + + pgpool-II-pgXX-devel + Header files for developers + + + +
+ + + Pgpool-II needs PostgreSQL's + library and extensions directory. Since the directory paths are different in + the particular PostgreSQL versions, + Pgpool-II provides separate packages for each PostgreSQL version. + "XX" in the above package is a two-digit number representing the version of PostgreSQL. + Choose Pgpool-II RPM corresponding to your PostgreSQL version. + (For example, if you are using PostgreSQL 18, you need to install pgpool-II-pg18) + + + + Before Installing + + Since Pgpool-II related packages are also included in + PostgreSQL YUM repository, + if PostgreSQL repository package is already installed, + add the "exclude" settings to /etc/yum.repos.d/pgdg-redhat-all.repo, + so that Pgpool-II will not be installed from + PostgreSQL YUM repository. + If Pgpool-II and PostgreSQL + are installed on separate servers, you can skip this section. + + +vi /etc/yum.repos.d/pgdg-redhat-all.repo + + + The following is a setting example of /etc/yum.repos.d/pgdg-redhat-all.repo. + + +[pgdg-common] +... +exclude=pgpool* + +[pgdg18] +... +exclude=pgpool* + +[pgdg17] +... +exclude=pgpool* + +[pgdg16] +... +exclude=pgpool* + +[pgdg15] +... +exclude=pgpool* + +[pgdg14] +... +exclude=pgpool* + +[pgdg13] +... +exclude=pgpool* + + + + + Installing RPM + + Here we install Pgpool-II using + Pgpool-II official YUM repository. + + + + The following commands assume that you are using Pgpool-II 4.6.x for PostgreSQL 18 on RHEL10. + If you are using other versions, replace "pgXX" with your PostgreSQL version. + + + First, install the repository corresponding to your Pgpool-II + version and distribution. + For REHL9/8, see here. + + +dnf install https://www.pgpool.net/yum/rpms/4.6/redhat/rhel-10-x86_64/pgpool-II-release-4.6-1.noarch.rpm + + + Then, install Pgpool-II. + + +dnf install pgpool-II-pg18 + + + To use online recovery feature, install pgpool-II-pg18-extensions + on all PostgreSQL servers. + Because pgpool-II-pgXX-extensions depends on + pgpool-II-pgXX package, + if Pgpool-II and PostgreSQL + are installed on separate servers, pgpool-II-pgXX also need to be installed + on PostgreSQL servers. + + - This chapter describes the installation - of Pgpool-II from PRM. If you are - going to install from the source code, please - check . + pgpool-II-pgXX-extensions needs to be installed + on the PostgreSQL servers. + If Pgpool-II and PostgreSQL + are installed on separate servers, + it is not required to install it on the servers where Pgpool-II are running. - - - Installing RPM - - Pgpool-II official RPMs can be - obtained from - http://www.pgpool.net/yum. - - - - For RHEL and its derivatives do following once: - -yum install http://www.pgpool.net/yum/rpms/3.6/redhat/rhel-7-x86_64/pgpool-II-release-3.6-1.noarch.rpm - - Then: - -yum install pgpool-II-pg96 - - - pg96 means PostgreSQL - 9.5. Pgpool-II - needs PostgreSQL's library and - extensions directory. Since the directory paths are different in - the particular PostgreSQL versions, - You must choose appropriate RPM for - your PostgreSQL rpm installation. We - also assume you are - using PostgreSQL - community rpms. - - Optionally you can install: - -yum install pgpool-II-pg96-debuginfo - - which makes it easier to retrieve debugging symbols from the core - or the backtrace. We recommend to install it. - - There is an optional package for developers. - -yum install pgpool-II-pg96-devel - - This installs header files which developers are interested in - - - - On all the PostgreSQL servers you need - to install: - -yum install pgpool-II-pg96-extensions - - - - - - - Configuration with RPM - - All the Pgpool-II configuration files - live in /etc/pgpool-II. Please refer - to to see how to set up - configuration files. - - - - - Starting/stopping Pgpool-II - - On RHEL7/CentOS 7, do this once. - - + + +dnf install pgpool-II-pg18-extensions pgpool-II-pg18 + + + + Optionally you can install debuginfo and devel packages for developers if necessary. + + +dnf install pgpool-II-pg18-debuginfo pgpool-II-pg18-devel + + + + + Configuration Pgpool-II + + All the Pgpool-II configuration files + are installed in /etc/pgpool-II. Please refer + to to see how to set up + configuration files. + + + + + Starting/stopping Pgpool-II + + On RHEL10/9/8, do this once, if set the automatic startup of Pgpool-II. + systemctl enable pgpool.service - + - After this, restart the whole system or: + After this, to start Pgpool-II, + run the following command or restart the whole system. + Please note that PostgreSQL servers must have been started before this. - + systemctl start pgpool.service - + - Please note that PostgreSQL servers - must have been started before this. - - To stop Pgpool-II: - + To stop Pgpool-II, do this once. + Please note that Pgpool-II must be stopped + before stopping PostgreSQL. + systemctl stop pgpool.service - - - After this, you can stop PostgreSQL - servers. - - - On RHEL6/CentOS 6, do this once. - - -chkconfig pgpool on - - - After this, restart the whole system or: - - -service start pgpool - - - Please note that PostgreSQL servers - must have been started before this. - - To stop Pgpool-II: - -service stop pgpool - - - After this, you can stop PostgreSQL - servers. - - - + -
+ After this, you can stop PostgreSQL + servers. + + +
diff --git a/doc/src/sgml/installation-tips.sgml b/doc/src/sgml/installation-tips.sgml index 43d504ebc..8c9c61043 100644 --- a/doc/src/sgml/installation-tips.sgml +++ b/doc/src/sgml/installation-tips.sgml @@ -1,47 +1,65 @@ - Tips for Installation - - This chapter gathers random tips for installing Pgpool-II. - - - - Firewalls - - When Pgpool-II connects to - other Pgpool-II servers - or PostgreSQL servers, the target port - must be accessible by enabling firewall management softwares. - - - - Here is an example for CentOS/RHEL7 when access - to PostgreSQL is required. - -firewall-cmd --permanent --zone=public --add-service=postgresql -firewall-cmd --reload - - "postgresql" is the service name assigned - to PostgreSQL. The list of service - names can be obtained by: - - firewall-cmd --get-services - - Note that you can define your own service name in - /usr/lib/firewalld/services/. - - - - If PostgreSQL is listening on 11002 - port, rather than the standard 5432 port, you can do: - - firewall-cmd --zone=public --remove-service=popstgresql --permanent - firewall-cmd --zone=public --add-port=11002/tcp --permanent - firewall-cmd --reload - - - - + Tips for Installation + + This chapter gathers random tips for installing Pgpool-II. + + + + Firewalls + + When Pgpool-II connects to + other Pgpool-II servers + or PostgreSQL servers, the target port + must be accessible by enabling firewall management softwares. + + + + First, allow to access port that Pgpool-II use. + + In the example below, let Pgpool-II listen + port number be 9999, PCP listen + port number be 9898, watchdog + listen port number be 9000 and heartbeat listen port number be + 9694. Notice that only heartbeat port uses UDP and others use TCP. + + + firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp --add-port=9000/tcp + firewall-cmd --permanent --zone=public --add-port=9694/udp + firewall-cmd --reload + + + + + Here is an example for Rocky Linux/RHEL10 when access + to PostgreSQL is required. + + + firewall-cmd --permanent --zone=public --add-service=postgresql + firewall-cmd --reload + + "postgresql" is the service name assigned + to PostgreSQL. The list of service + names can be obtained by: + + firewall-cmd --get-services + + Note that you can define your own service name in + /usr/lib/firewalld/services/. + + + + If PostgreSQL is listening on 11002 + port, rather than the standard 5432 port, you can do: + + firewall-cmd --zone=public --remove-service=postgresql --permanent + firewall-cmd --zone=public --add-port=11002/tcp --permanent + firewall-cmd --reload + + + + diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index ecf952abb..3c56b718a 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -1,30 +1,172 @@ - - Installation of <productname>Pgpool-II</productname> + + Installation of <productname>Pgpool-II</productname> - - installation - + + installation + - - Installation of Pgpool-II + + Planning - This chapter describes the installation - of Pgpool-II. First, installation from - source code distribution is explained. Then installation from RPM - packages is explained. + Since Pgpool-II is a tool to manage + PostgreSQL, we need to decide how to + deploy them first. In addition, it is possible to have multiple + number of Pgpool-II installations to + enhance the availability of Pgpool-II + itself. We need to plan how many installations of + Pgpool-II is required before hand. In + this chapter we first discuss the running mode of + PostgreSQL then the deployment of + Pgpool-II. + + + Clustering mode of PostgreSQL + + It is possible to have more than or equal to one installation of + PostgreSQL, it is common to have more + than 2 installations of it because if there's only one + installation, the whole database system goes down if the + PostgreSQL is not available. When we + use two or more PostgreSQL servers, it + is necessary to sync the databases in some way. We call the + methods of syncing databases as "clustering running mode". The + most popular mode ever used is "streaming replication mode". + Unless there's necessity to have special consideration, it is + recommended to use the streaming replication mode. See for more details of running mode. + + + The next thing we need to consider is how many + PostgreSQL installations we want. If + there are two, we can continue to operate the database + system. However it is not uncommon to use more than two + PostgreSQL if you want to employ read + query load balancing by running multiple read quires on multiple + servers. Pgpool-II provides rich + variety of options to tune load balancing. See for more details. + + + Since it is possible to add PostgreSQL + servers later on in Pgpool-II, two + PostgreSQL can be a good starter for + you. + + + + + Deployment of Pgpool-II + + Although it is possible to use only one + Pgpool-II, we recommend to use more + than 1 Pgpool-II to avoid whole + database unavailability due to the + Pgpool-II being down. Multiple + Pgpool-II work together and monitor + each other. One of them is called "leader" and it has a virtual + IP. Clients do not need to aware that there are multiple + Pgpool-II because they always access + the same VIP. (See for + watchdog). If one of Pgpool-II goes + down, other Pgpool-II takes over the + leader role. + + + Since it is not allowed to have multiple leader, watchdog votes to + decide a new leader. If there are even number of + Pgpool-II, it is impossible to decide + the new leader by voting. Thus we recommend to deploy + Pgpool-II in more than or equal to 3 odd numbers. + + + Please note that it is possible to have + Pgpool-II and + PostgreSQL on a same server. For + example you can have only three servers to run both + Pgpool-II and + PostgreSQL on each of it. + + + You can find a production level detailed example using three + Pgpool-II and two + PostgreSQL in streaming replication + mode in for those who want to + have a production level Pgpool-II + installation today. + + + + + + Installation of Pgpool-II + + This chapter describes the installation + of Pgpool-II. First, installation from + source code distribution is explained. Then installation from RPM + packages is explained. + Requirements + + System requirements + + Pgpool-II is supposed to run on most + UNIX compatible environments. Windows is not supported. + Followings are the list of platforms the development community + have been verifying. Other platforms have not been verified. + + + + Rocky Linux 10 (x86_64) + + + + + Rocky Linux 9 (x86_64) + + + + + Rocky Linux 8 (x86_64) + + + + Linux distributions compatible with them should + run Pgpool-II. + + - In general, a modern Unix-compatible platform should be able to run - Pgpool-II. Windows is not supported. + packages + for Debian/Ubuntu are provided. + + We have some reports from users who successfully + run Pgpool-II. + + + + Ubuntu 20.04 (x86_64) + + + + + OpenBSD + + + + + + + + Software requirements + The following software packages are required for building Pgpool-II: @@ -41,9 +183,9 @@ (GNU make is sometimes installed under the name gmake.) To test for GNU make enter: - -make --version - + + make --version + @@ -64,6 +206,13 @@ + + + Several packages of PostgreSQL are required to + install Pgpool-II. You install postgresql-libs + and postgresql-devel packages from rpm. + + @@ -105,9 +254,9 @@ If you need to get a GNU package, you can find it at your local GNU mirror site (see + url="http://www.gnu.org/order/ftp.html"> for a list) or at . + url="ftp://ftp.gnu.org/gnu/">. @@ -118,6 +267,7 @@ 4 GB. Use the df command to check free disk space. + @@ -130,9 +280,9 @@ get a file named pgpool-II-&version;.tar.gz. After you have obtained the file, unpack it: - + tar xf pgpool-II-&version;.tar.gz - + This will create a directory pgpool-II-&version; under the current directory with the Pgpool-II sources. @@ -142,339 +292,341 @@ - - Installing Pgpool-II - - After extracting the source tarball, execute the configure script. - + + Installing Pgpool-II + + After extracting the source tarball, follow the steps below to build + the source code and install Pgpool-II. + + + Since Pgpool-II 4.5, files such as + configure generated by autoconf/autoreconf + have been removed from the repository, so first run + autoreconf -fi to generate configure. + +dnf install libtool + +cd pgpool-II-&version; +autoreconf -fi + + + + Next, execute the configure script. + ./configure - - + + - - You can customize the build and installation process by supplying one - or more of the following command line options to - configure: - + + You can customize the build and installation process by supplying one + or more of the following command line options to + configure: + - + - - - - + + + + Specifies the top directory where Pgpool-II binaries and related files like docs will be installed in. Default value is /usr/local. - - - - - - - - + + + + + + + + Specifies the top directory where PostgreSQL's client libraries are installed. Default value is the path provided by pg_config command. - - - - - - - - - Pgpool-II binaries will be built - with OpenSSL - support. OpenSSL support is - disabled by default. - - - - - - - - - Use insert_lock compatible - with Pgpool-II 3.0 series - (until 3.0.4). Pgpool-II locks - against a row in the sequence - table. PostgreSQL 8.2 or later - which was released after June 2011 cannot use this lock - method. - - - - - - - - - Use insert_lock compatible - with Pgpool-II 2.2 and 2.3 - series. Pgpool-II locks - against the insert target table. This lock method is - deprecated because it causes a lock conflict - with VACUUM. - - - - - - - - - Pgpool-II binaries will use memcached for in - memory query cache. You have to - install libmemcached. - - - - - - - - - Pgpool-II binaries will be built with PAM authentication support. - PAM authentication support is disabled by dafault. - - - - - + + + - - + + + + + Pgpool-II binaries will be built + with OpenSSL support. The required + minimum version of OpenSSL is + 1.0.2. If you plan to encrypt passwords using AES256 encryption, + you need this option too. + See for more + details. + OpenSSL support is + disabled by default. + + + + + + + + + Use insert_lock compatible + with Pgpool-II 3.0 series + (until 3.0.4). Pgpool-II locks + against a row in the sequence + table. PostgreSQL 8.2 or later + which was released after June 2011 cannot use this lock + method. + + + + + + + + + Use insert_lock compatible + with Pgpool-II 2.2 and 2.3 + series. Pgpool-II locks + against the insert target table. This lock method is + deprecated because it causes a lock conflict + with VACUUM. + + + + + + + + + Pgpool-II binaries will use memcached for in + memory query cache. You have to + install libmemcached. + + + + + + + + + Pgpool-II binaries will be built + with PAM authentication support. + PAM authentication support is disabled by default. + + + + + + + + + Pgpool-II binaries will be built + with LDAP authentication + support. LDAP authentication support is disabled by default. + + + + + + + + Compile the source file. + make + + + + Install Pgpool-II. + make install - - This will install Pgpool-II. (If you use Solaris or FreeBSD, replace make with gmake) - + + This will install Pgpool-II. (If you use Solaris or FreeBSD, replace make with gmake) + - + - - Installing pgpool_recovery - - This is required in all Pgpool-II - installation. - -$ cd pgpool-II-x.x.x/src/sql/pgpool-recovery + + Installing pgpool_recovery + + Pgpool-II need function of pgpool_recovery, + pgpool_remote_start and pgpool_switch_xlog, + when you use the online recovery that describes latter. + Also pgpoolAdmin of management tool, stop, restart or reload a + PostgreSQL on the screen by use pgpool_pgctl. + + + + This is required in all Pgpool-II + installation. + +$ cd pgpool-II-&version/src/sql/pgpool-recovery $ make $ make install - -After this: - -$ psql template1 + + After this, execute the following command to create the functions + pgpool_recovery, pgpool_remote_start + and pgpool_switch_xlog in the database specified in + + (The default is 'postgres'). + If a value other than the default is configured for + , replace "postgres" + with the setting of . + +$ psql postgres =# CREATE EXTENSION pgpool_recovery; - + - or - -$ psql -f pgpool-recovery.sql template1 - + or + +$ psql -f pgpool-recovery.sql postgres + - + - - With Pgpool-II 3.3 or later, you need - to tweak postgresql.conf. Suppose the path - to pg_ctl - is /usr/local/pgsql/bin/pg_ctl. Then you - add following to postgresql.conf. + + With Pgpool-II 3.3 or later, you need + to tweak postgresql.conf. Suppose the path + to pg_ctl + is /usr/local/pgsql/bin/pg_ctl. Then you + add following to postgresql.conf. - + pgpool.pg_ctl = '/usr/local/pgsql/bin/pg_ctl' - + - Probably you want to execute following after this: - + Probably you want to execute following after this: + $ pg_ctl reload -D /usr/local/pgsql/data - + - - + +
- - Installing pgpool-regclass - - If you are using PostgreSQL 9.4 or - later, you can skip this section. - + + Installing pgpool-regclass + + If you are using PostgreSQL 9.4 or + later, you can skip this section. + - - If you are using PostgreSQL 8.0 - to PostgreSQL 9.3, installing - pgpool_regclass function on - all PostgreSQL to be accessed by - Pgpool-II is strongly recommended, as - it is used internally by Pgpool-II. - Without this, handling of duplicate table names in different - schema might cause trouble (temporary tables aren't a problem). - If you are using PostgreSQL 9.4 or - later, installing pgpool_regclass is not - necessary since an equivalent (to_regclass) - is included in the PostgreSQL core. - + + If you are using PostgreSQL 8.0 + to PostgreSQL 9.3, installing + pgpool_regclass function on + all PostgreSQL to be accessed by + Pgpool-II is strongly recommended, as + it is used internally by Pgpool-II. + Without this, handling of duplicate table names in different + schema might cause trouble (temporary tables aren't a problem). + If you are using PostgreSQL 9.4 or + later, installing pgpool_regclass is not + necessary since an equivalent (to_regclass) + is included in the PostgreSQL core. + - - -$ cd pgpool-II-x.x.x/src/sql/pgpool-regclass + + +$ cd pgpool-II-&version/src/sql/pgpool-regclass $ make $ make install - - After this: + + After this: - + $ psql template1 =# CREATE EXTENSION pgpool_regclass; - + -or + or - + $ psql -f pgpool-regclass.sql template1 - - - Executing CREATE EXTENSION - or pgpool-regclass.sql should be performed - on every databases accessed - via Pgpool-II. However, you do not need to - do this for a database created after the execution of - CREATE EXTENSION or - psql -f pgpool-regclass.sql template1, - as this template database will be cloned to create new databases. - - - - - - Creating insert_lock table + + + Executing CREATE EXTENSION + or pgpool-regclass.sql should be performed + on every databases accessed + via Pgpool-II. However, you do not need to + do this for a database created after the execution of + CREATE EXTENSION or + psql -f pgpool-regclass.sql template1, + as this template database will be cloned to create new databases. + - - If you are not going to use the native replication mode, you can skip this section. - + - - If you plan to use native replication mode and insert_lock, - creating pgpool_catalog.insert_lock - table for mutual exclusion is strongly recommended. Without - this, insert_lock works so far. However in that - case Pgpool-II locks against the - insert target table. This behavior is same - table lock conflicts with VACUUM, so INSERT - processing may be thereby kept waiting for a long time. - - - $ cd pgpool-II-x.x.x/src/sql - $ psql -f insert_lock.sql template1 - + + Creating insert_lock table - + + If you are not going to use + the + nor , you can skip this + section. + - - Executing insert_lock.sql should be - performed on every databases accessed - via Pgpool-II. You do not need to - do this for a database created after the execution of - psql -f insert_lock.sql template1, as this - template database will be cloned to create new databases. - - + + If you plan to use the + or and insert_lock, + creating pgpool_catalog.insert_lock table + for mutual exclusion is strongly recommended. Without this, + insert_lock works so far. However in that + case Pgpool-II locks against the insert + target table. This behavior is same table lock conflicts + with VACUUM, so INSERT + processing may be thereby kept waiting for a long time. + + +$ cd pgpool-II-&version/src/sql +$ psql -f insert_lock.sql template1 + - - Setting up pgpool.conf + - - For each Pgpool-II operation mode, - there are sample configurations. - + + Executing insert_lock.sql should be + performed on every databases accessed + via Pgpool-II. You do not need to + do this for a database created after the execution of + psql -f insert_lock.sql template1, as this + template database will be cloned to create new databases. + +
- - pgpool.conf samples - - - - - Operation mode - Configuration file name - - - - - - Streaming replication mode - pgpool.conf.sample-stream - - - Replication mode - pgpool.conf.sample-replication - - - Master slave mode - pgpool.conf.sample-master-slave - - - Raw mode - pgpool.conf.sample - - - Logical replication mode - pgpool.conf.sample-logical - - - -
+ + Compiling and installing documents - - These configuration files are located at /usr/local/etc with - default installation from source code. - You can copy one of them as pgpool.conf. - (probably you need root privilege for this) - -# cd /usr/local/etc -# cp pgpool.conf.sample-stream pgpool.conf - - - + + Tool Sets - - Compiling and installing documents - - - Tool Sets - - - Pgpool-II documents are written in - SGML (more precisely, DocBook, which is a language implemented - using SGML). To generate readable HTML documents, you need to - compile them using docbook tools. To install Docbook tools on - RHEL or similar systems, use: - - yum install docbook-dtds docbook-style-dsssl docbook-style-xsl libxslt openjade - - - - - - Compiling docs - - Once the tool sets are installed on the system, you can compile the docs: - - $ cd doc - $ make - $ cd .. - $ cd doc.ja - $ make - - You will see English HTML docs under doc/src/sgml/html, and online docs under sgml/man[1-8]. - Japanese docs can be found under doc.ja/src/sgml/html, and online docs under sgml/man[1-8]. - - - + + Pgpool-II documents are written in + SGML (more precisely, DocBook, which is a language implemented + using SGML). To generate readable HTML documents, you need to + compile them using docbook tools. To install Docbook tools on + RHEL or similar systems, use: + +dnf install --enablerepo=powertools docbook-dtds docbook-style-dsssl docbook-style-xsl libxslt openjade + + + + + + Compiling docs + + Once the tool sets are installed on the system, you can compile the docs: + +$ cd doc +$ make +$ cd .. +$ cd doc.ja +$ make + + You will see English HTML docs under doc/src/sgml/html, and online docs under sgml/man[1-8]. + Japanese docs can be found under doc.ja/src/sgml/html, and online docs under sgml/man[1-8]. + + +
- &installation-rpm; + &installation-rpm; - &installation-tips; + &installation-tips; diff --git a/doc/src/sgml/intro.sgml b/doc/src/sgml/intro.sgml index 3b9bfc6fb..40ddf4e00 100644 --- a/doc/src/sgml/intro.sgml +++ b/doc/src/sgml/intro.sgml @@ -30,25 +30,25 @@ describes the installation and - administration of the server. Everyone who runs a - Pgpool-II server, be it for private - use or for others, should read this part. + administration of the server. Everyone who runs a + Pgpool-II server, be it for private + use or for others, should read this part. explains several configuration examples - so that users can choose the starting point of their actual systems. + so that users can choose the starting point of their actual systems. contains reference information about - SQL commands, client and server programs. This part supports - the other parts with structured information sorted by command or - program. + SQL commands, client and server programs. This part supports + the other parts with structured information sorted by command or + program. @@ -58,14 +58,14 @@ - + + contains assorted information that might be of + use to PostgreSQL developers. + + + --> @@ -74,136 +74,176 @@ What is <productname>Pgpool-II</productname>? - Pgpool-II is a proxy software that sits - between PostgreSQL servers and a - PostgreSQL database client. It provides - the following features: + Pgpool-II manages a + pool of + PostgreSQL servers to achieve some + features that are not available with single + PostgreSQL installation. The features + include: + + + + + High Availability + + + Pgpool-II provides a high + availability (HA) feature by using multiple + PostgreSQL servers so that it + automatically removes broken server from the server pool to + continue the database task. This is called automatic + failover. Also Pgpool-II + offers an HA feature for Pgpool-II + itself, called Watchdog (see for more details). Moreover + Pgpool-II hires sophisticated + quorum algorithm to avoid false positive + errors and split brain problem to make the whole HA system + highly reliable. See for more details. + + + - + + Load balancing + + + Pgpool-II distributes read queries + over multiple PostgreSQL servers to + gain higher performance. This feature is called load + balancing. Write queries are sent to either the + primary server (in streaming replication mode) or all servers + (in native replication mode and snapshot isolation mode). See + for more details about these + mode. In any case, Pgpool-II + automatically distinguish the read queries from the write + queries. + + + + + + + Besides these essential features, Pgpool-II also provides useful + features such as: + + + - - Connection Pooling - + + Connection Pooling + - Pgpool-II maintains established - connections to the PostgreSQL - servers, and reuses them whenever a new connection with the - same properties (i.e. user name, database, protocol version) - comes in. It reduces the connection overhead, and improves - system's overall throughput. + Pgpool-II maintains established + connections to the PostgreSQL + servers, and reuses them whenever a new connection with the + same properties (i.e. user name, database, protocol version, and other connection parameters if any) + comes in. It reduces the connection overhead, and improves + system's overall throughput. - - + + - - Load Balancing - + + Online Recovery + - If a database is replicated (because running in either - replication mode or master/slave mode), performing a SELECT - query on any server will return the same result. Pgpool-II - takes advantage of the replication feature in order to reduce - the load on each PostgreSQL server. It does that by - distributing SELECT queries among available servers, improving - the system's overall throughput. In an ideal scenario, read - performance could improve proportionally to the number of - PostgreSQL servers. Load balancing works best in a scenario - where there are a lot of users executing many read-only - queries at the same time. + Pgpool-II can perform online recovery of database + node by executing one command. When the online recovery is used with the + automated fail over, a detached node by fail over is possible to attach as + standby node automatically. It is possible to synchronize and attach new + PostgreSQL server too. - - + + - - Automated fail over - + + Limiting Exceeding Connections + - If one of database servers goes down or becomes unrechable, - Pgpool-II will detaches it and continues operations using rest - of database servers. There are some sophiscated features which - help the automated fail over including timeout and retries. + There is a limit on the maximum number of concurrent + connections with PostgreSQL, and + new connections are rejected when this number is + reached. Raising this maximum number of connections, however, + increases resource consumption and has a negative impact on + overall system + performance. Pgpool-II also has a + limit on the maximum number of connections, but extra + connections will be queued instead of returning an error + immediately. However, you can configure to return an error + when the connection limit is exceeded (4.1 or later). - - + + - - Replication - + + Watchdog + - Pgpool-II can manage - multiple PostgreSQL - servers. Activating the replication feature makes it possible - to create a real time backup on 2 or - more PostgreSQL clusters, so that - the service can continue without interruption if one of those - clusters fails. Pgpool-II has - built-in replication (native replication). However user can - use external replication features including streaming - replication of PostgreSQL. + Watchdog can coordinate multiple Pgpool-II, + create a robust cluster system and avoid the single point of failure or split brain. + To avoid the split brain, you need at least 3 Pgpool-II nodes. + Watchdog can perform lifecheck against other pgpool-II nodes, + to detect a fault of Pgpool-II. + If active Pgpool-II goes down, standby + Pgpool-II can be promoted to active, and take over Virtual IP. - - + + - - Limiting Exceeding Connections - + + In Memory Query Cache + - There is a limit on the maximum number of concurrent - connections with PostgreSQL, and - new connections are rejected when this number is - reached. Raising this maximum number of connections, however, - increases resource consumption and has a negative impact on - overall system - performance. Pgpool-II also has a - limit on the maximum number of connections, but extra - connections will be queued instead of returning an error - immediately. - - - - - + In memory query cache allows to save a pair of SELECT statement and its result. + If an identical SELECTs comes in, Pgpool-II returns the + value from cache. Since no SQL parsing nor access to PostgreSQL + are involved, using in memory cache is extremely fast. On the other hand, it might + be slower than the normal path in some cases, because it adds some overhead of storing cache data. + + + + + - Pgpool-II speaks PostgreSQL's backend - and frontend protocol, and relays messages between a backend and a - frontend. Therefore, a database application (frontend) thinks - that Pgpool-II is the - actual PostgreSQL server, and the - server (backend) sees Pgpool-II as one - of its clients. Because - Pgpool-II is transparent to both the server and the client, an - existing database application can be used with Pgpool-II almost - without a change to its source code. + Pgpool-II speaks PostgreSQL's backend + and frontend protocol, and relays messages between a backend and a + frontend. Therefore, a database application (frontend) thinks + that Pgpool-II is the + actual PostgreSQL server, and the + server (backend) sees Pgpool-II as one + of its clients. Because + Pgpool-II is transparent to both the server and the client, an + existing database application can be used with Pgpool-II almost + without a change to its source code. - Pgpool-II works on Linux, Solaris, - FreeBSD, and most of the UNIX-like architectures. Windows is not - supported. Supported PostgreSQL server's versions are 6.4 and - higher. If you are using PostgreSQL - 7.3 or older, some features - of Pgpool-II won't be available. But - you shouldn't use such an old release anyway. You must also make - sure that all of your PostgreSQL - servers are using the same major version. In addition to this, we - do not recommend mixing - different PostgreSQL installation with - different build options: including supporting SSL or not, to use - --disable-integer-datetimes or not, different block size. These - might affect part of functionality - of Pgpool-II. The difference of - PostgreSQL minor versions is not - usually a problem. However we do not test every occurrence of - minor versions and we recommend to use exact same minor version of - PostgreSQL. + Pgpool-II works on Linux, FreeBSD, and + most of the UNIX-like architectures. Windows is not + supported. Supported PostgreSQL server's versions are 7.4 and + higher (some of the features may not work with older versions of + PostgreSQL). You must also make sure + that all of your PostgreSQL servers are + using the same major version. In addition to this, we do not + recommend mixing different PostgreSQL + installation with different build options: including supporting SSL + or not, to use --disable-integer-datetimes or not, different block + size. These might affect part of functionality of + Pgpool-II. The difference of + PostgreSQL minor versions is not usually + a problem. However we do not test every occurrence of minor + versions and we recommend to use exact same minor version of + PostgreSQL. - There are some restrictions to using SQL via Pgpool-II. - See Restrictions for more details. + There are some restrictions to using SQL via Pgpool-II. + See Restrictions for more details. diff --git a/doc/src/sgml/legal.sgml b/doc/src/sgml/legal.sgml index bab7400c5..4e5f8cb65 100644 --- a/doc/src/sgml/legal.sgml +++ b/doc/src/sgml/legal.sgml @@ -1,9 +1,9 @@ -2018 +2023 - 2003-2018 + 2003-2026 The Pgpool Global Development Group @@ -11,12 +11,12 @@ Legal Notice - Pgpool and Pgpool-II are Copyright © 2003-2018 + Pgpool and Pgpool-II are Copyright © 2003-2026 by the Pgpool Global Development Group. - PostgreSQL are Copyright © 1996-2018 + PostgreSQL are Copyright © 1996-2023 by the PostgreSQL Global Development Group. diff --git a/doc/src/sgml/loadbalance.sgml b/doc/src/sgml/loadbalance.sgml index 8b0eda0d2..0c57e37f6 100644 --- a/doc/src/sgml/loadbalance.sgml +++ b/doc/src/sgml/loadbalance.sgml @@ -1,433 +1,455 @@ - Load Balancing + Load Balancing - - Pgpool-II load balancing of SELECT queries - works with Master Slave mode () - and Replication mode (). When enabled + + Pgpool-II load balancing of SELECT queries + works with any clustering mode except raw mode. When enabled Pgpool-II sends the writing queries to the - primay node in Master Slave mode, all of the + primary node in Native Replication mode, all of the backend nodes in Replication mode, and other queries get load balanced among all backend nodes. To which node the load balancing mechanism sends read queries is decided at the session - start time and will not be changed until the session ends. However + start time and will not be changed until the session ends unless is specified. However there are some exceptions. See below for more details. + + + + Queries which are sent to primary node or replicated because they cannot be balanced are + also accounted for in the load balancing algorithm. - - - Queries which are sent to primary node or replicated because they cannot be balanced are - also accounted for in the load balancing algorithm. - - - - - If you don't want a query that qualifies for the load balancing to be - load balanced by Pgpool-II, you can put - /*NO LOAD BALANCE*/ comment before the SELECT - statement. This will disable the load balance of the particular query - and Pgpool-II will send it to the master node (the primary node in Master Slave mode). - - + - - - You can check which DB node is assigned as the load balancing - node by using . - - - + + + You can check which DB node is assigned as the load balancing + node by using . + + + Condition for Load Balancing - For a query to be load balanced, all the following requirements - must be met: - + For a query to be load balanced, all the following requirements + must be met: + - + PostgreSQL version 7.4 or later - + - - either in replication mode or master slave mode - + + either + in , + , + or + logical + replication mode. + - + the query must not be in an explicitly declared transaction (i.e. not in a BEGIN ~ END block) - - - - - However, if following conditions are met, load balance is possible - even if in an explicit transaction - - - - transaction isolation level is not SERIALIZABLE - - - - - transaction has not issued a write query yet (until a write - query is issued, load balance is possible. Here "write query" - means non SELECT DML or DDL. SELECTs having write functions as - specified in black or white function list is not regarded as - a write query. This may be changed in the future.) - - - - - If black and white function list is empty, SELECTs having - functions is regarded as a read only query. - - - - - - + + + + + However, if following conditions are met, load balance is possible + even if in an explicit transaction + + + + transaction isolation level is not SERIALIZABLE + + + + + transaction has not issued a write query yet (until a write + query is issued, load balance is possible. Here "write query" + means non SELECT DML or DDL. Before Pgpool-II 4.1, + SELECTs having write functions as specified in write or + read_only function list is not regarded as a write query.) + + + + + If write and read_only function list is empty, SELECT having + functions which are not volatile is regarded as a read only query. + + + + + + - + it's not SELECT INTO - + - + it's not SELECT FOR UPDATE nor FOR SHARE - + - + it starts with "SELECT" or one of COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... = true - will ignore leading white space. - (Except for SELECTs using writing functions specified in or - ) + will ignore leading white space. + (Except for SELECTs using writing functions specified in or + ) - - in master slave mode, in addition to above, following conditions must be met: - - - - - does not use temporary tables - - - - - does not use unlogged tables - - - - - does not use system catalogs - - - - - + + in in addition to above, following conditions must be met: + + + + + temporary tables are not used (temporary tables are not replicated) + + + + + unlogged tables are not used (unlogged tables are not replicated) + + + + + system catalogs are not used (system catalog information is + important and it is desirable to avoid replication delay) + + + + + - + You could suppress load balancing by inserting arbitrary comments just in front of the SELECT query: - - + + /*REPLICATION*/ SELECT ... - If you want to use comments without supressing load balancing, you can set - to on. - Please refer to as well. + If you want to use comments without suppressing load balancing, you can set + to on. + Please refer to as well. - + The JDBC driver has an autocommit option. If the autocommit is false, the JDBC driver sends "BEGIN" and "COMMIT" by itself. In this case the same restriction above regarding load balancing will be applied. - + - Writing queries may affect Load Balancing - - In general, read queries are load balanced if certain conditions - are met. However, writing queries may affect the load - balancing. Here "writing queries" mean all the queries except - below: - + Writing queries may affect Load Balancing + + In general, read queries are load balanced if certain conditions + are met. However, writing queries may affect the load + balancing. Here "writing queries" mean all the queries except + below: + - + - - - SELECT/WITH without FOR UPDATE/SHARE - - - - - COPY TO STODUT - - + + + SELECT/WITH without writing functions. + Volatile functions are regarded writing functions. + You can define your own writing functions by using + or . + + - - - EXPLAIN - - + + + SELECT/WITH without FOR UPDATE/SHARE + + - - - EXPLAIN ANALYZE and the query is SELECT not including writing functions - - + + + WITH without DML statements + + - - - SHOW - - + + + COPY TO STDOUT + + + + + + EXPLAIN + + + + + + EXPLAIN ANALYZE and the query is SELECT not including writing functions + + + + + + SHOW + + - + - - If writing queires appear, succeeding read queries may not be - load balanced. i.e. sent to primary node (in streaming - replication mode) or master node (in other mode) depending on the - setting of . - + + If writing queries appear, succeeding read queries may not be + load balanced. i.e. sent to primary node (in streaming + replication mode) or main node (in other mode) depending on the + setting of . + - + - Load Balancing in Streaming Replication + Load Balancing in Streaming Replication - + While using Streaming replication and Hot Standby, it is important to determine which query can be sent to the primary or the standby, and which one should not be sent to the standby. Pgpool-II's Streaming Replication mode carefully takes care of this. - + - + We distinguish which query should be sent to which node by looking at the query itself. - + + + + These queries should be sent to the primary node only + - - These queries should be sent to the primary node only - - - - INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT - - - - - SELECT ... FOR SHARE | UPDATE - - - - - SELECT in transaction isolation level SERIALIZABLE - - - - - LOCK command more strict than ROW EXCLUSIVE MODE - - - - - DECLARE, FETCH, CLOSE - - - - - SHOW - - - - - Some transactional commands: - - - - BEGIN READ WRITE, START TRANSACTION READ WRITE - - - - - SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE - - - - - SET transaction_read_only = off - - - - - - - - Two phase commit commands: PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED - - - - - LISTEN, UNLISTEN, NOTIFY - - - - - VACUUM - - - - - Some sequence functions (nextval and setval) - - - - - Large objects creation commands - - - - - - - - These queries can be sent to both the primary node and the standby node. - If load balancing is enabled, these types of queries can be sent to the standby node. - However, if delay_threshold is set and the replication delay is higher than - , queries are sent to the primary node. - - - - - SELECT not listed above - - - - - - COPY TO STDOUT - - - - - - EXPLAIN - - - - - - EXPLAIN ANALYZE and the query is SELECT not including writing functions - - - - - - SHOW - - - - - - - - - These queries are sent to both the primary node and the standby node - - - - SET - - - - - DISCARD - - - - - DEALLOCATE ALL - - - - + + INSERT, UPDATE, DELETE, COPY FROM, TRUNCATE, CREATE, DROP, ALTER, COMMENT + + + + + SELECT ... FOR SHARE | UPDATE + + + + + SELECT in transaction isolation level SERIALIZABLE + - - - - - In an explicit transaction: - - - - Transaction starting commands such as BEGIN are sent to both the primary node - and the standby node. - + + LOCK command more strict than ROW EXCLUSIVE MODE + - - Following SELECT and some other queries that can be sent to both - primary or standby are executed in the transaction or on the standby node. - + + DECLARE, FETCH, CLOSE + - - Commands which cannot be executed on the standby such as INSERT are sent - to the primary. - After one of these commands, even SELECTs are sent to the primary node, - This is because these SELECTs might want to see the result of an INSERT immediately. - This behavior continues until the transaction closes or aborts. - + + SHOW + - - + + + Some transactional commands: + + + + BEGIN READ WRITE, START TRANSACTION READ WRITE + + + + + SET TRANSACTION READ WRITE, SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE + + + + + SET transaction_read_only = off + + + + + + + + Two phase commit commands: PREPARE TRANSACTION, COMMIT PREPARED, ROLLBACK PREPARED + + + + + LISTEN, UNLISTEN, NOTIFY + + + + + VACUUM + + + + + Some sequence functions (nextval and setval) + + + + + Large objects creation commands + + + + + Multi-statement queries (multiple SQL commands on single line) + + + + + + + + These queries can be sent to both the primary node and the standby node. + If load balancing is enabled, these types of queries can be sent to the standby node. + However, if delay_threshold is set and the replication delay is higher than + , queries are sent to the primary node. + + + + + SELECT not listed above + + + + + + COPY TO STDOUT + + + + + + EXPLAIN + + + + + + EXPLAIN ANALYZE and the query is SELECT not including writing functions + + + + + + SHOW + + + + + + + + + These queries are sent to both the primary node and the standby node + + + + SET + + + + + DISCARD + + + + + DEALLOCATE ALL + + + + + SAVEPOINT (and related commands such as RELEASE SAVEPOINT) + + + + + + + - + + In an explicit transaction: + + + + + Transaction starting commands such as BEGIN are sent to both the primary node + and the standby node. + + + + + Following SELECT and some other queries that can be sent to both + primary or standby are executed in the transaction or on the standby node. + + + + + Commands which cannot be executed on the standby such as INSERT are sent + to the primary. + After one of these commands, even SELECTs are sent to the primary node, + This is because these SELECTs might want to see the result of an INSERT immediately. + This behavior continues until the transaction closes or aborts. + + + + + + In the extended protocol, it is possible to determine if the query can be sent to standby or not in load balance mode while parsing the query. The rules are the same as for the non extended protocol. For example, INSERTs are sent to the primary node. Following bind, describe and execute will be sent to the primary node as well. - - - - - If the parse of a SELECT statement is sent to the standby node due to load - balancing, and then a DML statement, such as an INSERT, is sent to Pgpool-II, - then the parsed SELECT will have to be executed on the primary node. - Therefore, we re-parse the SELECT on the primary node. - - + + - Lastly, queries that Pgpool-II's parser thinks to be an - error are sent to the primary node. + If the parse of a SELECT statement is sent to the standby node due to load + balancing, and then a DML statement, such as an INSERT, is sent to Pgpool-II, + then the parsed SELECT will have to be executed on the primary node. + Therefore, we re-parse the SELECT on the primary node. + + + + Lastly, queries that Pgpool-II's parser thinks to be an + error are sent to the primary node. + @@ -436,505 +458,1068 @@ - - load_balance_mode (boolean) - - load_balance_mode configuration parameter - - - - - When set to on, Pgpool-II enables the - load balancing on incoming SELECT queries. - i.e. SELECT queries from the clients gets distributed to - the configured PostgreSQL backends. - Default is off. - - - This parameter can only be set at server start. - - - + + load_balance_mode (boolean) + + load_balance_mode configuration parameter + + + + + When set to on, Pgpool-II enables the + load balancing on incoming SELECT queries. + i.e. SELECT queries from the clients gets distributed to + the configured PostgreSQL backends. + Default is on. + + + This parameter can only be set at server start. + + + - ignore_leading_white_space (boolean) - - ignore_leading_white_space configuration parameter - - - - - When set to on, Pgpool-II ignores the - white spaces at the beginning of SQL queries in load balancing. - It is useful if used with APIs like DBI/DBD:Pg which adds - white spaces against the user's intention. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - white_function_list (string) - - white_function_list configuration parameter - - - - - Specifies a comma separated list of function names that - DO NOT update the database. SELECTs including - functions not specified in this list are not load balanced. - These are replicated among all the DB nodes in Replication mode, - sent to the primary node only in Maste Slave mode. - - - You can use regular expression to match function names, - to which ^ and $ are automatically added. - + ignore_leading_white_space (boolean) + + ignore_leading_white_space configuration parameter + + + + + When set to on, Pgpool-II ignores the + white spaces at the beginning of SQL queries in load balancing. + It is useful if used with APIs like DBI/DBD:Pg which adds + white spaces against the user's intention. + The default is on. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + read_only_function_list (string) + + read_only_function_list configuration parameter + + + + + Specifies a comma separated list of function names that + DO NOT update the database. SELECTs including + functions not specified in this list are not load balanced. + These are replicated among all the DB nodes in Replication mode, + sent to the primary node only in other mode. + + + You can use regular expression to match function names, + to which ^ and $ are automatically added. + - - Using regular expression - - If you have prefixed all your read only function - with 'get_' or 'select_', You can - set the like below: - -white_function_list = 'get_.*,select_.*' - - - + + Using regular expression + + If you have prefixed all your read only function + with 'get_' or 'select_', You can + set the like below: + +read_only_function_list = 'get_.*,select_.*' + + + - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - black_function_list (string) - - black_function_list configuration parameter - - - - - Specifies a comma separated list of function names that - DO update the database. - SELECTs including functions specified in this list are - not load balanced. - These are replicated among all the DB nodes in Replication mode, - sent to the primary node only in Maste Slave mode. - - - You can use regular expression to match function names, - to which ^ and $ are automatically added. - + + + If the queries can refer to the function with and without the schema + qualification then you must add both entries (with and without + schema name) in the list. + +#For example: +#If the queries sometime use "f1()" and other times "public.f1()" +#to refer the function f1 then the read_only_function_list +#would be configured as follows. + +read_only_function_list = "f1,public.f1" + + + + + + + + If this parameter and + is empty string, function's volatile property will be checked. If + the property is volatile, the function is regarded as a writing + function. This is convenient and recommended way. However this + requires one extra query against system catalog for the first + time (in the next time cached query result is used and no extra + query will be sent). If you don't want to send such query, you + can keep on using this parameter. + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + write_function_list (string) + + write_function_list configuration parameter + + + + + Specifies a comma separated list of function names that + DO update the database. + SELECTs including functions specified in this list are + not load balanced. + These are replicated among all the DB nodes in Replication mode, + sent to the primary node only in other mode. + + + You can use regular expression to match function names, + to which ^ and $ are automatically added. + + + + Using regular expression + + If you have prefixed all your updating functions + with 'set_', 'update_', 'delete_' or 'insert_', You can + set the like below: + +write_function_list = 'nextval,setval,set_.*,update_.*,delete_.*,insert_.*' + + + + + + + If the queries can refer the function with and without the schema + qualification then you must add both entries(with and without + schema name) in the list. + +#For example: +#If the queries sometime use "f1()" and other times "public.f1()" +#to refer the function f1 then the write_function_list +#would be configured as follows. + +write_function_list = "f1,public.f1" + + + + + + + + and + are mutually exclusive and only one of the two lists can be set in the configuration. + + + + + Configuring using <literal>nextval()</literal> and <literal>setval()</literal> to land on proper backend + + Prior to Pgpool-IIV3.0, + nextval() and setval() were known as functions writing to the database. + You can configure this by setting + and as follows + +read_only_function_list = '' +write_function_list = 'nextval,setval,lastval,currval' + + + + + + + PostgreSQL also contains lastval() and + currval() in addition to + nextval() and setval(). + Though lastval() and currval() + are not writing function type, but it is advised to treat + lastval() and currval() + as writing functions to avoid errors which occur when + these functions are accidentally load balanced. + + + + + + If this parameter and + is empty string, function's volatile proper will be checked. If + the property is volatile, the function is regarded as a writing + function. This is convenient and recommended way. However this + requires one extra query against system catalog for the first + time (in the next time cached query result is used and no extra + query will be sent). If you don't want to send such query, you + can keep on using this parameter. + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + primary_routing_query_pattern_list (string) + + primary_routing_query_pattern_list configuration parameter + + + + + Specifies a semicolon separated list of SQL patterns that + should be sent to primary node. + SQL that matched patterns specified in this list are + not load balanced. + Other than Only Native Replication mode is supported. + + + You can use regular expression to match SQL patterns, + to which ^ and $ are automatically added. + When using special characters in regular expressions + (such as "'", ";", "*", "(", ")", "|", "+", ".", "\", "?", "^", "$", + "{","}", "{" or "}", etc.) + in SQL patterns, you need to escape them by using "\". + SQL pattern specified in this parameter is case-insensitive. + + + + Using regular expression + + If the following SQL should be sent to the primary node only, You can + set the like below: + + + + SELECT * FROM table_name1; + + + + + SELECT col1, col2 FROM table_name2 WHERE col1 LIKE '%a%'; + + + + + SQL including table_name3 + + + + + + + +primary_routing_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM table_name2 WHERE col1 LIKE \'%a%\'\;;.*table_name3.*' + + + + + + + If SQL matches both and + , + setting is ignored and the SQL should be sent only to the primary node. + + + + Depending on the SQL patterns, performance might be 1-2% lower when using this feature. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + user_redirect_preference_list (string) + + user_redirect_preference_list configuration parameter + + + + + Specifies the list of "user-name:node id(ratio)" pairs + to send SELECT queries to a particular backend + node for a particular user connection at a specified load balance ratio. + The load balance ratio specifies a value between 0 and 1. The default is 1.0. + + + For example, by specifying "user1:1(0.5)", Pgpool-II + will redirect 50% SELECT queries to the backend node of ID 1 for + the connection of user user1. + + + You can specify multiple "user-name:node id(ratio)" pairs + by separating them using comma (,). + + + Regular expressions are also accepted for user name. + You can use special keywords as node id. + If "primary" is specified, queries are sent to the primary node, and + if "standby" is specified, one of the standby nodes are selected randomly + based on load balance ratio. + - - Using regular expression - - If you have prefixed all your updating functions - with 'set_', 'update_', 'delete_' or 'insert_', You can - set the like below: - -black_function_list = 'nextval,setval,set_.*,update_.*,delete_.*,insert_.*' - - - - - - - and - are mutually exclusive and only one of the two lists can be set in the configuration. - - - - - Configuring using <literal>nextval()</literal> and <literal>setval()</literal> to land on proper backend - - Prior to Pgpool-IIV3.0, - nextval() and setval() were known as functions writing to the database. - You can configure this by setting - and as follows - -white_function_list = '' -black_function_list = 'nextval,setval,lastval,currval' - - - - - - - PostgreSQL also contains lastval() and - currval() in addition to - nextval() and setval(). - Though lastval() and currval() - are not writing function type, but it is advised to treat - lastval() and currval() - as writing functions to avoid errors which occur when - these functions are accidentally load balanced. - - + + Using user_redirect_preference_list + + If you want to configure the following SELECT query routing rules: + + + + - This parameter can be changed by reloading the Pgpool-II configurations. + Route all SELECT queries from the connections + using user postgres to the primary backend node. - - - - - black_query_pattern_list (string) - - black_query_pattern_list configuration parameter - - - + + - Specifies a semicolon separated list of SQL patterns that - should be sent to primary node. - SQL that matched patterns specified in this list are - not load balanced. - Only Maste Slave mode is supported. + Route 30% SELECT queries from the connections + using user user0 or user1 + to backend node of ID 1. + The other 70% SELECT queries will be sent to other backend nodes. + + - You can use regular expression to match SQL patterns, - to which ^ and $ are automatically added. - When using special characters in regular expressions - (such as "'", ";", "*", "(", ")", "|", "+", ".", "\", "?", "^", "$", - "{","}", "{" or "}", etc.) - in SQL patterns, you need to escape them by using "\". - SQL pattern specified in this parameter is case-insensitive. + Route all SELECT queries from the connections + using user user2 to standby backend nodes. + - - Using regular expression - - If the following SQL should be sent to the primary node only, You can - set the like below: - - - - SELECT * FROM table_name1; - - - - - SELECT col1, col2 FROM table_name2 WHERE col1 LIKE '%a%'; - - - - - SQL including table_nama3 - - - - - - - -black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM table_name2 WHERE col1 LIKE \'%a%\'\;;.*table_name3.*' - - - - - - - If SQL matches both and - , - setting is ignored and the SQL should be sent only to the primary node. - - - - Depending on the SQL patterns, performance might be 1-2% lower when using this feature. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - + + + then the will be configured as follows: + +user_redirect_preference_list = 'postgres:primary,user[01]:1(0.3),user2:standby' + + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + - database_redirect_preference_list (string) - - database_redirect_preference_list configuration parameter - - - + database_redirect_preference_list (string) + + database_redirect_preference_list configuration parameter + + + + + Specifies the list of "database-name:node id(ratio)" pairs + to send SELECT queries to a particular backend + node for a particular database connection at a specified load balance ratio. + The load balance ratio specifies a value between 0 and 1. The default is 1.0. + + + For example, by specifying "test:1(0.5)", Pgpool-II + will redirect 50% SELECT queries to the backend node of ID 1 for + the connection to test database. + + + You can specify multiple "database-name:node id(ratio)" pairs + by separating them using comma (,). + + + Regular expressions are also accepted for database name. + You can use special keywords as node id. + If "primary" is specified, queries are sent to the primary node, and + if "standby" is specified, one of the standby nodes are selected randomly + based on load balance ratio. + + + + Using database_redirect_preference_list + + If you want to configure the following SELECT query routing rules: + + + + - Specifies the list of "database-name:node id(ratio)" pairs - to send SELECT queries to a particular backend - node for a particular database connection at a specified load balance ratio. - The load balance ratio specifies a value between 0 and 1. The default is 1.0. + Route all SELECT queries on postgres + database to the primary backend node. + + - For example, by specifying "test:1(0.5)", Pgpool-II - will redirect 50% SELECT queries to the backend node of ID 1 for - the connection to "test" database. - You can specify multiple "database name:node id" pair by separating them - using comma (,). + Route 30% SELECT queries on mydb0 or on + mydb1 databases to backend node of ID 1. + The other 70% SELECT queries will be sent to other backend nodes. + + - Regular expressions are also accepted for database name. - You can use special keywords as node id. - If "primary" is specified, queries are sent to the primary node, and - if "standby" is specified, one of the standby nodes are selected randomly - based on weights (). + Route all SELECT queries on mydb2 + database to standby backend nodes. + - - Using database_redirect_preference_list - - If you want to configure the following SELECT query routing rules: - - - - - - Route all SELECT queries on postgres - database to the primary backend node. - - - - - Route 30% SELECT queries on mydb0 or on - mydb1 databases to backend node of ID. - The other 70% SELECT queries will be sent to other backend nodes. - - - - - Route all SELECT queries on mydb2 - database to standby backend nodes. - - - - - - then the will be configured as follows: - + + + then the will be configured as follows: + database_redirect_preference_list = 'postgres:primary,mydb[01]:1(0.3),mydb2:standby' - - - + + + - - This parameter can be changed by reloading the Pgpool-II configurations. - - - + + This parameter can be changed by reloading the Pgpool-II configurations. + + + - app_name_redirect_preference_list (string) - - app_name_redirect_preference_list configuration parameter - - - + app_name_redirect_preference_list (string) + + app_name_redirect_preference_list configuration parameter + + + - - Specifies the list of "application-name:node id(ratio)" pairs - to send SELECT queries to a particular backend - node for a particular client application connection at a specified load balance ratio. - + + Specifies the list of "application-name:node id(ratio)" pairs + to send SELECT queries to a particular backend + node for a particular client application connection at a specified load balance ratio. + The load balance ratio specifies a value between 0 and 1. The default is 1.0. + You can specify multiple "application-name:node id(ratio)" pairs + by separating them using comma (,). + - - - In PostgreSQL V9.0 or later the "Application name" is a name specified - by a client when it connects to database. - - + + + In PostgreSQL V9.0 or later the "Application name" is a name specified + by a client when it connects to database. + + - - For example, application name of psql command is - "psql". - + + For example, application name of psql command is + "psql". + - - - Pgpool-II recognizes the application name - only specified in the start-up packet. - Although a client can provide the application name - later in the session, but that does not get considered by the - Pgpool-II for query routing. - - + + + Pgpool-II recognizes the application name + only specified in the start-up packet. + Although a client can provide the application name + later in the session, but that does not get considered by the + Pgpool-II for query routing. + + - - The notion of - is same as the - thus you can also use the regular expressions for application names. - Similarly special keyword "primary" indicates the primary node and - "standby" indicates one of standby nodes. - The load balance weight specifies a value between 0 and 1. The default is 1.0. - + + Regular expressions are also accepted for database name. + You can use special keywords as node id. + If "primary" is specified, queries are sent to the primary node, and + if "standby" is specified, one of the standby nodes are selected randomly + based on load balance ratio. + - - Using app-name_redirect_preference_list - - If you want to configure the following SELECT query routing rules: - - - - - - Route all SELECT from psql - client to the primary backend node. - - - - - Route 30% SELECT queries from myapp1 - client to backend node of ID 1. The other 70% SELECT queries will be sent to other backend nodes. - - - - - Route all SELECT queries from myapp2 - client to standby backend nodes. - - - - - - then the will be configured as follows: - -app_name_redirect_preference_list = 'psql:primary,myapp1:1(0.3),myapp2:standby' - - - - - - - takes precedence - over the . - - - For example, if you set - database_redirect_preference_list = 'postgres:standby(1.0)' and - app_name_redirect_preference_list = 'myapp1:primary(1.0)', - all SELECT from application myapp1 on postgres database will be sent to primary backend node. - - - - - - By specifying of and - , when multiple database - names and application names are matched, the first setting will be used. - - - For example, if you set - database_redirect_preference_list = 'postgres:primary,postgres:standby', - "postgres: primary" will be used. - - - - - - JDBC driver postgreSQL-9.3 and earlier versions - does not send the application name in the startup packet even if - the application name is specified using the JDBC - driver option "ApplicationName" and - "assumeMinServerVersion=9.0". - So if you want to use the - feature through JDBC, Use postgreSQL-9.4 or later version of the driver. - - + + Using app-name_redirect_preference_list + + If you want to configure the following SELECT query routing rules: + + + - This parameter can be changed by reloading the Pgpool-II configurations. + Route all SELECT from psql + client to the primary backend node. - - - - - allow_sql_comments (boolean) - - allow_sql_comments configuration parameter - - - + + - When set to on, Pgpool-II ignore the - SQL comments when identifying if the load balance - or query cache is possible on the query. - When this parameter is set to off, the SQL comments - on the query could effectively prevent the query from being - load balanced or cached (pre Pgpool-II - V3.4 behavior). + Route 30% SELECT queries from myapp1 + client to backend node of ID 1. The other 70% SELECT queries will be sent to other backend nodes. + + - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. + Route all SELECT queries from myapp2 + client to standby backend nodes. - - + + + + + then the will be configured as follows: + +app_name_redirect_preference_list = 'psql:primary,myapp1:1(0.3),myapp2:standby' + + + + + + + The priority of , + and + are: + +app_name_redirect_preference_list > database_redirect_preference_list > user_redirect_preference_list + + + + For example, if you set + database_redirect_preference_list = 'postgres:standby(1.0)' and + app_name_redirect_preference_list = 'myapp1:primary(1.0)', + all SELECT from application myapp1 on postgres database will be sent to primary backend node. + + + + + + By specifying of , + and + , + when multiple database names and application names are matched, + the first setting will be used. + + + For example, if you set + database_redirect_preference_list = 'postgres:primary,postgres:standby', + "postgres: primary" will be used. + + + + + + JDBC driver PostgreSQL-9.3 and earlier versions + does not send the application name in the startup packet even if + the application name is specified using the JDBC + driver option "ApplicationName" and + "assumeMinServerVersion=9.0". + So if you want to use the + feature through JDBC, Use PostgreSQL-9.4 or later version of the driver. + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + allow_sql_comments (boolean) + + allow_sql_comments configuration parameter + + + + + When set to on, Pgpool-II ignore the + SQL comments when identifying if the load balance + or query cache is possible on the query. + When this parameter is set to off, the SQL comments + on the query could effectively prevent the query from being + load balanced or cached (pre Pgpool-II + V3.4 behavior). + The default is off. + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + - disable_load_balance_on_write (string) - - disable_load_balance_on_write configuration parameter - - - - - Specify load balance behavior after write queries appear. - This parameter is especially useful in streaming replication - mode. When write queries are sent to primary server, the - changes are applied to standby servers but there's a time - lag. So if a client read the same row right after the write - query, the client may not see the latest value of the - row. If that's the problem, clients should always read data - from the primary server. However this effectively disables - load balancing, which leads to lesser performance. This - parameter allows a fine tuning for the trade off between - not-clustering-aware applications compatibility and - performance. - - - If this parameter is set to off, read - queries are load balanced even if write queries appear. This - gives the best load balance performance but clients may see - older data. This is useful for an environment where - PostgreSQL parameter synchronous_commit = 'remote_apply', or - in the native replication mode, since there's no replication - delay in such environments. - - - If this parameter is set to transaction - and write queries appear in an explicit transaction, - subsequent read queries are not load balanced until the - transaction ends. Please note that read queries not in an - explicit transaction are not affected by the parameter. This - setting gives the best balance in most cases and you should - start from this. This is the default and same behavior in - Pgpool-II 3.7 or before. - - - If this parameter is set - to trans_transaction and write queries - appear in an explicit transaction, subsequent read queries - are not load balanced in the transaction and subsequent - explicit transaction until the session ends. So this - parameter is safer for older applications but give lesser - performance than transaction. Please note - that read queries not in an explicit transaction are not - affected by the parameter. - + disable_load_balance_on_write (enum) + + disable_load_balance_on_write configuration parameter + + + + + Specify load balance behavior after write queries appear. + This parameter is especially useful in streaming replication + mode. When write queries are sent to primary server, the + changes are applied to standby servers but there's a time + lag. So if a client read the same row right after the write + query, the client may not see the latest value of the + row. If that's the problem, clients should always read data + from the primary server. However this effectively disables + load balancing, which leads to lesser performance. This + parameter allows a fine tuning for the trade off between + not-clustering-aware applications compatibility and + performance. + + + If this parameter is set to off, read + queries are load balanced even if write queries appear. This + gives the best load balance performance but clients may see + older data. This is useful for an environment where + PostgreSQL parameter synchronous_commit = 'remote_apply', or + in the native replication mode, since there's no replication + delay in such environments. + + + If this parameter is set to transaction + and write queries appear in an explicit transaction, + subsequent read queries are not load balanced until the + transaction ends. Please note that read queries not in an + explicit transaction are not affected by the parameter. This + setting gives the best balance in most cases and you should + start from this. This is the default and same behavior in + Pgpool-II 3.7 or before. + + + If this parameter is set + to trans_transaction and write queries + appear in an explicit transaction, subsequent read queries + are not load balanced in the transaction and subsequent + explicit transaction until the session ends. So this + parameter is safer for older applications but give lesser + performance than transaction. Please note + that read queries not in an explicit transaction are not + affected by the parameter. + - - If this parameter is set to always and - write queries appear, subsequent read queries are not load - balanced until the session ends regardless they are in - explicit transactions or not. This gives the highest - compatibility with not-clustering-aware applications and the - lowest performance. - - - + + If this parameter is set to always and + write queries appear, subsequent read queries are not load + balanced until the session ends regardless they are in + explicit transactions or not. This gives the highest + compatibility with not-clustering-aware applications and the + lowest performance. + + + + If this parameter is set to dml_adaptive Pgpool-II + keep track of each TABLE referenced in the WRITE statements within + the explicit transactions and will not load balances the subsequent + READ queries if the TABLE they are reading from is previously modified + inside the same transaction. + Dependent functions, triggers, and views on the tables can be configured + using + + + + If this parameter is set to dml_adaptive_global, + Pgpool-II behaves like dml_adaptive + (per-transaction write tracking) and additionally uses shared memory to + track recently written tables across all sessions cluster-wide. When a + table is written in any session, subsequent reads of that table from any + session are routed to primary until a TTL (based on measured replication + delay) expires. This prevents stale reads after writes even across + different connections. + See for the + sub-parameters that control the shared-memory tracking behavior. + + + Note, however, you cannot + use to track + dependency among table and other objects + if is set + to dml_adaptive_global. + + + + + + dml_adaptive_object_relationship_list (string) + + dml_adaptive_object_relationship_list configuration parameter + + + + + + To prevent load balancing of READ dependent objects, you may specify the object name + followed by a colon(:) and then a comma(,) separated list of dependent object names. + "[object]:[dependent-object]" + In an explicit transaction block after a WRITE statement has been issues, this will prevent + load balancing of any READ statements containing references of dependent object(s). + + Configuring dml adaptive object relationship + + If you have a trigger installed on table_1 that do INSERT in table_2 for each + INSERT on table_1. Then you would want to make sure that + read on table_2 must not get load-balanced within the same transaction + after INSERT into table_1. + For this configuration you can set + +dml_adaptive_object_relationship_list = 'table_1:table_2' + + + + + This parameter is only valid for + ='dml_adaptive' + + + + To configure the dependency on the function, + The function must be present in the + + + + + + + + + + statement_level_load_balance (boolean) + + statement_level_load_balance configuration parameter + + + + + When set to on and is set to on, the load balancing node is decided for each read query. + When set to off, load balancing node is decided at the session start time + and will not be changed until the session ends. + For example, in applications that use connection pooling remain connections + open to the backend server, because the session may be held for a long time, + the load balancing node does not change until the session ends. + In such applications, when statement_level_load_balance is enabled, + it is possible to decide load balancing node per query, not per session. + The default is off. + + + + + In streaming replication mode, certain kind of queries such as + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE ALL/DISCARD are sent to + primary node and load balance node. If + is on, such + queries are sent to all standby nodes as well. This is not + usually a problem. But when one of standbys are in remote + network, the network latency may cause significant slow down in + case of such queries. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + + + Table Mutation Tracking Configuration + + + These parameters configure the track table mutation feature, which is + activated by setting + + to dml_adaptive_global. The feature tracks recently + written tables to prevent stale reads from replica nodes during replication + lag. + + + + When a table is modified (INSERT/UPDATE/DELETE), it is marked as "stale" + for a TTL period (replication_delay * + track_table_mutation_ttl_factor). Any SELECT queries on stale + tables are routed to the primary node instead of replicas, ensuring + read-after-write consistency. + + + + This feature requires time-based replication delay monitoring. This can be + provided by either + (external command mode) or by + setting (which + uses pg_stat_replication.replay_lag from PostgreSQL + 10+). If neither is configured, the TTL remains at its default minimum + value (100 milliseconds) and is never updated based on actual replication + delay, which may result in suboptimal routing decisions. + + + + + Enabling dml_adaptive_global increases shared memory + consumption. With default settings, the feature requires approximately 80 + KB of shared memory for table tracking: + track_table_mutation_table_size * 40 bytes + (default: 2048 * 40 = ~80 KB). + + + + + + + track_table_mutation_ttl_factor (floating point) + + track_table_mutation_ttl_factor configuration parameter + + + + + Multiplier for calculating the TTL: TTL = replication_delay * + track_table_mutation_ttl_factor. Higher values provide more + safety margin but may reduce read replica utilization. + + + Valid range: 1.0-100.0. Default is 5.0. This + parameter can be changed by reloading the Pgpool-II + configurations. + + + + + + track_table_mutation_max_staleness (integer) + + track_table_mutation_max_staleness configuration parameter + + + + + Maximum duration in milliseconds that a single table entry can + continuously force queries to primary, measured from when the table was + first marked stale. When this cap is reached, the entry is expired + regardless of recent writes. If the table is written to again after + expiry, a fresh tracking entry is created. + + + This parameter bounds the cross-session impact of table mutation + tracking. Even if a table is written to in a tight loop, its effect on + other sessions' load balancing is limited to this duration. For + legitimately busy tables, the gap between forced expiry and the next + write re-marking the table is negligible (typically milliseconds). + + + Set to 0 to disable the cap (not recommended for production). Valid + range: 0-3600000 ms. Default is 60000 (60 seconds). + This parameter can be changed by reloading the Pgpool-II + configurations. + + + + + + track_table_mutation_cold_start_duration (integer) + + track_table_mutation_cold_start_duration configuration parameter + + + + + Duration in milliseconds to route all queries to primary after a child + process starts. This prevents stale reads when a new connection is + established before the track table mutation is populated with recent + write history. + + + When watchdog is enabled and the local node becomes the leader, + Pgpool-II also triggers a global cold start + for this duration to avoid stale reads after leadership changes. + + + Valid range: 0-60000 ms. Default is 2000 (2 seconds). + Set to 0 to disable cold start behavior. This parameter can be changed + by reloading the Pgpool-II configurations. + + + + + + track_table_mutation_table_buckets (integer) + + track_table_mutation_table_buckets configuration parameter + + + + + Number of hash buckets for the track table mutation hash table. Higher + values reduce hash collisions and improve lookup performance. + + + Valid range: 64-65536. Default is 1024. This + parameter can only be set at server start. + + + + + + track_table_mutation_table_size (integer) + + track_table_mutation_table_size configuration parameter + + + + + Maximum number of tables that can be tracked simultaneously in the track + table mutation. When full, oldest entries are evicted using a simple + eviction strategy. + + + Valid range: 128-131072. Default is 2048. Memory + usage: approximately 40 bytes per entry. This parameter can only be set + at server start. + + + + + + Track Table Mutation Configuration Example + + To enable track table mutation with replication delay monitoring: + + +# Enable dml_adaptive_global mode (includes track table mutation) +disable_load_balance_on_write = 'dml_adaptive_global' +track_table_mutation_ttl_factor = 5.0 +track_table_mutation_max_staleness = 60000 +track_table_mutation_cold_start_duration = 2000 + +# Option A: Use external command for replication delay +replication_delay_source_cmd = '/path/to/get-replication-delay.sh' +replication_delay_source_timeout = 10 + +# Option B: Use pg_stat_replication replay_lag (PG 10+) +# delay_threshold_by_time = 1000 + +# Adjust table map size based on workload +track_table_mutation_table_size = 4096 + + + Shared memory required for above configuration: approximately 160 KB for + the table map. Default configuration (2048 tables) requires approximately + 80 KB. + + + + + Limitations + + The track table mutation feature has the following limitations: + + + + + PREPARE statements are not tracked. When a prepared + statement containing data modification is executed, the table mutation + is not recorded. + + + + + A maximum of 128 tables can be tracked per SELECT query for staleness + checking. This limit is shared with the query cache subsystem + (POOL_MAX_SELECT_OIDS). + + + + + If your application uses prepared statements and requires read-after-write + consistency, consider using explicit transaction routing or + the /*NO LOAD BALANCE*/ comment directive for affected + queries. + + + The following statement types are tracked and will + mark tables as stale: + + + + + INSERT, UPDATE, DELETE + statements (including those with RETURNING clauses). + + + + + TRUNCATE statements (including multiple tables). + + + + + MERGE statements (PostgreSQL 15+). + + + + + WITH clauses containing data modifications (Common + Table Expressions + with INSERT, UPDATE, + or DELETE). For example, WITH deleted AS + (DELETE FROM t1 RETURNING *) SELECT * FROM deleted will + properly mark table t1 as stale. + + + + + Transaction Rollback Behavior: Within explicit + transactions, tables are only marked as stale in shared memory when the + transaction is committed. If the transaction is rolled back, no tables are + marked, since no actual data modification occurred on replicas. This + prevents rolled-back transactions from unnecessarily disabling load + balancing. For autocommit statements (outside explicit transactions), + tables are marked immediately upon command completion. + + + + Cross-Session Impact and Safety Bounds: + Unlike dml_adaptive (which only affects the session + that issued the write), + dml_adaptive_global affects all sessions reading the + same table in the same database. The following safety mechanisms bound + this cross-session impact: + + + + + Maximum staleness cap: + The parameter + (default: 60 seconds) limits how long any single table entry can + continuously force primary routing. Even under sustained writes, the + entry expires after this period and is only renewed by subsequent + committed writes. + + + + + Database isolation: Table staleness tracking is + scoped by database OID. Writes in one database never affect load + balancing decisions for sessions connected to a different database. In + multi-tenant deployments where tenants use separate databases, one + tenant's write activity cannot influence another tenant's query routing. + + + + + Committed writes only: Only committed transactions + mark tables as stale. Rolled-back transactions have no effect on the + shared tracking state. + + + + + Bounded table map size: The shared memory table map + has a fixed maximum size + (). At most this + many tables can be marked stale simultaneously, providing a natural + ceiling on the feature's impact. + + + + + + diff --git a/doc/src/sgml/memcache.sgml b/doc/src/sgml/memcache.sgml index 640f2a56e..065de41ee 100644 --- a/doc/src/sgml/memcache.sgml +++ b/doc/src/sgml/memcache.sgml @@ -1,475 +1,649 @@ - In Memory Query Cache - + In Memory Query Cache + + + In memory query cache can be used with all modes of + Pgpool-II. + The in memory query cache keeps the SELECT results and the results are reused. + When the underlying table gets updated, corresponding cache entries are deleted (in case is on. This parameter is on by default), thus restarting Pgpool-II is not necessary. + + + In memory cache saves the pair of user name, database name, SELECT statement + and its result + (along with the Bind parameters, if the SELECT is an + extended query). If the same user name, database name and SELECTs comes in, + Pgpool-II returns the value from + cache. Since no SQL parsing nor access + to PostgreSQL are involved, the serving + of results from the in memory cache is extremely fast. + + + + + First of all if the query starts with SQL comment: + + /*FORCE QUERY CACHE*/ + + is checked (case insensitive). If so, the result of the query is + cached unconditionally as long as it is not SELECT or WITH + SELECT. + However you must be very careful to use this feature. For example, + + /*FORCE QUERY CACHE*/SELECT now(); + + will return the same timestamp until pgpool restarts, once the + query is cached. The query cache will not be discarded even with a + query: + + /*NO QUERY CACHE*/SELECT now(); + + Because it just prevents to create a cache entry for the query, and + does not affect the query using the FORCE QUERY CACHE comment. You + can delete such a query cache by + using command, + or command. + - In memory query cache can be used with all modes of - Pgpool-II. - Pgpool-II does not - need a restart when the cache gets outdated because of - the underlying table updates. + Note that for following query: + + /*FORCE QUERY CACHE*/SELECT * FROM t1; + + usual cache validation due to an update to the table (in this case + t1) works. - In memory cache saves the pair of SELECT statement - and its result - (along with the Bind parameters, if the SELECT is an - extended query). If the same SELECTs comes in, - Pgpool-II returns the value from - cache. Since no SQL parsing nor access - to PostgreSQL are involved, the serving - of results from the in memory cache is extremely fast. + If the query does not start with FORCE QUERY CACHE comment, + following checks are performed. If one of followings is satisfied, + SELECT will not be cached. + + SELECT including non immutable functions + SELECT including temp tables, unlogged tables + SELECT including TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + SELECT including CAST to TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + SELECT including SQLValueFunction (CURRENT_TIME, CURRENT_USER etc.) + SELECT result is too large (memqcache_maxcache) + SELECT FOR SHARE/UPDATE + SELECT starting with "/*NO QUERY CACHE*/" comment (case insensitive) + SELECT including system catalogs + SELECT using TABLESAMPLE + SELECT uses row security enabled tables + + However, VIEWs and SELECTs accessing unlogged tables can be + cached by specifying in + the . + - - - Basically following SELECTs will not be cached: + + + Since consistency between the query cache and database content can + be lost by following commands, the query cache is all deleted if + they are executed: + + ALTER DATABASE + ALTER ROLE or USER (except WITH CONNECTION LIMIT and WITH [ENCRYPTED] PASSWORD) + ALTER TABLE + REVOKE + + Moreover, if SET ROLE or SET SESSION AUTHORIZATION are executed, + the query cache will not be used and new cache will not be created + in the session. + Pgpool-II assumes that two query cache + are different if their session users are different. On the other + hand, PostgreSQL manages access control + depending on current user. Thus these commands may break the + consistency between these two access controls. However, cache + invalidation by update commands are performed in the same way in + that these commands are not used. + + + + + + If multiple functions having the same name are registered and one + of them returns TIMESTAMP WITH TIMEZONE or TIME WITH + TIMEZONE, Pgpool-II thinks that the + query cannot be cached even if it uses a version of function which + does not return TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE. In + this case you can create a wrapper function returning TIMESTAMP + WITHOUT TIMEZONE or TIME WITHOUT TIMEZONE, or use /*FORCE QUERY + CACHE*/ comment so that you can use the query cache. + + + + + On the other hand, it might be slower than the normal path + in some cases, because it adds some overhead to store cache. + Moreover when a table is updated, Pgpool-II + automatically deletes all the caches related to the + table. Therefore, the performance will be degraded by a system with + a lot of updates. If the query cache hit ratio (it can be checked + by using ) is lower than 70%, + you might want to disable in memory cache. + + + + A SELECT result is basically registered when + SELECT normally finishes. If an explicit transaction is executing, + SELECT result is not registered until the + transaction is committed. Also in extended query mode, the timing + of cache registration varies depending on clustering mode. In + streaming + replication mode and logical + replication mode, cache is registered when + Sync message is sent from frontend, and the + response (Ready for query message) is returned + from backend. Thus even if commands are sent from frontend, the + second Execute (SELECT 1) will not use query cache. + + Parse (SELECT 1) + Bind (SELECT 1) + Execute (SELECT 1) + Parse (SELECT 1) + Bind (SELECT 1) + Execute (SELECT 1) + Sync + + + On the other hand, in other clustering mode, since the result of + first Execute (SELECT 1) is registered, the second Execute (SELECT + 1) will use the query cache. + + + + Enabling in memory query cache + + + + + memory_cache_enabled (boolean) + + memory_cache_enabled configuration parameter + + + + + Setting to on enables the memory cache. + Default is off. + + + This parameter can only be set at server start. + + + + + The query cache will also be used by shared relation cache if + is set to on. Moreover the + query cache is used even if + parameter is set to off. See for more details to relation cache. + + + + + + + + + Choosing cache storage + + + + + memqcache_method (enum) + + memqcache_method configuration parameter + + + + + Specifies the storage type to be used for the cache. + Below table contains the list of all valid values for the parameter. + + + + Memqcache method options + + + + Value + Description + + + + + + shmem + Use shared memory + + + + memcached + Use memcached + + + + +
+ + + In general shmem is faster + than memcached because the former does not + involve any network access. However, the upper limit size of + memqcache_total_size is limited by the total + shared memory size defined by the system. The size is large + enough in modern Linux systems, but in other systems there maybe + smaller upper limit. In this case you need to change the system + settings regarding the maximum shared memory size. There's a + good explanation about shared memory + in PostgreSQL + documentation. + + + If you are not sure which memqcache_method to be used, start with shmem. + + + Default is shmem. + + + + This parameter can only be set at server start. + +
+
+
+
+ + + Common configurations + + These below parameter are valid for both shmem + and memcached type query cache. + + + + + memqcache_expire (integer) + + memqcache_expire configuration parameter + + + + + Specifies the life time of query cache in seconds. + Default is 0. which means no cache expiration and cache remains + valid until the table is updated. + + + This parameter can only be set at server start. + + + + + memqcache_expire and + are orthogonal to each other. + + + + + + + + memqcache_auto_cache_invalidation (boolean) + + memqcache_auto_cache_invalidation configuration parameter + + + + + Setting to on, automatically deletes the cache related to the updated tables. + When off, cache is not deleted. + + + Default is on. + + + + This parameters + and are orthogonal to each other. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + memqcache_maxcache (integer) + + memqcache_maxcache configuration parameter + + + + + Specifies the maximum size in bytes of the SELECT query result to be cached. + The result with data size larger than this value will not be cached by + Pgpool-II. + When the caching of data is rejected because of the size constraint the following + message is shown. - SELECTs including non immutable functions - SELECTs including temp tables, unlogged tables - SELECT result is too large (memqcache_maxcache) - SELECT FOR SHARE/UPDATE - SELECT starting with "/*NO QUERY CACHE*/" comment - SELECT including system catalogs - SELECT uses TABLESAMPLE + LOG: pid 13756: pool_add_temp_query_cache: data size exceeds memqcache_maxcache. current:4095 requested:111 memq_maxcache:4096 - However, VIEWs and SELECTs accessing unlogged tables can be - cached by specifying in - the . - -
+ + + + For the shared memory query('shmem') cache the + memqcache_maxcache must be set lower than + and for 'memcached' + it must be lower than the size of slab (default is 1 MB). + + + + This parameter can only be set at server start. + + + + + + cache_safe_memqcache_table_list (string) + + cache_safe_memqcache_table_list configuration parameter + + + + + + Specifies a comma separated list of table names whose + SELECT results should be cached by + Pgpool-II. This parameter only + applies to VIEWs and SELECTs accessing unlogged tables. + Regular tables can be cached unless specified + by . + + + + You can use regular expression into the list to match table name + (to which ^ and $ are automatically added). + + + + + If the queries can refer the table with and without the schema + qualification then you must add both entries(with and without + schema name) in the list. + + #For example: + #If the queries sometime use "table1" and other times "public.table1" + #to refer the table1 then the cache_safe_memqcache_table_list + #would be configured as follows. + + cache_safe_memqcache_table_list = "table1,public.table1" + + + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + cache_unsafe_memqcache_table_list (string) + + cache_unsafe_memqcache_table_list configuration parameter + + + + + Specifies a comma separated list of table names whose SELECT + results should NOT be cached by the + Pgpool-II. + + + + You can use regular expression into the list to match table name + (to which ^ and $ are automatically added), + + + + + If the queries can refer the table with and without the schema + qualification then you must add both entries(with and without + schema name) in the list. + + #For example: + #If the queries sometime use "table1" and other times "public.table1" + #to refer the table1 then the cache_unsafe_memqcache_table_list + #would be configured as follows. + + cache_unsafe_memqcache_table_list = "table1,public.table1" + + + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + cache_unsafe_memqcache_table_list + precedence over + + + + + + + + memqcache_oiddir (string) + + memqcache_oiddir configuration parameter + + + + + Specifies the full path to the directory for storing the + oids of tables used by SELECT queries. + + + memqcache_oiddir directory contains the sub directories + for the databases. The directory name is the OID of the database. In addition, each + database directory contains the files for each table used by SELECT statement. + Again the name of the file is the OID of the table. + These files contains the pointers to query cache which are used as key for + deleting the caches. + + + + Normal restart of Pgpool-II does not clear the + contents of memqcache_oiddir. + + + + This parameter can only be set at server start. + + + + + + + + + Configurations to use shared memory + + + These are the parameters used with shared memory as the cache storage. + + + + + + memqcache_total_size (integer) + + memqcache_total_size configuration parameter + + + + + Specifies the shared memory cache size. + The default is 64MB. + + + Each cache is stored in fixed-size blocks specified + by . The number + of blocks can be calculated + by + / . Any decimal + places are truncated so that the number of blocks is an + integer. If the number becomes 0, an error is raised. That + is, memqcache_total_size must be greater + than . Query + results and their management data are not stored across multiple + blocks, so if the query result data length + 64 bytes is greater + than , it cannot + be stored in a block and will not be cached. + + + When one block is filled with cache, the next block is used. + When all blocks are full, the oldest block is flushed and reused + (Note that the oldest block does not necessarily holds the + oldest cache data because new cache data is registered whenever + the first fitting space is found). While + smaller memqcache_total_size does not raise + an error, performance decreases because the cache hit ratio + decreases. The cache hit ratio can be checked by + consulting cache_hit_ratio + of . + + + This parameter can only be set at server start. + + + + + + memqcache_max_num_cache (integer) + + memqcache_max_num_cache configuration parameter + + + + + Specifies the number of cache entries. The default is 1,000,000. + + + If you attempt to register more + than memqcache_max_num_cache caches, a block + containing cached data is flushed and reused. While + smaller memqcache_max_num_cache does not + raise an error, performance decreases because the cache hit + ratio decreases. The cache hit ratio can be checked by + consulting cache_hit_ratio + of . + + + + The cache is managed by a hash table in shared memory for fast + access. The hash table space size can be calculated by: + memqcache_max_num_cache * 64 bytes. Number + of hash entries can be found + in used_hash_entries + of . Number of the hash + table entries usually + matches memqcache_max_num_cache, but may not + match if memqcache_max_num_cache is not a + power of 2. In this case it is rounded to a power of 2 greater + than memqcache_max_num_cache. Number of + hash entries in use can be found + at used_hash_entries. + + + + This parameter can only be set at server start. + + + + + + memqcache_cache_block_size (integer) + + memqcache_cache_block_size configuration parameter + + + + + Specifies the cache block size. + The default is 1MB. + + + Query results and their management data are not stored across + multiple blocks, so if the query result data length + 64 bytes + is greater than , + it cannot be stored in a block and will not be cached. + + + memqcache_cache_block_size must be set to at least 512. + + + This parameter can only be set at server start. + + + + + + + + + Configurations to use memcached - On the other hand, it might be slower than the normal path - in some cases, because it adds some overhead to store cache. - Moreover when a table is updated, Pgpool-II - automatically deletes all the caches related to the - table. Therefore, the performance will be degraded by a system with - a lot of updates. If the query cache hit ratio (it can be checked - by using ) is lower than 70%, - you might want to disable in memory cache. + These are the parameters used with memcached as the cache storage. - - Enabling in memory query cache - - - - - memory_cache_enabled (boolean) - - memory_cache_enabled configuration parameter - - - - - Setting to on enables the memory cache. - Default is off. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - - - - - - Choosing cache storage - - - - - memqcache_method (string) - - memqcache_method configuration parameter - - - - - Specifies the storage type to be used for the cache. - Below table contains the list of all valid values for the parameter. - - - - Memcache method options - - - - Value - Description - - - - - - 'shmem' - Use shared memory - - - - 'memcached' - Use memcached - - - - -
- - - Default is 'shmem'. - - - - This parameter can only be set at server start. - -
-
-
-
- - - Common configurations - - These below parameter are valid for both shmem - and memcached type query cache. - - - - - memqcache_expire (integer) - - memqcache_expire configuration parameter - - - - - Specifies the life time of query cache in seconds. - Default is 0. which means no cache expiration and cache remains - valid until the table is updated. - - - This parameter can be changed by reloading - the Pgpool-II configurations. - - - - - memqcache_expire and - are orthogonal to each other. - - - - - - - - memqcache_auto_cache_invalidation (boolean) - - memqcache_auto_cache_invalidation configuration parameter - - - - - Setting to on, automatically deletes the cache related to the updated tables. - When off, cache is not deleted. - - - Default is on. - - - - This parameters - and are orthogonal to each other. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - memqcache_maxcache (integer) - - memqcache_maxcache configuration parameter - - - - - Specifies the maximum size in bytes of the SELECT query result to be cached. - The result with data size larger than this value will not be cached by - Pgpool-II. - When the caching of data is rejected because of the size constraint the following - message is shown. - - LOG: pid 13756: pool_add_temp_query_cache: data size exceeds memqcache_maxcache. current:4095 requested:111 memq_maxcache:4096 - - - - - For the shared memory query('shmem') cache the - memqcache_maxcache must be set lower than - and for 'memcached' - it must be lower than the size of slab (default is 1 MB). - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - white_memqcache_table_list (string) - - white_memqcache_table_list configuration parameter - - - - - - Specifies a comma separated list of table names whose - SELECT results should be cached by - Pgpool-II. This parameter only - applies to VIEWs and SELECTs accessing unlogged tables. - Regular tables can be cached unless specified - by . - - - - You can use regular expression into the list to match table name - (to which ^ and $ are automatically added). - - - - - If the queries can refer the table with and without the schema - qualification then you must add both entries(with and without - schema name) in the list. - - #For example: - #If the queries sometime use "table1" and other times "public.table1" - #to refer the table1 then the white_memqcache_table_list - #would be configured as follows. - - white_memqcache_table_list = "table1,public.table1" - - - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - black_memqcache_table_list (string) - - black_memqcache_table_list configuration parameter - - - - - Specifies a comma separated list of table names whose SELECT - results should NOT be cached by the - Pgpool-II. - - - - You can use regular expression into the list to match table name - (to which ^ and $ are automatically added), - - - - - If the queries can refer the table with and without the schema - qualification then you must add both entries(with and without - schema name) in the list. - - #For example: - #If the queries sometime use "table1" and other times "public.table1" - #to refer the table1 then the black_memqcache_table_list - #would be configured as follows. - - black_function_list = "table1,public.table1" - - - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - black_memqcache_table_list - precedence over - - - - - - - - memqcache_oiddir (string) - - memqcache_oiddir configuration parameter - - - - - Specifies the full path to the directory for storing the - oids of tables used by SELECT queries. - - - memqcache_oiddir directory contains the sub directories - for the databases. The directory name is the OID of the database. In addition, each - database directory contains the files for each table used by SELECT statement. - Again the name of the file is the OID of the table. - These files contains the pointers to query cache which are used as key for - deleting the caches. - - - - Normal restart of Pgpool-II does not clear the - contents of memqcache_oiddir. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - - - - Configurations to use shared memory - - - These are the parameters used with shared memory as the cache storage. - - - - - - memqcache_total_size (integer) - - memqcache_total_size configuration parameter - - - - - Specifies the shared memory cache size in bytes. - - - This parameter can only be set at server start. - - - - - - memqcache_max_num_cache (integer) - - memqcache_max_num_cache configuration parameter - - - - - Specifies the number of cache entries. This is used to define the size of cache management space. - - - - The management space size can be calculated by: - memqcache_max_num_cache * 48 bytes. - Too small number will cause an error while registering cache. - On the other hand too large number will just waste space. - - - - This parameter can only be set at server start. - - - - - - memqcache_cache_block_size (integer) - - memqcache_cache_block_size configuration parameter - - - - - Specifies the cache block size. Pgpool-II uses the - cache memory arranged in memqcache_cache_block_size blocks. - SELECT result is packed into the block and must fit in a single block. - And the results larger than memqcache_cache_block_size are - not cached. - - - - memqcache_cache_block_size must be set to atleast 512. - - - - This parameter can only be set at server start. - - - - - - - - - Configurations to use memcached - - - These are the parameters used with memcached as the cache storage. - - - - - - memqcache_memcached_host (string) - - memqcache_memcached_host configuration parameter - - - - - Specifies the host name or the IP address on which memcached - works. You can use 'localhost' if memcached - and Pgpool-II resides on same server. - - - This parameter can only be set at server start. - - - - - - memqcache_memcached_port (integer) - - memqcache_memcached_port configuration parameter - - - - - Specifies the port number of memcached. - Default is 11211. - - - This parameter can only be set at server start. - - - - - - + + + + memqcache_memcached_host (string) + + memqcache_memcached_host configuration parameter + + + + + Specifies the host name or the IP address on which memcached + works. You can use 'localhost' if memcached + and Pgpool-II resides on same server. + + + This parameter can only be set at server start. + + + + + + memqcache_memcached_port (integer) + + memqcache_memcached_port configuration parameter + + + + + Specifies the port number of memcached. + Default is 11211. + + + This parameter can only be set at server start. + + + + + +
diff --git a/doc/src/sgml/misc-config.sgml b/doc/src/sgml/misc-config.sgml index 230736eb5..d4c20fd99 100644 --- a/doc/src/sgml/misc-config.sgml +++ b/doc/src/sgml/misc-config.sgml @@ -1,167 +1,331 @@ - Misc Configuration Parameters - - - - - relcache_expire (integer) - - relcache_expire configuration parameter - - - - - - Specifies the relation cache expiration time in seconds. - The relation cache is used for caching the query result of - PostgreSQL system catalogs that is used by Pgpool-II - to get various informations including the table - structures and to check table types(e.g. To check if the referred - table is a temporary table or not). The cache is maintained in - the local memory space of Pgpool-II - child process and its lifetime is same as of the child process. - So If the table is modified using ALTER TABLE - or some other means, the relcache becomes inconsistent. - For this purpose, relcache_expire controls - the life time of the cache. - Default is 0, which means the cache never expires. - - - - This parameter can only be set at server start. - - - - - - - relcache_size (integer) - - relcache_size configuration parameter - - - - - - Specifies the number of relcache entries. - Default is 256. - - - - If the below message frequently appears in the - Pgpool-II log, you may need to - increase the relcache_size for better performance. - -"pool_search_relcache: cache replacement happened" - - - - - This parameter can only be set at server start. - - - - - - - check_temp_table (boolean) - - check_temp_table configuration parameter - - - - - - Setting to on, enables the temporary table check in the SELECT - statements. To check the temporary table Pgpool-II - queries the system catalog of primary/master PostgreSQL backend, which increases - the load on the primary/master server. - If you are absolutely sure that your system never uses temporary tables, then - you can safely turn off the check_temp_table. - Default is on. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - - check_unlogged_table (boolean) - - check_unlogged_table configuration parameter - - - - - - Setting to on, enables the unlogged table check in the SELECT - statements. To check the unlogged table Pgpool-II - queries the system catalog of primary/master PostgreSQL backend which increases - the load on the primary/master server. - If you are absolutely sure that your system never uses the unlogged tables - (for example, you are using 9.0 or earlier version of PostgreSQL) then you - can safely turn off the check_unlogged_table. - Default is on. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - - - - - pid_file_name (string) - - pid_file_name configuration parameter - - - - - - Specifies the full path to a file to store the Pgpool-II - process id. - The pid_file_name path can be specified as relative to the - location of pgpool.conf file or as an absolute path - Default is "/var/run/pgpool/pgpool.pid". - - - - This parameter can only be set at server start. - - - - - - - logdir (string) - - logdir configuration parameter - - - - - - Specifies the full path to a directory to store the pool_status. - Default is "/tmp". - - - - This parameter can only be set at server start. - - - - - - + Misc Configuration Parameters + + + + + relcache_expire (integer) + + relcache_expire configuration parameter + + + + + + Specifies the relation cache expiration time in seconds. + The relation cache is used for caching the query result of + PostgreSQL system catalogs that is used by Pgpool-II + to get various information including the table + structures and to check table types(e.g. To check if the referred + table is a temporary table or not). The cache is maintained in + the local memory space of Pgpool-II + child process and its lifetime is same as of the child process. + The cache is also maintained in shared memory to share among child + processes,if enable . + So If the table is modified using ALTER TABLE + or some other means, the relcache becomes inconsistent. + For this purpose, relcache_expire controls + the life time of the cache. + Default is 0, which means the cache never expires. + + + + This parameter can only be set at server start. + + + + + + + relcache_size (integer) + + relcache_size configuration parameter + + + + + + Specifies the number of relcache entries. Default is 256. + The cache is created about 10 entries per table. So you can estimate + the required number of relation cache at "number of using table * 10". + + + + If the below message frequently appears in the + Pgpool-II log, you may need to + increase the relcache_size for better performance. + + "pool_search_relcache: cache replacement occurred" + + + + + This parameter can only be set at server start. + + + + + + + enable_shared_relcache (boolean) + + enable_shared_relcache configuration parameter + + + + + By setting to on, relation cache is shared among + Pgpool-II child processes using the in + memory query cache (see for more + details). Default is on. Each child process needs to access to + the system catalog from PostgreSQL. + By enabling this feature, other process can extract the catalog + lookup result from the query cache and it should reduce the + frequency of the query. Cache invalidation is not happen even if + the system catalog is modified. So it is strongly recommend to + set time out base cache invalidation by using parameter. + + + This parameter can be used even if is off. In this case some + query cache parameters(, + and each cache storage + parameter) is used together. + + + Pgpool-II search the local relation + cache first. If it is not found on the cache, the shared relation + query cache is searched if this feature is enabled. If it is + found on query cache, it is copied into the local relation + cache. If a cache entry is not found on anywhere, + Pgpool-II executes the query against + PostgreSQL, and the result is stored + into the shared relation cache and the local cache. + + + This parameter can only be set at server start. + + + + + + relcache_query_target (enum) + + relcache_query_target configuration parameter + + + + + The target node to send queries to create relation cache + entries. If set to primary, queries will + be sent to primary node. This is the default and + recommended to most users because the query could get the + latest information. If you want to lower the load of + primary node, you can set the parameter to + load_balance_node, which will send + queries to the load balance node. This is especially useful + for such a system + where Pgpool-II/primary server is + on a continent A while + other Pgpool-II/standby server is + on other continent B. Clients on B want read data from the + standby because it's much geographically closer. In this + case you can set backend_weight0 (this represents primary) + to 0, backend_weight1 to 1 (this represents standby) and set + relcache_query_target + to load_balance_node. + + + Note, however, if you send query to the standby node, + recently created tables and rows might not be available on + the standby server yet because of replication delay. Thus + such a configuration is not recommended for systems where + data modification activity is high. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + + + + + + check_temp_table (enum) + + check_temp_table configuration parameter + + + + + + Setting to catalog + or trace, enables the temporary table + check in the SELECT statements. To check + the temporary table Pgpool-II + queries the system catalog of + primary/main PostgreSQL backend + if catalog is specified, which + increases the load on the primary/main server. + + + If trace is + set, Pgpool-II traces temporary + table creation and dropping to obtain temporary table + info. So no need to access system catalogs. However, if + temporary table creation is invisible + to Pgpool-II (done in functions + or triggers, for + example), Pgpool-II cannot + recognize the creation of temporary tables. + + + If you are absolutely sure that your system never uses + temporary tables, then you can safely set to none. + + + + For a backward compatibility sake for 4.0 or + before, Pgpool-II + accepts on, which is same + as catalog and off, + which is same as none, they may be + deleted in the future version. + + + + Default is catalog. + + + This parameter can be changed by reloading + the Pgpool-II configurations. + You can also use command to + alter the value of this parameter for a current session. + + + + + + + check_unlogged_table (boolean) + + check_unlogged_table configuration parameter + + + + + + Setting to on, enables the unlogged table check in the SELECT + statements. To check the unlogged table Pgpool-II + queries the system catalog of primary/main PostgreSQL backend which increases + the load on the primary/main server. + If you are absolutely sure that your system never uses the unlogged tables + (for example, you are using 9.0 or earlier version of PostgreSQL) then you + can safely turn off the check_unlogged_table. + Default is on. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + + + + + pid_file_name (string) + + pid_file_name configuration parameter + + + + + + Specifies the full path to a file to store the Pgpool-II + process id. + The pid_file_name path can be specified as relative to the + location of pgpool.conf file or as an absolute path + Default is "/var/run/pgpool/pgpool.pid". + + + + This parameter can only be set at server start. + + + + + + + work_dir (string) + + work_dir configuration parameter + + + + + + Specifies the full path to a directory to store the pgpool_status. + Default is '/tmp'. + + + + This parameter can only be set at server start. + + + + + + + health_check_test (boolean) + + health_check_test configuration parameter + + + + + + Do not set this parameter to on in a production + environment. This feature is purely for testing purpose. + + + + Setting to on, + enables the testing facility of health checking. In this case the + health check process looks + into backend_down_request + under . The file may contain multiple + lines, and each line corresponds to each backend. A line in the + file starts with backend id (must be a decimal number starting + with zero), then a TAB, and ends with "down". The backend is + assumed in down status and Pgpool-II + will start a failover. Once the failover completes, the "down" is + rewritten to "already_down" by health check process to prevent + repeating failovers. + + + This feature is particularly useful for + testing . Suppose + we have 3 watchdog node. Each watchdog checks healthiness of + backend 0. By setting "0 down" in the file only under watchdog 0, + other watchdogs disagree with the unhealthiness of backend 0, so + failover will not occur. This kind of partial network failure can + be simulated using this feature. + + + Default is off. + + + + This parameter can only be set at server start. + + + + + + diff --git a/doc/src/sgml/online-recovery.sgml b/doc/src/sgml/online-recovery.sgml index f1c9d3379..e8ee40528 100644 --- a/doc/src/sgml/online-recovery.sgml +++ b/doc/src/sgml/online-recovery.sgml @@ -1,421 +1,555 @@ - Online Recovery + Online Recovery + + online recovery + + + Pgpool-II can synchronize database + nodes and attach a node without stopping the service. This + feature is called "online recovery". Online + recovery can be executed by + using command. + + + For online recovery, the recovery target node must be in detached + state. This means the node must be either manually detached by + or automatically detached + by Pgpool-II as a consequence of + failover. + + + If you wish to add a PostgreSQL server + node dynamically, reload the + pgpool.conf after adding the + and its associated + parameters. This will register the new server + to Pgpool-II as a detached backend + node, after that you execute command, + the server is add. + + + - Pgpool-II can synchronize database - nodes and attach a node without stopping the service. This - feature is called "online recovery". Online - recovery can be executed by - using command. - - - For online recovery, the recovery target node must be in detached - state. This means the node must be either manually detached by - or automatically detached - by Pgpool-II as a consequnece of - failover. + The recovery target PostgreSQL server must not + be running for performing the online recovery. If the + target PostgreSQL server has already started, + you must shut it down before starting the online recovery. + + + + Online recovery is performed in two phases. The first phase is + called "first stage" and the second phase is called "second + stage". Only and require the second stage. + For other modes including streaming replication mode the second + stage is not performed and you don't need to provide a script for + the stage in . i.e. you can safely leave + it as an empty string. + + + + In the first stage the standby (replica) node is created by using + PostgreSQL's + pg_basebackup, for example, from a backup of the + main (primary) node. Update data while executing the first stage + will be logged into the PostgreSQL's + transaction log. + + + + In the second stage the target recovery node is started. The + transaction log will be replayed and the replica node will be + completely synced with the master node. + + + + You need to provide scripts for each stage. Complete sample scripts + are provided at /etc/pgpool-II/recovery_1st_stage.sample + and /etc/pgpool-II/recovery_2nd_stage.sample. + Example installation using those scripts can be found in . + + + + Connections from clients are not allowed only in the second stage + while the data can be updated or retrieved during the first stage. + + + Pgpool-II performs the follows steps in online recovery: + + + + + + CHECKPOINT. + + + + + Execute first stage of online recovery. + + + + + Wait until all client connections have disconnected (only in and ). + + + + + CHECKPOINT (only in and + ). + + + + + Execute second stage of online recovery (only in and ). + + + + + Start up postmaster (perform pgpool_remote_start) + + + The pgpool_remote_start is script to start up the PostgreSQL node of recovery target. + pgpool_remote_start receives following 2 parameters: + + + + Hostname of the backend node to be recovered. + + + + + Path to the database cluster of the main(primary) node. + + + + The script example can be found in . + + + The script path and filename are hard coded, $PGDATA/pgpool_remote_start is executed on main(primary) node. + + + + + + + Node attach + + + + + - If you wish to add a PostgreSQL server - node dynamically, reload the - pgpool.conf after adding the - and its associated - parameters. This will register the new server - to Pgpool-II as a detached backend - node. + There is a restriction in the online recovery in + and . + If Pgpool-II itself is installed + on multiple hosts without enabling watchdog, + online recovery does not work correctly, + because Pgpool-II has to stop all + the clients during the 2nd stage of online recovery. + If there are several Pgpool-II hosts, + only one of them will have received the online recovery command and will + block the connections from clients. - - - The recovery target PostgreSQL server must not - be running for performing the online recovery. If the - target PostgreSQL server has already started, - you must shut it down before starting the online recovery. + If recovery_password is left blank Pgpool-II + will first try to get the password for from + file before using the empty password. + + + You can also specify AES256-CBC encrypted password in recovery_password field. + To specify the AES encrypted password, password string must be prefixed with + AES after encrypting (using aes-256-cbc algorithm) and + encoding to base64. + + + To specify the unencrypted clear text password, prefix the password string with + TEXT. For example if you want to set mypass as + a password, you should specify TEXTmypass in the password field. + In the absence of a valid prefix, Pgpool-II will considered + the string as a plain text password. + + + You can also use utility to create the correctly formatted + AES encrypted password strings. + + + Pgpool-II will require a valid decryption key at the + startup to use the encrypted passwords. + see for more details on providing the + decryption key to Pgpool-II + + - - - Online recovery is performed in two phases. The first phase is - called "first stage" and the second phase is called "second - stage". You need to provide scripts for each - stage. Only requires the - second stage. For other modes including streaming replication - mode the second stage is not performed and you don't need to - provide a script for the stage - in . i.e. you can - safely leave it as an empty string. - - - Connections from cliens are not allowd only in the second stage - while the data can be updated or retrieved during the first statge. - - - Pgpool-II performs the follows steps in online recovery: - - + + This parameter can be changed by reloading the Pgpool-II configurations. + + + - + + recovery_database (string) + + recovery_database configuration parameter + + + + + Specifies the PostgreSQL database name to be used for online recovery. + The default is 'postgres'. If an empty string ('') + is specified, Pgpool-II will attempt to use + the "postgres" database. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + To perform online recovery, the functions pgpool_recovery, + pgpool_remote_start and + pgpool_switch_xlog must be created in the database + specified by the parameter. + To install these functions in the default database + "postgres", execute the following command + (if a value other than the default is configured, replace + "postgres" with the setting of + recovery_database): + +$ psql postgres -c "CREATE EXTENSION pgpool_recovery" + + + + + + + + recovery_1st_stage_command (string) + + recovery_1st_stage_command configuration parameter + + + + + Specifies a command to be run by main (primary) node at the + first stage of online recovery. The command file must be placed in the + database cluster directory for security reasons. + For example, if recovery_1st_stage_command = + 'sync-command', then Pgpool-II will + look for the command script in $PGDATA directory and will + try to execute $PGDATA/sync-command. + + + recovery_1st_stage_command receives following 7 parameters: + + + + - CHECKPOINT. + Path to the database cluster of the main (primary) node. - - + + - Execute first stage of online recovery. + Hostname of the backend node to be recovered. - - + + - Wait until all client connections have disconnected (only - in ). + Path to the database cluster of the node to be recovered. - - + + - CHECKPOINT (only in ). - specified). + Port number of the main (primary) node (Pgpool-II 3.4 or after). - - + + - Execute second stage of online recovery (only - in ). + Node number to be recovered (Pgpool-II 4.0 or after) - - + + - Start up postmaster (perform pgpool_remote_start) + Port number to be recovered (Pgpool-II 4.1 or after) - - + + - Node attach + Hostname of the main (primary) node + (Pgpool-II 4.3 or after) - - - - - - There is a restriction in the online recovery in - . If - Pgpool-II itself is installed - on multiple hosts, online recovery does not work correctly, - because Pgpool-II has to stop all - the clients during the 2nd stage of online recovery. - If there are several Pgpool-II hosts, - only one of them will have received the online recovery command and will - block the connections from clients. - - - - - - recovery_user (string) - - recovery_user configuration parameter - - - - Specifies the PostgreSQL user name to perform online recovery. + Before the hostname of the main (primary) node was obtained by + using hostname command. This is mostly ok + since the script runs on the main (primary) node + anyway. However in some systems the hostname obtained + by hostname command is different from the + hostname defined in backend_hostname configuration parameter. + This could cause a trouble + in because it checks + connectivity between primary and standby node by + using host parameter + in primary_conninfo parameter, which is + generated + by recovery_1st_stage_command. Thus it is + strongly recommended to use this parameter instead of + using hostname command to obtain the + hostname of the primary node + in recovery_1st_stage_command. - - This parameter can be changed by reloading the Pgpool-II configurations. - - - + + - - recovery_password (string) - - recovery_password configuration parameter - - - - - Specifies the password for the PostgreSQL user name configured in - to perform online recovery. - - - If recovery_password is left blank Pgpool-II - will first try to get the password for from - file before using the empty password. - - - You can also specify AES256-CBC encrypted password in recovery_password field. - To specify the AES encrypted password, password string must be prefixed with - AES after encrypting (using aes-256-cbc algorithm) and - encoding to base64. - - - To specify the unencrypted clear text password, prefix the password string with - TEXT. For example if you want to set mypass as - a password, you should specify TEXTmypass in the password field. - In the absence of a valid prefix, Pgpool-II will considered - the string as a plain text password. - - - You can also use utility to create the correctly formatted - AES encrypted password strings. - - - Pgpool-II will require a valid decryption key at the - startup to use the encrypted passwords. - see for more details on providing the - decryption key to Pgpool-II - - - + + + Pgpool-II accept connections and queries + while recovery_1st_stage command is executed, + so you can retrieve and update data. + + - - This parameter can be changed by reloading the Pgpool-II configurations. - - - + + + recovery_1st_stage command runs as a SQL + command from PostgreSQL's point of view. So recovery_1st_stage command + can get prematurely killed by PostgreSQL if the PostgreSQL's + statement_time_out is configured with the value that is + smaller than the time recovery_1st_stage_command takes for + completion. + + + Typical error in such case is + + rsync used in the command is killed by signal 2 for example. + + + - - recovery_1st_stage_command (string) - - recovery_1st_stage_command configuration parameter - - - - - Specifies a command to be run by master (primary) node at the - first stage of online recovery. The command file must be placed in the - database cluster directory for security reasons. - For example, if recovery_1st_stage_command = - 'sync-command', then Pgpool-II will - look for the command scrit in $PGDATA directory and will - try to execute $PGDATA/sync-command. - - - recovery_1st_stage_command receives following 5 parameters: - - - - - - Path to the database cluster of the master (primary) node. - - - - - Hostname of the backend node to be recovered. - - - - - Path to the database cluster of the node to be recovered. - - - - - Port number of the master (primary) node (Pgpool-II 3.4 or after). - - - - - Node number to be recovered (Pgpool-II 4.0 or after) - - - - - - - Pgpool-II accept connections and queries - while recovery_1st_stage command is executed, - so you can retrieve and update data. - - - - - - recovery_1st_stage command runs as a SQL - command from PostgreSQL's point of view. So recovery_1st_stage command - can get prematuraly killed by PostgreSQL if the PostgreSQL's - statement_time_out is configured with the value that is - smaller than the time recovery_1st_stage_command takes for - completion. - - - Typical error in such case is - -rsync used in the command is killed by signal 2 for example. - - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - + + This parameter can be changed by reloading the Pgpool-II configurations. + + + - - recovery_2nd_stage_command (string) - - recovery_2nd_stage_command configuration parameter - - - + + recovery_2nd_stage_command (string) + + recovery_2nd_stage_command configuration parameter + + + - - Specifies a command to be run by master node at the second - stage of online recovery. This parameter only neccessary for - . The command file must - be placed in the database cluster directory for security - reasons. For example, - if recovery_2nd_stage_command = - 'sync-command', - then Pgpool-II will look for the - command scrit in $PGDATA directory and - will try to execute $PGDATA/sync-command. - - - recovery_2nd_stage_command receives following 5 parameters: - + + Specifies a command to be run by main node at the second + stage of online recovery. This command is required only + , so for other modes don't need + to provide a command file. The command file must be placed in the + database cluster directory for security reasons. + For example, if recovery_2nd_stage_command = + 'sync-command', then Pgpool-II will + look for the command script in $PGDATA directory and will + try to execute $PGDATA/sync-command. + + + recovery_2nd_stage_command receives following 7 parameters: + - - - - Path to the database cluster of the master(primary) node. - - - - - Hostname of the backend node to be recovered. - - - - - Path to the database cluster of the node to be recovered. - - - - - Port number of the master (primary) node (Pgpool-II 3.4 or after). - - - - - Node number to be recovered (Pgpool-II 4.0 or after) - - - + + + + Path to the database cluster of the main(primary) node. + + + + + Hostname of the backend node to be recovered. + + + + + Path to the database cluster of the node to be recovered. + + + + + Port number of the main (primary) node (Pgpool-II 3.4 or after). + + + + + Node number to be recovered (Pgpool-II 4.0 or after) + + + + + Port number to be recovered (Pgpool-II 4.1 or after) + + + + + Hostname of the main (primary) node + (Pgpool-II 4.3 or after) + + + - - - Pgpool-II does not - accept client connections and queries during the execution - of recovery_2nd_stage_command command, and waits - for the existing clients to close their connections before executing the - command. - Therefore, the recovery_2nd_stage_command may not execute - if the client stays connected for a long time. - - + + + Pgpool-II does not + accept client connections and queries during the execution + of recovery_2nd_stage_command command, and waits + for the existing clients to close their connections before executing the + command. + Therefore, the recovery_2nd_stage_command may not execute + if the client stays connected for a long time. + + - - - recovery_2nd_stage command runs as a SQL - command from PostgreSQL's point of view. Therefore, recovery_2nd_stage command - can get prematuraly killed by PostgreSQL if the PostgreSQL's - statement_time_out is configured with the value that is - smaller than the time recovery_2nd_stage_command takes for - completion. - - + + + recovery_2nd_stage command runs as a SQL + command from PostgreSQL's point of view. Therefore, recovery_2nd_stage command + can get prematurely killed by PostgreSQL if the PostgreSQL's + statement_time_out is configured with the value that is + smaller than the time recovery_2nd_stage_command takes for + completion. + + - - This parameter can be changed by reloading the Pgpool-II configurations. - - - + + This parameter can be changed by reloading the Pgpool-II configurations. + + + - - recovery_timeout (integer) - - recovery_timeout configuration parameter - - - - - Specifies the timeout in seconds to cancel the online recovery if it - does not completes within this time. - Since Pgpool-II does not accepts the connections - during the second stage of online recovery, this parameter can be used to cancel - the online recovery to manage the service down time during the online recovery. - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - + + recovery_timeout (integer) + + recovery_timeout configuration parameter + + + + + Specifies the timeout in seconds to cancel the online recovery if it + does not completes within this time. + Since Pgpool-II does not accepts the connections + during the second stage of online recovery, this parameter can be used to cancel + the online recovery to manage the service down time during the online recovery. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + - - client_idle_limit_in_recovery (integer) - - client_idle_limit_in_recovery configuration parameter - - - - - Specifies the time in seconds to disconnect a client if it remains idle - since the last query during the online recovery. - client_idle_limit_in_recovery is similar to the - but only takes effect during the - second stage of online recovery. - - - This is useful for preventing the Pgpool-II - recovery from being disturbed by the lazy clients or if the TCP/IP - connection between the client and Pgpool-II - is accidentally down (a cut cable for instance). - + + client_idle_limit_in_recovery (integer) + + client_idle_limit_in_recovery configuration parameter + + + + + Specifies the time in seconds to disconnect a client if it remains idle + since the last query during the online recovery. + client_idle_limit_in_recovery is similar to the + but only takes effect during the + second stage of online recovery. + + + This is useful for preventing the Pgpool-II + recovery from being disturbed by the lazy clients or if the TCP/IP + connection between the client and Pgpool-II + is accidentally down (a cut cable for instance). + - - - client_idle_limit_in_recovery must be smaller than - . - Otherwise, comes - first and you will see following error while executing online recovery: - -ERROR: node recovery failed, waiting connection closed in the other pgpools timeout - - - + + + client_idle_limit_in_recovery must be smaller than + . + Otherwise, comes + first and you will see following error while executing online recovery: + + ERROR: node recovery failed, waiting connection closed in the other pgpools timeout + + + - - If set to -1, all clients get immediately disconnected when the second - stage of online recovery starts. - The default is 0, which turns off the feature. - + + If set to -1, all clients get immediately disconnected when the second + stage of online recovery starts. + The default is 0, which turns off the feature. + - - This parameter can be changed by reloading the Pgpool-II configurations. - You can also use command to alter the value of - this parameter for a current session. - - - + + This parameter can be changed by reloading the Pgpool-II configurations. + You can also use command to alter the value of + this parameter for a current session. + + + - + diff --git a/doc/src/sgml/performance.sgml b/doc/src/sgml/performance.sgml new file mode 100644 index 000000000..be9f0c72f --- /dev/null +++ b/doc/src/sgml/performance.sgml @@ -0,0 +1,384 @@ + + + + Performance Considerations + + + performance + of the server + + + + There are number of configuration parameters that affect the + performance of + Pgpool-II. In this chapter we present + how to tune them. + + + + Resource Requirement + + + Pgpool-II does not consume too much + resource. However there are minimum requirements for + resource. In this section we are going to explain one by one. + + + + Memory Requirement + + + There are two types of memory usage + in Pgpool-II: shared memory and + process private memory. The former is allocated at the startup + of Pgpool-II main server process + and will not be freed until + whole Pgpool-II servers shut down. + The latter is allocated within + each Pgpool-II child process and + will be freed at the end of the process. + + + + Shared Memory Requirement + + + Here is a formula to calculate the shared memory requirement. + + Shared memory requirement (in mega bytes) = 10 + * * 0.02 + + For example if you have num_init_children = 32 (the default) and max_pool = 4 (the + default), then you will need 10 + 32 * 4 * 0.02 = 12.6 MB. + + + + If you plan to use in memory query cache + (see for more + details) in the shared memory, you will need more RAM for + it. See + and + for required RAM + size. + + + + Note that, however, in Pgpool-II 4.1 + or after, even if the in memory query cache is not enabled, it + consumes additional 128MB of shared memory, if is enabled (it is enabled + by default). + + + + + Process Memory Requirement + + + Here is a formula to calculate the process memory requirement. + + Process memory requirement in total (in mega bytes) = * 0.16 + + For example if you have num_init_children = 32 + (the default), you will need 5.2MB. Please note that this is + minimum memory requirement + upon Pgpool-II child process starting + up. Once the process runs, it will consume more memory depending + on the message packet sizes and other factors. It is recommended + to measure the amount of memory actually used by the process + before starting production use. + + + + + + Disk Requirement + + Pgpool-II does not consume much + disk space. Also it does not require high speed disk because + disk I/O traffic caused + by Pgpool-II is small. However, + if you plan to emit much logs, of course you need disk space + for them. + + + + + + Managing Client Connections + + As the number of client connections accepted is growing, the + number of Pgpool-II child process + which can accept new connections from client is decreasing and + finally reaches to 0. In this situation new clients need to wait + until a child process becomes free. Under heavy load, it could + be possible that the queue length of waiting clients is getting + longer and longer and finally hits the system's limit (you might + see "535 times the listen queue of a socket overflowed" + error"). In this case you need to increase the queue + limit. There are several ways to deal with this problem. + + + + Controlling num_init_children + + The obvious way to deal with the problem is increasing the + number of child process. This can be done by + tweaking . However + increasing child process requires more CPU and memory + resource. Also you have to be very careful about + max_connections parameter + of PostgreSQL because once the + number of child process is greater than + max_connections, PostgreSQL refuses + to accept new connections, and failover will be triggered. + + + Another drawback of increasing num_init_children is, so called + "thundering herd problem". When new connection request comes + in, the kernel wake up any sleeping child process to issue + accept() system call. This triggers fight of process to get + the socket and could give heavy load to the system. To + mitigate the problem, you could set serialize_accept to on so + that there's only one process to grab the accepting socket. + However notice that the performance may be dropped when the number + of concurrent clients is small. + + + In Pgpool-II 4.4 or later, it is + possible to use for + more efficient management. By + setting process-management-mode + to dynamic, when the number of concurrent + clients is small, the number of child process + of Pgpool-II can be decreased thus we + can save the resource consumption. On the other hand when the + number of concurrent clients gets larger, the number of child + process increases so that it can respond to the more demand of + connections. However, notice that the time for connection + establishment could be increasing because new process need to be + started to have more child process. + + + See also for + understanding process-management-mode. + + + + + Controlling listen_backlog_multiplier + + Another solution would be increasing the connection request + queue. This could be done by + increasing . + + + + + When to use reserved_connections + + However, none of above solutions guarantees that the + connection accepting the queue would not be filled up. If a + client connection request arrives quicker than the rate of + processing queries, the queue will be filled in someday. For + example, if there are some heavy queries that take long time, + it could easily trigger the problem. + + + The solution is + setting so that + overflowed connection requests are rejected + as PostgreSQL already does. This + gives visible errors to applications ("Sorry max_connections + already") and force them retrying. So the solution should only + be used when you cannot foresee the upper limit of system + load. + + + + + + + Read Query Load Balancing + + If there are multiple PostgreSQL + nodes and Pgpool-II operates in + streaming replication mode, logical replication mode, + or replication mode (for those running mode + see for more details), it is + possible to distribute read queries among those database nodes + to get more throughput since each database nodes processes + smaller number of queries. To enable the feature you need to + turn on . + + + + At this point vast majority of systems use streaming replication + mode, so from now on we focus on the mode. + + + + Session Level Load Balancing vs. Statement Level Load Balancing + + By default load balance mode is "session level" which means + the node read queries are sent is determined when a client + connects to Pgpool-II. For example, + if we have node 0 and node 1, one of the node is selected + randomly each time new session is created. In the long term, + the possibility which node is chosen will be getting closer to + the ratio specified by 0 + and + 1. If those two values are + equal, the chance each node is chosen will be even. + + + + On the other hand, if + is set to + on, the load balance node is determined at the time each query + starts. This is useful in case that application has its own + connection pooling which keeps on connecting + to Pgpool-II and the load balance + node will not be changed once the application starts. Another + use case is a batch application. It issues tremendous number + of queries but there's only 1 session. With statement level + load balancing it can utilize multiple servers. + + + + + Creating Specific Purpose Database Node + + In OLAP environment sometimes it is desirable to have a large + read-only database for specific purpose. By creating such a + database is possible by creating a replica database using + streaming replication. In this case it is possible to redirect + read queries to the database in two ways: specifying database + names(s) or specifying application name(s). For former, + use . For + latter use . + + + + + + + In Memory Query Caching + + Pgpool-II allows to cache read query + results for later use. This will bring huge benefit for a type + of applications which issue same read queries many times. If + there are two queries and the query strings (parameter for + prepared statements if any) are identical, two queries are + regarded as "same". For the first time the query is + sent, Pgpool-II saves the query + result, and use it for the second query without asking anything + to PostgreSQL. This technique is + explained in . + + + + When not to Use in Memory Query Caching + + When a table is modified, query results against the table + could be changed. To avoid + inconsistency, Pgpool-II discards + query cache data when corresponding table is modified. So + frequently updated database will not be suitable to use in + memory query caching. You can check if your database is + suitable to use query caching or not, you could + use . If query cache hit + ration is lower than 70%, probably you want to avoid using the + query cache. + + + + + + Relation Cache + + Except in raw mode (see ) + or is set to off, + sometimes Pgpool-II needs to + ask PostgreSQL to get meta + information, such as whether a table is a temporary one or + not. To get those + information, Pgpool-II sends queries + primary PostgreSQL which could be up + to as many as 10 queries (in 4.1 or after, the number of queries + has been decreased, it is not zero, however). To reduce the + overhead, Pgpool-II maintains + "relation cache". Next time same table is included in a + query, Pgpool-II extracts the + information from the cache. + + + There are some parameters to configure the relation + cache. See , , , + for more details. + + + + Shared Relation Cache + + The relation cache basically lives in process private memory, + which is bound to a process. So even if a relation cache is + created to for a table, in different process the relation + cache might not be created yet. After all, until a relation + cache entry is created in all process, queries continue to + sent to PostgreSQL. + Pgpool-II 4.1 overcomes the issue + by creating relation cache in shared memory. If a session + creates a relation cache entry in the shared memory, other + sessions will get the cache result by looking at the shared + relation + cache. See + configuration parameter section for more details. This feature + is pretty effective and we recommend this feature be enabled. + + + + + + Other Performance Considerations + + This section introduces some other performance considerations. + + + + Thundering Herd Problem + + If is large, it is + possible that many Pgpool-II process + are woke up and heavy context switching happens. This leads to + high system load and hurt the overall system performance. This + problem is called "the thundering herd + problem". Enabling could + solve the problem. Please note that for + smaller , + might make the system performance worse. Please take a look at + the guidance in section. + + + + + Disaster recovery settings + + To create a disaster recovery setting, it is possible to deploy a + Pgpool-II plus + PostgreSQL primary server, and another + Pgpool-II plus standby + PostgreSQL server in a geographically + distant place. Clients close to the standby server send read only + queries to the Pgpool-II, being close + to the standby server. However, since standby + Pgpool-II sends internal queries to + system catalog of primary PostgreSQL + server, query performance may be getting worse. To avoid the + problem, it is possible to use so that such queries are sent + to the standby. See for + more details. + + + + diff --git a/doc/src/sgml/pgpool.sgml b/doc/src/sgml/pgpool.sgml index 2aae0768a..23bf1925f 100644 --- a/doc/src/sgml/pgpool.sgml +++ b/doc/src/sgml/pgpool.sgml @@ -12,7 +12,7 @@ ]> - + pgpool-II &version; Documentation @@ -36,7 +36,6 @@ &start; - &advanced; @@ -52,72 +51,42 @@ &installation; &runtime; + &advanced; &config; - &connection-settings; - &connection-pooling; - &loadbalance; - &healthcheck; - &failover; - &online-recovery; - &stream-check; - &memcache; - &ssl; - &watchdog; - &misc-config; - &config-last; + &connection-settings; + &connection-pooling; + &loadbalance; + &healthcheck; + &failover; + &online-recovery; + &stream-check; + &memcache; + &ssl; + &watchdog; + &misc-config; + &config-last; &client-auth; + &performance; &examples; &reference; - - Appendixes - + something... - + &release; + &biblio; ]]> diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml index 4b9897a07..7127cb553 100644 --- a/doc/src/sgml/ref/allfiles.sgml +++ b/doc/src/sgml/ref/allfiles.sgml @@ -1,12 +1,13 @@ + @@ -16,23 +17,32 @@ Complete list of usable sgml source files in this directory. + + + + - + + + + + + diff --git a/doc/src/sgml/ref/pcp_attach_node.sgml b/doc/src/sgml/ref/pcp_attach_node.sgml index 5c8de7a6e..ef0a3396e 100644 --- a/doc/src/sgml/ref/pcp_attach_node.sgml +++ b/doc/src/sgml/ref/pcp_attach_node.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_attach_node - attaches the given node to Pgpool-II. + attaches the given node to Pgpool-II. @@ -31,37 +31,37 @@ Pgpool-II documentation Description - pcp_attach_node - attaches the given node to Pgpool-II. + pcp_attach_node + attaches the given node to Pgpool-II. Options - - + + - - - - - - The index of backend node to attach. - - - + + + + + + The index of backend node to attach. + + + - - - - - See . - - - + + + + + See . + + + - - + + diff --git a/doc/src/sgml/ref/pcp_common_options.sgml b/doc/src/sgml/ref/pcp_common_options.sgml index 431632bc8..05889f54d 100644 --- a/doc/src/sgml/ref/pcp_common_options.sgml +++ b/doc/src/sgml/ref/pcp_common_options.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_common_options - common options used in PCP commands + common options used in PCP commands @@ -32,114 +32,114 @@ Pgpool-II documentation Description - There are some arguments common to all PCP commands. Most of - these are for authentication and the rest are about verbose - mode, debug message, and so on. + There are some arguments common to all PCP commands. Most of + these are for authentication and the rest are about verbose + mode, debug message, and so on.
Options - - - - - - - - - The host name of the machine on which the server is running. If the - value begins with a slash, it is used as the directory for the Unix-domain socket. - - - - - - - - - - The PCP port number (default:"9898"). - - - - - - - - - - The user name for PCP authentication (default: OS user name). - - - - - - - - - - Never prompt for password. And if a password is not available - by a .pcppass file, the connection - attempt will fail. This option can be useful in batch jobs - and scripts where no user is present to enter a password. - - - - - - - - - - Force password prompt (should happen automatically). - - - - - - - - - - Enable debug message. - - - - - - - - - - Enable verbose output. - - - - - - - - - - Print the command version, then exit. - - - - - - - - - - Shows help for the command line arguments, then exit. - - - - - - + + + + + + + + + The host name of the machine on which the server is running. If the + value begins with a slash, it is used as the directory for the Unix-domain socket. + + + + + + + + + + The PCP port number (default:"9898"). + + + + + + + + + + The user name for PCP authentication (default: OS user name). + + + + + + + + + + Never prompt for password (should happen automatically). And if a password is not available + by a .pcppass file, the connection + attempt will fail. This option can be useful in batch jobs + and scripts where no user is present to enter a password. + + + + + + + + + + Force password prompt. + + + + + + + + + + Enable debug message. + + + + + + + + + + Enable verbose output. + + + + + + + + + + Print the command version, then exit. + + + + + + + + + + Shows help for the command line arguments, then exit. + + + + + + diff --git a/doc/src/sgml/ref/pcp_detach_node.sgml b/doc/src/sgml/ref/pcp_detach_node.sgml index 5234e25ea..94aee6de0 100644 --- a/doc/src/sgml/ref/pcp_detach_node.sgml +++ b/doc/src/sgml/ref/pcp_detach_node.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_detach_node - detaches the given node from Pgpool-II. Exisiting connections to Pgpool-II are forced to be disconnected. + detaches the given node from Pgpool-II. Existing connections to Pgpool-II are forced to be disconnected. @@ -32,47 +32,65 @@ Pgpool-II documentation Description - pcp_detach_node - detaches the given node from Pgpool-II. Exisiting connections to Pgpool-II are forced to be disconnected. + pcp_detach_node detaches the given node from + Pgpool-II. If and/or are specified, they are + executed too. Existing connections to + Pgpool-II are forced to be disconnected. + + + pcp_detach_node just detaches the node, and does + not touch running backend behind the node. This command is useful + when admin needs to maintain the + PostgreSQL node. He/she can shutdown or + stop the backend as many times as he/she wants. + + + The safest way to re-attach the detached node is, stopping the + backend and apply . However if + you are sure that there's no replication delay (or the delay will + be recovered later on) and the role of the node (primary/standby) + will not be changed, you can use . Options - - + + - - - - - - The index of backend node to detach. - - - + + + + + + The index of backend node to detach. + + + - - - - - - wait until all clients are disconnected (unless client_idle_limit_in_recovery is -1 or recovery_timeout is expired). - - - + + + + + + wait until all clients are disconnected (unless client_idle_limit_in_recovery is -1 or recovery_timeout is expired). + + + - - - - - See . - - - + + + + + See . + + + - - + + diff --git a/doc/src/sgml/ref/pcp_health_check_stats.sgml b/doc/src/sgml/ref/pcp_health_check_stats.sgml new file mode 100644 index 000000000..824b6341d --- /dev/null +++ b/doc/src/sgml/ref/pcp_health_check_stats.sgml @@ -0,0 +1,102 @@ + + + + + pcp_health_check_stats + + + + pcp_health_check_stats + 1 + PCP Command + + + + pcp_health_check_stats + + displays health check statistics data on given node ID + + + + + pcp_health_check_stats + option + node_id + + + + + Description + + pcp_health_check_stats + displays health check statistics data on given node ID. + + + + + Options + + + + + + + + + The index of backend node to get information of. + + + + + + + + + See . + + + + + + + + + Example + + Here is an example output: + +$ pcp_health_check_stats -h localhost -p 11001 -w 0 +0 /tmp 11002 up primary 2020-02-24 22:02:42 3 3 0 0 0 0.000000 0 5 1 3.666667 2020-02-24 22:02:47 2020-02-24 22:02:47 +$ pcp_health_check_stats -h localhost -p 11001 -w -v 0 +Node Id : 0 +Host Name : /tmp +Port : 11002 +Status : up +Role : primary +Last Status Change : 2020-02-24 22:02:42 +Total Count : 5 +Success Count : 5 +Fail Count : 0 +Skip Count : 0 +Retry Count : 0 +Average Retry Count : 0.000000 +Max Retry Count : 0 +Max Health Check Duration : 5 +Minimum Health Check Duration : 1 +Average Health Check Duration : 4.200000 +Last Health Check : 2020-02-24 22:03:07 +Last Successful Health Check : 2020-02-24 22:03:07 +Last Skip Health Check : +Last Failed Health Check : + + + + + See for details of data. + + + + diff --git a/doc/src/sgml/ref/pcp_invalidate_query_cache.sgml b/doc/src/sgml/ref/pcp_invalidate_query_cache.sgml new file mode 100644 index 000000000..6e8882140 --- /dev/null +++ b/doc/src/sgml/ref/pcp_invalidate_query_cache.sgml @@ -0,0 +1,66 @@ + + + + + pcp_invalidate_query_cache + + + + pcp_invalidate_query_cache + 1 + PCP Command + + + + pcp_invalidate_query_cache + + invalidate query cache contents + + + + + pcp_invalidate_query_cache + options + + + + + Description + + pcp_invalidate_query_cache places a query cache + invalidation request on the shared memory area. The request is + processed by one of Pgpool-II child + process, which corresponds to each pgpool client session, when a + message from the client is processed. This means that if there's no + client connecting to Pgpool-II, or + all clients are sitting idle, the request will not be + processed until next message arrives. + + + Although this command does not modifies the statistics data shown by + , part of the statistics data + is affected since this command invalidate the contents of query + cache. num_cache_hits + and num_selects continue to increase after the + query cache + invalidated. used_hash_entries, num_cache_entries + and used_cache_entries_size starts off with + 0. free_cache_entries_size will increase. + + + If + is false, this command emits an error and exits. + + + + + Options + + See . + + + + diff --git a/doc/src/sgml/ref/pcp_log_rotate.sgml b/doc/src/sgml/ref/pcp_log_rotate.sgml new file mode 100644 index 000000000..be1ecbe7b --- /dev/null +++ b/doc/src/sgml/ref/pcp_log_rotate.sgml @@ -0,0 +1,73 @@ + + + + + pcp_log_rotate + + + + pcp_log_rotate + 1 + PCP Command + + + + pcp_log_rotate + + rotates the Pgpool-II's log file + + + + + pcp_log_rotate + options + + + + + Description + + pcp_log_rotate + rotates the Pgpool-II's log file. + + + + + Options + + + + + + + + + Specifies the breadth of a command's impact. + + + The supported command scopes are as follows (The default is "local"): + + c, cluster : rotates the Pgpool-II's log files of all Pgpool-II nodes part of the cluster + l, local : rotates the Pgpool-II's log file of local Pgpool-II node only + + + + + + + + + + See . + + + + + + + + + diff --git a/doc/src/sgml/ref/pcp_node_count.sgml b/doc/src/sgml/ref/pcp_node_count.sgml index 6e07ad34d..1625634dd 100644 --- a/doc/src/sgml/ref/pcp_node_count.sgml +++ b/doc/src/sgml/ref/pcp_node_count.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_node_count - displays the total number of database nodes + displays the total number of database nodes @@ -32,28 +32,28 @@ Pgpool-II documentation Description - pcp_node_count - displays the total number of database nodes defined in pgpool.conf. It does - not distinguish between nodes status, ie attached/detached. ALL nodes are counted. + pcp_node_count + displays the total number of database nodes defined in pgpool.conf. It does + not distinguish between nodes status, ie attached/detached. ALL nodes are counted.
Options - - See . - + + See . + Example - - Here is an example output: - -$ pcp_node_count -p 11001 -Password: -2 - - + + Here is an example output: + + $ pcp_node_count -p 11001 + Password: + 2 + + diff --git a/doc/src/sgml/ref/pcp_node_info.sgml b/doc/src/sgml/ref/pcp_node_info.sgml index 06cae4a3e..c6a568699 100644 --- a/doc/src/sgml/ref/pcp_node_info.sgml +++ b/doc/src/sgml/ref/pcp_node_info.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_node_info - displays the information on the given node ID + displays the information on the given node ID @@ -31,86 +31,211 @@ Pgpool-II documentation Description - pcp_node_info - displays the information on the given node ID. + pcp_node_info + displays the information on the given node ID. Options - - + + + + + + + + + The index of backend node to get information of. + + + - - - - - - The index of backend node to get information of. - - - + + + + + + Display all backend nodes information. + + + - - - - - See . - - - - - + + + + + See . + + + + + Example - - Here is an example output: - -$ pcp_node_info -h localhost -U postgres 1 -/tmp 11003 2 0.500000 up standby 208 2018-07-03 08:26:39 - + + Here is an example output: + +$ pcp_node_info -w -p 11001 -n 1 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 + - The result is in the following order: - + The result is in the following order: + 1. hostname 2. port number 3. status 4. load balance weight 5. status name -6. backend role -7. replication delay -8. last status change time - +6. actual backend status (obtained using PQpingParams. Pgpool-II 4.3 or later) +7. backend role +8. actual backend role (obtained using pg_is_in_recovery. Pgpool-II 4.3 or later) +9. replication delay +10. replication state (taken from pg_stat_replication. Pgpool-II 4.1 or later) +11. sync replication state (taken from pg_stat_replication. Pgpool-II 4.1 or later) +12. last status change time + + + + 3 (status) is represented by a digit from [0 to 3]. + + 0 - This state is only used during the initialization. PCP will never display it. + 1 - Node is up. No connections yet. + 2 - Node is up. Connections are pooled. + 3 - Node is down. + + + + 4 (load balance weight) is displayed in normalized format (0 - 1). + + + 5 (status name) indicates the status of a + PostgreSQL node as recognized by + Pgpool-II. It corresponds to the numeric value + shown in "3 (status)" and represents the node's internal state + in a human-readable format maintained by Pgpool-II. - Status is represented by a digit from [0 to 3]. - - 0 - This state is only used during the initialization. PCP will never display it. - 1 - Node is up. No connections yet. - 2 - Node is up. Connections are pooled. - 3 - Node is down. - + 6 (actual backend status) shows the backend status in real time. The info is obtained by + calling PQpingParams at the time when the + command is invoked. PQpingParams is only + available in PostgreSQL 9.1 or later. If + Pgpool-II was built with + PostgreSQL 9.0 or earlier, the column + shows "unknown". Also + if health check + is disabled, it shows "unknown". + When a backend node is detached by , the status managed by + Pgpool-II will be "down", while the + actual backend status is "up". Thus it is possible that 5 does not + match with 6. However it should not happen that 5 is "up" while 6 + is "down". - The load balance weight is displayed in normalized format. + 7 (backend role) indicates the role of a PostgreSQL + node (primary or standby) from the perspective of + Pgpool-II, based on its internally maintained + information. - The option can help understand the output. For example: + 8 (actual backend role) shows the backend status in real time. The result will be either + "primary" or "standby", and possibly "unknown" if information + retrieval failed. Since Pgpool-II + searches backend nodes in the node id order and assumes the last + found node is primary, it is possible that 7 does not match 8 when + there are multiple nodes that are not standby by erroneous + operations (this command is useful to find such that situation). + In other than streaming replication mode, the status will be either + "main" or "replica". Unlike streaming replication mode + pg_is_in_recovery is not called and value for + 7 and 8 will be always the same. + + + To correctly display 9, 10 and 11, + must not be 0. + Additionally, to correctly display 10 and 11, the following + settings are required. + + + + must be configured. + + + The value set for each backend_application_nameX + must match the value specified in application_name + of primary_conninfo for the corresponding node. + + + In particular, when creating standby nodes using Pgpool-II's + command and community-provided + sample scripts, please ensure that the value of + backend_application_nameX matches that of + backend_hostnameX. For specific configuration examples, + please refer to . + + + + + must either be a + PostgreSQL superuser or have been granted the + privileges of the pg_monitor role. + + + + + + To grant the privileges of the pg_monitor role to + , execute following SQL command + by PostgreSQL super user (replace + "sr_check_user" with the setting of ): + +GRANT pg_monitor TO sr_check_user; + + For PostgreSQL 9.6, there's no + pg_monitor group and must + be PostgreSQL super user. + + + + + + From Pgpool-II 4.4, 9 (replication + delay) is displayed in either bytes or + seconds. See for more + details. + + + + The or option lists all backend nodes information. + + +$ pcp_node_info -w -p 11001 -a +/tmp 11002 1 0.500000 waiting up primary primary 0 none none 2021-02-27 14:51:30 +/tmp 11003 1 0.500000 waiting up standby standby 0 streaming async 2021-02-27 14:51:30 + + + + The option can help understand the output. For example: - -$ pcp_node_info --verbose -h localhost -U postgres 1 -Hostname : /tmp -Port : 11003 -Status : 2 -Weight : 0.500000 -Status Name : up -Role : standby -Replication Delay : 208 -Last Status Change: 2018-07-03 08:26:39 - + +$ pcp_node_info -w -p 11001 --verbose 1 +Hostname : /tmp +Port : 11003 +Status : 1 +Weight : 0.500000 +Status Name : waiting +Backend Status Name : up +Role : standby +Backend Role : standby +Replication Delay : 0 +Replication State : streaming +Replication Sync State : async +Last Status Change : 2021-02-27 14:51:30 + diff --git a/doc/src/sgml/ref/pcp_pool_status.sgml b/doc/src/sgml/ref/pcp_pool_status.sgml index 30d542544..05b40e156 100644 --- a/doc/src/sgml/ref/pcp_pool_status.sgml +++ b/doc/src/sgml/ref/pcp_pool_status.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_pool_status - displays the parameter values as defined in pgpool.conf + displays the parameter values as defined in pgpool.conf @@ -30,40 +30,40 @@ Pgpool-II documentation Description - pcp_pool_status - displays the parameter values as defined in pgpool.conf. + pcp_pool_status + displays the parameter values as defined in pgpool.conf. Options - - See . - + + See . + Example - - Here is an example output: - -$ pcp_pool_status -h localhost -U postgres -name : listen_addresses -value: localhost -desc : host name(s) or IP address(es) to listen to + + Here is an example output: + + $ pcp_pool_status -h localhost -U postgres + name : listen_addresses + value: localhost + desc : host name(s) or IP address(es) to listen to -name : port -value: 9999 -desc : pgpool accepting port number + name : port + value: 9999 + desc : pgpool accepting port number -name : socket_dir -value: /tmp -desc : pgpool socket directory + name : socket_dir + value: /tmp + desc : pgpool socket directory -name : pcp_port -value: 9898 -desc : PCP port # to bind - + name : pcp_port + value: 9898 + desc : PCP port # to bind + diff --git a/doc/src/sgml/ref/pcp_proc_count.sgml b/doc/src/sgml/ref/pcp_proc_count.sgml index 0880ebf6f..c81d45bff 100644 --- a/doc/src/sgml/ref/pcp_proc_count.sgml +++ b/doc/src/sgml/ref/pcp_proc_count.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_proc_count - displays the list of Pgpool-II children process IDs + displays the list of Pgpool-II children process IDs @@ -30,16 +30,16 @@ Pgpool-II documentation Description - pcp_proc_count - displays the list of Pgpool-II children process IDs. If there is more than one process, IDs will be delimited by a white space. + pcp_proc_count + displays the list of Pgpool-II children process IDs. If there is more than one process, IDs will be delimited by a white space. Options - - See . - + + See . + diff --git a/doc/src/sgml/ref/pcp_proc_info.sgml b/doc/src/sgml/ref/pcp_proc_info.sgml index 1365142fd..9a433da4f 100644 --- a/doc/src/sgml/ref/pcp_proc_info.sgml +++ b/doc/src/sgml/ref/pcp_proc_info.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_proc_info - displays the information on the given Pgpool-II child process ID + displays the information on the given Pgpool-II child process ID @@ -31,113 +31,187 @@ Pgpool-II documentation Description - pcp_proc_info - displays the information on the given Pgpool-II child process ID. + pcp_proc_info + displays the information on the given Pgpool-II child process ID. Options - - + + - - - - - - Display all child processes and their available connection slots. - - - + + + + + + Display all child processes and their available connection slots. + + + - - - - - - PID of Pgpool-II child process. - - - + + + + + + PID of Pgpool-II child process. + + + - - - - - See . - - - - + + + + + See . + + + + - If -a nor -P is not specified, process information of all - connected Pgpool-II child process will - be printed. In this case if there's no - connected Pgpool-II child process, - nothing but "No process information available" message will be - printed. - + If -a nor -P is not specified, process information of all + connected Pgpool-II child process will + be printed. In this case if there's no + connected Pgpool-II child process, + nothing but "No process information available" message will be + printed. + Example - - Here is an example output: - -$ pcp_proc_info -p 11001 1406 -test t-ishii 2018-07-09 16:43:53 2018-07-09 16:44:08 3 0 1 1435 1 1406 0 -test t-ishii 2018-07-09 16:43:53 2018-07-09 16:44:08 3 0 1 1436 1 1406 1 - + + Here is an example output: + +$ pcp_proc_info -p 11001 +test t-ishii 2025-06-24 10:53:35 0 3 0 2025-06-24 10:55:58 2025-06-24 10:55:59 0 1 1336703 1 1336537 0 Idle 0 192.168.10.11 39216 +test t-ishii 2025-06-24 10:53:35 0 3 0 2025-06-24 10:55:58 2025-06-24 10:55:59 0 1 1336704 1 1336537 1 Idle 1 192.168.10.11 39216 +test t-ishii 2025-06-24 10:53:35 (4:03 before process restarting) 1 3 0 2025-06-24 10:53:42 2025-06-24 10:53:42 0 2025-06-24 10:55:37 1 1336573 0 1336544 0 Wait for connection 0 192.168.10.11 39162 +test t-ishii 2025-06-24 10:53:35 (4:03 before process restarting) 1 3 0 2025-06-24 10:53:42 2025-06-24 10:53:42 0 2025-06-24 10:55:37 1 1336574 0 1336544 1 Wait for connection 0 192.168.10.11 39162 + - The result is in the following order: - -1. connected database name -2. connected user name -3. process start-up timestamp -4. connection created timestamp -5. protocol major version -6. protocol minor version -7. connection-reuse counter -8. PostgreSQL backend process id -9. 1 if frontend conncted 0 if not -10. pgpool child process id -11. PostgreSQL backend id - + The result is in the following order: + + 1. connected database name + 2. connected user name + 3. process start-up timestamp (If is set not 0, the time before process restarting is displayed.) + 4. process-reuse counter for + 5. protocol major version + 6. protocol minor version + 7. connection created timestamp + 8. last client connected timestamp + 9. client idle duration (sec) (If is set not 0, the time before client disconnected is displayed.) + 10. last client disconnected timestamp + 11. connection-reuse counter + 12. PostgreSQL backend process id + 13. 1 if frontend connected 0 if not + 14. pgpool child process id + 15. PostgreSQL backend id + 16. process status + 17. 1 if backend is load balance node and frontend connected, 0 otherwise + 18. client's host name + 19. client's port number (not shown if Unix domain socket or localhost) + 20. SQL statement last executed + - If there is no connection to the backends, nothing will be displayed. - If there are multiple connections, one connection's information will be displayed on each line multiple times. + If -a or --all option is not specified and + there is no connection to the backends, nothing will be displayed. If there are + multiple connections, one connection's information will be displayed on each + line multiple times. Timestamps are displayed in EPOCH format. - The option can help understand the output. For example: + The option can help understand the output. For example: - -$ pcp_proc_info -p 11001 --verbose 1406 -Database : test -Username : t-ishii -Start time : 2018-07-09 16:43:53 -Creation time: 2018-07-09 16:44:08 -Major : 3 -Minor : 0 -Counter : 1 -Backend PID : 1435 -Connected : 1 -PID : 1406 -Backend ID : 0 -Database : test -Username : t-ishii -Start time : 2018-07-09 16:43:53 -Creation time: 2018-07-09 16:44:08 -Major : 3 -Minor : 0 -Counter : 1 -Backend PID : 1436 -Connected : 1 -PID : 1406 -Backend ID : 1 - + +$ pcp_proc_info -p 11001 --verbose +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 +Client connection count : 0 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:55:58 +Client connection time : 2025-06-24 10:55:59 +Client idle duration : 0 +Client disconnection time : +Pool Counter : 1 +Backend PID : 1336703 +Connected : 1 +PID : 1336537 +Backend ID : 0 +Status : Idle +Load balance node : 0 +client_host : 192.168.10.11 +client_port : 39216 +statement : + +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 +Client connection count : 0 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:55:58 +Client connection time : 2025-06-24 10:55:59 +Client idle duration : 0 +Client disconnection time : +Pool Counter : 1 +Backend PID : 1336704 +Connected : 1 +PID : 1336537 +Backend ID : 1 +Status : Idle +Load balance node : 1 +client_host : 192.168.10.11 +client_port : 39216 +statement : select 1; + +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 (4:33 before process restarting) +Client connection count : 1 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:53:42 +Client connection time : 2025-06-24 10:53:42 +Client idle duration : 0 +Client disconnection time : 2025-06-24 10:55:37 +Pool Counter : 1 +Backend PID : 1336573 +Connected : 0 +PID : 1336544 +Backend ID : 0 +Status : Wait for connection +Load balance node : 0 +client_host : 192.168.10.11 +client_port : 39162 +statement : DISCARD ALL + +Database : test +Username : t-ishii +Start time : 2025-06-24 10:53:35 (4:33 before process restarting) +Client connection count : 1 +Major : 3 +Minor : 0 +Backend connection time : 2025-06-24 10:53:42 +Client connection time : 2025-06-24 10:53:42 +Client idle duration : 0 +Client disconnection time : 2025-06-24 10:55:37 +Pool Counter : 1 +Backend PID : 1336574 +Connected : 0 +PID : 1336544 +Backend ID : 1 +Status : Wait for connection +Load balance node : 0 +client_host : 192.168.10.11 +client_port : 39162 +statement : + diff --git a/doc/src/sgml/ref/pcp_promote_node.sgml b/doc/src/sgml/ref/pcp_promote_node.sgml index 5f804fa51..e6d5bb6b6 100644 --- a/doc/src/sgml/ref/pcp_promote_node.sgml +++ b/doc/src/sgml/ref/pcp_promote_node.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_promote_node - promotes the given node as new master to Pgpool-II + promotes the given node as new main to Pgpool-II @@ -26,53 +26,172 @@ Pgpool-II documentation options node_id gracefully + switchover Description - pcp_promote_node - promotes the given node as new master to Pgpool-II. In master/slave streaming replication only. Please note that this command does not actually promote standby PostgreSQL backend: it just changes the internal status of Pgpool-II and trigger failover and users have to promote standby PostgreSQL outside Pgpool-II. + pcp_promote_node promotes the given node as new + primary to Pgpool-II. In streaming + replication mode only. Please note that this command does not + actually promote standby PostgreSQL + backend unless switchover option is specified: + it just changes the internal status of + Pgpool-II and trigger failover and users + have to promote standby PostgreSQL + outside Pgpool-II. + + + If switchover is specified, + Pgpool-II detaches current primary + (changes the internal status to down) and execute the , with the new main node argument to + be set to the specified node id. Because most failover scripts + promote the new main node, the specified node will be the new + primary node. The is + necessary to be set properly to turn the former primary into + standby. + + + + pcp_promote_node executes followings if + switchover is not specified. Please be + warned that if is set, + the command will be executed. It is a standard advice that you + disable before + executing this command. + + + + + + Change the status of standby + PostgreSQL from standby to + primary. It just changes the internal status of + Pgpool-II and it does not actually + promote PostgreSQL standby server. + + + + + + Change the status of PostgreSQL node + which is not specified by this command's argument to down. It + just changes the internal status of + Pgpool-II and it does not actually + make PostgreSQL standby server down. + + + + + + If is set, execute + against + PostgreSQL. + + + + + + + + pcp_promote_node executes followings if + switchover is specified. If is set, the command will be + executed. You need to set before executing this command + because failover script will create the new primary and other nodes + need to be turned into standbys + + + + + + Change the status of primary + PostgreSQL from up to down. This + triggers execution, with + the new main node argument to be set to the specified node + id. Because most failover scripts promote the new main node, the + specified node will become the new primary node. + + + + + + Change the status of standby + PostgreSQL node which is not + specified by this command's argument to down. It just changes + the internal status of Pgpool-II and + it does not actually make PostgreSQL + standby server down. + + + + + + If is set, execute + against + PostgreSQL. + + + + + + Options - - - - - - - - - The index of backend node to promote as new master. - - - - - - - - - - Wait until all clients are disconnected (unless client_idle_limit_in_recovery is -1 or recovery_timeout is expired). - - - - - - - - - See . - - - - - - + + + + + + + + + The index of backend node to promote as new main. + The specified node must be in "up" or "waiting" status. + + + + + + + + + + Wait until all clients are disconnected (unless client_idle_limit_in_recovery is -1 or recovery_timeout is expired). + + + + + + + + + + Let the specified node to be actually promoted by triggering + the . Also change the + current primary node status to down. + + + + + + + + + See . + + + + + + diff --git a/doc/src/sgml/ref/pcp_recovery_node.sgml b/doc/src/sgml/ref/pcp_recovery_node.sgml index a52f1bc1b..5916467a2 100644 --- a/doc/src/sgml/ref/pcp_recovery_node.sgml +++ b/doc/src/sgml/ref/pcp_recovery_node.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_recovery_node - attaches the given backend node with recovery + attaches the given backend node with recovery @@ -31,38 +31,38 @@ Pgpool-II documentation Description - pcp_recovery_node - attaches the given backend node with recovery. - See to set up necessary parameters of pgpool.conf. + pcp_recovery_node + attaches the given backend node with recovery. + See to set up necessary parameters of pgpool.conf. Options - - + + - - - - - - The index of backend node. - - - + + + + + + The index of backend node. + + + - - - - - See . - - - + + + + + See . + + + - - + + diff --git a/doc/src/sgml/ref/pcp_reload_config.sgml b/doc/src/sgml/ref/pcp_reload_config.sgml new file mode 100644 index 000000000..c21ed81c1 --- /dev/null +++ b/doc/src/sgml/ref/pcp_reload_config.sgml @@ -0,0 +1,73 @@ + + + + + pcp_reload_config + + + + pcp_reload_config + 1 + PCP Command + + + + pcp_reload_config + + reload pgpool-II config file + + + + + pcp_reload_config + options + + + + + Description + + pcp_reload_config + reload Pgpool-II config file. + + + + + Options + + + + + + + + + Specifies the breadth of a command's impact. + + + The supported command scopes are as follows (The default is "local"): + + c, cluster : reload config files of all Pgpool-II nodes part of the cluster + l, local : reload config file of local Pgpool-II node only + + + + + + + + + + See . + + + + + + + + + diff --git a/doc/src/sgml/ref/pcp_stop_pgpool.sgml b/doc/src/sgml/ref/pcp_stop_pgpool.sgml index f9f10551a..a9e9dc29f 100644 --- a/doc/src/sgml/ref/pcp_stop_pgpool.sgml +++ b/doc/src/sgml/ref/pcp_stop_pgpool.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_stop_pgpool - terminates the Pgpool-II process + terminates the Pgpool-II process @@ -31,45 +31,63 @@ Pgpool-II documentation Description - pcp_stop_pgpool - terminates the Pgpool-II process. + pcp_stop_pgpool + terminates the Pgpool-II process. Options - - + + - - - - - - Shutdown mode for terminating the Pgpool-II process. - - - The available modes are as follows: - - s, smart : smart mode - f, fast : fast mode - i, immediate : immediate mode - - - - + + + + + + Shutdown mode for terminating the Pgpool-II process. + + + The available modes are as follows (The default is "smart"): + + s, smart : smart mode + f, fast : fast mode + i, immediate : immediate mode + + Regarding the meaning of each mode, please refer to manual. + + + - - - - - See . - - - + + + + + + Specifies the breadth of a command's impact. + + + The supported command scopes are as follows (The default is "local"): + + c, cluster : terminates all Pgpool-II nodes part of the cluster + l, local : terminates local Pgpool-II node only + + + + - - + + + + + See . + + + + + + diff --git a/doc/src/sgml/ref/pcp_watchdog_info.sgml b/doc/src/sgml/ref/pcp_watchdog_info.sgml index 1eda9887f..81da9a651 100644 --- a/doc/src/sgml/ref/pcp_watchdog_info.sgml +++ b/doc/src/sgml/ref/pcp_watchdog_info.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pcp_watchdog_info - displays the watchdog status of the Pgpool-II + displays the watchdog status of the Pgpool-II @@ -31,122 +31,134 @@ Pgpool-II documentation Description - pcp_node_info - displays the information on the given node ID. + pcp_watchdog_info + displays the information on the given node ID. Options - - - - - - - - - The index of other Pgpool-II to get information for. - - - Index 0 gets one's self watchdog information. - - - If ommitted then gets information of all watchdog nodes. - - - - - - - - - See . - - - - - + + + + + + + + + The index of other Pgpool-II to get information for. + + + Index 0 gets one's self watchdog information. + + + If omitted then gets information of all watchdog nodes. + + + + + + + + + See . + + + + + Example - - Here is an example output: - -$ pcp_watchdog_info -h localhost -U postgres - -3 NO Linux_host1.localdomain_9991 host1 - -Linux_host1.localdomain_9991 host1 9991 9001 7 STANDBY -Linux_host2.localdomain_9992 host2 9992 9002 4 MASTER -Linux_host3.localdomain_9993 host3 9993 9003 7 STANDBY - + + Here is an example output: + +$ pcp_watchdog_info -h localhost -p 9898 -U postgres +Password: +3 3 YES server1:9999 Linux server1.localdomain server1 + +server1:9999 Linux server1.localdomain server1 9999 9000 4 LEADER 0 MEMBER YES +server2:9999 Linux server2.localdomain server2 9999 9000 7 STANDBY 0 MEMBER YES +server3:9999 Linux server3.localdomain server3 9999 9000 7 STANDBY 0 MEMBER YES + - The result is in the following order: - -The first output line describes the watchdog cluster information: - -1. Total watchdog nodes in the cluster -2. Is VIP is up on current node? -3. Master node name -4. Master node host - - -Next is the list of watchdog nodes: - -1. node name -2. hostname -3. pgpool port -4. watchdog port -5. current node state -6. current node state name - + The result is in the following order: + + The first output line describes the watchdog cluster information: + + 1. Total watchdog nodes in the cluster + 2. Total watchdog nodes in the cluster with active membership + 3. Local node's escalation status + 4. Leader node name + 5. Leader node host + + + Next is the list of watchdog nodes: + + 1. node name + 2. hostname + 3. pgpool port + 4. watchdog port + 5. current node state + 6. current node state name + 7. current cluster membership status + 8. current cluster membership status name + 9. Lifecheck start status + - The option can help understand the output. For example: + The option can help understand the output. For example: - -$ pcp_watchdog_info -h localhost -v -U postgres - -Watchdog Cluster Information -Total Nodes : 3 -Remote Nodes : 2 -Quorum state : QUORUM EXIST -Alive Remote Nodes : 2 -VIP up on local node : NO -Master Node Name : Linux_host2.localdomain_9992 -Master Host Name : localhost - -Watchdog Node Information -Node Name : Linux_host1.localdomain_9991 -Host Name : host1 -Delegate IP : 192.168.1.10 -Pgpool port : 9991 -Watchdog port : 9001 -Node priority : 1 -Status : 7 -Status Name : STANDBY - -Node Name : Linux_host2.localdomain_9992 -Host Name : host2 -Delegate IP : 192.168.1.10 -Pgpool port : 9992 -Watchdog port : 9002 -Node priority : 1 -Status : 4 -Status Name : MASTER - -Node Name : Linux_host3.localdomain_9993 -Host Name : host3 -Delegate IP : 192.168.1.10 -Pgpool port : 9993 -Watchdog port : 9003 -Node priority : 1 -Status : 7 -Status Name : STANDBY - + +$ pcp_watchdog_info -h localhost -p 9898 -U pgpool -v +Password: +Watchdog Cluster Information +Total Nodes : 3 +Remote Nodes : 2 +Member Remote Nodes : 2 +Alive Remote Nodes : 2 +Nodes required for quorum: 2 +Quorum state : QUORUM EXIST +Local node escalation : YES +Leader Node Name : server1:9999 Linux server1.localdomain +Leader Host Name : server1 + +Watchdog Node Information +Node Name : server1:9999 Linux server1.localdomain +Host Name : server1 +Delegate IP : 192.168.56.150 +Pgpool port : 9999 +Watchdog port : 9000 +Node priority : 1 +Status : 4 +Status Name : LEADER +Membership Status : MEMBER +Lifecheck Started : YES + +Node Name : server2:9999 Linux server2.localdomain +Host Name : server2 +Delegate IP : 192.168.56.150 +Pgpool port : 9999 +Watchdog port : 9000 +Node priority : 1 +Status : 7 +Status Name : STANDBY +Membership Status : MEMBER +Lifecheck Started : YES + +Node Name : server3:9999 Linux server3.localdomain +Host Name : server3 +Delegate IP : 192.168.56.150 +Pgpool port : 9999 +Watchdog port : 9000 +Node priority : 1 +Status : 7 +Status Name : STANDBY +Membership Status : MEMBER +Lifecheck Started : YES + diff --git a/doc/src/sgml/ref/pg_enc.sgml b/doc/src/sgml/ref/pg_enc.sgml index d639b7366..48be6bb91 100644 --- a/doc/src/sgml/ref/pg_enc.sgml +++ b/doc/src/sgml/ref/pg_enc.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pg_enc - AES256 password encryption utility + AES256 password encryption utility @@ -37,129 +37,171 @@ Pgpool-II documentation Description - pg_enc - AES256 password encryption utility. + pg_enc + AES256 password encryption utility. Options - - - - - - - - - Set the path to the encryption key file. Default is the .pgpoolkey file - located in the users home directory. - - - - - - - - - - Encryption key to be used for encrypting database passwords. - - - - - - - - - - Specifies the pgpool.conf file. - - - - - - - - - - Prompt for database password using standard input. - - - - - - - - - - Prompt for encryption key using standard input. - - - - - - - - - - Create encrypted password entry in the pool_passwd file. - - - - - - - - - - Creates the pool_passwd entry for the database user called - your_username. - - - - - - - - - - Prints the help for pg_enc. - - - - - - + + + + + + + + + Set the path to the encryption key file. Default is the .pgpoolkey file + located in the users home directory, which can be overridden by the environment variable PGPOOLKEYFILE. + + + + + + + + + + Encryption key to be used for encrypting database passwords. + + + + + + + + + + Specifies the pgpool.conf file. + + + + + + + + + + Specifies file containing username and password pairs. + + + + + + + + + + Prompt for database password using standard input. + + + + + + + + + + Prompt for encryption key using standard input. + + + + + + + + + + Create encrypted password entry in the pool_passwd file. + + + + + + + + + + Creates the pool_passwd entry for the database user called + your_username. + + + + + + + + + + Prints the help for pg_enc. + + + + + + + + If you are providing the password as an argument to pg_enc and the password contains a "$" character, + you must escape it. + + + For example, if you want to use "ABC$123" as password, + +pg_enc -m -f /path/to/pgpool.conf -u username ABC\$123 + + + + Example - - Here is an example output: - -pg_enc -p -db password: [your password] - + + Here is an example output: + + pg_enc -p + db password: [your password] + - or + or -./pg_enc foo -trying to read key from file /home/pgpool/.pgpoolkey + ./pg_enc foo + trying to read key from file /home/pgpool/.pgpoolkey -jglid1QRgiCl/vfhHUDyVA== -pool_passwd string: AESjglid1QRgiCl/vfhHUDyVA== + jglid1QRgiCl/vfhHUDyVA== + pool_passwd string: AESjglid1QRgiCl/vfhHUDyVA== - pg_enc can be used for pool_passwd passwords with: - -pg_enc -m -f /path/to/pgpool.conf -u username -p -db password: [your password] - - which will add an entry for username with the password given. + pg_enc can be used for pool_passwd passwords with: + + pg_enc -m -f /path/to/pgpool.conf -u username -p + db password: [your password] + + which will add an entry for username with the password given. + + To avoid password prompt or password in command parameter, + pg_enc can read user name:password pairs from file. + It will add all user names and encrypted password to + authentication file. + + $ cat users.txt + username1:secretpassword1 + username2:secretpassword2 + + $ pg_enc -m -f /path/to/pgpool.conf -i users.txt + trying to read key from file /home/pgpool/.pgpoolkey + trying to read user:password pairs from file users.text + + $ cat /path/to/pool_passwd + username1:AESrx5QdpGyW/+4CB80KWtwhg== + username2:AESUAdohy7nCUhWliRI9WiYQA== + + + diff --git a/doc/src/sgml/ref/pg_md5.sgml b/doc/src/sgml/ref/pg_md5.sgml index 5b1050275..73353fb3d 100644 --- a/doc/src/sgml/ref/pg_md5.sgml +++ b/doc/src/sgml/ref/pg_md5.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pg_md5 - produces encrypted password in md5 + produces encrypted password in md5 @@ -36,88 +36,125 @@ Pgpool-II documentation Description - pg_md5 - produces encrypted password in md5. + pg_md5 + produces encrypted password in md5. Options - - - - - - - - - Prompt password using standard input. - - - - - - - - - - Produce md5 authentication password to authentication file pool_passwd. - - - - - - - - - - When producing a md5 authentication password, create the pool_passwd entry for your_username. - - - - - - - - - - Specify the path to the pgpool.conf configuration file. - - - - - - + + + + + + + + + Prompt password using standard input. + + + + + + + + + + Produce md5 authentication password to authentication file pool_passwd. + + + + + + + + + + When producing a md5 authentication password, create the pool_passwd entry for your_username. + + + + + + + + + + Specify the path to the pgpool.conf configuration file. + + + + + + + + + + Specifies file containing user name and password pairs. + + + + + + Example - - The following are examples to encrypt your password into md5 hash format for pcp.conf. - + + The following are examples to encrypt your password into md5 hash format for pcp.conf. + $ pg_md5 -p password: [your password] - + - or + or - + $ pg_md5 [your password] acbd18db4cc2f85cedef654fccc4a4d8 - + - - pg_md5 can also be used for adding an entry of user name and - md5 encrypted password to - authentication file. - -$pg_md5 -m -f /path/to/pgpool.conf -u username -p + + pg_md5 can also be used for adding an entry of user name and + md5 encrypted password to + authentication file. + +$ pg_md5 -m -f /path/to/pgpool.conf -u username -p password: [your password] $ cat /path/to/pool_passwd username:md55a231fcdb710d73268c4f44283487ba2 - - + + + To avoid password prompt or password in command parameter, + pg_md5 can read user name:password pairs from file. + It will add all user names and md5 hashed password to + authentication file. + +$ cat users.txt +username1:secretpassword1 +username2:secretpassword2 + +$ pg_md5 -m -f /path/to/pgpool.conf -i users.txt +trying to read username:password pairs from file users.txt + +$ cat /path/to/pool_passwd +username1:md533314126ba0b187df1e37f5ce6a489a8 +username2:md58ae92c6e1d6a48d80e2583fe715e2b36 + + + To just display the md5 hashed string, not adding an entry to , pass a string concatenating password and user name. + For example, if password is "password" and user name is "user", the output would be: + +$ pg_md5 passworduser +4d45974e13472b5a0be3533de4666414 + + Please note that the actual entry to be inserted into + should have "md5" on top of the + result string. That is: "md54d45974e13472b5a0be3533de4666414". + diff --git a/doc/src/sgml/ref/pgpool.sgml b/doc/src/sgml/ref/pgpool.sgml index d06a7b34d..d65674e20 100644 --- a/doc/src/sgml/ref/pgpool.sgml +++ b/doc/src/sgml/ref/pgpool.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pgpool - Pgpool-II main server + Pgpool-II main server @@ -42,80 +42,80 @@ Pgpool-II documentation Description - the Pgpool-II main server + the Pgpool-II main server Usages - pgpool runs in 3 modes: start, stop and reload. - If none of stop or reload is given, it is assumed that "start" is specified. + pgpool runs in 3 modes: start, stop and reload. + If none of stop or reload is given, it is assumed that "start" is specified. Common options - These are common options for 3 modes. - - - - - - - - - Set the path to the pool_hba.conf configuration file. - Mandatory if the file is placed other than the standard location. - - - - - - - - - - Set the path to the pgpool.conf configuration file. - Mandatory if the file is placed other than the standard location. - - - - - - - - - - Set the path to the pcp.conf configuration file. - Mandatory if the file is placed other than the standard location. - - - - - - - - - - Set the path to the .pgpoolkey file. - Mandatory if you use AES256 encrypted password and the file is placed other than the standard locatiaon and used. - - - - - - - - - - Print help. - - - - - + These are common options for 3 modes. + + + + + + + + + Set the path to the pool_hba.conf configuration file. + Mandatory if the file is placed other than the standard location. + + + + + + + + + + Set the path to the pgpool.conf configuration file. + Mandatory if the file is placed other than the standard location. + + + + + + + + + + Set the path to the pcp.conf configuration file. + Mandatory if the file is placed other than the standard location. + + + + + + + + + + Set the path to the .pgpoolkey file. + Mandatory if you use AES256 encrypted password and the file is placed other than the standard location and used. + + + + + + + + + + Print help. + + + + + @@ -123,114 +123,123 @@ Pgpool-II documentation Starting <productname>Pgpool-II</productname> main server - - Here are options for the start mode. - - - - - - - - - Run Pgpool-II in debug mode. - Lots of debug messages are produced. - - - - - - - - - - Don't run in daemon mode, does not detach control ttys. - - - - - - - - - - Turns on various assertion checks, This is a debugging aid. - - - - - - - - - - Clear query cache oidmaps when is - memcached. - - - If memqcache_method - is shmem, Pgpool-II - always discards oidmaps at the start-up time. So this option - is not necessary. - - - - - - - - + + Here are options for the start mode. + + + + + + + + + Run Pgpool-II in debug mode. + Lots of debug messages are produced. + + + + + + + + + + Don't run in daemon mode, does not detach control ttys. + + + + + + + + + + Turns on various assertion checks, This is a debugging aid. + + + + + + + + + + Clear query cache oidmaps when is + memcached. + + + If memqcache_method + is shmem, Pgpool-II + always discards oidmaps at the start-up time. So this option + is not necessary. + + + + + + + + + + Discard pgpool_status file and do not + restore previous status. + + - Discard pgpool_status file and do not - restore previous status. + This option is testing purpose only for developers and you + should not use it for other purposes. + If pgpool_status is accidentally + removed, Pgpool-II may go into + split-brain (there are multiple primary servers exist). - - - - + + + + + Stopping <productname>Pgpool-II</productname> main server - - Here are options for the stop mode. - - - - - - - - - Stop Pgpool-II. - shutdown_mode is - either smart, fast - or immediate. If smart - is specified, Pgpool-II will wait - for all clients are disconnected. If fast - or immediate are - specified, Pgpool-II immediately - stops itself without waiting for all clients are - disconnected. There's no difference - between fast - and immediate in the current - implementation. - - - - - - + + Here are options for the stop mode. + + + + + + + + + Stop Pgpool-II. + shutdown_mode is + either smart, fast + or immediate. If smart + is specified, Pgpool-II will wait + for all clients are disconnected. If fast + or immediate are + specified, Pgpool-II immediately + stops itself without waiting for all clients are + disconnected. There's no difference + between fast + and immediate in the current + implementation. + + + + + + - Reloading <productname>Pgpool-II</productname> configuration files - - Reload configuration file - of Pgpool-II. No specific options - exist for realod mode. Common options are applicable. - + Reloading <productname>Pgpool-II</productname> configuration files + + Reload configuration file + of Pgpool-II. No specific options + exist for reload mode. Common options are applicable. + diff --git a/doc/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml b/doc/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml index ffdf0d132..c8cbf7611 100644 --- a/doc/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml +++ b/doc/src/sgml/ref/pgpool_adm_pcp_attach_node.sgml @@ -17,85 +17,85 @@ Pgpool-II documentation pgpool_adm_pcp_attach_node - a function to attach given node ID + a function to attach given node ID - - - pcp_attach_node returns record - integer node_id - text host - integer port - text username - text password - out node_attached boolean - + + + pcp_attach_node returns record + integer node_id + text host + integer port + text username + text password + out node_attached boolean + - - pcp_attach_node returns record - integer node_id - text pcp_server - out node_attached boolean - + + pcp_attach_node returns record + integer node_id + text pcp_server + out node_attached boolean + - + Description - pcp_attach_node attaches a node - to Pgpool-II. + pcp_attach_node attaches a node + to Pgpool-II. Arguments - - + + - - node_id - - - The index of backend node to attach. - - - + + node_id + + + The index of backend node to attach. + + + - - pcp_server - - - The foreign server name for pcp server. - - - + + pcp_server + + + The foreign server name for pcp server. + + + - - - - - See . - - - - - + + + + + See . + + + + + Example - - Here is an example output: - -test=# SELECT * FROM pcp_attach_node(1,'localhost',11001,'t-ishii','t-ishii'); - node_attached ---------------- - t -(1 row) - + + Here is an example output: + + test=# SELECT * FROM pcp_attach_node(node_id => 1, host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + node_attached + --------------- + t + (1 row) + diff --git a/doc/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml b/doc/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml index 97bf70027..103dc5d2b 100644 --- a/doc/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml +++ b/doc/src/sgml/ref/pgpool_adm_pcp_detach_node.sgml @@ -17,97 +17,97 @@ Pgpool-II documentation pgpool_adm_pcp_detach_node - a function to detach given node ID + a function to detach given node ID - - - pcp_detach_node returns record - integer node_id - boolean gracefully - text host - integer port - text username - text password - out node_detached boolean - + + + pcp_detach_node returns record + integer node_id + boolean gracefully + text host + integer port + text username + text password + out node_detached boolean + - - pcp_detach_node returns record - integer node_id - boolean gracefully - text pcp_server - out node_detached boolean - + + pcp_detach_node returns record + integer node_id + boolean gracefully + text pcp_server + out node_detached boolean + - + Description - pcp_detach_node detaches a node - from Pgpool-II. + pcp_detach_node detaches a node + from Pgpool-II. Arguments - - + + - - node_id - - - The index of backend node to detach. - - - + + node_id + + + The index of backend node to detach. + + + - - gracefully - - - If true, wait for all session - of pgpool-II terminates. - - - + + gracefully + + + If true, wait for all session + of pgpool-II terminates. + + + - - pcp_server - - - The foreign server name for pcp server. - - - + + pcp_server + + + The foreign server name for pcp server. + + + - - - - - See . - - - - - + + + + + See . + + + + + Example - - Here is an example output: - -test=# SELECT * FROM pcp_detach_node(1, 'false', 'localhost',11001,'t-ishii','t-ishii'); - node_detached ---------------- - t -(1 row) - + + Here is an example output: + + test=# SELECT * FROM pcp_detach_node(node_id => 1, gracefully => 'false', host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + node_detached + --------------- + t + (1 row) + diff --git a/doc/src/sgml/ref/pgpool_adm_pcp_health_check_stats.sgml b/doc/src/sgml/ref/pgpool_adm_pcp_health_check_stats.sgml new file mode 100644 index 000000000..2edc5b228 --- /dev/null +++ b/doc/src/sgml/ref/pgpool_adm_pcp_health_check_stats.sgml @@ -0,0 +1,162 @@ + + + + + pgpool_adm_pcp_health_check_stats + + + + pgpool_adm_pcp_health_check_stats + 3 + pgpool_adm extension + + + + pgpool_adm_pcp_health_check_stats + + a function to display health check statistics data on given node ID + + + + + + pcp_health_check_stats returns record + integer node_id + text host + integer port + text username + text password + out node_id integer + out host text + out port integer + out status text + out role text + out last_status_change timestamp + out total_count bigint + out success_count bigint + out fail_count bigint + out skip_count bigint + out retry_count bigint + out average_retry_count bigint + out max_retry_count bigint + out max_health_check_duration bigint + out min_health_check_duration bigint + out average_health_check_duration float4 + out last_health_check timestamp + out last_successful_health_check timestamp + out last_skip_health_check timestamp + out last_failed_health_check timestamp + + + + pcp_health_check_stats returns record + integer node_id + text pcp_server + out node_id integer + out host text + out port integer + out status text + out role text + out last_status_change timestamp + out total_count bigint + out success_count bigint + out fail_count bigint + out skip_count bigint + out retry_count bigint + out average_retry_count bigint + out max_retry_count bigint + out max_health_check_duration bigint + out min_health_check_duration bigint + out average_health_check_duration float4 + out last_health_check timestamp + out last_successful_health_check timestamp + out last_skip_health_check timestamp + out last_failed_health_check timestamp + + + + + + + Description + + pcp_health_check_stats + displays health check statistics data on given node ID. + + + + + Arguments + + + + + node_id + + + The index of backend node to get information of. + + + + + + pcp_server + + + The foreign server name for pcp server. + + + + + + + + + See . + + + + + + + + + Example + + Here is an example output: + +test=# select * from pcp_health_check_stats(node_id => 0, host => '', port => 11001, username => 't-ishii', password => 't-ishii'); +-[ RECORD 1 ]-----------------+-------------------- +node_id | 0 +host | /tmp +port | 11002 +status | up +role | primary +last_status_change | 2020-02-25 16:05:29 +total_count | 3 +success_count | 3 +fail_count | 0 +skip_count | 0 +retry_count | 0 +average_retry_count | 0 +max_retry_count | 0 +max_health_check_duration | 5 +min_health_check_duration | 3 +average_health_check_duration | 4.333333 +last_health_check | 2020-02-25 16:05:47 +last_successful_health_check | 2020-02-25 16:05:47 +last_skip_health_check | +last_failed_health_check | + + + + + See for details of data. + + + + + diff --git a/doc/src/sgml/ref/pgpool_adm_pcp_node_count.sgml b/doc/src/sgml/ref/pgpool_adm_pcp_node_count.sgml index 11ec2f218..689713bf1 100644 --- a/doc/src/sgml/ref/pgpool_adm_pcp_node_count.sgml +++ b/doc/src/sgml/ref/pgpool_adm_pcp_node_count.sgml @@ -17,72 +17,72 @@ Pgpool-II documentation pgpool_adm_pcp_node_count - a function to retrieves number of backend nodes. + a function to retrieves number of backend nodes. - - - pcp_node_count returns integer - text host - integer port - text username - text password - + + + pcp_node_count returns integer + text host + integer port + text username + text password + - - pcp_node_count returns integer - text pcp_server - + + pcp_node_count returns integer + text pcp_server + - + Description - pcp_node_count retrieves number of DB nodes. + pcp_node_count retrieves number of DB nodes. Arguments - - + + - - pcp_server - - - The foreign server name for pcp server. - - - + + pcp_server + + + The foreign server name for pcp server. + + + - - - - - See . - - - - - + + + + + See . + + + + + Example - - Here is an example output: - -test=# SELECT * FROM pcp_node_count('localhost',11001,'t-ishii','t-ishii'); - node_count ------------- - 2 -(1 row) - + + Here is an example output: + + test=# SELECT * FROM pcp_node_count(host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + node_count + ------------ + 2 + (1 row) + diff --git a/doc/src/sgml/ref/pgpool_adm_pcp_node_info.sgml b/doc/src/sgml/ref/pgpool_adm_pcp_node_info.sgml index 2939b3ed7..e4e85cda0 100644 --- a/doc/src/sgml/ref/pgpool_adm_pcp_node_info.sgml +++ b/doc/src/sgml/ref/pgpool_adm_pcp_node_info.sgml @@ -17,107 +17,139 @@ Pgpool-II documentation pgpool_adm_pcp_node_info - a function to display the information on the given node - ID + a function to display the information on the given node + ID - - - pcp_node_info returns record - integer node_id - text host - integer port - text username - text password - out status text - out weight float4 - out role text - out replication_delay bigint - out last_status_change timestamp - - - - pcp_node_info returns record - integer node_id - text pcp_server - out status text - out weight float4 - out role text - out replication_delay bigint - out last_status_change timestamp - - - + + + pcp_node_info returns record + integer node_id + text host + integer port + text username + text password + out status text + out pg_status text + out weight float4 + out role text + out pg_role text + out replication_delay bigint + out replication_state text + out replication_sync_state text + out last_status_change timestamp + + + + pcp_node_info returns record + integer node_id + text pcp_server + out status text + out pg_status text + out weight float4 + out role text + out pg_role text + out replication_delay bigint + out replication_state text + out replication_sync_state text + out last_status_change timestamp + + + Description - pcp_node_info - displays the information on the given node ID. + pcp_node_info + displays the information on the given node ID. Arguments - - - - - node_id - - - The index of backend node to get information of. - - - - - - pcp_server - - - The foreign server name for pcp server. - - - - - - - - - See . - - - - - + + + + + node_id + + + The index of backend node to get information of. + + + + + + pcp_server + + + The foreign server name for pcp server. + + + + + + + + + See . + + + + + Example - - Here is an example output: - -test=# SELECT * FROM pcp_node_info(0,'',11001,'t-ishii','t-ishii'); - host | port | status | weight | role | replication_delay | last_status_change -------+-------+-------------------+--------+---------+-------------------+--------------------- - /tmp | 11002 | Connection in use | 0 | Primary | 0 | 2018-07-04 17:34:39 + + Here is an example output: + +test=# SELECT * FROM pcp_node_info(node_id => 1, host => '', port => 11001, username => 't-ishii', password => 't-ishii'); + host | port | status | pg_status | weight | role | pg_role | replication_delay | replication_state | replication_sync_state | last_status_change +------+-------+-------------------+-----------+--------+---------+---------+-------------------+-------------------+------------------------+--------------------- + /tmp | 11003 | Connection in use | up | 0.5 | Standby | standby | 0 | streaming | async | 2021-02-27 15:10:19 (1 row) - + - - role, replication_delay, last_status_change - out parameters are new - from Pgpool-II 4.0. If you have - already installed pre-4.0 pgpool_adm extension, you can upgrade - to the new one by using ALTER EXTENSION SQL command. - - ALTER EXTENSION pgpool_adm UPDATE; - - + + role, replication_delay, last_status_change + out parameters are new + from Pgpool-II 4.0. If you have + already installed pre-4.0 pgpool_adm extension, you can upgrade + to the new one by using ALTER EXTENSION SQL command. + + ALTER EXTENSION pgpool_adm UPDATE; + + + + + + + replication_state and replication_sync_state out parameters are new from Pgpool-II 4.1. If you have + already installed pre-4.1 pgpool_adm extension, you can upgrade + to the new one by using ALTER EXTENSION SQL command. + + ALTER EXTENSION pgpool_adm UPDATE; + + + + + + + pg_status, pg_role + out parameters are new from Pgpool-II + 4.3. If you have already installed pre-4.2 pgpool_adm extension, + you can upgrade to the new one by using ALTER EXTENSION SQL + command. + + ALTER EXTENSION pgpool_adm UPDATE; + + diff --git a/doc/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml b/doc/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml index 2a0107d00..0745f3ad6 100644 --- a/doc/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml +++ b/doc/src/sgml/ref/pgpool_adm_pcp_pool_status.sgml @@ -17,83 +17,83 @@ Pgpool-II documentation pgpool_adm_pcp_pool_status - a function to retrieves parameters in pgpool.conf. + a function to retrieves parameters in pgpool.conf. - - - pcp_pool_status returns record - text host - integer port - text username - text password - out item text - out value text - out description text - + + + pcp_pool_status returns setof record + text host + integer port + text username + text password + out item text + out value text + out description text + - - pcp_pool_status returns record - text pcp_server - out item text - out value text - out description text - + + pcp_pool_status returns setof record + text pcp_server + out item text + out value text + out description text + - + Description - pcp_pool_status retrieves parameters in - pgpool.conf. + pcp_pool_status retrieves parameters in + pgpool.conf. Arguments - - + + - - pcp_server - - - The foreign server name for pcp server. - - - + + pcp_server + + + The foreign server name for pcp server. + + + - - - - - See . - - - - - + + + + + See . + + + + + Example - - Here is an example output: - - test=# SELECT * FROM pcp_pool_status('localhost',11001,'t-ishii','t-ishii') WHERE item ~ 'backend.*0'; - item | value | description --------------------------+------------------------------------------------+------------------------------- - backend_hostname0 | /tmp | backend #0 hostname - backend_port0 | 11002 | backend #0 port number - backend_weight0 | 0.500000 | weight of backend #0 - backend_data_directory0 | /home/t-ishii/work/pgpool-II/current/aaa/data0 | data directory for backend #0 - backend_status0 | 2 | status of backend #0 - backend_flag0 | ALLOW_TO_FAILOVER | backend #0 flag -(6 rows) - + + Here is an example output: + + test=# SELECT * FROM pcp_pool_status(host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii') WHERE item ~ 'backend.*0'; + item | value | description + -------------------------+------------------------------------------------+------------------------------- + backend_hostname0 | /tmp | backend #0 hostname + backend_port0 | 11002 | backend #0 port number + backend_weight0 | 0.500000 | weight of backend #0 + backend_data_directory0 | /home/t-ishii/work/pgpool-II/current/aaa/data0 | data directory for backend #0 + backend_status0 | 2 | status of backend #0 + backend_flag0 | ALLOW_TO_FAILOVER | backend #0 flag + (6 rows) + diff --git a/doc/src/sgml/ref/pgpool_adm_pcp_proc_info.sgml b/doc/src/sgml/ref/pgpool_adm_pcp_proc_info.sgml new file mode 100644 index 000000000..4346e68fd --- /dev/null +++ b/doc/src/sgml/ref/pgpool_adm_pcp_proc_info.sgml @@ -0,0 +1,271 @@ + + + + + pgpool_adm_pcp_proc_info + + + + pgpool_adm_pcp_proc_info + 3 + pgpool_adm extension + + + + pgpool_adm_pcp_proc_info + + a function to display the information + on Pgpool-II child process + + + + + + + pcp_proc_info returns record + text host + integer port + text username + text password + out database text + out username text + out start_time text + out client_connection_count text + out major text + out minor text + out backend_connection_time text + out client_connection_time text + out client_idle_duration text + out client_disconnection_time text + out pool_counter text + out backend_pid text + out connected text + out pid text + out backend_id text + out status text + out load_balance_node text + out client_host text + out client_port text + out statement + + + + pcp_proc_info returns record + integer node_id + text pcp_server + out database text + out username text + out start_time text + out client_connection_count text + out major text + out minor text + out backend_connection_time text + out client_connection_time text + out client_idle_duration text + out client_disconnection_time text + out pool_counter text + out backend_pid text + out connected text + out pid text + out backend_id text + out status text + out load_balance_node text + out client_host text + out client_port text + out statement + + + + + + + Description + + pcp_proc_info + displays the information + on Pgpool-II child process. + All the information is same as . + All the data types are "text". + + + + + Arguments + + + + + pcp_server + + + The foreign server name for pcp server. + + + + + + + + + See . + + + + + + + + + Example + + In the example below a search condition "connected" column = '1' is + specified, and only the information on the process connected from + clients. In this psql session pcp_proc_info is called in the from + clause, and the information is shown on row 1 and 2. The select + statement is sent to only backend_id = '0' (which is probably the + primary), and the "status" column of the row 1 is "Execute + command", the "statement" column shows the select statement which + was executed. On the other hand the "statement" column of the row 2 + is empty, since the select statement is was not sent to backend_id + = '1'. + + + The information on the other psql session is shown on the row 2 and + 3. In this example "select 1" was sent to "backend_id" = '1' + (probably standby). + +test=# select * from pcp_proc_info(host => '', port => 11001, username => 't-ishii', password => 't-ishii') where connected = '1'; +-[ RECORD 1 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:37 +client_connection_time | 2025-02-22 20:58:37 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14750 +connected | 1 +pid | 14585 +backend_id | 0 +status | Execute command +load_balance_node | 1 +client_host | 127.0.0.1 +client_port | 59120 +statement | select * from pcp_proc_info(host => '', port => 11001, username => 't-ishii', password => 't-ishii') where connected = '1'; +-[ RECORD 2 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:37 +client_connection_time | 2025-02-22 20:58:37 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14751 +connected | 1 +pid | 14585 +backend_id | 1 +status | Execute command +load_balance_node | 0 +client_host | 127.0.0.1 +client_port | 59120 +statement | +-[ RECORD 3 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:56 +client_connection_time | 2025-02-22 20:58:56 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14767 +connected | 1 +pid | 14601 +backend_id | 0 +status | Idle +load_balance_node | 0 +client_host | 127.0.0.1 +client_port | 54072 +statement | +-[ RECORD 4 ]-------------+---------------------------------------------------------------------------------------------------------------------------- +database | test +username | t-ishii +start_time | 2025-02-22 20:56:08 +client_connection_count | 0 +major | 3 +minor | 0 +backend_connection_time | 2025-02-22 20:58:56 +client_connection_time | 2025-02-22 20:58:56 +client_idle_duration | 0 +client_disconnection_time | +pool_counter | 1 +backend_pid | 14768 +connected | 1 +pid | 14601 +backend_id | 1 +status | Idle +load_balance_node | 1 +client_host | 127.0.0.1 +client_port | 54072 +statement | select 1; + + + + In the example below we define a function called + "pgpool_query_info" which shows last executed query in each pgpool + child process along with associated information: usernae, database, + client host, client port, pgpool host, pgpool port, pgpool pid, + backend host, backend port, backend pid, backend role and SQL + statement, by joining pgpool_adm_pcp_proc_info, + pgpool_adm_pcp_node_info and pgpool_adm_pcp_pool_status. + +create function pgpool_query_info(pcp_host text, pcp_port int, pgpool_username text, password text) +returns table (username text, database text, client_host text, client_port text, +pgpool_host text, pgpool_port text, pgpool_pid text, +backend_host text, backend_port text, backend_pid text, backend_role text, statement text) as $$ +select p.username, p.database, p.client_host,p.client_port, +$1 as pgpool_host, s.value as pgpool_port, p.pid as pgpool_pid, +b.host as backend_host, b.port as backend_port, p.backend_pid as backend_pid, +b.role as backend_role, +p.statement +from pcp_proc_info(host=> $1, port => $2, username => $3, password => $4) as p, +pcp_node_info(node_id=>p.backend_id::int, host => $1, port => $2, +username => $3, password => $4) as b, +pcp_pool_status(host=> $1, port => $2, username => $3, password => $4) as s +where p.connected = 1::text and p.statement != '' and +p.statement !~ 'pcp_proc_info' and p.statement !~ 'pgpool_query_info' and +s.item = 'port' +$$ +language SQL; +CREATE FUNCTION + +select * from pgpool_query_info('192.168.10.11', 11001, 't-ishii', 't-ishii'); + username | database | client_host | client_port | pgpool_host | pgpool_port | pgpool_pid | backend_host | backend_port | backend_pid | backend_role | statement +----------+----------+---------------+-------------+---------------+-------------+------------+--------------+--------------+-------------+--------------+----------- + t-ishii | test | 192.168.10.11 | 60542 | 192.168.10.11 | 11000 | 1356156 | localhost | 11002 | 1356240 | Primary | select 2; + t-ishii | test | 192.168.10.11 | 43856 | 192.168.10.11 | 11000 | 1356167 | localhost | 11003 | 1356255 | Standby | select 1; +(2 rows) + + + + See for more information on each + shown data. + + + + + diff --git a/doc/src/sgml/ref/pgpool_reset.sgml b/doc/src/sgml/ref/pgpool_reset.sgml index 20dddb638..d6aec63a6 100644 --- a/doc/src/sgml/ref/pgpool_reset.sgml +++ b/doc/src/sgml/ref/pgpool_reset.sgml @@ -20,28 +20,28 @@ PostgreSQL documentation - -PGPOOL RESET configuration_parameter -PGPOOL RESET ALL - + + PGPOOL RESET configuration_parameter + PGPOOL RESET ALL + Description - PGPOOL RESET command restores the value of - Pgpool-II configuration parameters to - the default value. - The default value is defined as the value that the parameter would have had, - if no PGPOOL SET had ever been issued for it in the - current session. - - This command is similar to the - + PGPOOL RESET command restores the value of + Pgpool-II configuration parameters to + the default value. + The default value is defined as the value that the parameter would have had, + if no PGPOOL SET had ever been issued for it in the + current session. + + This command is similar to the + RESET command in PostgreSQL with an addition - of PGPOOL keyword to distinguish it from the - PostgreSQL RESET command. + of PGPOOL keyword to distinguish it from the + PostgreSQL RESET command. @@ -78,15 +78,15 @@ PGPOOL RESET ALL Reset the value of parameter: - -PGPOOL RESET client_idle_limit; - + + PGPOOL RESET client_idle_limit; + Reset the value of all parameter to default: - -PGPOOL RESET ALL; - + + PGPOOL RESET ALL; + diff --git a/doc/src/sgml/ref/pgpool_set.sgml b/doc/src/sgml/ref/pgpool_set.sgml index 4f082dad4..99e0372a8 100644 --- a/doc/src/sgml/ref/pgpool_set.sgml +++ b/doc/src/sgml/ref/pgpool_set.sgml @@ -20,9 +20,9 @@ PostgreSQL documentation - -PGPOOL SET configuration_parameter { TO | = } { value | 'value' | DEFAULT } - + + PGPOOL SET configuration_parameter { TO | = } { value | 'value' | DEFAULT } + @@ -33,46 +33,46 @@ PGPOOL SET configuration_parameter The PGPOOL SET command changes the value of Pgpool-II configuration parameters for the current session. - This command is similar to the - + This command is similar to the + SET command in PostgreSQL with an addition - of PGPOOL keyword to distinguish it from the - PostgreSQL SET command. - Many of the configuration parameters listed in + of PGPOOL keyword to distinguish it from the + PostgreSQL SET command. + Many of the configuration parameters listed in can be changed on-the-fly with - PGPOOL SET and it only affects the value used by the current - session. + PGPOOL SET and it only affects the value used by the current + session. - + Examples Change the value of parameter: -PGPOOL SET client_idle_limit = 350; + PGPOOL SET client_idle_limit = 350; Reset the value of parameter to default: -PGPOOL SET client_idle_limit TO DEFAULT; + PGPOOL SET client_idle_limit TO DEFAULT; Change the value of parameter: -PGPOOL SET log_min_messages TO INFO; + PGPOOL SET log_min_messages TO INFO; - + See Also diff --git a/doc/src/sgml/ref/pgpool_set_cache.sgml b/doc/src/sgml/ref/pgpool_set_cache.sgml new file mode 100644 index 000000000..8ae8d42f5 --- /dev/null +++ b/doc/src/sgml/ref/pgpool_set_cache.sgml @@ -0,0 +1,97 @@ + + + + + PGPOOL SET + + + + PGPOOL SET CACHE + 1 + SQL - Language Statements + + + + PGPOOL SET CACHE + delete query cache + + + + + PGPOOL SET CACHE DELETE 'query' + + + + + Description + + + The PGPOOL SET CACHE DELETE command deletes the + query cache + previously created by the query. The query string must be exactly + identical to the previous query, including + trailing ';'. Nevertheless if the query + includes ' (single quore), it needs to be + prefixed by ' like: + +PGPOOL SET CACHE DELETE 'SELECT ''FOO'';'; + + This command is particularly useful for queries that are not + invalidated by + the auto + cache invalidation feature because the query does not have + any reference to tables. + + + If you do not remember the previous query, you can + use to delete all the + query cache including the cache you want to delete. However it + requires the Pgpool-II admin privilege. + + + Upon successful deletion of the query cache, this command emits a + notice message: + +NOTICE: query cache deleted. query: "query string" + + If the cache does not exist or query cache is not enabled, it emits + a notice message: + +NOTICE: query cache does not exist for query: "query string" + + + + + + Examples + + + Accidentally created an unwanted query cache. Delete it by using + the command. + +test=# /*FORCE QUERY CACHE*/SELECT current_timestamp; + current_timestamp +------------------------------- + 2024-10-18 18:25:07.826423+09 +(1 row) + +test=# PGPOOL SET CACHE DELETE '/*FORCE QUERY CACHE*/SELECT current_timestamp;'; +NOTICE: query cache deleted. query: "/*FORCE QUERY CACHE*/SELECT current_timestamp;" +SET + + + + + + + See Also + + + + + + + diff --git a/doc/src/sgml/ref/pgpool_setup.sgml b/doc/src/sgml/ref/pgpool_setup.sgml index 9b2e02d34..ab8fd2771 100644 --- a/doc/src/sgml/ref/pgpool_setup.sgml +++ b/doc/src/sgml/ref/pgpool_setup.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pgpool_setup - Create a temporary installation of Pgpool-II cluster + Create a temporary installation of Pgpool-II cluster @@ -32,281 +32,344 @@ Pgpool-II documentation Description - pgpool_setup creates a temporary - installation of Pgpool-II cluster, which - includes a Pgpool-II installation and - specified number of PostgreSQL - installations under current directory. - Current directory must be empty before running pgpool_setup. + pgpool_setup creates a temporary + installation of Pgpool-II cluster, which + includes a Pgpool-II installation and + specified number of PostgreSQL + installations under current directory. + Current directory must be empty before running pgpool_setup. - pgpool_setup is for testing purpose - only and should not be used to create production installations. + pgpool_setup is for testing purpose + only and should not be used to create production installations. - Currently pgpool_setup supports - streaming replication mode, native replication mode, raw mode and - logical replication mode. To support watchdog, - see for details. + pgpool_setup executes + ssh against localhost. You need to + configure ssh so that it can login to + localhost without password. + + + + Currently pgpool_setup supports + streaming replication mode, native replication mode, raw mode, + logical replication mode and snapshot isolation mode. To support watchdog, + see for details. Options - - pgpool_setup accepts the following command-line arguments: - - - - - - - - Specifies the running mode. mode - can be r (native replication mode), s (streaming replication mode), - n (raw mode), l - (logical replication mode) or y (slony mode). If this is - omitted, s is assumed. - - - - - - - - - Specifies the number of PostgreSQL installations. - If this is omitted, 2 is used. - - - - - - - - - Specify the base port number used by Pgpool-II and PostgreSQL. - Pgpool-II port is base_port. pcp port is base_port + 1. The - first PostgreSQL node's port is base_port + 2, second - PostgreSQL node's port is base_port + 3 and so on. - - - If -pg option is specified, the first PostgreSQL node's port is - assigned to pg_base_port, the second PostgreSQL node's port is - pg_base_port + 1 and so on. - - - If this is omitted, 11000 is used. - - - - - - - - - Specify the base port number used by PostgreSQL. - The first PostgreSQL node's port is base_port + 2, second - PostgreSQL node's port is base_port + 3 and so on. - - - If this is omitted, base_port+2 is used. - - - - - - - - - - Do not stop pgpool and PostgreSQL after the work. - - - - - - - - - Start pgpool with debug mode. - - - - - - - - - In streaming replication mode, use replication slot instead - of archive. Since the archive directory is shared by all - PostgreSQL clusters, if a standby - is promoted, the time line in the archive directory will be - changed and other standby servers will be stopped. Using a - replication slot does not have this problem and is always - preferable if you can - use PostgreSQL 9.4 or later, which - supports replication slot. The replication slot name used - by pgpool_setup - is pgpool_setup_slot. - - - - - - - - - Use pg_rewind command in recovery script - (basebackup.sh). If the command fails, switch to use ordinal - rsync command. In certain cases recovery - using pg_rewind is much faster than rsync - since it does not copy whole database cluster. - - - - - - + + pgpool_setup accepts the following command-line arguments: + + + + + + + + Specifies the running mode. mode + can be r (native replication mode), s (streaming replication mode), + n (raw mode), l + (logical replication mode), or i (snapshot isolation mode). If this is + omitted, s is assumed. + + + + + + + + + Specifies the number of PostgreSQL installations. + If this is omitted, 2 is used. + + + + + + + + + Specify the base port number used by Pgpool-II and PostgreSQL. + Pgpool-II port is base_port. pcp port is base_port + 1. The + first PostgreSQL node's port is base_port + 2, second + PostgreSQL node's port is base_port + 3 and so on. + + + If -pg option is specified, the first PostgreSQL node's port is + assigned to pg_base_port, the second PostgreSQL node's port is + pg_base_port + 1 and so on. + + + If this is omitted, 11000 is used. + + + + + + + + + Specify the base port number used by PostgreSQL. + The first PostgreSQL node's port is base_port + 2, second + PostgreSQL node's port is base_port + 3 and so on. + + + If this is omitted, base_port+2 is used. + + + + + + + + + + Do not stop pgpool and PostgreSQL after the work. + + + + + + + + + Start pgpool with debug mode. + + + + + + + + + In streaming replication mode, use replication slot instead + of archive. Since the archive directory is shared by all + PostgreSQL clusters, if a standby + is promoted, the time line in the archive directory will be + changed and other standby servers will be stopped. Using a + replication slot does not have this problem and is always + preferable if you can + use PostgreSQL 9.4 or later, which + supports replication slot. The replication slot name used + by pgpool_setup + is pgpool_setup_slot. + + + + + + + + + Use pg_rewind command in recovery script + (basebackup.sh). If the command fails, switch to use ordinal + rsync command. In certain cases recovery + using pg_rewind is much faster than rsync + since it does not copy whole database cluster. + + + + + + + + + Omit to create PostgreSQL database + This option is intended to be used by + watchdog_setup and probably useless for + other purposes. + + + + + + + + + Set some additional parameters to pgpool.conf so that the + regression test can performs tests against existing + installation. Currently the parameter is + . + + + + + + + + + Use the sample scripts and configuration files installed in + /etc/pgpool-II/ directory. + + + This option was added for the purpose of testing the sample scripts and + configuration files contained in Pgpool-II RPM packages. + Make sure you have installed the sample scripts and configuration files in + /etc/pgpool-II/ directory before you specify this option. + + + + + + Environment variables - - pgpool_setup recognizes following environment variables: - - - - - - - - Specifies the Pgpool-II installation directory. Pgpool-II - binaries is expected to be placed under PGPOOL_INSTALL_DIR/bin - and pgpool.conf and pool_hba.conf etc. are expected to be placed under - PGPOOL_INSTALL_DIR/etc. The default is /usr/local. - - - - - - - - - Specifies the path to Pgpool-II configuration files. - The default is PGPOOL_INSTALL_DIR/etc. - - - - - - - - - Specifies the path to PostgreSQL commands such as initdb, pg_ctl and psql. - The default is /usr/local/pgsql/bin. - - - - - - - - - Specifies the path to PostgreSQL shared libraries. - The default is /usr/local/pgsql/lib. - - - - - - - - - Specifies the path to Unix socket directory. - The default is /tmp. - - - - - - - - - Specifies the arguments for initdb command. - The default is "--no-locale -E UTF_8". - - - - - - - - - If "true", in streaming replication mode, use replication slot instead - of archive. This brings the same effect as "-s" option is specified. - - - - - - - - - If "true", in streaming replication mode, use pg_rewind in basebackup.sh script. - This brings the same effect as "-r" option is specified. - - - - - - - + + pgpool_setup recognizes following environment variables: + + + + + + + + Specifies the Pgpool-II installation directory. Pgpool-II + binaries is expected to be placed under PGPOOL_INSTALL_DIR/bin + and pgpool.conf and pool_hba.conf etc. are expected to be placed under + PGPOOL_INSTALL_DIR/etc. The default is /usr/local. + + + + + + + + + Specifies the path to Pgpool-II configuration files. + The default is PGPOOL_INSTALL_DIR/etc. + + + + + + + + + Specifies the path to PostgreSQL commands such as initdb, pg_ctl and psql. + The default is /usr/local/pgsql/bin. + + + + + + + + + Specifies the path to PostgreSQL shared libraries. + The default is /usr/local/pgsql/lib. + + + + + + + + + Specifies the path to Unix socket directory. + The default is /tmp. + + + + + + + + + Specifies the arguments for initdb command. + The default is "--no-locale -E UTF_8". + + + + + + + + + If "true", in streaming replication mode, use replication slot instead + of archive. This brings the same effect as "-s" option is specified. + + + + + + + + + If "true", in streaming replication mode, use pg_rewind in basebackup.sh script. + This brings the same effect as "-r" option is specified. + + + + + + + + + If "true", act as if "-t" option is specified. + + + + + + + + + If "true", act as if "-c" option is specified. + + + + + + Example - - -$ pgpool_setup + + +$ pgpool_setup +PostgreSQL major version: 124 Starting set up in streaming replication mode creating startall and shutdownall creating failover script -creating database cluster /home/t-ishii/tmp/test/data0...done. +creating database cluster /tmp/test/data0...done. update postgresql.conf creating pgpool_remote_start creating basebackup.sh creating recovery.conf -creating database cluster /home/t-ishii/tmp/test/data1...done. +creating database cluster /tmp/test/data1...done. update postgresql.conf creating pgpool_remote_start creating basebackup.sh creating recovery.conf temporarily start data0 cluster to create extensions temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 11003 | down | 0.500000 | standby | 0 | false | 0 + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | | | 2020-08-18 13:50:19 + 1 | /tmp | 11003 | down | 0.500000 | standby | 0 | false | 0 | | | 2020-08-18 13:50:18 (2 rows) recovery node 1...pcp_recovery_node -- Command Successful done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 +creating follow primary script + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | | | 2020-08-18 13:50:19 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 | | | 2020-08-18 13:50:23 (2 rows) shutdown all pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/tmp/test/startall. -To shutdown the whole system, use /home/t-ishii/tmp/test/shutdownall. +To start the whole system, use /tmp/test/startall. +To shutdown the whole system, use /tmp/test/shutdownall. pcp command user name is "t-ishii", password is "t-ishii". Each PostgreSQL, pgpool-II and pcp port is as follows: #1 port is 11002 @@ -314,34 +377,36 @@ Each PostgreSQL, pgpool-II and pcp port is as follows: pgpool port is 11000 pcp port is 11001 The info above is in README.port. - -$ ls -README.port bashrc.ports data1 log pgpool_reload run startall -archivedir data0 etc pcppass pgpool_setup.log shutdownall - -$ ./startall -waiting for server to start....11840 2016-08-18 13:08:51 JST LOG: redirecting log output to logging collector process -11840 2016-08-18 13:08:51 JST HINT: Future log output will appear in directory "pg_log". +t-ishii$ ./startall +waiting for server to start....5744 2020-08-18 13:50:27 JST LOG: starting PostgreSQL 12.4 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit +5744 2020-08-18 13:50:27 JST LOG: listening on IPv4 address "0.0.0.0", port 11002 +5744 2020-08-18 13:50:27 JST LOG: listening on IPv6 address "::", port 11002 +5744 2020-08-18 13:50:27 JST LOG: listening on Unix socket "/tmp/.s.PGSQL.11002" +5744 2020-08-18 13:50:27 JST LOG: redirecting log output to logging collector process +5744 2020-08-18 13:50:27 JST HINT: Future log output will appear in directory "log". done server started -waiting for server to start....11853 2016-08-18 13:08:52 JST LOG: redirecting log output to logging collector process -11853 2016-08-18 13:08:52 JST HINT: Future log output will appear in directory "pg_log". +waiting for server to start....5757 2020-08-18 13:50:27 JST LOG: starting PostgreSQL 12.4 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit +5757 2020-08-18 13:50:27 JST LOG: listening on IPv4 address "0.0.0.0", port 11003 +5757 2020-08-18 13:50:27 JST LOG: listening on IPv6 address "::", port 11003 +5757 2020-08-18 13:50:27 JST LOG: listening on Unix socket "/tmp/.s.PGSQL.11003" +5757 2020-08-18 13:50:27 JST LOG: redirecting log output to logging collector process +5757 2020-08-18 13:50:27 JST HINT: Future log output will appear in directory "log". done server started -$ psql -p 11000 test -Pager usage is off. -psql (9.5.4) +t-ishii$ psql -p 11000 test +psql (12.4) Type "help" for help. test=# show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | | | 2020-08-18 13:50:32 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 | streaming | async | 2020-08-18 13:50:32 (2 rows) - - + + diff --git a/doc/src/sgml/ref/pgpool_show.sgml b/doc/src/sgml/ref/pgpool_show.sgml index 13e43f892..ec627e835 100644 --- a/doc/src/sgml/ref/pgpool_show.sgml +++ b/doc/src/sgml/ref/pgpool_show.sgml @@ -20,11 +20,11 @@ PostgreSQL documentation - -PGPOOL SHOW configuration_parameter -PGPOOL SHOW configuration_parameter_group -PGPOOL SHOW ALL - + + PGPOOL SHOW configuration_parameter + PGPOOL SHOW configuration_parameter_group + PGPOOL SHOW ALL + @@ -34,15 +34,15 @@ PGPOOL SHOW ALL PGPOOL SHOW will display the current value of Pgpool-II configuration parameters. - This command is similar to the - + This command is similar to the + SHOW command in PostgreSQL with an addition - of PGPOOL keyword to distinguish it from the - PostgreSQL SHOW command. + of PGPOOL keyword to distinguish it from the + PostgreSQL SHOW command. - + Parameters @@ -50,60 +50,66 @@ PGPOOL SHOW ALL configuration_parameter + + The name of a Pgpool-II configuration parameter. + Available parameters are documented in . + + - The name of a Pgpool-II configuration parameter. - Available parameters are documented in + If the parameter contains uppercase letters (e.g. ), + the parameter name must be enclosed in double quotes. + - + configuration_parameter_group - - The name of the Pgpool-II configuration parameter group. - Currently there are three parameter groups. - - - - backend - - - Configuration group of all backend config parameters. - - - - - - other_pgpool - - - Configuration group of all watchdog node config parameters. - - - - - - heartbeat - - - configuration group of all watchdog heartbeat node config parameters. - - - - - - health_check - - - configuration group of all health check parameters. - - - - - + + The name of the Pgpool-II configuration parameter group. + Currently there are four parameter groups. + + + + backend + + + Configuration group of all backend config parameters. + + + + + + watchdog + + + Configuration group of all watchdog node config parameters. + + + + + + heartbeat + + + configuration group of all watchdog heartbeat config parameters. + + + + + + health_check + + + configuration group of all health check parameters. + + + + + - + ALL @@ -122,69 +128,68 @@ PGPOOL SHOW ALL Show the current setting of the parameter : - + PGPOOL SHOW port; port ------ 9999 (1 row) - + - Show the current setting of the parameter : - -PGPOOL SHOW black_function_list; - black_function_list - --------------------- - nextval,setval - (1 row) - + Show the current setting of the parameter : + +PGPOOL SHOW write_function_list; +write_function_list +--------------------- +nextval,setval +(1 row) + - + Show the current settings of all the configuration parameters belonging to backend group: - - PGPOOL SHOW backend; - item | value | description - -------------------------+-------------------------+----------------------------------------------------------- - backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port0 | 5434 | port number of PostgreSQL backend. - backend_weight0 | 0 | load balance weight of backend. - backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. - backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. - backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port1 | 5432 | port number of PostgreSQL backend. - backend_weight1 | 1 | load balance weight of backend. - backend_data_directory1 | /home/work/installed/pg | data directory of the backend. - backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. - (10 rows) - + +PGPOOL SHOW backend; +item | value | description +-------------------------+-------------------------+----------------------------------------------------------- +backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port0 | 5434 | port number of PostgreSQL backend. +backend_weight0 | 0 | load balance weight of backend. +backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. +backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. +backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port1 | 5432 | port number of PostgreSQL backend. +backend_weight1 | 1 | load balance weight of backend. +backend_data_directory1 | /home/work/installed/pg | data directory of the backend. +backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. +(10 rows) + Show all settings: - - PGPOOL SHOW ALL; - item | value | description - -------------------------+-------------------------+----------------------------------------------------------- - backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port0 | 5434 | port number of PostgreSQL backend. - backend_weight0 | 0 | load balance weight of backend. - backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. - backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. - backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. - backend_port1 | 5432 | port number of PostgreSQL backend. - backend_weight1 | 1 | load balance weight of backend. - backend_data_directory1 | /home/work/installed/pg | data directory of the backend. - backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. - other_pgpool_hostname0 | localhost | Hostname of other pgpool node for watchdog connection. - . - . - . - ssl | off | Enables SSL support for frontend and backend connections - (138 rows) - - + +PGPOOL SHOW ALL; +item | value | description +-------------------------+-------------------------+----------------------------------------------------------- +backend_hostname0 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port0 | 5434 | port number of PostgreSQL backend. +backend_weight0 | 0 | load balance weight of backend. +backend_data_directory0 | /var/lib/pgsql/data | data directory of the backend. +backend_flag0 | ALLOW_TO_FAILOVER | Controls various backend behavior. +backend_hostname1 | 127.0.0.1 | hostname or IP address of PostgreSQL backend. +backend_port1 | 5432 | port number of PostgreSQL backend. +backend_weight1 | 1 | load balance weight of backend. +backend_data_directory1 | /home/work/installed/pg | data directory of the backend. +backend_flag1 | ALLOW_TO_FAILOVER | Controls various backend behavior. +hostname0 | localhost | Hostname of pgpool node for watchdog connection. +. +. +. +ssl | off | Enables SSL support for frontend and backend connections +(138 rows) + diff --git a/doc/src/sgml/ref/pgproto.sgml b/doc/src/sgml/ref/pgproto.sgml index dfa0478bd..420b03b61 100644 --- a/doc/src/sgml/ref/pgproto.sgml +++ b/doc/src/sgml/ref/pgproto.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation pgproto - tests PostgreSQL or any other servers that understand the frontend/backend protocol. + tests PostgreSQL or any other servers that understand the frontend/backend protocol. @@ -30,248 +30,263 @@ Pgpool-II documentation Description - pgproto - tests PostgreSQL or any other servers that understand the frontend/backend protocol. + pgproto + tests PostgreSQL or any other servers that understand the frontend/backend protocol. Options - - - - - - - - The host name of the machine on which the server is running. If the value begins with a slash, it is used as the directory for the Unix-domain socket (default: Unix-domain socket). - - - + + + + + + + + The host name of the machine on which the server is running. If the value begins with a slash, it is used as the directory for the Unix-domain socket (default: Unix-domain socket). + + + - - - - - - The port number (default:5432). - - - + + + + + + The port number (default:5432). + + + - - - - - - The user name (default: OS user name). - - - + + + + + + The user name (default: OS user name). + + + - - - - - - The database name (default: same as user). - - - + + + + + + The database name (default: same as user). + + + - - - - - - Text file describing message data to be sent to PostgreSQL (default: pgproto.data). - - - + + + + + + Text file describing message data to be sent to PostgreSQL (default: pgproto.data). + + + - - - - - - The nap time in micro seconds (default:0). - Greater than 0 will let pgproto sleep between each data reading from socket. - This is useful to simulate slow clients. - - - + + + + + + The nap time in micro seconds (default:0). + Greater than 0 will let pgproto sleep between each data reading from socket. + This is useful to simulate slow clients. + + + - - - - - - Enable debug message. - - - + + + + + + Enable debug message. + + + - - - - - - Print the command version, then exit. - - - + + + + + + Print the command version, then exit. + + + - - - - - - Shows help for the command line arguments, then exit. - - - + + + + + + Shows help for the command line arguments, then exit. + + + - - + + Example - In the example below, the first character in the file (i.e. 'Q') - indicates the message kind specified in the PostgreSQL frontend/backend protocol. + In the example below, the first character in the file (i.e. 'Q') + indicates the message kind specified in the PostgreSQL frontend/backend protocol. - Exceptions are 'Y' and 'y'. 'Y' reads messages from backend - until 'Ready for query' is received. - 'y' reads messages from backend while messages are coming from backend then stops - if messages are not available for 1 second. - 'Y' is used for waiting for reply of 'Q' (simple query) or after 'S' (sync) in extended queries. - 'y' can be used for receiving messages after 'H' (flush). + Exceptions are 'Y' , 'y' and 'z'. 'Y' reads messages from backend + until 'Ready for query' is received. + 'y' reads messages from backend while messages are coming from backend then stops + if messages are not available for 1 second. + 'Y' is used for waiting for reply of 'Q' (simple query) or after 'S' (sync) in extended queries. + 'y' can be used for receiving messages after 'H' (flush). + 'z' reads 1 messages from backend. If no message arrives within 1 second, 'z' stops. + If you want to read multiple messages, you can use repeat 'z' for the message count. + 'z' can be useful for 'H' message test when you already know how + many reply messages will come. - If you want to include a " (double quotation) in a string data type, - for example "SELECT * FROM "aaa"", you can qualify it by using \ (back slash) like ""SELECT * FROM "aaa"" + If you want to include a " (double quotation) in a string data type, + for example "SELECT * FROM "aaa"", you can qualify it by using \ (back slash) like ""SELECT * FROM "aaa"" - A command line spread over multiple lines can be created using \ as well. - -'Q' "SELECT * FROM aaa \ -WHERE a = 1" - + A command line spread over multiple lines can be created using \ as well. + + 'Q' "SELECT * FROM aaa \ + WHERE a = 1" + + + + You can insert a new line by using "\n" if you want to use some + commands like COPY. Below is an example. + + 'Q' "COPY t1 FROM STDIN" + 'd' "1\n" + 'd' "2\n" + 'c' + 'Y' + - Here is an example input file: - -# -# Test data example -# -'Q' "SELECT * FROM aaa" -'Y' -'P' "S1" "BEGIN" 0 -'B' "" "S1" 0 0 0 -'E' "" 0 -'C' 'S' "S1" -'P' "foo" "SELECT 1" 0 -'B' "myportal" "foo" 0 0 0 -'E' "myportal" 0 -'P' "S2" "COMMIT" 0 -'B' "" "S2" 0 0 0 -'E' "" 0 -'C' 'S' "S2" -'S' -'Y' -'X' - + Here is an example input file: + + # + # Test data example + # + 'Q' "SELECT * FROM aaa" + 'Y' + 'P' "S1" "BEGIN" 0 + 'B' "" "S1" 0 0 0 + 'E' "" 0 + 'C' 'S' "S1" + 'P' "foo" "SELECT 1" 0 + 'B' "myportal" "foo" 0 0 0 + 'E' "myportal" 0 + 'P' "S2" "COMMIT" 0 + 'B' "" "S2" 0 0 0 + 'E' "" 0 + 'C' 'S' "S2" + 'S' + 'Y' + 'X' + - Here is an example output: - -$ pgproto -p 11000 -d test -f sample.data -FE=> Query (query="SELECT * FROM aaa") -<= BE RowDescription -<= BE CommandComplete(SELECT 0) -<= BE ReadyForQuery(I) -FE=> Parse(stmt="S1", query="BEGIN") -FE=> Bind(stmt="S1", portal="") -FE=> Execute(portal="") -FE=> Close(stmt="S1") -FE=> Parse(stmt="foo", query="SELECT 1") -FE=> Bind(stmt="foo", portal="myportal") -FE=> Execute(portal="myportal") -FE=> Parse(stmt="S2", query="COMMIT") -FE=> Bind(stmt="S2", portal="") -FE=> Execute(portal="") -FE=> Close(stmt="S2") -FE=> Sync -<= BE ParseComplete -<= BE BindComplete -<= BE CommandComplete(BEGIN) -<= BE CloseComplete -<= BE ParseComplete -<= BE BindComplete -<= BE DataRow -<= BE CommandComplete(SELECT 1) -<= BE ParseComplete -<= BE BindComplete -<= BE CommandComplete(COMMIT) -<= BE CloseComplete -<= BE ReadyForQuery(I) -FE=> Terminate - + Here is an example output: + + $ pgproto -p 11000 -d test -f sample.data + FE=> Query (query="SELECT * FROM aaa") + <= BE RowDescription + <= BE CommandComplete(SELECT 0) + <= BE ReadyForQuery(I) + FE=> Parse(stmt="S1", query="BEGIN") + FE=> Bind(stmt="S1", portal="") + FE=> Execute(portal="") + FE=> Close(stmt="S1") + FE=> Parse(stmt="foo", query="SELECT 1") + FE=> Bind(stmt="foo", portal="myportal") + FE=> Execute(portal="myportal") + FE=> Parse(stmt="S2", query="COMMIT") + FE=> Bind(stmt="S2", portal="") + FE=> Execute(portal="") + FE=> Close(stmt="S2") + FE=> Sync + <= BE ParseComplete + <= BE BindComplete + <= BE CommandComplete(BEGIN) + <= BE CloseComplete + <= BE ParseComplete + <= BE BindComplete + <= BE DataRow + <= BE CommandComplete(SELECT 1) + <= BE ParseComplete + <= BE BindComplete + <= BE CommandComplete(COMMIT) + <= BE CloseComplete + <= BE ReadyForQuery(I) + FE=> Terminate + - Other example data files: + Other example data files: - Copy - -# -# Test data example -# + Copy + + # + # Test data example + # -# CopyIn -# -'Q' "COPY t1 FROM STDIN" -# CopyData -'d' "abc" -# CopyDone -'c' -'Y' + # CopyIn + # + 'Q' "COPY t1 FROM STDIN" + # CopyData + 'd' "abc\n" + # CopyDone + 'c' + 'Y' -# CopyOut -# -'Q' "COPY t1 TO STDOUT" -'Y' + # CopyOut + # + 'Q' "COPY t1 TO STDOUT" + 'Y' -# -# Copy fail case -# -'Q' "COPY t1 FROM STDIN" -# CopyData -'d' "abc" -# CopyFail -'f' "pgproto copy fail test" -'Y' -'X' - + # + # Copy fail case + # + 'Q' "COPY t1 FROM STDIN" + # CopyData + 'd' "abc\n" + # CopyFail + 'f' "pgproto copy fail test" + 'Y' + 'X' + - Function Call - -# -# Test data example -# + Function Call + + # + # Test data example + # -# Function call (lo_creat) -# from PostgreSQL's src/include/catalog/pg_proc.data -# { oid => '957', descr => 'large object create', -# proname => 'lo_creat', provolatile => 'v', proparallel => 'u', -# prorettype => 'oid', proargtypes => 'int4', prosrc => 'be_lo_creat' }, + # Function call (lo_creat) + # from PostgreSQL's src/include/catalog/pg_proc.data + # { oid => '957', descr => 'large object create', + # proname => 'lo_creat', provolatile => 'v', proparallel => 'u', + # prorettype => 'oid', proargtypes => 'int4', prosrc => 'be_lo_creat' }, -'F' 957 1 0 1 1 "0" 0 -'Y' -'X' - + 'F' 957 1 0 1 1 "0" 0 + 'Y' + 'X' + diff --git a/doc/src/sgml/ref/show_pool_backend_stats.sgml b/doc/src/sgml/ref/show_pool_backend_stats.sgml new file mode 100644 index 000000000..f6c760247 --- /dev/null +++ b/doc/src/sgml/ref/show_pool_backend_stats.sgml @@ -0,0 +1,66 @@ + + + + + SHOW POOL_BACKEND_STATS + + + + SHOW POOL_BACKEND_STATS + 1 + SQL - Language Statements + + + + SHOW POOL_BACKEND_STATS + + show backend SQL command statistics + + + + + + SHOW POOL_BACKEND_STATS + + + + + Description + + + SHOW POOL_BACKEND_STATS displays the node id, + the hostname, the port, the status, the role, the + SELECT/INSERT/UPDATE/DELETE/DDL/other query counts issued to each + backend. Also error messages returned from backend are counted and + shown, classified by the severity. The node id, the hostname, the + port, the status, the role are same as . + + + select_cnt, insert_cnt, update_cnt, delete_cnt, ddl_cnt, other_cnt + are the numbers of SQL command: SELECT, INSERT, UPDATE, DELETE, DDL + and others issued since Pgpool-II + started. Failed commands (for example SELECT from non-existing + table) are counted. Commands rolled back are also + counted. Currently, other than + SELECT/WITH/INSERT/UPDATE/DELETE/CHECKPOINT/DEALLOCATE/DISCARD/EXECUTE/ + EXPLAIN/LISTEN/LOAD/LOCK/NOTIFY/PREPARE/SET/SHOW/Transaction + commands/UNLISTEN are considered as DDL. + + + Here is an example session: + +test=# show pool_backend_stats; + node_id | hostname | port | status | role | select_cnt | insert_cnt | update_cnt | delete_cnt | ddl_cnt | other_cnt | panic_cnt | fatal_cnt | error_cnt +---------+----------+-------+--------+---------+------------+------------+------------+------------+---------+-----------+-----------+-----------+----------- + 0 | /tmp | 11002 | up | primary | 12 | 10 | 30 | 0 | 2 | 30 | 0 | 0 | 1 + 1 | /tmp | 11003 | up | standby | 12 | 0 | 0 | 0 | 0 | 23 | 0 | 0 | 1 +(2 rows) + + + + + diff --git a/doc/src/sgml/ref/show_pool_cache.sgml b/doc/src/sgml/ref/show_pool_cache.sgml index aea796bdd..4f489c9b8 100644 --- a/doc/src/sgml/ref/show_pool_cache.sgml +++ b/doc/src/sgml/ref/show_pool_cache.sgml @@ -4,56 +4,158 @@ --> - - SHOW - - - - SHOW POOL_CACHE - 1 - SQL - Language Statements - - - - SHOW POOL_CACHE - - displays cache storage statistics - - - - - -SHOW POOL_CACHE - - - - - Description - - - SHOW POOL_CACHE - displays in memory - query cache statistics if in memory query cache is - enabled. Here is an example session: - -test=# \x -\x -Expanded display is on. -test=# show pool_cache; -show pool_cache; --[ RECORD 1 ]---------------+--------- -num_cache_hits | 891703 -num_selects | 99995 -cache_hit_ratio | 0.90 -num_hash_entries | 131072 -used_hash_entries | 99992 -num_cache_entries | 99992 -used_cache_enrties_size | 12482600 -free_cache_entries_size | 54626264 -fragment_cache_entries_size | 0 - - - - + + SHOW + + + + SHOW POOL_CACHE + 1 + SQL - Language Statements + + + + SHOW POOL_CACHE + + displays cache storage statistics + + + + + + SHOW POOL_CACHE + + + + + Description + + + SHOW POOL_CACHE + displays in memory + query cache statistics if in memory query cache is + enabled. Here is an example session: + See for a description of each item. + + test=# \x + \x + Expanded display is on. + test=# show pool_cache; + show pool_cache; + -[ RECORD 1 ]---------------+--------- + num_cache_hits | 891703 + num_selects | 99995 + cache_hit_ratio | 0.90 + num_hash_entries | 131072 + used_hash_entries | 99992 + num_cache_entries | 99992 + used_cache_entries_size | 12482600 + free_cache_entries_size | 54626264 + fragment_cache_entries_size | 0 + + + + + + + If the cache storage is memcached, values for all columns except + num_cache_hits, num_selects and cache_hit_ratio show 0. + + + + + Items displayed in show pool_cache + + + + Name + Description + + + + + + + num_cache_hits + The number of hits against the query cache. + + + + num_selects + The number of SELECT that did not hit against the query cache. + + + + cache_hit_ratio + The cache hit ratio. + Calculated as num_cache_hits/(num_cache_hits+num_selects). + + + + num_hash_entries + The number of entries in the hash table used to manage + the cache. In order to manage large number of + cache Pgpool-II uses the hash table. + The number of hash entries is automatically adjusted to the + nearest power of two greater + than . For + example, 100,000, which is the default + for is adjusted to + 131,072 (2 to the 17th power). + + + + + used_hash_entries + + The number of used hash entries. If the value + approaches num_hash_entries, it is + recommended to increase num_hash_entries. + Even if all the hash table entries are used, no error is + raised. However, performance suffers because hash table + entries and caches are reused to register new cache entries. + + + + + num_cache_entries + + The number of cache entries already used. In the current + implementation the number should be identical + to used_hash_entries. + + + + + free_cache_entries_size + + The size in bytes of the unused cache. As this value approaches + 0, it removes the registered cache and registers a new cache, + which does not cause an error, but reduces performance. + Consider to increase . + + + + + fragment_cache_entries_size + + The size in bytes of the fragmented cache. When a registered + cache is evicted, the space becomes fragmented until the next + time that block is reused. + Pgpool-II writes cache in fixed-size + blocks specified + by . When a + registered cache is evicted, the space becomes fragmented + until the next time that block is reused. + fragment_cache_entries_size displays the + total size of such fragmented regions. + + + + + +
+ +
diff --git a/doc/src/sgml/ref/show_pool_health_check_stats.sgml b/doc/src/sgml/ref/show_pool_health_check_stats.sgml new file mode 100644 index 000000000..9e53f4805 --- /dev/null +++ b/doc/src/sgml/ref/show_pool_health_check_stats.sgml @@ -0,0 +1,274 @@ + + + + + SHOW POOL_HEALTH_CHECK_STATS + + + + SHOW POOL_HEALTH_CHECK_STATS + 1 + SQL - Language Statements + + + + SHOW POOL_HEALTH_CHECK_STATS + + show health check statistics data + + + + + + SHOW POOL_HEALTH_CHECK_STATS + + + + + Description + + + SHOW POOL_HEALTH_CHECK_STATS displays health + check (see ) statistic + data mostly collected by health check process. This command helps + Pgpool-II admin to study events related + to health check. For example, admin can easily locate the failover + event in the log file by looking at "last_failed_health_check" + column. Another example is finding unstable connection to backend + by evaluating "average_retry_count" column. If particular node + shows higher retry count than other node, there may be problem to + the connection to the backend. + + + + shows each column name and its description. + + + + Statistics data shown by pool_health_check_stats command + + + + Column Name + Description + + + + + + + node_id + + Backend node id. + + + + + hostname + + Backend hostname or UNIX domain socket path. + + + + + port + + Backend port number. + + + + + status + + Backend status. One of up, down, waiting, unused or quarantine. + + + + + role + + Role of the node. Either primary or standby in streaming + replication mode. Either main or replica in other mode. + + + + + last_status_change + + Timestamp of last backend status changed. + + + + + total_count + + Number of health check count in total. + + + + + success_count + + Number of successful health check count in total. + + + + + fail_count + + Number of failed health check count in total. + + + + + skip_count + + Number of skipped health check count in total. If the node is + already down, health check skips the node. + + + + + retry_count + + Number of retried health check count in total. + + + + + average_retry_count + + Number of average retried health check count in a health check + session. + + + + + max_retry_count + + Number of maximum retried health check count in a health check + session. + + + + + max_duration + + Maximum health check duration in Millie seconds. If a health + check session retries, the health check duration is sum of each + retried health check. + + + + + min_duration + + Minimum health check duration in Millie seconds. If a health + check session retries, the health check duration is sum of each + retried health check. + + + + + average_duration + + Average health check duration in Millie seconds. If a health + check session retries, the health check duration is sum of each + retried health check. + + + + + last_health_check + + Timestamp of last health check. If heath check does not + performed yet, empty string. + + + + + last_successful_health_check + + Timestamp of last successful health check. If heath check does + not succeeds yet, empty string. + + + + + last_skip_health_check + + Timestamp of last skipped health check. If heath check is not + skipped yet, empty string. Note that it is possible that this + field is an empty string even if the status is down. In this + case failover was triggered by other than health check process. + + + + + last_failed_health_check + + Timestamp of last failed health check. If heath check does not + fail yet, empty string. Note that it is possible that this + field is an empty string even if the status is down. In this + case failover was triggered by other than health check process. + + + + + +
+ + + Here is an example session: + +test=# show pool_health_check_stats; +-[ RECORD 1 ]----------------+-------------------- +node_id | 0 +hostname | /tmp +port | 11002 +status | up +role | primary +last_status_change | 2020-01-26 19:08:45 +total_count | 27 +success_count | 27 +fail_count | 0 +skip_count | 0 +retry_count | 0 +average_retry_count | 0.000000 +max_retry_count | 0 +max_duration | 9 +min_duration | 2 +average_duration | 6.296296 +last_health_check | 2020-01-26 19:12:45 +last_successful_health_check | 2020-01-26 19:12:45 +last_skip_health_check | +last_failed_health_check | +-[ RECORD 2 ]----------------+-------------------- +node_id | 1 +hostname | /tmp +port | 11003 +status | down +role | standby +last_status_change | 2020-01-26 19:11:48 +total_count | 19 +success_count | 12 +fail_count | 1 +skip_count | 6 +retry_count | 3 +average_retry_count | 0.230769 +max_retry_count | 3 +max_duration | 83003 +min_duration | 0 +average_duration | 6390.307692 +last_health_check | 2020-01-26 19:12:48 +last_successful_health_check | 2020-01-26 19:10:15 +last_skip_health_check | 2020-01-26 19:12:48 +last_failed_health_check | 2020-01-26 19:11:48 + + +
+ +
diff --git a/doc/src/sgml/ref/show_pool_nodes.sgml b/doc/src/sgml/ref/show_pool_nodes.sgml index b20b04b9e..ba701e327 100644 --- a/doc/src/sgml/ref/show_pool_nodes.sgml +++ b/doc/src/sgml/ref/show_pool_nodes.sgml @@ -4,63 +4,73 @@ --> - - SHOW POOL_NODES - + + SHOW POOL_NODES + - - SHOW POOL NODES - 1 - SQL - Language Statements - + + SHOW POOL NODES + 1 + SQL - Language Statements + - - SHOW POOL_NODES - - sends back a list of all configured nodes - - + + SHOW POOL_NODES + + sends back a list of all configured nodes + + - - -SHOW POOL_NODES - - + + + SHOW POOL_NODES + + - - Description + + Description - - SHOW POOL_NODES displays the node id, the - hostname, the port, the status, the weight (only meaningful if - you use the load balancing mode), the role, the SELECT query - counts issued to each backend, whether each node is the load - bakance node or not, the replication delay (only if in streaming - replication mode) and last status change time. The possible - values in the status column are explained in - the reference. If the hostname is - something like "/tmp", that means - Pgpool-II is connecting to backend by - using UNIX domain sockets. The SELECT count does not include - internal queries used - by Pgoool-II. Also the counters are - reset to zero upon starting up - of Pgpool-II. The last status change - time is initially set to the - time Pgpool-II starts. After that - whenever "status" or "role" is changed, it is updated. - - - Here is an example session: - + + SHOW POOL_NODES displays the node id, the + hostname, the port, the status, the weight (only meaningful if + you use the load balancing mode), the role, the SELECT query + counts issued to each backend, whether each node is the load + balance node or not, the replication delay (only if in streaming + replication mode) and last status change time. In addition to + this replication state and sync state are shown for standby nodes + in Pgpool-II 4.1 or after. + Also actual node status and node role are shown in + Pgpool-II 4.3 or after. + + + The + possible values in the status column are explained in + the reference. + + + If the hostname is + something like "/tmp", that means + Pgpool-II is connecting to backend by + using UNIX domain sockets. The SELECT count does not include + internal queries used + by Pgpool-II. Also the counters are + reset to zero upon starting up + of Pgpool-II. The last status change + time is initially set to the + time Pgpool-II starts. After that + whenever "status" or "role" is changed, it is updated. + + + Here is an example session: + test=# show pool_nodes; - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change ----------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | true | 0 | 2018-06-12 21:45:59 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 | 2018-06-12 21:45:59 + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+----------+-------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | /tmp | 11002 | up | up | 0.500000 | primary | primary | 0 | false | 0 | | | 2021-02-27 15:10:19 + 1 | /tmp | 11003 | up | up | 0.500000 | standby | standby | 0 | true | 0 | streaming | async | 2021-02-27 15:10:19 (2 rows) - - - + + + diff --git a/doc/src/sgml/ref/show_pool_pools.sgml b/doc/src/sgml/ref/show_pool_pools.sgml index 46ff9a662..6dad9279b 100644 --- a/doc/src/sgml/ref/show_pool_pools.sgml +++ b/doc/src/sgml/ref/show_pool_pools.sgml @@ -4,389 +4,248 @@ --> - - SHOW POOL_POOLS - - - - SHOW POOL_POOLS - 1 - SQL - Language Statements - - - - SHOW POOL_POOLS - - sends back a list of pools handled - by Pgpool-II. - - - - - -SHOW POOL_POOLS - - - - - Description - - - SHOW POOL_POOLS sends back a list of pools - handled by - Pgpool-II - - - It has 11 columns: + + SHOW POOL_POOLS + + + + SHOW POOL_POOLS + 1 + SQL - Language Statements + + + + SHOW POOL_POOLS + + sends back a list of pools handled + by Pgpool-II. + + + + + + SHOW POOL_POOLS + + + + + Description + + + SHOW POOL_POOLS sends back a list of pools + handled by + Pgpool-II + + + It has 20 columns: + + + + pool_pid is the PID of the + displayed Pgpool-II process. + + + + + + start_time is the timestamp of when + this process was launched. - - - pool_pid is the PID of the - displayed Pgpool-II process. - - - - - - start_time is the timestamp of when - this process was launched. - - - - - - pool_id is the pool identifier (should - be between 0 and - 1) - - - - - - backend_id is the backend identifier (should - be between 0 and the number of configured backends minus one) - - - - - - database is the database name for this - process's pool id connection. - - - - - - username is the user name for this - process's pool id connection. - - - - - - create_time is the creation time and - date of the connection. - - - - - - majorversion - and minorversion are the protocol - version numbers used in this connection. - - - - - - pool_counter counts the number of times - this pool of connections (process) has been used by - clients. - - - - - - pool_backendpid is the PID of the - PostgreSQL process. - - - - - - pool_connected is true (1) if a - frontend is currently using this backend. - - - - - - - It'll always return * * - number_of_backends lines. Here is an example session: - + + + If is set not 0, + the time before process restarting is displayed. + + + + + + + + + client_connection_count counts the number of times + this process has been used by clients. + + + + + + pool_id is the pool identifier (should + be between 0 and - 1) + + + + + + backend_id is the backend identifier (should + be between 0 and the number of configured backends minus one) + + + + + + database is the database name for this + process's pool id connection. + + + + + + username is the user name for this + process's pool id connection. + + + + + + backend_connection_time is the creation time and + date of the connection. + + + + + + client_connection_time is the date when a client + last used this connection. + + + + + + client_disconnection_time is the date when a client + last disconnected from this connection. + + + + + + client_idle_duration is the time (sec) that a client + is in idle. + + + + If is set not 0, + the time before client disconnected is displayed. + + + + + + + + + majorversion + and minorversion are the protocol + version numbers used in this connection. + + + + + + pool_counter counts the number of times + this pool of connections (process) has been used by + clients. + + + + + + pool_backendpid is the PID of the + PostgreSQL process. + + + + + + pool_connected is true (1) if a + frontend is currently using this backend. + + + + + + status is current status of this process. Possible values are: + + + + Execute command: Executing a command. + + + + + Idle: The process is waiting for a new client command. + + + + + Idle in transaction: The process is waiting for a new client command + in a transaction. + + + + + Wait for connection: The process is waiting for a new client connection. + + + + + + + + + load_balance_node is true (1) if a + frontend is currently using this backend and the backend is load balance node. + + + + + client_host is client's host name or IP address. + + + + + + client_port is client's port number. + + + + + statement is the SQL statement last executed. + + + + + + + It'll always return * * + number_of_backends lines. Here is an example session: + test=# show pool_pools; - pool_pid | start_time | pool_id | backend_id | database | username | create_time | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected -----------+---------------------+---------+------------+----------+----------+---------------------+--------------+--------------+--------------+-----------------+---------------- - 19696 | 2016-10-17 13:24:17 | 0 | 0 | postgres | t-ishii | 2016-10-17 13:35:12 | 3 | 0 | 1 | 20079 | 1 - 19696 | 2016-10-17 13:24:17 | 0 | 1 | postgres | t-ishii | 2016-10-17 13:35:12 | 3 | 0 | 1 | 20080 | 1 - 19696 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19696 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19697 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19698 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19699 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19700 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19701 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19702 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19703 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19704 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19705 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19706 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19707 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19708 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19709 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19710 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19711 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19712 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19713 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19714 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19715 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19716 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19717 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19718 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19719 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19720 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 0 | 0 | test | t-ishii | 2016-10-17 14:30:53 | 3 | 0 | 1 | 22055 | 1 - 20024 | 2016-10-17 13:33:46 | 0 | 1 | test | t-ishii | 2016-10-17 14:30:53 | 3 | 0 | 1 | 22056 | 1 - 20024 | 2016-10-17 13:33:46 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20024 | 2016-10-17 13:33:46 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 20600 | 2016-10-17 13:46:58 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19723 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19724 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19725 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19726 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 0 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 0 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 1 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 1 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 2 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 2 | 1 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 3 | 0 | | | | 0 | 0 | 0 | 0 | 0 - 19727 | 2016-10-17 13:24:17 | 3 | 1 | | | | 0 | 0 | 0 | 0 | 0 + pool_pid | start_time | client_connection_count | pool_id | backend_id | database | username | backend_connection_time | client_connection_time | client_disconnection_time | client_idle_duration | majorversion | minorversion | pool_counter | pool_backendpid | pool_connected | status | load_balance_node | client_host | client_port | statement +----------+------------------------------------------------------+-------------------------+---------+------------+----------+----------+-------------------------+------------------------+---------------------------+----------------------+--------------+--------------+--------------+-----------------+----------------+---------------------+-------------------+---------------+-------------+------------- +[snip] + 1336537 | 2025-06-24 10:53:35 | 0 | 0 | 0 | test | t-ishii | 2025-06-24 10:55:58 | 2025-06-24 10:55:59 | | 0 | 3 | 0 | 1 | 1336703 | 1 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 0 | 1 | test | t-ishii | 2025-06-24 10:55:58 | 2025-06-24 10:55:59 | | 0 | 3 | 0 | 1 | 1336704 | 1 | Idle | 1 | 192.168.10.11 | 39216 | select 1; + 1336537 | 2025-06-24 10:53:35 | 0 | 1 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 1 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | select 1; + 1336537 | 2025-06-24 10:53:35 | 0 | 2 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 2 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | select 1; + 1336537 | 2025-06-24 10:53:35 | 0 | 3 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | + 1336537 | 2025-06-24 10:53:35 | 0 | 3 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Idle | 0 | 192.168.10.11 | 39216 | select 1; +[snip] + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 0 | 0 | test | t-ishii | 2025-06-24 10:53:42 | 2025-06-24 10:53:42 | 2025-06-24 10:55:37 | 0 | 3 | 0 | 1 | 1336573 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 0 | 1 | test | t-ishii | 2025-06-24 10:53:42 | 2025-06-24 10:53:42 | 2025-06-24 10:55:37 | 0 | 3 | 0 | 1 | 1336574 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 1 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 1 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 2 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 2 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 3 | 0 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | DISCARD ALL + 1336544 | 2025-06-24 10:53:35 (0:23 before process restarting) | 1 | 3 | 1 | | | | | | 0 | 0 | 0 | 0 | 0 | 0 | Wait for connection | 0 | 192.168.10.11 | 39162 | +[snip] (256 rows) - + - - + +
diff --git a/doc/src/sgml/ref/show_pool_processes.sgml b/doc/src/sgml/ref/show_pool_processes.sgml index dc069d127..cb33f0cb0 100644 --- a/doc/src/sgml/ref/show_pool_processes.sgml +++ b/doc/src/sgml/ref/show_pool_processes.sgml @@ -4,122 +4,140 @@ --> - - SHOW POOL_PROCESSES - + + SHOW POOL_PROCESSES + - - SHOW POOL_PROCESSES - 1 - SQL - Language Statements - + + SHOW POOL_PROCESSES + 1 + SQL - Language Statements + - - SHOW POOL_PROCESSES - - sends back a list of all Pgpool-II - processes waiting for connections and dealing with a connection - - + + SHOW POOL_PROCESSES + + sends back a list of all Pgpool-II + processes waiting for connections and dealing with a connection + + - - -SHOW POOL_PROCESSES - - + + + SHOW POOL_PROCESSES + + - - Description + + Description - - SHOW POOL_PROCESSES sends back a list of all - Pgpool-II processes waiting for - connections and dealing with a connection. - - - It has 6 columns: + + SHOW POOL_PROCESSES sends back a list of all + Pgpool-II processes waiting for + connections and dealing with a connection. + + + It has 8 columns: + + + + pool_pid is the PID of the + displayed Pgpool-II process. + + + + + start_time is the timestamp of when + this process was launched. - - - pool_pid is the PID of the - displayed Pgpool-II process. - - - - - start_time is the timestamp of when - this process was launched. - - - - - database is the database name of the - currently active backend for this process. - - - - - username is the user name used in the - connection of the currently active backend for this - process. - - - - - create_time is the creation time and - date of the connection. - - - - - pool_counter counts the number of times - this pool of connections (process) has been used by - clients. - - - - - - Here is an example session: - + + + If is set not 0, + the time before process restarting is displayed. + + + + + + + + client_connection_count counts the number of times + this process has been used by clients. + + + + + database is the database name of the + currently active backend for this process. + + + + + username is the user name used in the + connection of the currently active backend for this + process. + + + + + backend_connection_time is the creation time and + date of the connection. + + + + + pool_counter counts the number of times + this pool of connections (process) has been used by + clients. + + + + + status is current status of this process. Possible values are: + + + + Execute command: Executing a command. + + + + + Idle: The process is waiting for a new client command. + + + + + Idle: The process is waiting for a new client command + in a transaction. + + + + + Wait for connection: The process is waiting for a new client connection. + + + + + + + + + Here is an example session: + test=# show pool_processes; - pool_pid | start_time | database | username | create_time | pool_counter -----------+---------------------+----------+----------+---------------------+-------------- - 19696 | 2016-10-17 13:24:17 | postgres | t-ishii | 2016-10-17 13:35:12 | 1 - 19697 | 2016-10-17 13:24:17 | | | | - 19698 | 2016-10-17 13:24:17 | | | | - 19699 | 2016-10-17 13:24:17 | | | | - 19700 | 2016-10-17 13:24:17 | | | | - 19701 | 2016-10-17 13:24:17 | | | | - 19702 | 2016-10-17 13:24:17 | | | | - 19703 | 2016-10-17 13:24:17 | | | | - 19704 | 2016-10-17 13:24:17 | | | | - 19705 | 2016-10-17 13:24:17 | | | | - 19706 | 2016-10-17 13:24:17 | | | | - 19707 | 2016-10-17 13:24:17 | | | | - 19708 | 2016-10-17 13:24:17 | | | | - 19709 | 2016-10-17 13:24:17 | | | | - 19710 | 2016-10-17 13:24:17 | | | | - 19711 | 2016-10-17 13:24:17 | | | | - 19712 | 2016-10-17 13:24:17 | | | | - 19713 | 2016-10-17 13:24:17 | | | | - 19714 | 2016-10-17 13:24:17 | | | | - 19715 | 2016-10-17 13:24:17 | | | | - 19716 | 2016-10-17 13:24:17 | | | | - 19717 | 2016-10-17 13:24:17 | | | | - 19718 | 2016-10-17 13:24:17 | | | | - 19719 | 2016-10-17 13:24:17 | | | | - 19720 | 2016-10-17 13:24:17 | | | | - 20024 | 2016-10-17 13:33:46 | | | | - 19722 | 2016-10-17 13:24:17 | test | t-ishii | 2016-10-17 13:34:42 | 1 - 19723 | 2016-10-17 13:24:17 | | | | - 19724 | 2016-10-17 13:24:17 | | | | - 19725 | 2016-10-17 13:24:17 | | | | - 19726 | 2016-10-17 13:24:17 | | | | - 19727 | 2016-10-17 13:24:17 | | | | -(32 rows) - - - + pool_pid | start_time | client_connection_count | database | username | backend_connection_time | pool_counter | status +----------+------------------------------------------------------+-------------------------+----------+----------+-------------------------+--------------+--------------------- + 32641 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32642 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32643 | 2021-09-28 04:40:45 | 0 | test | kawamoto | 2021-09-28 04:40:48 | 1 | Idle + 32644 | 2021-09-28 04:40:45 | 0 | test | kawamoto | 2021-09-28 04:43:15 | 1 | Execute command + 32645 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32646 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32647 | 2021-09-28 04:40:45 | 0 | | | | | Wait for connection + 32648 | 2021-09-28 04:40:45 (3:15 before process restarting) | 2 | | | | | Wait for connection +(8 rows) + + + diff --git a/doc/src/sgml/ref/show_pool_status.sgml b/doc/src/sgml/ref/show_pool_status.sgml index 09667a901..5cf3a16fd 100644 --- a/doc/src/sgml/ref/show_pool_status.sgml +++ b/doc/src/sgml/ref/show_pool_status.sgml @@ -4,51 +4,51 @@ --> - - SHOW POOL_STATUS - - - - SHOW POOL STATUS - 1 - SQL - Language Statements - - - - SHOW POOL STATUS - - sends back the list of configuration parameters with their name, - value, and description - - - - - -SHOW POOL_STATUS - - - - - Description - - - SHOW POOL_STATUS displays the current value of - Pgpool-II configuration parameters. - - - This command is similar to the - command, but this is the older - version of it. It is recommended to - use instead. - - - - - See Also - - - - - + + SHOW POOL_STATUS + + + + SHOW POOL STATUS + 1 + SQL - Language Statements + + + + SHOW POOL STATUS + + sends back the list of configuration parameters with their name, + value, and description + + + + + + SHOW POOL_STATUS + + + + + Description + + + SHOW POOL_STATUS displays the current value of + Pgpool-II configuration parameters. + + + This command is similar to the + command, but this is the older + version of it. It is recommended to + use instead. + + + + + See Also + + + + + diff --git a/doc/src/sgml/ref/show_pool_version.sgml b/doc/src/sgml/ref/show_pool_version.sgml index ae55ce58a..c36798667 100644 --- a/doc/src/sgml/ref/show_pool_version.sgml +++ b/doc/src/sgml/ref/show_pool_version.sgml @@ -4,46 +4,46 @@ --> - - SHOW POOL_VERSION - - - - SHOW POOL_VERSION - 1 - SQL - Language Statements - - - - SHOW POOL_VERSION - - displays a string containing - the Pgpool-II release number. - - - - - -SHOW POOL_VERSION - - - - - Description - - - SHOW POOL_VERSION displays a string - containing the Pgpool-II release - number. Here is an example session: - -test=# show pool_version; - pool_version --------------------------- - 3.6.0 (subaruboshi) -(1 row) - - - - + + SHOW POOL_VERSION + + + + SHOW POOL_VERSION + 1 + SQL - Language Statements + + + + SHOW POOL_VERSION + + displays a string containing + the Pgpool-II release number. + + + + + + SHOW POOL_VERSION + + + + + Description + + + SHOW POOL_VERSION displays a string + containing the Pgpool-II release + number. Here is an example session: + + test=# show pool_version; + pool_version + -------------------------- + 3.6.0 (subaruboshi) + (1 row) + + + + diff --git a/doc/src/sgml/ref/watchdog_setup.sgml b/doc/src/sgml/ref/watchdog_setup.sgml index b1a70534f..76d7f2f03 100644 --- a/doc/src/sgml/ref/watchdog_setup.sgml +++ b/doc/src/sgml/ref/watchdog_setup.sgml @@ -17,7 +17,7 @@ Pgpool-II documentation watchdog_setup - Create a temporary installation of Pgpool-II clusters with watchdog + Create a temporary installation of Pgpool-II clusters with watchdog @@ -32,396 +32,421 @@ Pgpool-II documentation Description - watchdog_setup creates a temporary - installation of Pgpool-II clusters with watchdog enabled, which - includes a Pgpool-II installation and - specified number of PostgreSQL - installations under current directory. - Current directory must be empty before running watchdog_setup. + watchdog_setup creates a temporary + installation of Pgpool-II clusters with watchdog enabled, which + includes a Pgpool-II installation and + specified number of PostgreSQL + installations under current directory. + Current directory must be empty before running watchdog_setup. - watchdog_setup is for testing purpose - only and should not be used to create production installations. - Also please note that heartbeat is not used. + watchdog_setup is for testing purpose + only and should not be used to create production installations. - watchdog_setup - uses as a workhorse. + watchdog_setup + uses as a workhorse. - Currently watchdog_setup supports streaming replication mode, native replication mode, logical replication mode and raw mode. + Currently watchdog_setup supports streaming replication mode, snapshot isolation mode, native replication mode, logical replication mode and raw mode.
Options - - watchdog_setup accepts the following command-line arguments: - - - - - - - - Specifies the number of Pgpool-II installations. - If this is omitted, 3 is used. - - - - - - - - - Specify the starting base port number used by Pgpool-II and - PostgreSQL. For the first Pgpool-II, Pgpool-II port is - watchdog_base_port. pcp port is watchdog_base_port + 1, watchdog port is - watchdog_base_port + 2. wd_heartbeat_port is - watchdog_base_port + 3 (though heartbeat is not used). The - first PostgreSQL node's port is watchdog_base_port + 4, - second PostgreSQL node's port is watchdog_base_port + 5 and - so on. - - - If this is omitted, 50000 is used. - - - - - - - - - Specifies the running mode. mode - can be r (native replication mode), s (streaming replication mode), or - n (raw mode). - If this is omitted, s is used. - - - - - - - - - Specifies the number of PostgreSQL installations. - If this is omitted, 2 is used. - - - - - - - - - Do not stop pgpool and PostgreSQL after the work. - - - - - - - - - Start pgpool with debug mode. - - - - - + + watchdog_setup accepts the following command-line arguments: + + + + + + + + Specifies the number of Pgpool-II installations. + If this is omitted, 3 is used. + + + + + + + + + Specify the starting base port number used by Pgpool-II and + PostgreSQL. For the first Pgpool-II, Pgpool-II port is + watchdog_base_port. pcp port is watchdog_base_port + 1, watchdog port is + watchdog_base_port + 2. wd_heartbeat_port is + watchdog_base_port + 3 (though heartbeat is not used). The + first PostgreSQL node's port is watchdog_base_port + 4, + second PostgreSQL node's port is watchdog_base_port + 5 and + so on. + + + If this is omitted, 50000 is used. + + + + + + + + + Specifies the running mode. mode + can be r (native replication mode), i (snapshot isolation mode), s (streaming replication mode), l (logical replication mode) or n (raw mode). + If this is omitted, s is used. + + + + + + + + + Specifies the number of PostgreSQL installations. + If this is omitted, 2 is used. + + + + + + + + + Specify the virtual IP. If ip is omitted, it is assumed that + '127.0.0.1' is specified. The specified virtual IP is set + to parameter. Even if virtual + IP is specified, it will not be set to the system: just you + could confirm the action trying to set the virtual IP + in , or the log file, yet + this is useful how Pgpool-II reacts + trying to set the virtual IP. In additioin to delegate_ip, + following parameters will be set too. + + if_up_cmd = '/usr/bin/echo "if_up_cmd executed"' + if_down_cmd = 'usr/bin/echo "if_down_cmd executed"' + arping_cmd = '/usr/bin/true' + + + + + + + + + + Do not stop pgpool and PostgreSQL after the work. + + + + + + + + + Start pgpool with debug mode. + + + + + Environment variables - - watchdog_setup recognizes following environment variables: - - - - - - - - Specifies the path to pgpool_setup command. The default is - "pgpool_setup", thus it is assumed that pgpool_setup is in the - command search path. - - - - - - - - - Specifies the Pgpool-II installation directory. Pgpool-II - binaries is expected to be placed under PGPOOL_INSTALL_DIR/bin - and pgpool.conf and pool_hba.conf etc. are expected to be placed under - PGPOOL_INSTALL_DIR/etc. The default is /usr/local. - - - - - - - - - Specifies the path to Pgpool-II configuration files. - The default is PGPOOL_INSTALL_DIR/etc. - - - - - - - - - Specifies the path to PostgreSQL commands such as initdb, pg_ctl and psql. - The default is /usr/local/pgsql/bin. - - - - - - - - - Specifies the path to PostgreSQL shared libraries. - The default is /usr/local/pgsql/lib. - - - - - - - - - Specifies the path to Unix socket directory. - The default is /tmp. - - - - - - - - Specifies the arguments for initdb command. - The default is "--no-locale -E UTF_8". - - - - - - - + + watchdog_setup recognizes following environment variables: + + + + + + + + Specifies the path to pgpool_setup command. The default is + "pgpool_setup", thus it is assumed that pgpool_setup is in the + command search path. + + + + + + + + + Specifies the Pgpool-II installation directory. Pgpool-II + binaries is expected to be placed under PGPOOL_INSTALL_DIR/bin + and pgpool.conf and pool_hba.conf etc. are expected to be placed under + PGPOOL_INSTALL_DIR/etc. The default is /usr/local. + + + + + + + + + Specifies the path to Pgpool-II configuration files. + The default is PGPOOL_INSTALL_DIR/etc. + + + + + + + + + Specifies the path to PostgreSQL commands such as initdb, pg_ctl and psql. + The default is /usr/local/pgsql/bin. + + + + + + + + + Specifies the path to PostgreSQL shared libraries. + The default is /usr/local/pgsql/lib. + + + + + + + + + Specifies the path to Unix socket directory. + The default is /tmp. + + + + + + + + Specifies the arguments for initdb command. + The default is "--no-locale -E UTF_8". + + + + + + + Example - - -$ watchdog_setup -Starting set up -============= setting up pgpool 0 ============= -Starting set up in streaming replication mode -creating startall and shutdownall -creating failover script -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data0...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data1...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -temporarily start data0 cluster to create extensions -temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) - -recovery node 1...pcp_recovery_node -- Command Successful -done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | true | 0 -(2 rows) - -shutdown all - -pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/startall. -To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/shutdownall. -pcp command user name is "t-ishii", password is "t-ishii". -Each PostgreSQL, pgpool-II and pcp port is as follows: -#1 port is 51000 -#2 port is 51001 -pgpool port is 50000 -pcp port is 50001 -The info above is in README.port. -============= setting up pgpool 1 ============= -Starting set up in streaming replication mode -creating startall and shutdownall -creating failover script -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data0...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data1...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -temporarily start data0 cluster to create extensions -temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) - -recovery node 1...pcp_recovery_node -- Command Successful -done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 -(2 rows) - -shutdown all - -pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/startall. -To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/shutdownall. -pcp command user name is "t-ishii", password is "t-ishii". -Each PostgreSQL, pgpool-II and pcp port is as follows: -#1 port is 51000 -#2 port is 51001 -pgpool port is 50004 -pcp port is 50005 -The info above is in README.port. -============= setting up pgpool 2 ============= -Starting set up in streaming replication mode -creating startall and shutdownall -creating failover script -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data0...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data1...done. -update postgresql.conf -creating pgpool_remote_start -creating basebackup.sh -creating recovery.conf -temporarily start data0 cluster to create extensions -temporarily start pgpool-II to create standby nodes -INFO: unrecognized configuration parameter "debug_level" - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) - -recovery node 1...pcp_recovery_node -- Command Successful -done. -creating follow master script -Pager usage is off. - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 - 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 -(2 rows) - -shutdown all - -pgpool-II setting for streaming replication mode is done. -To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/startall. -To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/shutdownall. -pcp command user name is "t-ishii", password is "t-ishii". -Each PostgreSQL, pgpool-II and pcp port is as follows: -#1 port is 51000 -#2 port is 51001 -pgpool port is 50008 -pcp port is 50009 -The info above is in README.port. - -$ ls -pgpool0 pgpool1 pgpool2 shutdownall startall - -$ sh startall -waiting for server to start....16123 2016-08-18 16:26:53 JST LOG: redirecting log output to logging collector process -16123 2016-08-18 16:26:53 JST HINT: Future log output will appear in directory "pg_log". - done -server started -waiting for server to start....16136 2016-08-18 16:26:54 JST LOG: redirecting log output to logging collector process -16136 2016-08-18 16:26:54 JST HINT: Future log output will appear in directory "pg_log". - done -server started - -t-ishii@localhost: psql -p 50000 test - -Pager usage is off. -psql (9.5.4) -Type "help" for help. - -test=# \q - -$ pcp_watchdog_info -p 50001 -v -Password: -Watchdog Cluster Information -Total Nodes : 3 -Remote Nodes : 2 -Quorum state : QUORUM EXIST -Alive Remote Nodes : 2 -VIP up on local node : NO -Master Node Name : Linux_tishii-CF-SX3HE4BP_50004 -Master Host Name : localhost - -Watchdog Node Information -Node Name : Linux_tishii-CF-SX3HE4BP_50000 -Host Name : localhost -Delegate IP : Not_Set -Pgpool port : 50000 -Watchdog port : 50002 -Node priority : 1 -Status : 7 -Status Name : STANDBY - -Node Name : Linux_tishii-CF-SX3HE4BP_50004 -Host Name : localhost -Delegate IP : Not_Set -Pgpool port : 50004 -Watchdog port : 50006 -Node priority : 1 -Status : 4 -Status Name : MASTER - -Node Name : Linux_tishii-CF-SX3HE4BP_50008 -Host Name : localhost -Delegate IP : Not_Set -Pgpool port : 50008 -Watchdog port : 50010 -Node priority : 1 -Status : 7 -Status Name : STANDBY - - - + + + $ watchdog_setup + Starting set up + ============= setting up pgpool 0 ============= + Starting set up in streaming replication mode + creating startall and shutdownall + creating failover script + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data0...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/data1...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + temporarily start data0 cluster to create extensions + temporarily start pgpool-II to create standby nodes + INFO: unrecognized configuration parameter "debug_level" + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 + (2 rows) + + recovery node 1...pcp_recovery_node -- Command Successful + done. + creating follow primary script + Pager usage is off. + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | false | 0 + 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | true | 0 + (2 rows) + + shutdown all + + pgpool-II setting for streaming replication mode is done. + To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/startall. + To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool0/shutdownall. + pcp command user name is "t-ishii", password is "t-ishii". + Each PostgreSQL, pgpool-II and pcp port is as follows: + #1 port is 51000 + #2 port is 51001 + pgpool port is 50000 + pcp port is 50001 + The info above is in README.port. + ============= setting up pgpool 1 ============= + Starting set up in streaming replication mode + creating startall and shutdownall + creating failover script + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data0...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/data1...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + temporarily start data0 cluster to create extensions + temporarily start pgpool-II to create standby nodes + INFO: unrecognized configuration parameter "debug_level" + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 + (2 rows) + + recovery node 1...pcp_recovery_node -- Command Successful + done. + creating follow primary script + Pager usage is off. + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 + (2 rows) + + shutdown all + + pgpool-II setting for streaming replication mode is done. + To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/startall. + To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool1/shutdownall. + pcp command user name is "t-ishii", password is "t-ishii". + Each PostgreSQL, pgpool-II and pcp port is as follows: + #1 port is 51000 + #2 port is 51001 + pgpool port is 50004 + pcp port is 50005 + The info above is in README.port. + ============= setting up pgpool 2 ============= + Starting set up in streaming replication mode + creating startall and shutdownall + creating failover script + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data0...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + creating database cluster /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/data1...done. + update postgresql.conf + creating pgpool_remote_start + creating basebackup.sh + creating recovery.conf + temporarily start data0 cluster to create extensions + temporarily start pgpool-II to create standby nodes + INFO: unrecognized configuration parameter "debug_level" + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | down | 0.500000 | standby | 0 | false | 0 + (2 rows) + + recovery node 1...pcp_recovery_node -- Command Successful + done. + creating follow primary script + Pager usage is off. + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay + ---------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- + 0 | /tmp | 51000 | up | 0.500000 | primary | 0 | true | 0 + 1 | /tmp | 51001 | up | 0.500000 | standby | 0 | false | 0 + (2 rows) + + shutdown all + + pgpool-II setting for streaming replication mode is done. + To start the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/startall. + To shutdown the whole system, use /home/t-ishii/work/pgpool-II/current/pgpool2/src/test/a/pgpool2/shutdownall. + pcp command user name is "t-ishii", password is "t-ishii". + Each PostgreSQL, pgpool-II and pcp port is as follows: + #1 port is 51000 + #2 port is 51001 + pgpool port is 50008 + pcp port is 50009 + The info above is in README.port. + + $ ls + pgpool0 pgpool1 pgpool2 shutdownall startall + + $ sh startall + waiting for server to start....16123 2016-08-18 16:26:53 JST LOG: redirecting log output to logging collector process + 16123 2016-08-18 16:26:53 JST HINT: Future log output will appear in directory "pg_log". + done + server started + waiting for server to start....16136 2016-08-18 16:26:54 JST LOG: redirecting log output to logging collector process + 16136 2016-08-18 16:26:54 JST HINT: Future log output will appear in directory "pg_log". + done + server started + + t-ishii@localhost: psql -p 50000 test + + Pager usage is off. + psql (9.5.4) + Type "help" for help. + + test=# \q + + $ pcp_watchdog_info -p 50001 -v + Password: + Watchdog Cluster Information + Total Nodes : 3 + Remote Nodes : 2 + Member Remote Nodes : 2 + Nodes required for quorum: 2 + Quorum state : QUORUM EXIST + Alive Remote Nodes : 2 + VIP up on local node : NO + Leader Node Name : Linux_tishii-CF-SX3HE4BP_50004 + Leader Host Name : localhost + + Watchdog Node Information + Node Name : Linux_tishii-CF-SX3HE4BP_50000 + Host Name : localhost + Delegate IP : Not_Set + Pgpool port : 50000 + Watchdog port : 50002 + Node priority : 1 + Status : 7 + Status Name : STANDBY + Membership Status : MEMBER + + Node Name : Linux_tishii-CF-SX3HE4BP_50004 + Host Name : localhost + Delegate IP : Not_Set + Pgpool port : 50004 + Watchdog port : 50006 + Node priority : 1 + Status : 4 + Status Name : LEADER + Membership Status : MEMBER + + Node Name : Linux_tishii-CF-SX3HE4BP_50008 + Host Name : localhost + Delegate IP : Not_Set + Pgpool port : 50008 + Watchdog port : 50010 + Node priority : 1 + Status : 7 + Status Name : STANDBY + Membership Status : MEMBER + + + diff --git a/doc/src/sgml/ref/wd_cli.sgml b/doc/src/sgml/ref/wd_cli.sgml new file mode 100644 index 000000000..7944dfd04 --- /dev/null +++ b/doc/src/sgml/ref/wd_cli.sgml @@ -0,0 +1,284 @@ + + + + + wd_cli + + + + wd_cli + 1 + Other Commands + + + + wd_cli + + Watchdog Command Line Interface (CLI) utility for the + external health-check system integration. + + + + + + wd_cli + operation + node search option + option + + + + + Description + + wd_cli + Provides a convenient and easy to use interface to interact with + watchdog and perform health check related node operations. + + + + + Operations + + + + + + + + + Get the node status for node(s) based on node search criteria + + + + + + + + + + Update the watchdog node status. + Allowed values are DEAD and ALIVE + + + + + + + + + + Node Search Options + + + + + + + + + Select all nodes (only available with --info operation) + + + + + + + + + + Select watchdog node by node_id. + + + + + + + + + + Select watchdog node by name. + + + + + + + + + + Select watchdog node by hostname. + + + + + + + + + + Select watchdog node by port number. + + + + + + + + + + + Options + + + + + + + + + Watchdog auth key. + Specifying auth-key over rides the pgpool.conf->wd_authkey value. + + + + + + + + + + Specifies the pgpool.conf file. + + + + + + + + + + Path to the watchdog IPC socket directory. + Specifying socket-dir over rides the pgpool.conf->wd_ipc_socket_dir value. + + + + + + + + + + Port number of watchdog IPC socket. + Specifying ipc-port over rides the pgpool.conf->wd_port value. + + + + + + + + + + + Optional message string to be passed to Pgpool-II along with the node status. + + + + + + + + + + Enable verbose messages. + + + + + + + + + + Prints version information. + + + + + + + + + + Enable debug output. + + + + + + + + + + Prints the help for wd_cli. + + + + + + + + + + Example + + When some external health-check system is configured + to monitor the health of Pgpool-II cluster + and it detects a node failure. wd_cli utility can + be used to pass this information to Pgpool-II + cluster so that it can take the appropriate actions. + + + #inform Pgpool-II about node named RN-110 failure + wd_cli --inform DEAD -N 'RN-110' -p 9001 -m 'Pgpool node with name RN-110 is not reachable' + + + #inform Pgpool-II about node-id 10 failure + wd_cli --inform DEAD -n 10 -m 'Pgpool node with ID 10 is not responding' + + Similarly to inform Pgpool-II about the node is alive again. + + #inform Pgpool-II about node-id 10 re-joining + wd_cli --inform ALIVE -n 10 -m 'Pgpool node with ID 10 is reachable again' + + + wd_cli can also be used to get the current status of cluster nodes. + + wd_cli -f simple_conf/watchdog/pgpool_wd1.conf --info -v --all + + Total Watchdog nodes configured for lifecheck: 2 + ***************** + Node ID: 0 + Node Status code 4 + Node Status: LEADER + Node Name: localhost:9991 Linux localhost.localdomain + Node Host: localhost + Node WD Port: 9001 + Node Pgpool Port: 9991 + + Node ID: 1 + Node Status code 7 + Node Status: STANDBY + Node Name: localhost:9992 Linux localhost.localdomain + Node Host: localhost + Node WD Port: 9002 + Node Pgpool Port: 9992 + + + + + diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml index 0130e7c8d..6d2ea97ce 100644 --- a/doc/src/sgml/reference.sgml +++ b/doc/src/sgml/reference.sgml @@ -1,243 +1,261 @@ - Reference + Reference + + + + This part contains reference information for the Pgpool-II. + + + + The reference entries are also available as traditional + man pages. + + + + + Server commands + + This part contains reference information for server + commands. Currently only pgpool falls into + this category. + + + &pgpool; + + + + PCP commands + + + + This part contains reference information for PCP commands. + PCP commands are UNIX commands which manipulate pgpool-II via + the network. Please note that the parameter format for all + PCP commands has been changed since Pgpool-II + 3.5. + + + + PCP connection authentication + + PCP user names and passwords must be declared in + pcp.conf + in $prefix/etc directory + (see to know to create + the file). option can be used when + starting + Pgpool-II + if pcp.conf is placed somewhere else. + + + + + PCP password file + + The file .pcppass .pcppass in a user's home + directory or the file referenced by environment variable + PCPPASSFILE PCPPASSFILE can contain passwords to be used if no password has + been specified for the pcp connection (In Pgpool-II 4.4 or before, -w/--no-password option is needed). + See for more details. + + + This file should contain lines of the following format: + + + hostname:port:username:password + + + + + (You can add a reminder comment to the file by copying the line + above and preceding it with #.) Each of the first three fields + can be a literal value, or *, which matches anything. The password + field from the first line that matches the current connection + parameters will be used. (Therefore, put more-specific entries + first when you are using wildcards.) If an entry needs to contain + : or \, escape this character with \. The hostname field is matched + to the host connection parameter if that is specified, if the host + parameter is not 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 the default pcp socket directory path. + + - This part contains reference information for the Pgool-II. + The permissions on .pcppass must disallow any access to world or + group; achieve this by the command chmod 0600 ~/.pcppass. If the + permissions are less strict than this, the file will be + ignored. + + + + + &pcpCommonOptions; + &pcpNodeCount; + &pcpNodeInfo; + &pcpHealthCheckStats; + &pcpWatchdogInfo; + &pcpProcCount; + &pcpProcInfo; + &pcpPoolStatus; + &pcpDetachNode; + &pcpAttachNode; + &pcpPromoteNode; + &pcpStopPgpool; + &pcpReloadConfig; + &pcpRecoveryNode; + &pcpLogRotate; + &pcpInvalidateCache; + + + + + Other commands + + + + This part contains reference information for various Pgpool-II commands. + + + + + &pgMd5; + &pgEnc; + &pgproto; + &pgpoolSetup; + &watchdogSetup; + &wdCli; + + + + + SQL type commands + + + + This part contains reference information for various SQL type + Pgpool-II commands. These commands + can be issued inside the SQL session using the + standard PostgreSQL client + like psql. They are not forwarded to the + backend DB: instead they are processed + by Pgpool-II server. Please note + that SQL type commands cannot be used in extended query + mode. You will get parse errors + from PostgreSQL. + + + + + &pgpoolShow + &pgpoolSet + &pgpoolSetCache + &pgpoolReset + &showPoolStatus + &showPoolNodes + &showPoolProcesses + &showPoolPools + &showPoolVersion + &showPoolCache + &showPoolHealthCheckStats + &showPoolBackendStats + + + + pgpool_adm extension + + + + pgpool_adm is a set of extensions to allow + SQL access to (actually, pcp + libraries). It uses foreign data wrapper as shown in the + diagram below. + + +
+ How <command>pgpool_adm</command> works + + + + + +
+
+ + + It is possible to call the functions from either via pgpool-II + (1) or via PostgreSQL (2). In case + (1), Pgpool-II accepts query from + user (1), then forward + to PostgreSQL (3). + PostgreSQL connects + to Pgpool-II (5) + and Pgpool-II reply back + to PostgreSQL with the result + (3). PostgreSQL returns the result + to Pgpool-II (5) + and Pgpool-II forwards the data to + the user (6). + + + In case (2), PostgreSQL accepts query from user (2). + PostgreSQL connects + to Pgpool-II (5) + and Pgpool-II reply back + to PostgreSQL with the result (3). + PostgreSQL replies back the data to + the user (4). + + + There are two forms to call pgpool_adm functions: first form + accepts Pgpool-II host name (or IP + address), pcp port number, pcp user name, its password and + another parameters. + + + In the second form, Pgpool-II + server name is required. The server name must be already + defined using "CREATE FOREIGN SERVER" command + of PostgreSQL. The pcp port number + is hard coded as 9898, the pcp user name is assumes to be same + as caller's PostgreSQL user name. + password is extracted from $HOME/.pcppass. + + + + Installing pgpool_adm - The reference entries are also available as traditional - man pages. + pgpool_adm is an extension and should be installed on all + PostgreSQL servers. + + $ cd src/sql/pgpool_adm + $ make + $ make install + + Then issue following SQL command for every database you want to access. + + $ psql ... + $ CREATE EXTENSION pgpool_adm + + +
- - Server commands - - - - This part contains reference information for server - commands. Currently only pgpool falls into - this category. - - - &pgpool; - - - - PCP commands - - - - This part contains reference information for PCP commands. - PCP commands are UNIX commands which manipulate pgpool-II via the network. - Please note that the parameter format for all PCP commands has been changed since pgpool-II 3.5. - - - - PCP connection authentication - - PCP user names and passwords must be declared in - pcp.conf in $prefix/etc - directory. option can be used when starting - pgpool-II if pcp.conf is placed somewhere - else. - - - - - PCP password file - - The file .pcppass in a user's home - directory or the file referenced by environment variable - PCPPASSFILE can contain passwords to be used if no password has - been specified for the pcp connection. - - - This file should contain lines of the following format: - - - hostname:port:username:password - - - - - (You can add a reminder comment to the file by copying the line - above and preceding it with #.) Each of the first three fields - can be a literal value, or *, which matches anything. The password - field from the first line that matches the current connection - parameters will be 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 - connections coming from the local machine. - - - - The permissions on .pcppass must disallow any access to world or - group; achieve this by the command chmod 0600 ~/.pcppass. If the - permissions are less strict than this, the file will be - ignored. - - - - - - - &pcpCommonOptions; - &pcpNodeCount; - &pcpNodeInfo; - &pcpWatchdogInfo; - &pcpProcCount; - &pcpProcInfo; - &pcpPoolStatus; - &pcpDetachNode; - &pcpAttachNode; - &pcpPromoteNode; - &pcpStopPgpool; - &pcpRecoveryNode; - - - - - Other commands - - - - This part contains reference information for various Pgpool-II commands. - - - - - &pgMd5; - &pgEnc; - &pgproto; - &pgpoolSetup; - &watchdoglSetup; - - - - - SQL type commands - - - - This part contains reference information for various SQL type - Pgpool-II commands. These commands - can be issued inside the SQL session using the - standard PostgreSQL client - like psql. They are not forwarded to the - backend DB: instead they are processed - by Pgpool-II server. Please note - that SQL type commands cannot be used in extended query - mode. You will get parse errors - from PostgreSQL. - - - - - &pgpoolShow - &pgpoolSet - &pgpoolReset - &showPoolStatus - &showPoolNodes - &showPoolProcesses - &showPoolPools - &showPoolVersion - &showPoolCache - - - - - pgpool_adm extension - - - - pgpool_adm is a set of extensions to allow - SQL access to (actually, pcp - libraries). It uses foreign data wrapper as shown in the - diagram below. - - -
- How <command>pgpool_adm</command> works - - - - - -
-
- - - It is possible to call the functions from either via pgpool-II - (1) or via PostgreSQL (2). In case - (1), Pgpool-II accepts query from - user (1), then forward - to PostgreSQL (3). - PostgreSQL connects - to Pgpool-II (5) - and Pgpool-II reply back - to PostgreSQL with the result - (3). PostgreSQL returns the result - to Pgpool-II (5) - and Pgpool-II fowards the data to - the user (6). - - - In case (2), PostgreSQL accepts query from user (2). - PostgreSQL connects - to Pgpool-II (5) - and Pgpool-II reply back - to PostgreSQL with the result (3). - PostgreSQL replies back the data to - the user (6). - - - There are two forms to call pgpool_adm functions: first form - accepts Pgpool-II host name (or IP - address), pcp port number, pcp user name, its password and - another parameters. - - - In the second form, Pgpool-II - server name is required. The server name must be already - defined using "CREATE FOREIGN SERVER" command - of PostgreSQL. The pcp port number - is hard coded as 9898, the pcp user name is assumes to be same - as caller's PostgreSQL user name. - password is extraced from $HOME/.pcppass. - - - - Installing pgpool_adm - - pgpool_adm is an extension and should be installed on all - PostgreSQL servers. - -$ cd src/sql/pgpool_adm -$ make -$ make install - - Then issue following SQL command for every database you want to access. - -$ psql ... -$ CREATE EXTENSION pgpool_adm - - - - -
- - &pgpoolAdmPcpNodeInfo - &pgpoolAdmPcpPoolStatus - &pgpoolAdmPcpNodeCount - &pgpoolAdmPcpAttachNode - &pgpoolAdmPcpDetachNode - -
+ &pgpoolAdmPcpNodeInfo + &pgpoolAdmPcpHealthCheckStats + &pgpoolAdmPcpPoolStatus + &pgpoolAdmPcpNodeCount + &pgpoolAdmPcpAttachNode + &pgpoolAdmPcpDetachNode + &pgpoolAdmPcpProcInfo + +
diff --git a/doc/src/sgml/release-3.1.sgml b/doc/src/sgml/release-3.1.sgml index 6eccad056..1d4af1346 100644 --- a/doc/src/sgml/release-3.1.sgml +++ b/doc/src/sgml/release-3.1.sgml @@ -2,57 +2,57 @@ - Release 3.1.21 - - - Release Date - 2016-12-26 - - - - Bug fixes - - - - - - - Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) - - - It was intended to keep the consistency, but there's no point in other - than native replication mode. - - - - - - - Do not use random() while generating MD5 salt. (Tatsuo Ishii) - - - random() should not be used in security related applications. To - replace random(), import PostmasterRandom() from PostgreSQL. Also - store current time at the start up of Pgpool-II main process for later - use. - - - - - - - Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) - - - - - - + Release 3.1.21 + + + Release Date + 2016-12-26 + + + + Bug fixes + + + + + + + Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) + + + It was intended to keep the consistency, but there's no point in other + than native replication mode. + + + + + + + Do not use random() while generating MD5 salt. (Tatsuo Ishii) + + + random() should not be used in security related applications. To + replace random(), import PostmasterRandom() from PostgreSQL. Also + store current time at the start up of Pgpool-II main process for later + use. + + + + + + + Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) + + + + + + diff --git a/doc/src/sgml/release-3.2.sgml b/doc/src/sgml/release-3.2.sgml index 51eb91210..4b446f37c 100644 --- a/doc/src/sgml/release-3.2.sgml +++ b/doc/src/sgml/release-3.2.sgml @@ -2,165 +2,165 @@ - Release 3.2.22 - - - Release Date - 2017-09-05 - - - - Bug fixes - - - - - - Doc: Fix documentation about load-balancing. (Yugo Nagata) - - - - - - - - - - Fix ancient bug of pool_unread(). (Tatsuo Ishii) - - - When realloc() is called in pool_unread(), it did not update the - buffer size. This could cause variety of memory corruption and - unexpected data reading from backend. The reason why we did not found - that is, probably recently Pgpool-II starts extensively to use - pool_unread(). - - - - - - - - Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) - - - This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). - - - - - - - Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) - - - - - - - Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) - - - - - + Release 3.2.22 + + + Release Date + 2017-09-05 + + + + Bug fixes + + + + + + Doc: Fix documentation about load-balancing. (Yugo Nagata) + + + + + + + + + + Fix ancient bug of pool_unread(). (Tatsuo Ishii) + + + When realloc() is called in pool_unread(), it did not update the + buffer size. This could cause variety of memory corruption and + unexpected data reading from backend. The reason why we did not found + that is, probably recently Pgpool-II starts extensively to use + pool_unread(). + + + + + + + + Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) + + + This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). + + + + + + + Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) + + + + + + + Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) + + + + + - Release 3.2.21 + Release 3.2.21 - - Release Date - 2017-07-11 - + + Release Date + 2017-07-11 + - - Bug fixes + + Bug fixes - - + + - Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) + Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) - + - + - Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) + Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn - + - + - Fix query cache hang when used by node.js. (Tatsuo Ishii) + Fix query cache hang when used by node.js. (Tatsuo Ishii) - See [pgpool-general: 5511] for more details. + See [pgpool-general: 5511] for more details. - + - + - Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) + Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) - + - + - Fix query cache memory leak. (Tatsuo Ishii) + Fix query cache memory leak. (Tatsuo Ishii) - Clearing cache buffers in case of no oid queries (like BEGIN, - CHECKPOINT, VACUUM, etc) should have been done, but it did not. - Fix query cache memory leak. (Tatsuo Ishii) + Clearing cache buffers in case of no oid queries (like BEGIN, + CHECKPOINT, VACUUM, etc) should have been done, but it did not. + Fix query cache memory leak. (Tatsuo Ishii) - - - + + + - Release 3.2.20 + Release 3.2.20 - - Release Date - 2017-04-28 - + + Release Date + 2017-04-28 + - - Bug fixes + + Bug fixes - - + + @@ -169,210 +169,210 @@ Fix for 0000299: Errors on the reloading of configuration. (Bug 299) (Muhammad Usama) - + - + - + - Release 3.2.19 + Release 3.2.19 - - Release Date - 2017-03-17 - + + Release Date + 2017-03-17 + - - Bug fixes + + Bug fixes - + - + - Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) + Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) - The master node could not be promoted by pcp_promote_node with - the following error; + The master node could not be promoted by pcp_promote_node with + the following error; FATAL: invalid pgpool mode for process recovery request DETAIL: specified node is already primary node, can't promote node id 0 - + - In streaming replication mode, there is a case that Pgpool-II - regards the status of primary node as "standby" for some reasons, - for example, when pg_ctl promote is executed manually during - Pgpool-II is running, in which case, it seems to Pgpool-II - that the primary node doesn't exist. + In streaming replication mode, there is a case that Pgpool-II + regards the status of primary node as "standby" for some reasons, + for example, when pg_ctl promote is executed manually during + Pgpool-II is running, in which case, it seems to Pgpool-II + that the primary node doesn't exist. - This status mismatch should be fixe by pcp_promote_node, but when the node - is the master node (the first alive node), it fails as mentioned above. + This status mismatch should be fixed by pcp_promote_node, but when the node + is the master node (the first alive node), it fails as mentioned above. - The reason is as following. before changing the status, pcp_promote_node - checks if the specified node is already primary or not by comparing the - node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from - Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. - Hence, when the master node is specified to be promoted, pcp_promote_node - is confused that this node is already primary and doesn't have to be - promoted, and it exits with the error. + The reason is as following. before changing the status, pcp_promote_node + checks if the specified node is already primary or not by comparing the + node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from + Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. + Hence, when the master node is specified to be promoted, pcp_promote_node + is confused that this node is already primary and doesn't have to be + promoted, and it exits with the error. - To fix this, pcp_promote_node should check the node id by using - REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, - rather than PRIMARY_NODE_ID. + To fix this, pcp_promote_node should check the node id by using + REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, + rather than PRIMARY_NODE_ID. - + - + - Add the latest release note link to README file.(Bo Peng) + Add the latest release note link to README file.(Bo Peng) - + - + - Fix to release shared memory segments when Pgpool-IIexits. - (bug 272) (Tatsuo Ishii) + Fix to release shared memory segments when Pgpool-IIexits. + (bug 272) (Tatsuo Ishii) - + - + - Remove pool_log/pool_error calls from signal handlers. (Tatsuo Ishii) + Remove pool_log/pool_error calls from signal handlers. (Tatsuo Ishii) - See [pgpool-hackers: 1950] for details. + See [pgpool-hackers: 1950] for details. - + - + - Fix for 0000249: watchdog sometimes fails de-escalation. - (bug 249) (Muhammad Usama) + Fix for 0000249: watchdog sometimes fails de-escalation. + (bug 249) (Muhammad Usama) - The solution is to use the waitpid() system call without WNOHANG option. + The solution is to use the waitpid() system call without WNOHANG option. - + - + - Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) + Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) - + - + - Fix authentication timeout that can occur right after client connecttions. (Yugo Nagata) + Fix authentication timeout that can occur right after client connections. (Yugo Nagata) - + - + - + - Release 3.2.18 - - - Release Date - 2016-12-26 - - - - Bug fixes - - - - - - - Fix occasional segfault when query cache is enabled. (Tatsuo Ishii) - - - Per bug 263. - - - - - - - Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) - - - It was intended to keep the consistency, but there's no point in other - than native replication mode. - - - - - - - Do not use random() while generating MD5 salt. (Tatsuo Ishii) - - - random() should not be used in security related applications. To - replace random(), import PostmasterRandom() from PostgreSQL. Also - store current time at the start up of Pgpool-II main process for later - use. - - - - - - - Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) - - - - - - + Release 3.2.18 + + + Release Date + 2016-12-26 + + + + Bug fixes + + + + + + + Fix occasional segfault when query cache is enabled. (Tatsuo Ishii) + + + Per bug 263. + + + + + + + Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) + + + It was intended to keep the consistency, but there's no point in other + than native replication mode. + + + + + + + Do not use random() while generating MD5 salt. (Tatsuo Ishii) + + + random() should not be used in security related applications. To + replace random(), import PostmasterRandom() from PostgreSQL. Also + store current time at the start up of Pgpool-II main process for later + use. + + + + + + + Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) + + + + + + diff --git a/doc/src/sgml/release-3.3.sgml b/doc/src/sgml/release-3.3.sgml index 1bccecba5..38a376a0d 100644 --- a/doc/src/sgml/release-3.3.sgml +++ b/doc/src/sgml/release-3.3.sgml @@ -2,396 +2,396 @@ - Release 3.3.22 - - - Release Date - 2018-07-31 - - - - Bug fixes - - - - - Fix "write on backend 0 failed with error :"Success"" error. - (bug 403) (Tatsuo Ishii) - - - Don't treated it as an error if write() returns 0. - - - - - - - Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) - - - Patch provided by Christian Ehrhardt. - - - - + Release 3.3.22 + + + Release Date + 2018-07-31 + + + + Bug fixes + + + + + Fix "write on backend 0 failed with error :"Success"" error. + (bug 403) (Tatsuo Ishii) + + + Don't treated it as an error if write() returns 0. + + + + + + + Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) + + + Patch provided by Christian Ehrhardt. + + + + - Release 3.3.21 + Release 3.3.21 - - Release Date - 2018-04-17 - + + Release Date + 2018-04-17 + - - Bug fixes - - + + Bug fixes + + - Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) - + - - + + - Release 3.3.20 + Release 3.3.20 - - Release Date - 2018-02-13 - + + Release Date + 2018-02-13 + - - Changes - + + Changes + - + - Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) - + - + - Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) - - - + + + - - Bug fixes - + + Bug fixes + - + - Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) - + - - + + - Release 3.3.19 + Release 3.3.19 - - Release Date - 2018-01-09 - + + Release Date + 2018-01-09 + - - Bug fixes - + + Bug fixes + - + - Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) + Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) - Removeing "Type=forking" and add OPTS=" -n" to - run Pgpool-II with non-daemon mode, because we need to redirect logs. - Using "journalctl" command to see Pgpool-II systemd log. + Removing "Type=forking" and add OPTS=" -n" to + run Pgpool-II with non-daemon mode, because we need to redirect logs. + Using "journalctl" command to see Pgpool-II systemd log. - + - + - Fix timestamp data inconsistency by replication mode. (Bo Peng) + Fix timestamp data inconsistency by replication mode. (Bo Peng) - From PostgreSQL10 the column - default value such as 'CURRENT_DATE' changes, - Pgpool-II didn't rewrite - timestamp by the added default values. This caused data inconsistency. + From PostgreSQL10 the column + default value such as 'CURRENT_DATE' changes, + Pgpool-II didn't rewrite + timestamp by the added default values. This caused data inconsistency. - + - + - Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) - We return primary or master node state of ready for query message to - frontend. In most cases this is good. However if other than primary - node or master node returns an error state (this could happen if load - balance node is other than primary or master node and the query is an - errornous SELECT), this should be returned to frontend, because the - frontend already received an error. + We return primary or master node state of ready for query message to + frontend. In most cases this is good. However if other than primary + node or master node returns an error state (this could happen if load + balance node is other than primary or master node and the query is an + erroneous SELECT), this should be returned to frontend, because the + frontend already received an error. - + - - + + - Release 3.3.18 + Release 3.3.18 - - Release Date - 2017-11-01 - + + Release Date + 2017-11-01 + - - Bug fixes - + + Bug fixes + - + - Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) + Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) - In RHEL6, the "-n" option is needed to redirect log. + In RHEL6, the "-n" option is needed to redirect log. - + - + - Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) + Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) - See [pgpool-general: 5728] for mor details. + See [pgpool-general: 5728] for more details. - + - + - Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) + Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) - + - - + + - Release 3.3.17 - - - Release Date - 2017-09-05 - - - - Bug fixes - - - - - - Doc: Fix documentation about load-balancing. (Yugo Nagata) - - - - - - - - - - Fix ancient bug of pool_unread(). (Tatsuo Ishii) - - - When realloc() is called in pool_unread(), it did not update the - buffer size. This could cause variety of memory corruption and - unexpected data reading from backend. The reason why we did not found - that is, probably recently Pgpool-II starts extensively to use - pool_unread(). - - - - - - - - Test: Fix Java program in 005.regression test. (Tatsuo Ishii) - - - - - - - Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) - - - This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). - - - - - - - Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) - - - - - - - Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) - - - - + Release 3.3.17 + + + Release Date + 2017-09-05 + + + + Bug fixes + + + + + + Doc: Fix documentation about load-balancing. (Yugo Nagata) + + + + + + + + + + Fix ancient bug of pool_unread(). (Tatsuo Ishii) + + + When realloc() is called in pool_unread(), it did not update the + buffer size. This could cause variety of memory corruption and + unexpected data reading from backend. The reason why we did not found + that is, probably recently Pgpool-II starts extensively to use + pool_unread(). + + + + + + + + Test: Fix Java program in 005.regression test. (Tatsuo Ishii) + + + + + + + Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) + + + This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). + + + + + + + Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) + + + + + + + Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) + + + + - Release 3.3.16 + Release 3.3.16 - - Release Date - 2017-07-11 - + + Release Date + 2017-07-11 + - - Bug fixes + + Bug fixes - - + + - Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) + Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) - + - + - Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) + Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn - + - + - Fix query cache hang when used by node.js. (Tatsuo Ishii) + Fix query cache hang when used by node.js. (Tatsuo Ishii) - See [pgpool-general: 5511] for more details. + See [pgpool-general: 5511] for more details. - + - + - Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) + Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) - + - + - Fix query cache memory leak. (Tatsuo Ishii) + Fix query cache memory leak. (Tatsuo Ishii) - Clearing cache buffers in case of no oid queries (like BEGIN, - CHECKPOINT, VACUUM, etc) should have been done, but it did not. + Clearing cache buffers in case of no oid queries (like BEGIN, + CHECKPOINT, VACUUM, etc) should have been done, but it did not. - - - + + + - Release 3.3.15 + Release 3.3.15 - - Release Date - 2017-04-28 - + + Release Date + 2017-04-28 + - - Bug fixes + + Bug fixes - - + + @@ -400,323 +400,323 @@ Fix for 0000299: Errors on the reloading of configuration. (Bug 299) (Muhammad Usama) - + - + - Fix coverity warnings. (Muhammad Usama) + Fix coverity warnings. (Muhammad Usama) - + - + - Fix for 0000296: PGPool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. - (Bug 296) (Muhammad Usama) + Fix for 0000296: Pgpool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. + (Bug 296) (Muhammad Usama) - + - + - + - Release 3.3.14 + Release 3.3.14 - - Release Date - 2017-03-17 - + + Release Date + 2017-03-17 + - - Bug fixes + + Bug fixes - + - + - Add "Wants=network.target" to pgpool.service file. - (bug 294) (Bo Peng) + Add "Wants=network.target" to pgpool.service file. + (bug 294) (Bo Peng) - + - + - Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) + Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) - The master node could not be promoted by pcp_promote_node with - the following error; + The master node could not be promoted by pcp_promote_node with + the following error; FATAL: invalid pgpool mode for process recovery request DETAIL: specified node is already primary node, can't promote node id 0 - + - In streaming replication mode, there is a case that Pgpool-II - regards the status of primary node as "standby" for some reasons, - for example, when pg_ctl promote is executed manually during - Pgpool-II is running, in which case, it seems to Pgpool-II - that the primary node doesn't exist. + In streaming replication mode, there is a case that Pgpool-II + regards the status of primary node as "standby" for some reasons, + for example, when pg_ctl promote is executed manually during + Pgpool-II is running, in which case, it seems to Pgpool-II + that the primary node doesn't exist. - This status mismatch should be fixe by pcp_promote_node, but when the node - is the master node (the first alive node), it fails as mentioned above. + This status mismatch should be fixed by pcp_promote_node, but when the node + is the master node (the first alive node), it fails as mentioned above. - The reason is as following. before changing the status, pcp_promote_node - checks if the specified node is already primary or not by comparing the - node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from - Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. - Hence, when the master node is specified to be promoted, pcp_promote_node - is confused that this node is already primary and doesn't have to be - promoted, and it exits with the error. + The reason is as following. before changing the status, pcp_promote_node + checks if the specified node is already primary or not by comparing the + node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from + Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. + Hence, when the master node is specified to be promoted, pcp_promote_node + is confused that this node is already primary and doesn't have to be + promoted, and it exits with the error. - To fix this, pcp_promote_node should check the node id by using - REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, - rather than PRIMARY_NODE_ID. + To fix this, pcp_promote_node should check the node id by using + REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, + rather than PRIMARY_NODE_ID. - + - + - Add the latest release note link to README file.(Bo Peng) + Add the latest release note link to README file.(Bo Peng) - + - + - Fix to release shared memory segments when Pgpool-IIexits. - (bug 272) (Tatsuo Ishii) + Fix to release shared memory segments when Pgpool-IIexits. + (bug 272) (Tatsuo Ishii) - + - + - Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) + Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) - + - + - Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) + Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) - + - + - Fixing stack smashing detected. (bug 280) (Muhammad Usama) + Fixing stack smashing detected. (bug 280) (Muhammad Usama) - It was a buffer overflow in wd_get_cmd function + It was a buffer overflow in wd_get_cmd function - + - + - Remove pool_log/pool_error calls from signal handlers. (Tatsuo Ishii) + Remove pool_log/pool_error calls from signal handlers. (Tatsuo Ishii) - See [pgpool-hackers: 1950] for details. + See [pgpool-hackers: 1950] for details. - + - + - Fix for 0000249: watchdog sometimes fails de-escalation. (bug 249) (Muhammad Usama) + Fix for 0000249: watchdog sometimes fails de-escalation. (bug 249) (Muhammad Usama) - The solution is to use the waitpid() system call without WNOHANG option. + The solution is to use the waitpid() system call without WNOHANG option. - + - + - Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) + Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) - + - + - Fix authentication timeout that can occur right after client connecttions. (Yugo Nagata) + Fix authentication timeout that can occur right after client connections. (Yugo Nagata) - + - + - + - Release 3.3.13 - - - Release Date - 2016-12-26 - - - - Bug fixes - - - - - - - Tightening up the watchdog security. (Muhammad Usama) - - - - Now wd_authkey uses the HMAC SHA-256 hashing. - - - - - - - Add pgpool_adm extension in Pgpool-II RPM. (Bo Peng) - - - - - - - Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) - - - - - - - Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) - - - It was intended to keep the consistency, but there's no point in other - than native replication mode. - - - - - - - Change the default value of search_primary_node_timeout from 10 to 300. (Tatsuo Ishii) - - - Prior default value 10 seconds is sometimes too short for a standby to - be promoted. - - - Per [pgpool-general: 5026]. - - - - - - - Fix the case when all backends are down then 1 node attached. (bug 248) (Tatsuo Ishii) - - - When all backends are down, no connection is accepted. Then 1 - PostgreSQL becomes up, and attach the node using pcp_attach_node. It - successfully finishes. However, when a new connection arrives, still - the connection is refused because pgpool child process looks into the - cached status, in which the recovered node is still in down status if - mode is streaming replication mode (native replication and other modes - are fine). Solution is, if all nodes are down, force to restart all - pgpool child. - - - - - - - Do not use random() while generating MD5 salt. (Tatsuo Ishii) - - - random() should not be used in security related applications. To - replace random(), import PostmasterRandom() from PostgreSQL. Also - store current time at the start up of Pgpool-II main process for later - use. - - - - - - - Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) - - - - - - + Release 3.3.13 + + + Release Date + 2016-12-26 + + + + Bug fixes + + + + + + + Tightening up the watchdog security. (Muhammad Usama) + + + + Now wd_authkey uses the HMAC SHA-256 hashing. + + + + + + + Add pgpool_adm extension in Pgpool-II RPM. (Bo Peng) + + + + + + + Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) + + + + + + + Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) + + + It was intended to keep the consistency, but there's no point in other + than native replication mode. + + + + + + + Change the default value of search_primary_node_timeout from 10 to 300. (Tatsuo Ishii) + + + Prior default value 10 seconds is sometimes too short for a standby to + be promoted. + + + Per [pgpool-general: 5026]. + + + + + + + Fix the case when all backends are down then 1 node attached. (bug 248) (Tatsuo Ishii) + + + When all backends are down, no connection is accepted. Then 1 + PostgreSQL becomes up, and attach the node using pcp_attach_node. It + successfully finishes. However, when a new connection arrives, still + the connection is refused because pgpool child process looks into the + cached status, in which the recovered node is still in down status if + mode is streaming replication mode (native replication and other modes + are fine). Solution is, if all nodes are down, force to restart all + pgpool child. + + + + + + + Do not use random() while generating MD5 salt. (Tatsuo Ishii) + + + random() should not be used in security related applications. To + replace random(), import PostmasterRandom() from PostgreSQL. Also + store current time at the start up of Pgpool-II main process for later + use. + + + + + + + Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) + + + + + + diff --git a/doc/src/sgml/release-3.4.sgml b/doc/src/sgml/release-3.4.sgml index c21aefa4b..7f92a5c7f 100644 --- a/doc/src/sgml/release-3.4.sgml +++ b/doc/src/sgml/release-3.4.sgml @@ -1,21 +1,472 @@ - - Release 3.4.21 - - Release Date - 2018-11-22 - - - - Bug fixes + + Release 3.4.26 + + Release Date + 2019-10-31 + + + + Bug fixes + + + + Fix incorrect query rewrite in replication mode. (Bo Peng) + + + + + + + Fix assorted ancient v2 protocol bugs. (Tatsuo Ishii) + + + + + + + Fix problem that doesn't change by reload. + (bug 548) (Takuma Hoshiai) + + + + + + + Fix Pgpool-II shutdown failed in certain case. (Tatsuo Ishii) + + + + + + + Fix segfault when executing an erroneous query after DEALLOCATE a named statement. + (bug 546) (Tatsuo Ishii) + + + + + + + + Release 3.4.25 + + Release Date + 2019-08-15 + + + + Enhancements + + + + + Import some of memory manager debug facilities from PostgreSQL. (Tatsuo Ishii) + + + + + + Use pg_get_expr() instead of pg_attrdef.adsrc to support for PostgreSQL 12. (Bo Peng) + + + + + + Enhance shutdown script of . (Tatsuo Ishii) + + + + Make shutdownall to wait for completion of shutdown of Pgpool-II. + + + + + If environment variable CHECK_TIME_WAIT is set to true, use netstat command to confirm usage of the TCP/IP port while executing shutdown script. + + + + + + + + + Deal pgpool_adm extension with PostgreSQL 12. (Tatsuo Ishii) + + + + + + Bug fixes + + + + + Fix to produce correct follow master command. (Tatsuo Ishii) + + + + + + + Fix query cache module so that it checks oid array's bound. (Tatsuo Ishii) + + + + + + + Fix off-by-one error in query cache module. (Tatsuo Ishii) + + + + + + + Fix segfault when samenet is specified in pool_hba.conf. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 6601]. + + + + + + + Fix to deal with backslashes according to the config of standard_conforming_strings in native replication mode. + (bug 467) (Bo Peng) + + + + + + + Fix memory leaks. (Tatsuo Ishii) + + + + + + + + Release 3.4.24 + + Release Date + 2019-05-16 + + + + Enhancements + + + + + Speed up failover when all of backends are down. (Tatsuo Ishii) + + + If all of the backend are in down status, immediately give up finding + primary node regardless search_primary_node_timeout and promptly + finish the failover process. + + + Discussion: [pgpool-hackers: 3321] + + + + + + + pgpool-recovery extension and pgpool_setup is now ready for the next major release PostgreSQL 12. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + Fix the wrong error message "ERROR: connection cache is full", when all backend nodes are down. + (bug 487) (Bo Peng) + + + When all backend nodes are down, Pgpool-II throws an incorrect + error message "ERROR: connection cache is full". Change the error + message to "all backend nodes are down, pgpool requires at least one valid node". + + + + + + + Avoid exit/fork storm of pool_worker_child process. (Tatsuo Ishii) + + + pool_worker_child issues query to get WAL position using do_query(), + which could throws FATAL error. In this case pool_worker_child process + exits and Pgpool-II parent immediately forks new process. This cycle + indefinitely repeats and gives high load to the system. + To avoid the exit/fork storm, sleep sr_check_period. + + + + + + + Fix 's broken default value. (Tatsuo Ishii) + + + + + + + Fix "not enough space in buffer" error. + (bug 499) (Tatsuo Ishii) + + + The error occurred while processing error message returned from + backend and the cause is that the query string in question is too + big. Problem is, the buffer is in fixed size (8192 bytes). + Eliminate the fixed size buffer and use palloced buffer + instead. This also saves some memory copy work. + + + + + + + Fix DROP DATABASE failure. (Tatsuo Ishii) + + + + + + + Fix wrong variable in read_status_file() function. + (bug 493) (Takuma Hoshiai) + + + + + + + Fix compiler warnings. (Tatsuo Ishii) + + + + + + + + Release 3.4.23 + + Release Date + 2019-03-29 + + + + Enhancements + + + + + Add new configuration option . (Muhammad Usama) + + + Add the new setting to let users configure if they + want client's or server's cipher order to take preference. + + + The default for this parameter is off, which prioritize the client's + cipher order as usual. However this is just for keeping backward + compatibility, and it is possible that a malicious client uses weak + ciphers. For this reason we recommend to set this parameter to on at + all times. + + + + + + + Allow to set a client cipher list. (Tatsuo Ishii) + + + For this purpose new parameter , which specifies the cipher + list to be accepted by Pgpool-II, is added. + This is already implemented in PostgreSQL and useful to enhance security when SSL is enabled. + + + + + + Bug fixes + - + + + Fix unnecessary fsync() to pgpool_status file. (Tatsuo Ishii) + + + Whenever new connections are created to PostgreSQL backend, fsync() + was issued to pgpool_status file, which could generate excessive I/O + in certain conditions. + So reduce the chance of issuing fsync() so that it is issued only when + backend status is changed. + + + Discussion: [pgpool-general: 6436] + + + + + + + + Release 3.4.22 + + Release Date + 2019-02-21 + + + + Bug fixes + + + + + + Doc: Fix configuration change timing regarding . (Tatsuo Ishii) + + + + + + + Fix online recovery failed due to in certain cases. + (bug 431) (Tatsuo Ishii) + + + + + + + Fix corner case bug when strip_quote() handle a empty query string. (bug 458) (Tatsuo Ishii) + + + + + + + Fix Pgpool child segfault if failover occurs when trying to establish a connection. (Tatsuo Ishii) + + + See [pgpool-hackers: 3214] for discussion. + + + + + + + Fix Pgpool-II hang when idle_in_transaction_session_timeout = on. (bug 448) (Tatsuo Ishii) + + + + + + + + Release 3.4.21 + + Release Date + 2018-11-22 + + + + Bug fixes + + + + Fix to sort startup packet's parameters sent by client. @@ -23,15 +474,15 @@ If order of startup packet's parameters differ between cached connection - pools and connection request, did't use connection pool ,and created new + pools and connection request, didn't use connection pool ,and created new connection pool. - + - + Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. @@ -40,808 +491,808 @@ If the number of parameter format codes is specified to one, but the number of the original query's parameter is zero, bind_rewrite_timestamp() - will call memcpy with a negative value. - This causes segmentation fault. + will call memcpy with a negative value. + This causes segmentation fault. Patch is provided by Yugo Nagata. - + - + Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) - + - + Fix query cache invalidation bug. (Tatsuo Ishii) - + - + Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) - - - - - - Release 3.4.20 - - - Release Date - 2018-10-31 - - - - Changes - - - - - Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) - - - - - - - Test: Add regression test for SSL connection. (Tatsuo Ishii) - - - - - - - Test: Add definition of PGLIB in regress.sh. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Bug fixes - - - - - Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) - - - Patch provided by Phil Ramirez. - - - - - - - Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) - - - In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. - - - - - - - Fix syntax error when queries including time functions and - IN (SELECT ...) in WHERE - clause in native replication mode. - (bug 433) (Bo Peng) - - - In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. - However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. - - - - - - - Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) - - - - - - - Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) - - - In a explicit transaction, the SELECT results are cached in temporary buffer. - If a write SQL is sent which modifies the table, the temporary buffe should be reset. - - - - - - - Test: Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) - - - - - - - Add missing pgpool_recovery--1.0--1.1.sql file to update - pgpool_recovery() function version to 1.1. (Bo Peng) - Add missing pgpool_recovery--1.0--1.1.sql file to update pgpool_recovery() function version to 1.1. (Bo Peng) - - - - - - - Do not update if the password length is incorrect. + + + + + + Release 3.4.20 + + + Release Date + 2018-10-31 + + + + Changes + + + + + Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) + + + + + + + Test: Add regression test for SSL connection. (Tatsuo Ishii) + + + + + + + Test: Add definition of PGLIB in regress.sh. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Bug fixes + + + + + Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) + + + Patch provided by Phil Ramirez. + + + + + + + Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) + + + In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. + + + + + + + Fix syntax error when queries including time functions and + IN (SELECT ...) in WHERE + clause in native replication mode. + (bug 433) (Bo Peng) + + + In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. + However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. + + + + + + + Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) + + + + + + + Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) + + + In a explicit transaction, the SELECT results are cached in temporary buffer. + If a write SQL is sent which modifies the table, the temporary buffer should be reset. + + + + + + + Test: Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) + + + + + + + Add missing pgpool_recovery--1.0--1.1.sql file to update + pgpool_recovery() function version to 1.1. (Bo Peng) + Add missing pgpool_recovery--1.0--1.1.sql file to update pgpool_recovery() function version to 1.1. (Bo Peng) + + + + + + + Do not update if the password length is incorrect. (bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - For Pgpool-II 3.7 or before, the password stored in - is MD5 password only. + + + For Pgpool-II 3.7 or before, the password stored in + is MD5 password only. So check the correctness of by scanning entire file. - - - - - - - Test: Update clean.sh which clean up regression test results. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Add .gitignore files. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Fix segfault when node 0 is in down status in case of both health check - and are disabled. (Tatsuo Ishii) - - - - - + + + + + + + Test: Update clean.sh which clean up regression test results. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Add .gitignore files. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Fix segfault when node 0 is in down status in case of both health check + and are disabled. (Tatsuo Ishii) + + + + + - Release 3.4.19 - - - Release Date - 2018-07-31 - - - - Bug fixes - - - - - Fix "write on backend 0 failed with error :"Success"" error. - (bug 403) (Tatsuo Ishii) - - - Don't treated it as an error if write() returns 0. - - - - - - - Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) - - - - - - - Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) - - - This led to a segfault issue mentioned on certain platform. - - - - - - - Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) - - - Patch provided by Christian Ehrhardt. - - - - - - - Test: Fix 006.memqcache test failure. (Tatsuo Ishii) - - - - + Release 3.4.19 + + + Release Date + 2018-07-31 + + + + Bug fixes + + + + + Fix "write on backend 0 failed with error :"Success"" error. + (bug 403) (Tatsuo Ishii) + + + Don't treated it as an error if write() returns 0. + + + + + + + Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) + + + + + + + Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) + + + This led to a segfault issue mentioned on certain platform. + + + + + + + Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) + + + Patch provided by Christian Ehrhardt. + + + + + + + Test: Fix 006.memqcache test failure. (Tatsuo Ishii) + + + + - Release 3.4.18 - - - Release Date - 2018-06-12 - - - - Bug fixes - - - - - Prevent from recovering "unused" status node. (Tatsuo Ishii) - - - This allowed to try to recovery a node without configuration data, - which leads to variety of problems. - - - See [pgpool-general: 5963] - for more details. - - - Also I fixed pgpool_recovery function so that it quotes an - empty string argument with double quotes. - - - - + Release 3.4.18 + + + Release Date + 2018-06-12 + + + + Bug fixes + + + + + Prevent from recovering "unused" status node. (Tatsuo Ishii) + + + This allowed to try to recovery a node without configuration data, + which leads to variety of problems. + + + See [pgpool-general: 5963] + for more details. + + + Also I fixed pgpool_recovery function so that it quotes an + empty string argument with double quotes. + + + + - Release 3.4.17 + Release 3.4.17 - - Release Date - 2018-04-17 - + + Release Date + 2018-04-17 + - - Bug fixes - + + Bug fixes + - + - Test: Add new regression test for node 0 is down. (Tatsuo Ishii) + Test: Add new regression test for node 0 is down. (Tatsuo Ishii) - + - + - Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) - + - + - Test: Improve the test script 003.failover. (Bo Peng) + Test: Improve the test script 003.failover. (Bo Peng) - + - + - Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) + Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) - + - + - Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) + Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) - - - + + + - Release 3.4.16 + Release 3.4.16 - - Release Date - 2018-02-13 - + + Release Date + 2018-02-13 + - - Changes - + + Changes + - + - Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) + Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) - TCP_NODELAY is employed by PostgreSQL, so do we it. + TCP_NODELAY is employed by PostgreSQL, so do we it. - + - + - Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) - + - + - Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) - - - + + + - - Bug fixes - + + Bug fixes + - + - Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) + Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) - + - + - Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) - + - - + + - Release 3.4.15 + Release 3.4.15 - - Release Date - 2018-01-09 - + + Release Date + 2018-01-09 + - - Bug fixes - + + Bug fixes + - + - Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) + Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) - + - + - Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) + Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) - Removeing "Type=forking" and add OPTS=" -n" to - run Pgpool-II with non-daemon mode, because we need to redirect logs. - Using "journalctl" command to see Pgpool-II systemd log. + Removing "Type=forking" and add OPTS=" -n" to + run Pgpool-II with non-daemon mode, because we need to redirect logs. + Using "journalctl" command to see Pgpool-II systemd log. - + - + - Fix timestamp data inconsistency by replication mode. (Bo Peng) + Fix timestamp data inconsistency by replication mode. (Bo Peng) - From PostgreSQL10 the column - default value such as 'CURRENT_DATE' changes, - Pgpool-II didn't rewrite - timestamp by the added default values. This caused data inconsistency. + From PostgreSQL10 the column + default value such as 'CURRENT_DATE' changes, + Pgpool-II didn't rewrite + timestamp by the added default values. This caused data inconsistency. - + - + - Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) - We return primary or master node state of ready for query message to - frontend. In most cases this is good. However if other than primary - node or master node returns an error state (this could happen if load - balance node is other than primary or master node and the query is an - errornous SELECT), this should be returned to frontend, because the - frontend already received an error. + We return primary or master node state of ready for query message to + frontend. In most cases this is good. However if other than primary + node or master node returns an error state (this could happen if load + balance node is other than primary or master node and the query is an + erroneous SELECT), this should be returned to frontend, because the + frontend already received an error. - + - + - Fix pgpool start message printed multiple times. (Tatsuo Ishii) + Fix pgpool start message printed multiple times. (Tatsuo Ishii) - + - - + + - Release 3.4.14 + Release 3.4.14 - - Release Date - 2017-11-01 - + + Release Date + 2017-11-01 + - - Bug fixes - + + Bug fixes + - + - Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) + Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) - In RHEL6, the "-n" option is needed to redirect log. + In RHEL6, the "-n" option is needed to redirect log. - + - + - Fix finding primary node is not working in 3.4.12, 3.4.13. (Tatsuo Ishii) + Fix finding primary node is not working in 3.4.12, 3.4.13. (Tatsuo Ishii) - + - + - Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) + Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) - See [pgpool-general: 5728] for mor details. + See [pgpool-general: 5728] for more details. - + - + - Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) + Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) - - - + + + - Release 3.4.13 - - - Release Date - 2017-09-05 - - - - Bug fixes - - - - - - Doc: Fix documentation about load-balancing. (Yugo Nagata) - - - - - - - - - - Fix ancient bug of pool_unread(). (Tatsuo Ishii) - - - When realloc() is called in pool_unread(), it did not update the - buffer size. This could cause variety of memory corruption and - unexpected data reading from backend. The reason why we did not found - that is, probably recently Pgpool-II starts extensively to use - pool_unread(). - - - - - - - - Test: Fix Java program in 005.regression test. (Tatsuo Ishii) - - - - - - - Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) - - - This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). - - - - - - - Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) - - - - - - - Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) - - - - - - - Allow make dist to include pgpool.service. (Yugo Nagata) - - - - + Release 3.4.13 + + + Release Date + 2017-09-05 + + + + Bug fixes + + + + + + Doc: Fix documentation about load-balancing. (Yugo Nagata) + + + + + + + + + + Fix ancient bug of pool_unread(). (Tatsuo Ishii) + + + When realloc() is called in pool_unread(), it did not update the + buffer size. This could cause variety of memory corruption and + unexpected data reading from backend. The reason why we did not found + that is, probably recently Pgpool-II starts extensively to use + pool_unread(). + + + + + + + + Test: Fix Java program in 005.regression test. (Tatsuo Ishii) + + + + + + + Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) + + + This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). + + + + + + + Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) + + + + + + + Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) + + + + + + + Allow make dist to include pgpool.service. (Yugo Nagata) + + + + - Release 3.4.12 + Release 3.4.12 - - Release Date - 2017-07-11 - + + Release Date + 2017-07-11 + - - Bug fixes + + Bug fixes - - + + - Importing the latest changes in the MemoryManager API from PostgreSQL code. (Muhammad Usama) + Importing the latest changes in the MemoryManager API from PostgreSQL code. (Muhammad Usama) - + - + - Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) + Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) - + - + - Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) + Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn - + - + - Fix query cache hang when used by node.js. (Tatsuo Ishii) + Fix query cache hang when used by node.js. (Tatsuo Ishii) - See [pgpool-general: 5511] for more details. + See [pgpool-general: 5511] for more details. - + - + - Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) + Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) - + - + - Fix query cache memory leak. (Tatsuo Ishii) + Fix query cache memory leak. (Tatsuo Ishii) - Clearing cache buffers in case of no oid queries (like BEGIN, - CHECKPOINT, VACUUM, etc) should have been done, but it did not. + Clearing cache buffers in case of no oid queries (like BEGIN, + CHECKPOINT, VACUUM, etc) should have been done, but it did not. - + - + - Fix corner case bug in Pgpool-II starting up. (Tatsuo Ishii) + Fix corner case bug in Pgpool-II starting up. (Tatsuo Ishii) - It is possible that a failover request is accepted before primary node - is searched. This leads Pgpool-II to a strange state: there's no - primary node if the failed node was a primary node (even if new - primary node exists as a result of promotion of existing standby). + It is possible that a failover request is accepted before primary node + is searched. This leads Pgpool-II to a strange state: there's no + primary node if the failed node was a primary node (even if new + primary node exists as a result of promotion of existing standby). - See [pgpool-hackers: 2321] for more details. + See [pgpool-hackers: 2321] for more details. - - - + + + - Release 3.4.11 + Release 3.4.11 - - Release Date - 2017-04-28 - + + Release Date + 2017-04-28 + - - Bug fixes + + Bug fixes - - + + @@ -850,418 +1301,418 @@ Fix for 0000299: Errors on the reloading of configuration. (Bug 299) (Muhammad Usama) - + - + - Fix coverity warnings. (Muhammad Usama) + Fix coverity warnings. (Muhammad Usama) - + - + - Fix for [pgpool-general: 5396] pam ldap failure. (Muhammad Usama) + Fix for [pgpool-general: 5396] pam ldap failure. (Muhammad Usama) - + - + - Fix for 0000296: PGPool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. - (Bug 296) (Muhammad Usama) + Fix for 0000296: Pgpool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. + (Bug 296) (Muhammad Usama) - + - + - + - Release 3.4.10 + Release 3.4.10 - - Release Date - 2017-03-17 - + + Release Date + 2017-03-17 + - - Bug fixes + + Bug fixes - + - + - Add "Wants=network.target" to pgpool.service file. - (bug 294) (Bo Peng) + Add "Wants=network.target" to pgpool.service file. + (bug 294) (Bo Peng) - - + + - Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) + Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) - The master node could not be promoted by pcp_promote_node with - the following error; + The master node could not be promoted by pcp_promote_node with + the following error; FATAL: invalid pgpool mode for process recovery request DETAIL: specified node is already primary node, can't promote node id 0 - + - In streaming replication mode, there is a case that Pgpool-II - regards the status of primary node as "standby" for some reasons, - for example, when pg_ctl promote is executed manually during - Pgpool-II is running, in which case, it seems to Pgpool-II - that the primary node doesn't exist. + In streaming replication mode, there is a case that Pgpool-II + regards the status of primary node as "standby" for some reasons, + for example, when pg_ctl promote is executed manually during + Pgpool-II is running, in which case, it seems to Pgpool-II + that the primary node doesn't exist. - This status mismatch should be fixe by pcp_promote_node, but when the node - is the master node (the first alive node), it fails as mentioned above. + This status mismatch should be fixed by pcp_promote_node, but when the node + is the master node (the first alive node), it fails as mentioned above. - The reason is as following. before changing the status, pcp_promote_node - checks if the specified node is already primary or not by comparing the - node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from - Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. - Hence, when the master node is specified to be promoted, pcp_promote_node - is confused that this node is already primary and doesn't have to be - promoted, and it exits with the error. + The reason is as following. before changing the status, pcp_promote_node + checks if the specified node is already primary or not by comparing the + node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from + Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. + Hence, when the master node is specified to be promoted, pcp_promote_node + is confused that this node is already primary and doesn't have to be + promoted, and it exits with the error. - To fix this, pcp_promote_node should check the node id by using - REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, - rather than PRIMARY_NODE_ID. + To fix this, pcp_promote_node should check the node id by using + REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, + rather than PRIMARY_NODE_ID. - + - + - Add the latest release note link to README file.(Bo Peng) + Add the latest release note link to README file.(Bo Peng) - + - + - Pgpool-IIshould not perform ping test after bringing down the VIP. (Muhammad Usama) + Pgpool-IIshould not perform ping test after bringing down the VIP. (Muhammad Usama) - This issue was reported by the reporter of - bug:[pgpool-II 0000249]: watchdog sometimes fails de-escalation + This issue was reported by the reporter of + bug:[pgpool-II 0000249]: watchdog sometimes fails de-escalation - + - + - Fix to release shared memory segments when Pgpool-IIexits. - (bug 272) (Tatsuo Ishii) + Fix to release shared memory segments when Pgpool-IIexits. + (bug 272) (Tatsuo Ishii) - + - + - Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) + Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) - + - + - Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) + Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) - + - + - Fix for 281: "segmentation fault" when execute pcp_attach_node. - (bug 281) (Muhammad Usama) + Fix for 281: "segmentation fault" when execute pcp_attach_node. + (bug 281) (Muhammad Usama) - + - + - Fix load balancing bug in streaming replication mode. (Tatsuo Ishii) + Fix load balancing bug in streaming replication mode. (Tatsuo Ishii) - In an explicit transaction, any SELECT will be load balanced until - write query is sent. After writing query is sent, any SELECT should be - sent to the primary node. However if a SELECT is sent before a sync - message is sent, this does not work since the treatment of writing - query is done after ready for query message arrives. + In an explicit transaction, any SELECT will be load balanced until + write query is sent. After writing query is sent, any SELECT should be + sent to the primary node. However if a SELECT is sent before a sync + message is sent, this does not work since the treatment of writing + query is done after ready for query message arrives. - Solution is, the treatment for writing query is done in executing the writing query as well. + Solution is, the treatment for writing query is done in executing the writing query as well. - The bug has been there since V3.5. + The bug has been there since V3.5. - + - + - Fix yet another kind mismatch error in streaming replication mode. (Tatsuo Ishii) + Fix yet another kind mismatch error in streaming replication mode. (Tatsuo Ishii) - + - + - Fix do_query()hangs after close message. (Tatsuo Ishii) + Fix do_query()hangs after close message. (Tatsuo Ishii) - + - + - Fixing stack smashing detected. (bug 280) (Muhammad Usama) + Fixing stack smashing detected. (bug 280) (Muhammad Usama) - It was a buffer overflow in wd_get_cmd function + It was a buffer overflow in wd_get_cmd function - + - + - Remove elog/ereport calls from signal handlers. (Tatsuo Ishii) + Remove elog/ereport calls from signal handlers. (Tatsuo Ishii) - See [pgpool-hackers: 1950] for details. + See [pgpool-hackers: 1950] for details. - + - + - Fix bug failed to create INET domain socket in FreeBSD if listen_addresses = '*'. (bug 202) (Bo Peng) + Fix bug failed to create INET domain socket in FreeBSD if listen_addresses = '*'. (bug 202) (Bo Peng) - + - + - Fix for 0000249: watchdog sometimes fails de-escalation. (bug 249) (Muhammad Usama) + Fix for 0000249: watchdog sometimes fails de-escalation. (bug 249) (Muhammad Usama) - The solution is to use the waitpid() system call without WNOHANG option. + The solution is to use the waitpid() system call without WNOHANG option. - + - + - Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) + Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) - + - + - Fix authentication timeout that can occur right after client connecttions. (Yugo Nagata) + Fix authentication timeout that can occur right after client connections. (Yugo Nagata) - + - + - + - Release 3.4.9 + Release 3.4.9 - - Release Date - 2016-12-26 - + + Release Date + 2016-12-26 + - - Bug fixes + + Bug fixes - + - - - - Tightening up the watchdog security. (Muhammad Usama) + + + + Tightening up the watchdog security. (Muhammad Usama) - Now wd_authkey uses the HMAC SHA-256 hashing. - - + Now wd_authkey uses the HMAC SHA-256 hashing. + + - - - - Add pgpool_adm extension in Pgpool-IIRPM. (Bo Peng) - - + + + + Add pgpool_adm extension in Pgpool-IIRPM. (Bo Peng) + + - - - - Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) - - + + + + Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) + + - - - - Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) - - - It was intended to keep the consistency, but there's no point in other - than native replication mode. - - + + + + Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) + + + It was intended to keep the consistency, but there's no point in other + than native replication mode. + + - - - - Remove obsoleted option "-c" in pgpool command. (Tatsuo Ishii) - - - Also fix typo in the help message. - - + + + + Remove obsoleted option "-c" in pgpool command. (Tatsuo Ishii) + + + Also fix typo in the help message. + + - - - - Change the default value of search_primary_node_timeout from 10 to 300. (Tatsuo Ishii) - - - Prior default value 10 seconds is sometimes too short for a standby to - be promoted. - - - Per [pgpool-general: 5026]. - - + + + + Change the default value of search_primary_node_timeout from 10 to 300. (Tatsuo Ishii) + + + Prior default value 10 seconds is sometimes too short for a standby to + be promoted. + + + Per [pgpool-general: 5026]. + + - - - - Fix the case when all backends are down then 1 node attached. (bug 248) (Tatsuo Ishii) - - - When all backends are down, no connection is accepted. Then 1 - PostgreSQL becomes up, and attach the node using pcp_attach_node. It - successfully finishes. However, when a new connection arrives, still - the connection is refused because pgpool child process looks into the - cached status, in which the recovered node is still in down status if - mode is streaming replication mode (native replication and other modes - are fine). Solution is, if all nodes are down, force to restart all - pgpool child. - - + + + + Fix the case when all backends are down then 1 node attached. (bug 248) (Tatsuo Ishii) + + + When all backends are down, no connection is accepted. Then 1 + PostgreSQL becomes up, and attach the node using pcp_attach_node. It + successfully finishes. However, when a new connection arrives, still + the connection is refused because pgpool child process looks into the + cached status, in which the recovered node is still in down status if + mode is streaming replication mode (native replication and other modes + are fine). Solution is, if all nodes are down, force to restart all + pgpool child. + + - - - - Do not use random() while generating MD5 salt. (Tatsuo Ishii) - - - random() should not be used in security related applications. To - replace random(), import PostmasterRandom() from PostgreSQL. Also - store current time at the start up of Pgpool-II main process for later - use. - - + + + + Do not use random() while generating MD5 salt. (Tatsuo Ishii) + + + random() should not be used in security related applications. To + replace random(), import PostmasterRandom() from PostgreSQL. Also + store current time at the start up of Pgpool-II main process for later + use. + + - - - - Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) - - + + + + Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) + + - + - + diff --git a/doc/src/sgml/release-3.5.sgml b/doc/src/sgml/release-3.5.sgml index b24e0a975..7125a42ad 100644 --- a/doc/src/sgml/release-3.5.sgml +++ b/doc/src/sgml/release-3.5.sgml @@ -1,1450 +1,2407 @@ - - Release 3.5.18 - - Release Date - 2018-11-22 - - - - Bug fixes + + Release 3.5.28 + + Release Date + 2020-11-19 + + + + Changes - - - + - Fix to sort startup packet's parameters sent by client. - (bug 444)(Takuma Hoshiai) + Pgpool-II doesn't support GSSAPI. + Allow Pgpool-II to deal with GSSAPI encrypted connection request from frontend instead of responding with an error. (Tatsuo Ishii) - If order of startup packet's parameters differ between cached connection - pools and connection request, did't use connection pool ,and created new - connection pool. + Patch is created by me, reviewed and tested by Umar Hayat. - + + + + + Bug fixes + - - - - Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. - (bug 443)(Bo Peng) - - - If the number of parameter format codes is specified to one, but the number - of the original query's parameter is zero, bind_rewrite_timestamp() - will call memcpy with a negative value. - This causes segmentation fault. - + - Patch is provided by Yugo Nagata. + Fix query rewrite syntax error of "INSERT ... ON CONFLICT" in native replication mode. + (bug 654) (Bo Peng) - + - - + - Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + Fix connection counter was not counted down when query is canceled. + (bug 656) (Tatsuo Ishii) - + - - + - Fix query cache invalidation bug. (Tatsuo Ishii) + Fix pgpool_setup bugs while checking the version of PostgreSQL. (Bo Peng) - + + + + + + Release 3.5.27 + + Release Date + 2020-09-17 + + + + Changes + - - + - Fix segfault in extended query + query cache case. (Tatsuo Ishii) + Follow the guide line of PostgreSQL 12.4 regarding extensions. (Tatsuo Ishii) - - - - - Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + CREATE OR REPLACE FUNCTION should be avoided. Use CREATE FUNCTION instead. - - - - - - Release 3.5.17 - - - Release Date - 2018-10-31 - - - - Changes - - - - - Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) - - - - - - - Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) - - - - - - - Test: Add regression test for SSL connection. (Tatsuo Ishii) - - - - - - - Test: Add definition of PGLIB in regress.sh. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Bug fixes - - - - - Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) - - - Patch provided by Phil Ramirez. - - - - - - - Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) - - - In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. - - - - - - - Fix syntax error when queries including time functions and IN (SELECT ...) in - WHERE clause in native replication mode. - (bug 433) (Bo Peng) - - - In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. - However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. - - - - - - - Fix occasional less data returned to frontend with extended protocol. (bug432) (Tatsuo Ishii) - - - The idea for fix is, use pending message data list. It records - messages from frontend, and it is expected that we will receive same - number of messages. - - - Initial patch is created by Yugo Nagata and fixed by Tatsuo Ishii. - - - - - - - Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) - - - - - - - Fix memory leak when query cache enabled in streaming replication mode + extended query case. (Tatsuo Ishii) - - - - - - - Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) - - - In a explicit transaction, the SELECT results are cached in temporary buffer. - If a write SQL is sent which modifies the table, the temporary buffe should be reset. - - - - - - - Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) - - - - - - - Test: Add EXECUTE/DEALLOCATE regression test. (Takuma Hoshiai) - - - - - - - Add missing pgpool_recovery--1.0--1.1.sql file to update - pgpool_recovery() function version to 1.1. (Bo Peng) - - - - - - - Fix kind mismatch error when DEALLOCATE statement is issued. (Bo Peng) - - - PREPARE should be add to pool_add_sent_message, - so that EXECUTE and DEALLOCATE - can be sent to the same node as PREPARE. - - - See [pgpool-general: 6226] for more details. - - - - - - - Do not update if the password length is incorrect. - (bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - For Pgpool-II 3.7 or before, the password stored in - is MD5 password only. - So check the correctness of by scanning entire file. - - - - - - - Test: Update clean.sh which clean up regression test results. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Add .gitignore files. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Fix segfault when node 0 is in down status in case of both health check - and are disabled. (Tatsuo Ishii) - - - - - - - - Release 3.5.16 - - - Release Date - 2018-07-31 - - - - Bug fixes - - - - - - Fix "write on backend 0 failed with error :"Success"" error. - (bug 403) (Tatsuo Ishii) - - - Don't treated it as an error if write() returns 0. - - - - - - - Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) - - - - - - - Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) - - - This led to a segfault issue mentioned on certain platform. - - - - - - - Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) - - - Patch provided by Christian Ehrhardt. - - - - - - Test: Fix 006.memqcache test failure. (Tatsuo Ishii) - - - - - - - - Release 3.5.15 - - - Release Date - 2018-06-12 - - - - Bug fixes - - - - - Fix Pgpool-II hung if replication delay is too much, when query cache enabled in extended query mode. (Tatsuo Ishii) - - - See [pgpool-general-jp: 1534] - for more details. - - - - - - - In extended query mode, do not set writing tx flag with SET TRANSACTION READ ONLY. (Tatsuo Ishii) - - - - - - - Prevent from recovering "unused" status node. (Tatsuo Ishii) - - - This allowed to try to recovery a node without configuration data, - which leads to variety of problems. - - - See [pgpool-general: 5963] - for more details. - - - Also I fixed pgpool_recovery function so that it quotes an - empty string argument with double quotes. - - - - - - - - Release 3.5.14 - - - Release Date - 2018-04-17 - - - - Bug fixes - + + - + + Bug fixes + + - Test: Add new regression test for node 0 is down. (Tatsuo Ishii) + Remove unnecessary checks in some code path. (Tatsuo Ishii) - - - - - Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + Patch contributed by Hou, Zhijie. - + - + - Test: Improve test script 003.failover. (Bo Peng) + Fix relcache query sometimes sent to other than primary. (Tatsuo Ishii) + + + In streaming replication mode, relcache queries are supposed to be + sent to the primary node. But actually they were not sent to the primary + node if primary node was not the master node. Typically this could + happen when the primary is not node 0. - + - + - Deal with "unable to bind D cannot get parse message "S1" error. (Tatsuo Ishii) + Fix not working when is enabled. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] - + - + - Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) + Display more informative error message in authentication process. (Tatsuo Ishii) - + - + - Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) + Fix segfault in pgpool child process in certain case. (Tatsuo Ishii) - - - - - - - Release 3.5.13 - - - Release Date - 2018-02-13 - - - This release fixed the bug with socket writing added in Pgpool-II 3.7.0, 3.6.6 and 3.5.10. Due to this bug, when the network load is high, an illegal message may be sent to the frontend or backend. All users using 3.7.x, 3.6.6 or later, 3.5.10 or later versions of Pgpool-II should update as soon as possible. + This issue can be reproduced with the following steps: + + + + Shutdown all backends. + + + + + Connect to pgpool with invalid client. I have used pcp_attach_node with pgpool's port number, not pcp's. + + + - + + + + - - Changes - - + + Release 3.5.26 + + Release Date + 2020-08-20 + + + + Changes + + - Allow to build with libressl. (Tatsuo Ishii) - - - See [pgpool-hackers: 2714] for more details. Patch by Sandino Araico Sanchez. + Add mention about hostssl/hostnossl to pool_hba.conf sample file. (Tatsuo Ishii) - + + + - + + Bug fixes + + - Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) + At pgpool startup, if pid file exists, truncate pid file to zero length before writing. (Bo Peng) - TCP_NODELAY is employed by PostgreSQL, so do we it. + Patch is created by maliangzhu. - + - + - Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + Fix does not work if primary node is not 0 in streaming replication mode. (Tatsuo Ishii) - + - + - Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + Fix pgpool_setup problem with -r option and PostgreSQL 12. (Tatsuo Ishii) - - - - - - Bug fixes - + - + - Fix writing transaction flag is accidentally set at commit or rollback. (Tatsuo Ishii) + Change PCP UNIX_DOMAIN_PATH of RPM package to /var/run/postgresql. (Bo Peng) - + - + - Fix bug with socket writing. (Tatsuo Ishii) + Fix query cache bugs. (Tatsuo Ishii) - pool_write_flush() is responsible for writing to sockets when pgpool's - write buffer is full (this function was introduced in 3.6.6 etc). When - network write buffer in kernel is full, it does retrying but it forgot - to update the internal buffer pointer. As a result, broken data is - written to the socket. This results in variety of problems including - too large message length. + If query cache is enable, when a table is updated, Pgpool-II should delete all the caches related to the table. + However, EXPLAIN ANALYZE and CTE with data-modifying SQLs + were mistakenly treated as normal read only query so that the query caches were not deleted. - + + Patch is created by Hou, Zhijie and modified by Tatsuo Ishii. + + - + - Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) + Fix Pgpool-II hang in a corner case. (Tatsuo Ishii) + - - - + - Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + If there are parameters other than "user", "database" and "application_name", reading startup packet failed. (Tatsuo Ishii) - - - - - - - - Release 3.5.12 - - - Release Date - 2018-01-09 - - - - Bug fixes - + - + - Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) + Fix miscount of connections when pg_terminate_backend() is executed. (Takuma Hoshiai) - + - + - Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) - - - Removeing "Type=forking" and add OPTS=" -n" to - run Pgpool-II with non-daemon mode, because we need to redirect logs. - Using "journalctl" command to see Pgpool-II systemd log. + Fix segmentation fault when application name is included in . (bug 615) (Tatsuo Ishii) - + + + + + + + Release 3.5.25 + + Release Date + 2020-05-21 + - + + Bug fixes + + - Fix timestamp data inconsistency by replication mode. (Bo Peng) + Fix build error on some system (Fedora 32). (Tatsuo Ishii) - - From PostgreSQL10 the column - default value such as 'CURRENT_DATE' changes, - Pgpool-II didn't rewrite - timestamp by the added default values. This caused data inconsistency. - - + - + - Downgrade a log message to debug message. (Tatsuo Ishii) + Fix unnecessary checks. (Tatsuo Ishii) - That was mistaken left while last development cycle. + Patch contributed by sherlockcpp. Discussion: [pgpool-general: 7004] - + - + - Fix for re-sync logic in reading packet from backend. (Tatsuo Ishii) + Fix watchdog ping probes fail with long hostnames due to small buffer. (bug 516) (Bo Peng) - - read_kind_from_backend(), which reads message kind - from backend, re-syncs backend nodes when a ready for query message is - received. Unfortunately it forgot to call - pool_pending_message_pull_out() to delete sync - pending message. This leads to random stuck while reading packets - from backend. Fix this to call pool_pending_message_pull_out(). - - + + + + - + + Release 3.5.24 + + Release Date + 2020-02-20 + + + + Changes + + - Fix Pgpool-II hangs. (bug 370) (Tatsuo Ishii) + Check if socket file exists at startup and remove them if PID file doesn't exist to avoid bind() failure. (Bo Peng) - - If an erroneous query is sent to primary and without a sync message - the next query that requires a catalog cache look up is send, - Pgpool-II hangs in do_query(). - - + + + - + + Bug fixes + + - Add SL_MODE macro for upper compatibility with Pgpool-II 3.7 or later. (Tatsuo Ishii) + Fix incorrect query rewriting in native replication mode. + (bug 551) (Bo Peng) - - - + + - Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + Fix to support PostgreSQL 12. (Tatsuo Ishii) + + + - We return primary or master node state of ready for query message to - frontend. In most cases this is good. However if other than primary - node or master node returns an error state (this could happen if load - balance node is other than primary or master node and the query is an - errornous SELECT), this should be returned to frontend, because the - frontend already received an error. + Fix occasional regression test failure. (Tatsuo Ishii) - + - + - Fix pgpool start message printed multiple times. (Tatsuo Ishii) + Fix replication delay worker segfault when application_name in primary_conninfo is an empty string. + (bug 565) (Tatsuo Ishii) - - - + + - Add an execute permission bit to the start/stop script in . (Tatsuo Ishii) + Fix the bug with ignored syslog setting. (Bo Peng) - - - + + + - - Release 3.5.11 - - - Release Date - 2017-11-01 - - - - Bug fixes - + + Release 3.5.23 + + Release Date + 2019-10-31 + - + + Bug fixes + + - Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) - - - In RHEL6, the "-n" option is needed to redirect log. + Fix incorrect query rewrite in replication mode. (Bo Peng) - + - + - Fix for bug in watchdog where sometime failover is not reliably performed. (Muhammad Usama) - - - Currently watchdog process only considers the node's watchdog state before - deciding if it can handle the failover and failover-locking requests. - - - But the problem with this technique is that, for the instance when the node has - announced itself as a master/coordinator of the cluster and is waiting for the - standby nodes to recognise it as a Master node. For that period of time the - watchdog state of the node is Master/coordinator, but it is yet not fully - capable of handling the failover and failover-locking requests. - - - So sometimes this leads to a situation where a failover is not reliably - performed in case when the failover request arrives while watchdog cluster is - in the process of electing a leader. - - - The fix for the above situation is to make sure that the node has fully acquired the Master status before accepting the failover and failover-locking requests. - + Fix assorted ancient v2 protocol bugs. (Tatsuo Ishii) - + - + - Fix bug with handling of 'H' (flush) message in streaming replication mode. (bug 345) (Tatsuo Ishii) - - - If user expects to read response right after 'H', Pgpool-II hangs. The - cause was, when 'H' received, extended query mode was reset and - pending message was not used. + Fix problem that doesn't change by reload. + (bug 548) (Takuma Hoshiai) - + - + - Doc: Fix pcp_node_info documents. (Tatsuo Ishii) + Fix Pgpool-II shutdown failed in certain case. (Tatsuo Ishii) - - - - + - + - Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) - - - See [pgpool-general: 5728] for mor details. + Fix segfault when executing an erroneous query after DEALLOCATE a named statement. + (bug 546) (Tatsuo Ishii) - + - + - Fix exit signal handlers to not call ereport. (Tatsuo Ishii) - - - See [pgpool-hackers: 2545] for more details. + Add "-I" option to command default setting. (Bo Peng) - + + + + - - + + Import some of memory manager debug facilities from PostgreSQL. (Tatsuo Ishii) + + + + + + Use pg_get_expr() instead of pg_attrdef.adsrc to support for PostgreSQL 12. (Bo Peng) + + + + + + Enhance shutdown script of . (Tatsuo Ishii) + + + + Make shutdownall to wait for completion of shutdown of Pgpool-II. + + + + + If environment variable CHECK_TIME_WAIT is set to true, use netstat command to confirm usage of the TCP/IP port while executing shutdown script. + + + + + + + - Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) + Deal pgpool_adm extension with PostgreSQL 12. (Tatsuo Ishii) - + + + + + Bug fixes + - - - + + + + Fix "unable to bind. cannot get parse message" error. + (bug 531) (Tatsuo Ishii) + + - - Release 3.5.10 + + + + Fix online-recovery is blocked after a child process exits abnormally with replication mode and watchdog. + (bug 483) (Muhammad Usama) + + - - Release Date - 2017-09-05 - + + + + Fix to produce correct follow master command. (Tatsuo Ishii) + + - - Bug fixes - - - - - Fix Pgpool-II hanging when error occurs in streaming replication mode and extended query. (Tatsuo Ishii) - - - If backend returns ERROR, Pgpool-II reads message from frontend until - a sync message is sent. Previous code assumed next message is sync. - However it is possible that more message coming before the sync - message, it's a low probability though. Fix it to continue reading - messages until the sync message is read. - - + + + + Fix query cache module so that it checks oid array's bound. (Tatsuo Ishii) + + - - - - Fix wd_authkey bug in that a request to add new node to the clusetr is rejected by master. (Yugo Nagata) - - - This is a bug due to the implementation of 3.5.6 and 3.6.3. - - - This changed the definition of tv_sec that is used to check wd_authkey so - that this was affected by the clock of OS. So, if there is a lag between - two nodes' clocks, the wd_authkey check fails. - - + + + + Fix off-by-one error in query cache module. (Tatsuo Ishii) + + - - - - Test: Fix load balance test driver. (Tatsuo Ishii) - - - Some tests only for native replication mode was executed in streaming replication mode as well. - - + + + + Fix segfault when query cache is enabled. (bug 525) (Tatsuo Ishii) + + - - - - Fix not working slony mode in extended query. (Tatsuo Ishii) - - - When response returned from backend, in progress flag was not reset in slony mode, which cause waiting for next message from backend in vain. - - + + + + Down grade LOG "checking zapping sent message ..." to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 6620] + + - - - - Fix ancient bug of stream write modules. (Tatsuo Ishii) - - - Fix bug with pool_write_noerror() when requested length exceeds remaining write buffer size. This could lead to a buffer overrun problem. - - - When write buffer is full, pool_flush_it() is called, which could write data to socket in the middle of message. To fix the problem directly write requested data if the write buffer is going to be full. - - - Enhance performance of pool_unread(). - - + + + + Fix segfault when samenet is specified in pool_hba.conf. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 6601]. + + - - - - Test: Some miscellanies small fixes in regression test scripts. (Muhammad Usama) - - + + + + Fix to deal with backslashes according to the config of standard_conforming_strings in native replication mode. + (bug 467) (Bo Peng) + + - - + + + + Fix memory leaks. (Tatsuo Ishii) + + - - - - Doc: Fix documentation about load-balancing. (Yugo Nagata) - - + + + + Make failover in progress check more aggressively to avoid potential segfault. (Tatsuo Ishii) + + + + + - - + + Release 3.5.21 + + Release Date + 2019-05-16 + - - - - Fix core dump and mishandling of temp tables. (Tatsuo Ishii) - - + + Enhancements + + + + + Speed up failover when all of backends are down. (Tatsuo Ishii) + + + If all of the backend are in down status, immediately give up finding + primary node regardless search_primary_node_timeout and promptly + finish the failover process. + + + Discussion: [pgpool-hackers: 3321] + + - - - - Fix ancient bug of pool_unread(). (Tatsuo Ishii) - - - When realloc() is called in pool_unread(), it did not update the - buffer size. This could cause variety of memory corruption and - unexpected data reading from backend. The reason why we did not found - that is, probably recently Pgpool-II starts extensively to use - pool_unread(). + + + + pgpool-recovery extension and pgpool_setup is now ready for the next major release PostgreSQL 12. (Tatsuo Ishii) + + + + - - + + Bug fixes + + + + + Fix the wrong error message "ERROR: connection cache is full", when all backend nodes are down. + (bug 487) (Bo Peng) + + + When all backend nodes are down, Pgpool-II throws an incorrect + error message "ERROR: connection cache is full". Change the error + message to "all backend nodes are down, pgpool requires at least one valid node". + + - - - - Fix handling of empty queries. (bug 328) (Tatsuo Ishii) - - - When empty query (empty string or all comment query) is sent, command - complete message was returned to frontend. This is not correct. An - empty query response should be returned to frontend. - - + + + + Avoid exit/fork storm of pool_worker_child process. (Tatsuo Ishii) + + + pool_worker_child issues query to get WAL position using do_query(), + which could throws FATAL error. In this case pool_worker_child process + exits and Pgpool-II parent immediately forks new process. This cycle + indefinitely repeats and gives high load to the system. + To avoid the exit/fork storm, sleep sr_check_period. + + - - - - Fix query cache bug with streaming replication mode and extended query case. (Tatsuo Ishii) - - + + + + Fix 's broken default value. (Tatsuo Ishii) + + - - - - Fix memory leak with streaming replication mode/extended query case. (bug 324) (Tatsuo Ishii) - - + + + + Fix "not enough space in buffer" error. + (bug 499) (Tatsuo Ishii) + + + The error occurred while processing error message returned from + backend and the cause is that the query string in question is too + big. Problem is, the buffer is in fixed size (8192 bytes). + Eliminate the fixed size buffer and use palloced buffer + instead. This also saves some memory copy work. + + - - - - Test: Fix Java program in 005.regression test. (Tatsuo Ishii) - - + + + + Fix DROP DATABASE failure. (Tatsuo Ishii) + + - - - - Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) - - - This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). - - + + + + Fix wrong variable in read_status_file() function. + (bug 493) (Takuma Hoshiai) + + - - - - Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) - - + + + + Abort session if failover/failback is ongoing to prevent potential segfault. + (bug 481, + bug 482) (Tatsuo Ishii) + + - - - - Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) - - + + + + Fix compiler warnings. (Tatsuo Ishii) + + + + + + + Fix memory leak in "batch" mode in extended query. + (bug 468) (Tatsuo Ishii) + + + + + + + + Release 3.5.20 + + Release Date + 2019-03-29 + + + + Enhancements + + + + + Add new configuration option . (Muhammad Usama) + + + Add the new setting to let users configure if they + want client's or server's cipher order to take preference. + + + The default for this parameter is off, which prioritize the client's + cipher order as usual. However this is just for keeping backward + compatibility, and it is possible that a malicious client uses weak + ciphers. For this reason we recommend to set this parameter to on at + all times. + + + + + + + Allow to set a client cipher list. (Tatsuo Ishii) + + + For this purpose new parameter , which specifies the cipher + list to be accepted by Pgpool-II, is added. + This is already implemented in PostgreSQL and useful to enhance security when SSL is enabled. + + + + + + + Bug fixes + + + + + Fix unnecessary fsync() to pgpool_status file. (Tatsuo Ishii) + + + Whenever new connections are created to PostgreSQL backend, fsync() + was issued to pgpool_status file, which could generate excessive I/O + in certain conditions. + So reduce the chance of issuing fsync() so that it is issued only when + backend status is changed. + + + Discussion: [pgpool-general: 6436] + + + + + + + + Release 3.5.19 + + Release Date + 2019-02-21 + + + + Bug fixes + + + + + + Test: Fix old JDBC functions and typos in regression test 068.memqcache_bug. (Takuma Hoshiai) + + + + + + + Doc: Fix configuration change timing regarding . (Tatsuo Ishii) + + + + + + + Fix online recovery failed due to in certain cases. + (bug 431) (Tatsuo Ishii) + + + + + + + Fix corner case bug when strip_quote() handle a empty query string. (bug 458) (Tatsuo Ishii) + + + + + + + Fix Pgpool child segfault if failover occurs when trying to establish a connection. (Tatsuo Ishii) + + + See [pgpool-hackers: 3214] for discussion. + + + + + + + Fix Pgpool-II hang if a client sends a extended query message such as close after sync message but before next simple query. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 3164] + + + + + + + Fix Pgpool-II hang when idle_in_transaction_session_timeout = on. (bug 448) (Tatsuo Ishii) + + + + + + + + Release 3.5.18 + + Release Date + 2018-11-22 + + + + Bug fixes + + + + + + + Fix to sort startup packet's parameters sent by client. + (bug 444)(Takuma Hoshiai) + + + If order of startup packet's parameters differ between cached connection + pools and connection request, didn't use connection pool ,and created new + connection pool. + + + + + + + + Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. + (bug 443)(Bo Peng) + + + If the number of parameter format codes is specified to one, but the number + of the original query's parameter is zero, bind_rewrite_timestamp() + will call memcpy with a negative value. + This causes segmentation fault. + + + Patch is provided by Yugo Nagata. + + + + + + + + Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + + + + + + Fix segfault in extended query + query cache case. (Tatsuo Ishii) + + + + + + + Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + + + + + + + + Release 3.5.17 + + + Release Date + 2018-10-31 + + + + Changes + + + + + Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) + + + + + + + Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) + + + + + + + Test: Add regression test for SSL connection. (Tatsuo Ishii) + + + + + + + Test: Add definition of PGLIB in regress.sh. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Bug fixes + + + + + Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) + + + Patch provided by Phil Ramirez. + + + + + + + Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) + + + In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. + + + + + + + Fix syntax error when queries including time functions and IN (SELECT ...) in + WHERE clause in native replication mode. + (bug 433) (Bo Peng) + + + In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. + However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. + + + + + + + Fix occasional less data returned to frontend with extended protocol. (bug432) (Tatsuo Ishii) + + + The idea for fix is, use pending message data list. It records + messages from frontend, and it is expected that we will receive same + number of messages. + + + Initial patch is created by Yugo Nagata and fixed by Tatsuo Ishii. + + + + + + + Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) + + + + + + + Fix memory leak when query cache enabled in streaming replication mode + extended query case. (Tatsuo Ishii) + + + + + + + Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) + + + In a explicit transaction, the SELECT results are cached in temporary buffer. + If a write SQL is sent which modifies the table, the temporary buffer should be reset. + + + + + + + Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) + + + + + + + Test: Add EXECUTE/DEALLOCATE regression test. (Takuma Hoshiai) + + + + + + + Add missing pgpool_recovery--1.0--1.1.sql file to update + pgpool_recovery() function version to 1.1. (Bo Peng) + + + + + + + Fix kind mismatch error when DEALLOCATE statement is issued. (Bo Peng) + + + PREPARE should be add to pool_add_sent_message, + so that EXECUTE and DEALLOCATE + can be sent to the same node as PREPARE. + + + See [pgpool-general: 6226] for more details. + + + + + + + Do not update if the password length is incorrect. + (bug 419) (Takuma Hoshiai, Tatsuo Ishii) + + + For Pgpool-II 3.7 or before, the password stored in + is MD5 password only. + So check the correctness of by scanning entire file. + + + + + + + Test: Update clean.sh which clean up regression test results. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Add .gitignore files. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Fix segfault when node 0 is in down status in case of both health check + and are disabled. (Tatsuo Ishii) + + + + + + + + Release 3.5.16 + + + Release Date + 2018-07-31 + + + + Bug fixes + + + + + + Fix "write on backend 0 failed with error :"Success"" error. + (bug 403) (Tatsuo Ishii) + + + Don't treated it as an error if write() returns 0. + + + + + + + Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) + + + + + + + Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) + + + This led to a segfault issue mentioned on certain platform. + + + + + + + Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) + + + Patch provided by Christian Ehrhardt. + + + + + + Test: Fix 006.memqcache test failure. (Tatsuo Ishii) + + + + + + + + Release 3.5.15 + + + Release Date + 2018-06-12 + + + + Bug fixes + + + + + Fix Pgpool-II hung if replication delay is too much, when query cache enabled in extended query mode. (Tatsuo Ishii) + + + See [pgpool-general-jp: 1534] + for more details. + + + + + + + In extended query mode, do not set writing tx flag with SET TRANSACTION READ ONLY. (Tatsuo Ishii) + + + + + + + Prevent from recovering "unused" status node. (Tatsuo Ishii) + + + This allowed to try to recovery a node without configuration data, + which leads to variety of problems. + + + See [pgpool-general: 5963] + for more details. + + + Also I fixed pgpool_recovery function so that it quotes an + empty string argument with double quotes. + + + + + + + + Release 3.5.14 + + + Release Date + 2018-04-17 + + + + Bug fixes + + + + + + Test: Add new regression test for node 0 is down. (Tatsuo Ishii) + + + + + + + Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + + + + + + + Test: Improve test script 003.failover. (Bo Peng) + + + + + + + Deal with "unable to bind D cannot get parse message "S1" error. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) + + + + + + + Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) + + + + + + + + Release 3.5.13 + + + Release Date + 2018-02-13 + + + + This release fixed the bug with socket writing added in Pgpool-II 3.7.0, 3.6.6 and 3.5.10. Due to this bug, when the network load is high, an illegal message may be sent to the frontend or backend. All users using 3.7.x, 3.6.6 or later, 3.5.10 or later versions of Pgpool-II should update as soon as possible. + + + + + Changes + + + + + Allow to build with libressl. (Tatsuo Ishii) + + + See [pgpool-hackers: 2714] for more details. Patch by Sandino Araico Sanchez. + + + + + + + Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) + + + TCP_NODELAY is employed by PostgreSQL, so do we it. + + + + + + + Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + + + + + + + Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + + + + + + + Bug fixes + + + + + + Fix writing transaction flag is accidentally set at commit or rollback. (Tatsuo Ishii) + + + + + + + Fix bug with socket writing. (Tatsuo Ishii) + + + pool_write_flush() is responsible for writing to sockets when pgpool's + write buffer is full (this function was introduced in 3.6.6 etc). When + network write buffer in kernel is full, it does retrying but it forgot + to update the internal buffer pointer. As a result, broken data is + written to the socket. This results in variety of problems including + too large message length. + + + + + + + Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) + + + + + + + + Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + + + + + + + + + Release 3.5.12 + + + Release Date + 2018-01-09 + + + + Bug fixes + + + + + + Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) + + + + + + + Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) + + + Removing "Type=forking" and add OPTS=" -n" to + run Pgpool-II with non-daemon mode, because we need to redirect logs. + Using "journalctl" command to see Pgpool-II systemd log. + + + + + + + Fix timestamp data inconsistency by replication mode. (Bo Peng) + + + From PostgreSQL10 the column + default value such as 'CURRENT_DATE' changes, + Pgpool-II didn't rewrite + timestamp by the added default values. This caused data inconsistency. + + + + + + + Downgrade a log message to debug message. (Tatsuo Ishii) + + + That was mistaken left while last development cycle. + + + + + + + Fix for re-sync logic in reading packet from backend. (Tatsuo Ishii) + + + read_kind_from_backend(), which reads message kind + from backend, re-syncs backend nodes when a ready for query message is + received. Unfortunately it forgot to call + pool_pending_message_pull_out() to delete sync + pending message. This leads to random stuck while reading packets + from backend. Fix this to call pool_pending_message_pull_out(). + + + + + + + Fix Pgpool-II hangs. (bug 370) (Tatsuo Ishii) + + + If an erroneous query is sent to primary and without a sync message + the next query that requires a catalog cache look up is send, + Pgpool-II hangs in do_query(). + + + + + + + Add SL_MODE macro for upper compatibility with Pgpool-II 3.7 or later. (Tatsuo Ishii) + + + + + + + Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + + + We return primary or master node state of ready for query message to + frontend. In most cases this is good. However if other than primary + node or master node returns an error state (this could happen if load + balance node is other than primary or master node and the query is an + erroneous SELECT), this should be returned to frontend, because the + frontend already received an error. + + + + + + + Fix pgpool start message printed multiple times. (Tatsuo Ishii) + + + + + + + Add an execute permission bit to the start/stop script in . (Tatsuo Ishii) + + + + + + + + Release 3.5.11 + + + Release Date + 2017-11-01 + + + + Bug fixes + + + + + + Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) + + + In RHEL6, the "-n" option is needed to redirect log. + + + + + + + Fix for bug in watchdog where sometime failover is not reliably performed. (Muhammad Usama) + + + Currently watchdog process only considers the node's watchdog state before + deciding if it can handle the failover and failover-locking requests. + + + But the problem with this technique is that, for the instance when the node has + announced itself as a master/coordinator of the cluster and is waiting for the + standby nodes to recognise it as a Master node. For that period of time the + watchdog state of the node is Master/coordinator, but it is yet not fully + capable of handling the failover and failover-locking requests. + + + So sometimes this leads to a situation where a failover is not reliably + performed in case when the failover request arrives while watchdog cluster is + in the process of electing a leader. + + + The fix for the above situation is to make sure that the node has fully acquired the Master status before accepting the failover and failover-locking requests. - - - - Fix Pgpool-II hung up bug or other errors in error case in extended query in replication mode. (Tatsuo Ishii) - - - And other fixes in this commit. - - - 1) Do not send intended error query to backend in streaming replication mode in ErrorResponse3(). - - - 2) Fix pool_virtual_master_db_node_id() to return the virtual_master_node_id only when query is in progress and query context exists. - - + + - - - - Allow make dist to include pgpool.service. (Yugo Nagata) - - + + + + Fix bug with handling of 'H' (flush) message in streaming replication mode. (bug 345) (Tatsuo Ishii) + + + If user expects to read response right after 'H', Pgpool-II hangs. The + cause was, when 'H' received, extended query mode was reset and + pending message was not used. + + - - - - - - Enhancements - + + + + Doc: Fix pcp_node_info documents. (Tatsuo Ishii) + + - - - - Test: Redirect build log to a log file. (Tatsuo Ishii) - - + + - - - - Test: Add more memory leak regression tests. (Tatsuo Ishii) - - + + + + Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) + + + See [pgpool-general: 5728] for more details. + + + + + + + Fix exit signal handlers to not call ereport. (Tatsuo Ishii) + + + See [pgpool-hackers: 2545] for more details. + + + + + + + Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) + + + + + + + + + Release 3.5.10 + + + Release Date + 2017-09-05 + + + + Bug fixes + + + + + Fix Pgpool-II hanging when error occurs in streaming replication mode and extended query. (Tatsuo Ishii) + + + If backend returns ERROR, Pgpool-II reads message from frontend until + a sync message is sent. Previous code assumed next message is sync. + However it is possible that more message coming before the sync + message, it's a low probability though. Fix it to continue reading + messages until the sync message is read. + + + + + + + Fix wd_authkey bug in that a request to add new node to the cluster is rejected by master. (Yugo Nagata) + + + This is a bug due to the implementation of 3.5.6 and 3.6.3. + + + This changed the definition of tv_sec that is used to check wd_authkey so + that this was affected by the clock of OS. So, if there is a lag between + two nodes' clocks, the wd_authkey check fails. + + + + + + + Test: Fix load balance test driver. (Tatsuo Ishii) + + + Some tests only for native replication mode was executed in streaming replication mode as well. + + + + + + + Fix not working slony mode in extended query. (Tatsuo Ishii) + + + When response returned from backend, in progress flag was not reset in slony mode, which cause waiting for next message from backend in vain. + + + + + + + Fix ancient bug of stream write modules. (Tatsuo Ishii) + + + Fix bug with pool_write_noerror() when requested length exceeds remaining write buffer size. This could lead to a buffer overrun problem. + + + When write buffer is full, pool_flush_it() is called, which could write data to socket in the middle of message. To fix the problem directly write requested data if the write buffer is going to be full. + + + Enhance performance of pool_unread(). + + + + + + + Test: Some miscellanies small fixes in regression test scripts. (Muhammad Usama) + + + + + + + + + + Doc: Fix documentation about load-balancing. (Yugo Nagata) + + + + + + + + + + Fix core dump and mishandling of temp tables. (Tatsuo Ishii) + + + + + + + Fix ancient bug of pool_unread(). (Tatsuo Ishii) + + + When realloc() is called in pool_unread(), it did not update the + buffer size. This could cause variety of memory corruption and + unexpected data reading from backend. The reason why we did not found + that is, probably recently Pgpool-II starts extensively to use + pool_unread(). + + + + + + + + Fix handling of empty queries. (bug 328) (Tatsuo Ishii) + + + When empty query (empty string or all comment query) is sent, command + complete message was returned to frontend. This is not correct. An + empty query response should be returned to frontend. + + + + + + + Fix query cache bug with streaming replication mode and extended query case. (Tatsuo Ishii) + + + + + + + Fix memory leak with streaming replication mode/extended query case. (bug 324) (Tatsuo Ishii) + + + + + + + Test: Fix Java program in 005.regression test. (Tatsuo Ishii) + + + + + + + Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) + + + This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). + + + + + + + Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) + + + + + + + Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) + + + + + + + Fix Pgpool-II hung up bug or other errors in error case in extended query in replication mode. (Tatsuo Ishii) + + + And other fixes in this commit. + + + 1) Do not send intended error query to backend in streaming replication mode in ErrorResponse3(). + + + 2) Fix pool_virtual_master_db_node_id() to return the virtual_master_node_id only when query is in progress and query context exists. + + + + + + + Allow make dist to include pgpool.service. (Yugo Nagata) + + + + + + + + + Enhancements + + + + + + Test: Redirect build log to a log file. (Tatsuo Ishii) + + - - + + + + Test: Add more memory leak regression tests. (Tatsuo Ishii) + + + + + - Release 3.5.9 + Release 3.5.9 - - Release Date - 2017-07-11 - + + Release Date + 2017-07-11 + - - Bug fixes + + Bug fixes - - + + - Fix for [pgpool-hackers: 2400] Garbage output (Muhammad Usama) + Fix for [pgpool-hackers: 2400] Garbage output (Muhammad Usama) - Mostly the log messages fixes and few code cleanups. + Mostly the log messages fixes and few code cleanups. - + - + - Importing the latest changes in the MemoryManager API from PostgreSQL code. (Muhammad Usama) + Importing the latest changes in the MemoryManager API from PostgreSQL code. (Muhammad Usama) - + - + - Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) + Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) - + - + - Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) + Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn - + - + - Fix a posible hang with streaming replication and extended protocol (Yugo Nagata) + Fix a possible hang with streaming replication and extended protocol (Yugo Nagata) - This hang occured under a certain condition. The following is an example. + This hang occurred under a certain condition. The following is an example. - - pgpool.conf is configured so that all read queries are sent to the standby. - - First, issue a writing query in a transaction block - - After commiting the transaction, issue a select query. - - When processing the query, send Describe (statement) message just after Parse. + - pgpool.conf is configured so that all read queries are sent to the standby. + - First, issue a writing query in a transaction block + - After committing the transaction, issue a select query. + - When processing the query, send Describe (statement) message just after Parse. - Without using JDBC, we can reproduce the problem by pgproto with the followeing messages. + Without using JDBC, we can reproduce the problem by pgproto with the following messages. - 'Q' "DROP TABLE IF EXISTS test_tbl" - 'Y' - 'Q' "CREATE TABLE test_tbl(i int)" - 'Y' - 'Q' "INSERT INTO test_tbl VALUES(1)" - 'Y' - - 'P' "" "BEGIN" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "COMMIT" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "S_1" "SELECT * FROM test_tbl" 0 - 'D' 'S' "S_1" - 'B' "C_1" "S_1" 0 0 0 - 'E' "C_1" 0 - 'S' - 'Y' - - 'X' + 'Q' "DROP TABLE IF EXISTS test_tbl" + 'Y' + 'Q' "CREATE TABLE test_tbl(i int)" + 'Y' + 'Q' "INSERT INTO test_tbl VALUES(1)" + 'Y' + + 'P' "" "BEGIN" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "COMMIT" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "S_1" "SELECT * FROM test_tbl" 0 + 'D' 'S' "S_1" + 'B' "C_1" "S_1" 0 0 0 + 'E' "C_1" 0 + 'S' + 'Y' + + 'X' - To fix it, parse_before_bind() should be called only if we are in a transaction block so that we can send Bind and Execute to the right backend. + To fix it, parse_before_bind() should be called only if we are in a transaction block so that we can send Bind and Execute to the right backend. - + - + - Fix Pgpool-II hang when used by erlang applications. (Tatsuo Ishii) + Fix Pgpool-II hang when used by erlang applications. (Tatsuo Ishii) - Erlang client sends "Describe" message followed by "Flush". So the - backend returns "Row description." However Pgpool-II forgets to reset - the query in progress flag upon receiving "Row description" message, - then Pgpool-II keeps on waiting for response from backend. This is the - cause of erlang client hanging. + Erlang client sends "Describe" message followed by "Flush". So the + backend returns "Row description." However Pgpool-II forgets to reset + the query in progress flag upon receiving "Row description" message, + then Pgpool-II keeps on waiting for response from backend. This is the + cause of erlang client hanging. - Fix is, just reset the query in progress flag upon receiving "Row - description" message. Same thing can be said to "no data" message. + Fix is, just reset the query in progress flag upon receiving "Row + description" message. Same thing can be said to "no data" message. - See [pgpool-general: 5555] for more details. + See [pgpool-general: 5555] for more details. - + - + - Fix bug with sending bind message to wrong target node. (bug 314) (Tatsuo Ishii) + Fix bug with sending bind message to wrong target node. (bug 314) (Tatsuo Ishii) - + - + - Fix query cache hang when used by node.js. (Tatsuo Ishii) + Fix query cache hang when used by node.js. (Tatsuo Ishii) - See [pgpool-general: 5511] for more details. + See [pgpool-general: 5511] for more details. - + - + - Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) + Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) - + - + - Fix query cache memory leak. (Tatsuo Ishii) + Fix query cache memory leak. (Tatsuo Ishii) - Clearing cache buffers in case of no oid queries (like BEGIN, - CHECKPOINT, VACUUM, etc) should have been done, but it did not. + Clearing cache buffers in case of no oid queries (like BEGIN, + CHECKPOINT, VACUUM, etc) should have been done, but it did not. - + - + - Fix extended query hang in certain case. (Tatsuo Ishii) + Fix extended query hang in certain case. (Tatsuo Ishii) - errlang PostgreSQL API produces Parse ('P'), Describe ('D'), - Flush ('H'), Bind ('B'), and Execute ('E'). Notice the 'H' message (this - does not happen in JDBC. I suspect that's the reason why this problem - is not popular before). After that, Pgpool-II dropped the extended - query mode, it failed to find which backend to read data. Thus Pgpool-II simply tries to read all of backend which causes hang - because it may have not send a message to some of backends. + errlang PostgreSQL API produces Parse ('P'), Describe ('D'), + Flush ('H'), Bind ('B'), and Execute ('E'). Notice the 'H' message (this + does not happen in JDBC. I suspect that's the reason why this problem + is not popular before). After that, Pgpool-II dropped the extended + query mode, it failed to find which backend to read data. Thus Pgpool-II simply tries to read all of backend which causes hang + because it may have not send a message to some of backends. - Solution is, after receiving the flush message set doing extended query flag. + Solution is, after receiving the flush message set doing extended query flag. - + - + - Fix corner case bug in Pgpool-II starting up. (Tatsuo Ishii) + Fix corner case bug in Pgpool-II starting up. (Tatsuo Ishii) - It is possible that a failover request is accepted before primary node - is searched. This leads Pgpool-II to a strange state: there's no - primary node if the failed node was a primary node (even if new - primary node exists as a result of promotion of existing standby). + It is possible that a failover request is accepted before primary node + is searched. This leads Pgpool-II to a strange state: there's no + primary node if the failed node was a primary node (even if new + primary node exists as a result of promotion of existing standby). - See [pgpool-hackers: 2321] for more details. + See [pgpool-hackers: 2321] for more details. - - - + + + - Release 3.5.8 + Release 3.5.8 - - Release Date - 2017-05-11 - + + Release Date + 2017-05-11 + - - Bug fixes + + Bug fixes - + - + - Add node 0 failover test. (Tatsuo Ishii) + Add node 0 failover test. (Tatsuo Ishii) - + - + - Fix Pgpool-II child process segfault reported in [pgpool-hackers: 2312]. (Tatsuo Ishii) + Fix Pgpool-II child process segfault reported in [pgpool-hackers: 2312]. (Tatsuo Ishii) - - - + + + - Release 3.5.7 + Release 3.5.7 - - Release Date - 2017-04-28 - + + Release Date + 2017-04-28 + - - Bug fixes + + Bug fixes - + - + - Fixing a mistake in the watchdog code. (Muhammad Usama) + Fixing a mistake in the watchdog code. (Muhammad Usama) - commit also adds some debug messages in the watchdog code. + commit also adds some debug messages in the watchdog code. - + - + @@ -1452,94 +2409,94 @@ Fix for 0000299: Errors on the reloading of configuration. (Bug 299) (Muhammad Usama) - + - + - Fix for 0000289: Inconsistent backend state. + Fix for 0000289: Inconsistent backend state. (Bug 289) (Muhammad Usama) - + - + - Enhancing the handling of split-brain scenario by the watchdog. (Muhammad Usama) + Enhancing the handling of split-brain scenario by the watchdog. (Muhammad Usama) - Previously, the watchdog cluster was used to call for re-election of the - master/coordinator node whenever the split-brain situation was detected. And - consequently every node was required to rejoin the watchdog network, Which was - essentially similar to the re-booting of the whole watchdog cluster. + Previously, the watchdog cluster was used to call for re-election of the + master/coordinator node whenever the split-brain situation was detected. And + consequently every node was required to rejoin the watchdog network, Which was + essentially similar to the re-booting of the whole watchdog cluster. - The candidate for the master/coordinator node is selected on the following criteria. + The candidate for the master/coordinator node is selected on the following criteria. - 1-- When two watchdog nodes are claiming to be the cluster master, the master - node that has performed the escalation keeps the master status and the other - node is asked to step down. + 1-- When two watchdog nodes are claiming to be the cluster master, the master + node that has performed the escalation keeps the master status and the other + node is asked to step down. - 2-- If the conflict could not be resolved by the escalation status of the nodes, - The node which holds the quorum remains the master/coordinator. + 2-- If the conflict could not be resolved by the escalation status of the nodes, + The node which holds the quorum remains the master/coordinator. - 3-- If the quorum status of both contenders is also same. The node with higher - number of connected alive nodes get the preference. + 3-- If the quorum status of both contenders is also same. The node with higher + number of connected alive nodes get the preference. - 4-- Finally, if all above three yields no winner, the older master (The node - that has the coordinator status for longer duration) remains the master. + 4-- Finally, if all above three yields no winner, the older master (The node + that has the coordinator status for longer duration) remains the master. - + - + - Enhancing the watchdog internal command mechanism to handle multiple concurrent commands. (Muhammad Usama) + Enhancing the watchdog internal command mechanism to handle multiple concurrent commands. (Muhammad Usama) - + - + - Add bool encode and decode functions to JSON framework for code compatibility.(Muhammad Usama) + Add bool encode and decode functions to JSON framework for code compatibility.(Muhammad Usama) - + - + - Comment out unsupported Java method in new JDBC drivers to prevent regression failure. (Tatsuo Ishii) + Comment out unsupported Java method in new JDBC drivers to prevent regression failure. (Tatsuo Ishii) - + - + - Downgrade parse before bind log message to debug1. (Tatsuo Ishii) + Downgrade parse before bind log message to debug1. (Tatsuo Ishii) - + - + - Fix for [pgpool-general: 5396] pam ldap failure. (Muhammad Usama) + Fix for [pgpool-general: 5396] pam ldap failure. (Muhammad Usama) - + - + - Consider SHOW command as kind of a read query. (Tatsuo Ishii) + Consider SHOW command as kind of a read query. (Tatsuo Ishii) - In streaming replication mode, if SHOW is issued then subsequent - SELECTs are sent to the primary node in an explicit transaction. This - is not a reasonable and unnecessary limitation. + In streaming replication mode, if SHOW is issued then subsequent + SELECTs are sent to the primary node in an explicit transaction. This + is not a reasonable and unnecessary limitation. - Also fix hang when parse command returns error. + Also fix hang when parse command returns error. - + - + - Fix memory leak problem caused by commit adcb636. (Tatsuo Ishii) + Fix memory leak problem caused by commit adcb636. (Tatsuo Ishii) - Commit adcb636 introduces "pending message queue". When a message - arrives, the info is added to the queue and a copy of object is - created at the same time, but forgot to free the object. Fix is, - creating a new function pool_pending_message_free_pending_message() - and call it after pool_pending_message_add(), - pool_pending_message_get() and pool_pending_message_pull_out(). + Commit adcb636 introduces "pending message queue". When a message + arrives, the info is added to the queue and a copy of object is + created at the same time, but forgot to free the object. Fix is, + creating a new function pool_pending_message_free_pending_message() + and call it after pool_pending_message_add(), + pool_pending_message_get() and pool_pending_message_pull_out(). - Problem reported by Sergey Kim. + Problem reported by Sergey Kim. - + - + - Mega patch to fix "kind mismatch" (or derived) errors in streaming replication mode. + Mega patch to fix "kind mismatch" (or derived) errors in streaming replication mode. (Bug 271) (Tatsuo Ishii) - The errors are caused by wrong prediction in which (or both) database - node will send response to Pgpool-II. Previous implementation using - "sync map" are weak and sometimes fail in the prediction. + The errors are caused by wrong prediction in which (or both) database + node will send response to Pgpool-II. Previous implementation using + "sync map" are weak and sometimes fail in the prediction. - This patch introduces new implementation using "pending message - queue", which records all sent message to backends. The element of the - queue stores info regarding messages types - (parse/bind/execute/describe/close/sync), to which database node the - message was sent and so on. It's a simple FIFO queue. When a message - arrives from backend, by looking at the head of the "pending message - queue", it is possible to reliably predict what kind of message and - from which database node it will arrive. After receiving the message, - the element is removed from the queue. + This patch introduces new implementation using "pending message + queue", which records all sent message to backends. The element of the + queue stores info regarding messages types + (parse/bind/execute/describe/close/sync), to which database node the + message was sent and so on. It's a simple FIFO queue. When a message + arrives from backend, by looking at the head of the "pending message + queue", it is possible to reliably predict what kind of message and + from which database node it will arrive. After receiving the message, + the element is removed from the queue. - I would like to thank to Sergey Kim, who has been helping me in - testing series of patches. + I would like to thank to Sergey Kim, who has been helping me in + testing series of patches. - See Bug 271 - and discussion in pgpool-hackers mailing list - [pgpool-hackers: 2043] and - [pgpool-hackers: 2140] + See Bug 271 + and discussion in pgpool-hackers mailing list + [pgpool-hackers: 2043] and + [pgpool-hackers: 2140] for more details. - + - + - Fix for 0000296: PGPool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. - (Bug 296) (Muhammad Usama) + Fix for 0000296: Pgpool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. + (Bug 296) (Muhammad Usama) - - + + - + - Release 3.5.6 + Release 3.5.6 - - Release Date - 2017-03-17 - + + Release Date + 2017-03-17 + - - Bug fixes + + Bug fixes - + - + - Add "Wants=network.target" to pgpool.service file. - (bug 294) (Bo Peng) + Add "Wants=network.target" to pgpool.service file. + (bug 294) (Bo Peng) - + - + - Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) + Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) - The master node could not be promoted by pcp_promote_node with - the following error; + The master node could not be promoted by pcp_promote_node with + the following error; FATAL: invalid pgpool mode for process recovery request DETAIL: specified node is already primary node, can't promote node id 0 - + - In streaming replication mode, there is a case that Pgpool-II - regards the status of primary node as "standby" for some reasons, - for example, when pg_ctl promote is executed manually during - Pgpool-II is running, in which case, it seems to Pgpool-II - that the primary node doesn't exist. + In streaming replication mode, there is a case that Pgpool-II + regards the status of primary node as "standby" for some reasons, + for example, when pg_ctl promote is executed manually during + Pgpool-II is running, in which case, it seems to Pgpool-II + that the primary node doesn't exist. - This status mismatch should be fixe by pcp_promote_node, but when the node - is the master node (the first alive node), it fails as mentioned above. + This status mismatch should be fixed by pcp_promote_node, but when the node + is the master node (the first alive node), it fails as mentioned above. - The reason is as following. before changing the status, pcp_promote_node - checks if the specified node is already primary or not by comparing the - node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from - Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. - Hence, when the master node is specified to be promoted, pcp_promote_node - is confused that this node is already primary and doesn't have to be - promoted, and it exits with the error. + The reason is as following. before changing the status, pcp_promote_node + checks if the specified node is already primary or not by comparing the + node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from + Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. + Hence, when the master node is specified to be promoted, pcp_promote_node + is confused that this node is already primary and doesn't have to be + promoted, and it exits with the error. - To fix this, pcp_promote_node should check the node id by using - REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, - rather than PRIMARY_NODE_ID. + To fix this, pcp_promote_node should check the node id by using + REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, + rather than PRIMARY_NODE_ID. - + - + - Add the latest release note link to README file.(Bo Peng) + Add the latest release note link to README file.(Bo Peng) - + - + - Pgpool-IIshould not perform ping test after bringing down the VIP. (Muhammad Usama) + Pgpool-IIshould not perform ping test after bringing down the VIP. (Muhammad Usama) + + + + This issue was reported by the reporter of + bug:[pgpool-II 0000249]: watchdog sometimes fails de-escalation + + + + + + + Fix to release shared memory segments when Pgpool-IIexits. + (bug 272) (Tatsuo Ishii) + + + + + + + Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) + + + + + + + Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) + + + + + + + Fix for 281: "segmentation fault" when execute pcp_attach_node. + (bug 281) (Muhammad Usama) + + + + + + + Fix load balancing bug in streaming replication mode. (Tatsuo Ishii) + + In an explicit transaction, any SELECT will be load balanced until + write query is sent. After writing query is sent, any SELECT should be + sent to the primary node. However if a SELECT is sent before a sync + message is sent, this does not work since the treatment of writing + query is done after ready for query message arrives. + + + Solution is, the treatment for writing query is done in executing the writing query as well. + + + + The bug has been there since V3.5. + + + + + + + Fix yet another kind mismatch error in streaming replication mode. (Tatsuo Ishii) + + + + + + + Fix do_query()hangs after close message. (Tatsuo Ishii) + + + + + + + Fixing stack smashing detected. (bug 280) (Muhammad Usama) + + + It was a buffer overflow in wd_get_cmd function + + + + + + + + Fixing the issue with the watchdog process restart. (Muhammad Usama) + + + When the watchdog process gets abnormally terminated because of some problem + (e.g. Segmentation fault) the new spawned watchdog process fails to start and + produces an error "bind on ... failed with reason: Address already in use". + + + Reason is the abnormally terminating watchdog process never gets the time to + clean-up the socket it uses for IPC and the new process gets an error because + the socket address is already occupied. + + + + Fix is, the Pgpool main process sets the flag in shared memory to mark the + watchdog process was abnormally terminated and at startup when the watchdog + process see that the flag is set, it performs the clean up of the socket file and + also performs the de-escalation (If the watchdog process was crashed when it + was master/coordinator node) if required before initializing itself. + + + + + + + Fix query cache bug reported in pgpool-general-jp:1441. (Tatsuo Ishii) + + + In streaming replication mode with query cache enabled, SELECT hangs + in the following scenario: + + + + 1) a SELECT hits query cache and returns rows from the query cache. + 2) following SELECT needs to search meta data and it hangs. + + + + In #1, while returning the cached result, it misses to call + pool_unset_pending_response(), which leave the pending_response flag + be set. In #2, do_query() checks the flag and tries to read pending + response from backend. Since there's no pending data in backend, it + hangs in reading data from backend. + + + + Fix is, just call pool_unset_pending_response() in #1 to reset the + flag. + + + + Bug report and fix provided by Nobuyuki Nagai. + + New regression test item (068) added by me. + + + + + + + + Remove elog/ereport calls from signal handlers. (Tatsuo Ishii) + + + See [pgpool-hackers: 1950] for details. + + + + + + + Fix bug failed to create INET domain socket in FreeBSD if listen_addresses = '*'. + (bug 202) (Bo Peng) + + + + + + + Fix for 0000249: watchdog sometimes fails de-escalation. + (bug 249) (Muhammad Usama) + + + + The solution is to use the waitpid() system call without WNOHANG option. + + + + + + + + Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) + + + + - This issue was reported by the reporter of - bug:[pgpool-II 0000249]: watchdog sometimes fails de-escalation + Fix authentication timeout that can occur right after client connections. (Yugo Nagata) - + + + + + + + + + + + + Release 3.5.5 + + + Release Date + 2016-12-26 + + + + Bug fixes + + - + - Fix to release shared memory segments when Pgpool-IIexits. - (bug 272) (Tatsuo Ishii) + Tightening up the watchdog security. (Muhammad Usama) - - - - Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) + Now wd_authkey uses the HMAC SHA-256 hashing. - + - + - Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) + Add pgpool_adm extension in Pgpool-II RPM. (Bo Peng) - + - + - Fix for 281: "segmentation fault" when execute pcp_attach_node. - (bug 281) (Muhammad Usama) + Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) - + - + - Fix load balancing bug in streaming replication mode. (Tatsuo Ishii) + Fix packet kind does not match error in extended protocol. (bug 231) (Tatsuo Ishii) - In an explicit transaction, any SELECT will be load balanced until - write query is sent. After writing query is sent, any SELECT should be - sent to the primary node. However if a SELECT is sent before a sync - message is sent, this does not work since the treatment of writing - query is done after ready for query message arrives. + According to the bug231, the bug seem to bite you if all of + following conditions are met: + + + + Streaming replication mode + + + + + Load balance node is not node 0 + + + + + Extended protocol is used + + + + + SELECT is executed, the statement is closed, then a + transaction command is executed + + + - Solution is, the treatment for writing query is done in executing the writing query as well. - + The sequence of how the problem bites is: + + + + SELECT executes on statement S1 on the load balance node 1 + + + + + Frontend send Close statement + + + + + Pgpool-II forward it to backend 1 + + + + + Frontend sends Parse, Bind, Execute of COMMIT + + + + + Pgpool-II forward it to backend 0 & 1 + + + + + Frontend sends sync message + + + + + Pgpool-II forward it to backend 0 & 1 + + + + + Backend 0 replies back Parse complete ("1"), while + backend 1 replies back close complete ("3") because of + #3. + + + + + Kind mismatch occurs + + + + - The bug has been there since V3.5. + The solution is, in #3, let Pgpool-II wait for response from backend + 1, but do not read the response message. Later on Pgpool-II's state + machine will read the response from it before the sync message is sent + in #6. With this, backend 1 will reply back "1" in #8, and the kind + mismatch error does not occur. - - - - - Fix yet another kind mismatch error in streaming replication mode. (Tatsuo Ishii) + Also, fix not calling pool_set_doing_extended_query_message() when + receives Close message. (I don't know why it was missed). - - - - - Fix do_query()hangs after close message. (Tatsuo Ishii) + New regression test "067.bug231" was added. - + - + - Fixing stack smashing detected. (bug 280) (Muhammad Usama) + Fix a race condition in a signal handler per bug 265. (Tatsuo Ishii) - It was a buffer overflow in wd_get_cmd function - + In child.c there's signal handler which calls elog. Since the signal + handler is not blocked against other signals while processing, deadlock + could occur in the system calls in the pgpool shutdown sequence. To + fix the problem, now the signal handler is blocked by using + POOL_SETMASK. + + + Ideally we should avoid calling elog in signal handlers though. - + - + - Fixing the issue with the watchdog process restart. (Muhammad Usama) - - - When the watchdog process gets abnormally terminated because of some problem - (e.g. Segmentation fault) the new spawned watchdog process fails to start and - produces an error "bind on ... failed with reason: Address already in use". + Back porting the improved failover command propagation mechanism from Pgpool-II 3.6 (Muhammad Usama) - Reason is the abnormally terminating watchdog process never gets the time to - clean-up the socket it uses for IPC and the new process gets an error because - the socket address is already occupied. + Overhauling the design of how failover, failback and promote node commands are + propagated to the watchdog nodes. Previously the watchdog on pgpool-II node that + needs to perform the node command (failover, failback or promote node) used to + broadcast the failover command to all attached pgpool-II nodes. And this + sometimes makes the synchronization issues, especially when the watchdog cluster + contains a large number of nodes and consequently the failover command sometimes + gets executed by more than one pgpool-II. - - Fix is, the Pgpool main process sets the flag in shared memory to mark the - watchdog process was abnormally terminated and at startup when the watchdog - process see that the flag is set, it performs the clean up of the socket file and - also performs the de-escalation (If the watchdog process was crashed when it - was master/coordinator node) if required before initializing itself. + Now with this commit all the node commands are forwarded to the + master/coordinator watchdog, which in turn propagates to all standby nodes. + Apart from above the commit also changes the failover command interlocking + mechanism and now only the master/coordinator node can become the lock holder + so the failover commands will only get executed on the master/coordinator node. - + - + - Fix query cache bug reported in pgpool-general-jp:1441. (Tatsuo Ishii) + Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) - In streaming replication mode with query cache enabled, SELECT hangs - in the following scenario: + It was intended to keep the consistency, but there's no point in other + than native replication mode. + - - 1) a SELECT hits query cache and returns rows from the query cache. - 2) following SELECT needs to search meta data and it hangs. - - + + - In #1, while returning the cached result, it misses to call - pool_unset_pending_response(), which leave the pending_response flag - be set. In #2, do_query() checks the flag and tries to read pending - response from backend. Since there's no pending data in backend, it - hangs in reading data from backend. + Remove obsoleted option "-c" in pgpool command. (Tatsuo Ishii) - - Fix is, just call pool_unset_pending_response() in #1 to reset the - flag. + Also fix typo in the help message. + + + - Bug report and fix provided by Nobuyuki Nagai. - - New regression test item (068) added by me. + Fix authentication failed error when PCP command is cancelled. (bug 252) (Muhammad Usama) + - - - + - Remove elog/ereport calls from signal handlers. (Tatsuo Ishii) + Change the default value of search_primary_node_timeout from 10 to 300. (Tatsuo Ishii) - See [pgpool-hackers: 1950] for details. + Prior default value 10 seconds is sometimes too short for a standby to + be promoted. - + - + - Fix bug failed to create INET domain socket in FreeBSD if listen_addresses = '*'. - (bug 202) (Bo Peng) + Fix the case when all backends are down then 1 node attached. (bug 248) (Tatsuo Ishii) - + + When all backends are down, no connection is accepted. Then 1 + PostgreSQL becomes up, and attach the node using pcp_attach_node. It + successfully finishes. However, when a new connection arrives, still + the connection is refused because pgpool child process looks into the + cached status, in which the recovered node is still in down status if + mode is streaming replication mode (native replication and other modes + are fine). Solution is, if all nodes are down, force to restart all + pgpool child. + + - + - Fix for 0000249: watchdog sometimes fails de-escalation. - (bug 249) (Muhammad Usama) + Fix for: [pgpool-general: 4997] Avoiding downtime when pgpool changes require a restart (Muhammad Usama) - - The solution is to use the waitpid() system call without WNOHANG option. - + To fix this, The verification mechanism of configuration parameter values is + reversed, previously the standby nodes used to verify their parameter values + against the respective values on the master pgpool-II node and when the + inconsistency was found the FATAL error was thrown, now with this commit the + verification responsibility is delegated to the master pgpool-II node. + Now the master node will verify the configuration parameter values of each + joining standby node against its local values and will produce + a WARNING message instead of an error in case of a difference. + This way the nodes having the different configurations will also be allowed to + join the watchdog cluster and the user has to manually look out for the + configuration inconsistency warnings in the master pgpool-II log to avoid the + surprises at the time of pgpool-II master switch over. - + - + - Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) + Add compiler flag "-fno-strict-aliasing" in configure.ac to fix compiler error. (Tatsuo Ishii) - + - + - Fix authentication timeout that can occur right after client connecttions. (Yugo Nagata) - - - - - - - - - - - - - Release 3.5.5 - - - Release Date - 2016-12-26 - - - - Bug fixes - - - - - - - Tightening up the watchdog security. (Muhammad Usama) + Do not use random() while generating MD5 salt. (Tatsuo Ishii) - - Now wd_authkey uses the HMAC SHA-256 hashing. - - - - - - - Add pgpool_adm extension in Pgpool-II RPM. (Bo Peng) - - - - - - - Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) - - - - - - - Fix packet kind does not match error in extended protocol. (bug 231) (Tatsuo Ishii) - - - According to the bug231, the bug seem to bite you if all of - following conditions are met: - - - - - Streaming replication mode - - - - - Load balance node is not node 0 - - - - - Extended protocol is used - - - - - SELECT is executed, the statement is closed, then a - transaction command is executed - - - - - The sequence of how the problem bites is: - - - - SELECT executes on statement S1 on the load balance node 1 - - - - - Frontend send Close statement - - - - - Pgool-II forward it to backend 1 - - - - - Frontend sends Parse, Bind, Execute of COMMIT - - - - - Pgool-II forward it to backend 0 & 1 - - - - - Frontend sends sync message - - - - - Pgool-II forward it to backend 0 & 1 - - - - - Backend 0 replies back Parse complete ("1"), while - backend 1 replies back close complete ("3") because of - #3. - - - - - Kind mismatch occurs - - - - - - - The solution is, in #3, let Pgpool-II wait for response from backend - 1, but do not read the response message. Later on Pgpool-II's state - machine will read the response from it before the sync message is sent - in #6. With this, backend 1 will reply back "1" in #8, and the kind - mismatch error does not occur. - - - Also, fix not calling pool_set_doing_extended_query_message() when - receives Close message. (I don't know why it was missed). - - - New regression test "067.bug231" was added. - - - - - - - Fix a race condition in a signal handler per bug 265. (Tatsuo Ishii) - - - In child.c there's signal handler which calls elog. Since the signal - handler is not blocked against other signals while processing, deadlock - could occur in the system calls in the pgpool shutdown sequence. To - fix the problem, now the signal handler is blocked by using - POOL_SETMASK. - - - Ideally we should avoid calling elog in signal handlers though. - - - - - - - Back porting the improved failover command propagation mechanism from Pgpool-II 3.6 (Muhammad Usama) - - - Overhauling the design of how failover, failback and promote node commands are - propagated to the watchdog nodes. Previously the watchdog on pgpool-II node that - needs to perform the node command (failover, failback or promote node) used to - broadcast the failover command to all attached pgpool-II nodes. And this - sometimes makes the synchronization issues, especially when the watchdog cluster - contains a large number of nodes and consequently the failover command sometimes - gets executed by more than one pgpool-II. - - - Now with this commit all the node commands are forwarded to the - master/coordinator watchdog, which in turn propagates to all standby nodes. - Apart from above the commit also changes the failover command interlocking - mechanism and now only the master/coordinator node can become the lock holder - so the failover commands will only get executed on the master/coordinator node. - - - - - - - Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii) - - - It was intended to keep the consistency, but there's no point in other - than native replication mode. - - - - - - - Remove obsoleted option "-c" in pgpool command. (Tatsuo Ishii) - - - Also fix typo in the help message. - - - - - - - Fix authentication failed error when PCP command is cancelled. (bug 252) (Muhammad Usama) - - - - - - - Change the default value of search_primary_node_timeout from 10 to 300. (Tatsuo Ishii) - - - Prior default value 10 seconds is sometimes too short for a standby to - be promoted. - - - - - - - Fix the case when all backends are down then 1 node attached. (bug 248) (Tatsuo Ishii) - - - When all backends are down, no connection is accepted. Then 1 - PostgreSQL becomes up, and attach the node using pcp_attach_node. It - successfully finishes. However, when a new connection arrives, still - the connection is refused because pgpool child process looks into the - cached status, in which the recovered node is still in down status if - mode is streaming replication mode (native replication and other modes - are fine). Solution is, if all nodes are down, force to restart all - pgpool child. - - - - - - - Fix for: [pgpool-general: 4997] Avoiding downtime when pgpool changes require a restart (Muhammad Usama) - - - To fix this, The verification mechanism of configuration parameter values is - reversed, previously the standby nodes used to verify their parameter values - against the respective values on the master pgpool-II node and when the - inconsistency was found the FATAL error was thrown, now with this commit the - verification responsibility is delegated to the master pgpool-II node. - Now the master node will verify the configuration parameter values of each - joining standby node against its local values and will produce - a WARNING message instead of an error in case of a difference. - This way the nodes having the different configurations will also be allowed to - join the watchdog cluster and the user has to manually look out for the - configuration inconsistency warnings in the master pgpool-II log to avoid the - surprises at the time of pgpool-II master switch over. - - - - - - - Add compiler flag "-fno-strict-aliasing" in configure.ac to fix compiler error. (Tatsuo Ishii) - - - - - - - Do not use random() while generating MD5 salt. (Tatsuo Ishii) - - - random() should not be used in security related applications. To - replace random(), import PostmasterRandom() from PostgreSQL. Also - store current time at the start up of Pgpool-II main process for later - use. - + random() should not be used in security related applications. To + replace random(), import PostmasterRandom() from PostgreSQL. Also + store current time at the start up of Pgpool-II main process for later + use. + - + - - - - Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) - - + + + + Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) + + - + - + diff --git a/doc/src/sgml/release-3.6.sgml b/doc/src/sgml/release-3.6.sgml index e7f482fde..b92c24634 100644 --- a/doc/src/sgml/release-3.6.sgml +++ b/doc/src/sgml/release-3.6.sgml @@ -1,3755 +1,5531 @@ - - Release 3.6.14 + + Release 3.6.28 Release Date - 2018-11-22 + 2021-11-18 - - Bug fixes + + Security release - - - + - Fix to sort startup packet's parameters sent by client. - (bug 444)(Takuma Hoshiai) + Reject extraneous data after SSL encryption handshake. (Tatsuo Ishii) - If order of startup packet's parameters differ between cached connection - pools and connection request, did't use connection pool ,and created new - connection pool. + In the server side implementation of SSL negotiation, it was possible for a + man-in-the-middle attacker to inject arbitrary SQL commands. This is + possible if Pgpool-II is configured to use cert authentication or + hostssl + trust. This resembles PostgreSQL's CVE-2021-23214. + + + Similarly, in the client side implementation of SSL negotiation, it was + possible for a man-in-the-middle attacker to inject arbitrary responses. + This is possible if PostgreSQL is using trust authentication with a + clientcert requirement. It is not possible with cert authentication because + Pgpool-II does not implement the cert authentication between Pgpool-II + and PostgreSQL. This resembles PostgreSQL's CVE-2021-23222. - + + + + + Changes + + - - + - Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. - (bug 443)(Bo Peng) + Deal with PostgreSQL 14 while processing + pg_terminate_backend(). (Tatsuo Ishii) + + + + - If the number of parameter format codes is specified to one, but the number - of the original query's parameter is zero, bind_rewrite_timestamp() - will call memcpy with a negative value. - This causes segmentation fault. + Enhance SIGCHLD handler of Pgpool-II main process. (Tatsuo Ishii) - Patch is provided by Yugo Nagata. + When Pgpool-II child is killed by SIGKILL signal, + the SIGCHLD handler just emitted LOG level message as other signals. But + SIGKILL is an important event, for example killed by OOM killer. So emit a + WARNING level message instead. + Per suggestion from Michail Alexakis. + Discussion: [pgpool-general: 7750] + - + + + + + + Bug fixes + + - - + - Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + Fix occasional hang in COPY FROM. (Tatsuo Ishii) + + + If an error occurs while doing COPY FROM, it was possible the + Pgpool-II waited forever for a response from + backend after COPY end marker was sent from frontend. + The bug was found by Bo Peng. - + - - + - Fix query cache invalidation bug. (Tatsuo Ishii) + Fix the incorrect display of load balancing node in raw mode. (Bo Peng) + + + In raw mode, Pgpool-II sends all queries to main node. + This is harmless, but it may confuse users. - + + + + + Documents + + - - + - Fix segfault in extended query + query cache case. (Tatsuo Ishii) + Fix documentation typos. (Bo Peng) + + + Patch is created by Kazufumi Noto. - + - + - Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + Doc: Mention that double quotes are required in PGPOOL SHOW command, + if the parameter contains uppercase letters. (Bo Peng) - - - - - - Release 3.6.13 - - Release Date - 2018-10-31 - + + - Changes - - - - - Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) - - - - - - - Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) - - - - - - - Doc: Add note to online recovery doc. (Tatsuo Ishii) - - - This warns that must be smaller than . - - - - - - - Test: Add regression test for SSL connection. (Tatsuo Ishii) - - - - - - - Doc: Add notes regarding failover script. (Tatsuo Ishii) - - - It's not recommended to access against Pgpool-II itself from failover/failback scripts. - - - - - - - Doc: Improve docs and error message. (Bo Peng) - - - Patch provided by Jesper Pedersen and modified by me. - - - - - - - Test: Add definition of PGLIB in regress.sh. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - + Test tools + - - Bug fixes - - - - Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) - - - Patch provided by Phil Ramirez. + Fix pgpool_setup to do nothing when no new main node is available. (Tatsuo Ishii) - + + + + + + + Regression tests + - + - Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) - - - In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. + Fix occasional 073.pg_terminate_backend regression test failure. (Tatsuo Ishii) - + - + - Fix syntax error when queries including time functions and IN (SELECT ...) in - WHERE clause in native replication mode. - (bug 433) (Bo Peng) - - - In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. - However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. + Fix psql command path to avoid test failure. (Bo Peng) - + + + + + + + + Release 3.6.27 + + Release Date + 2021-08-05 + + + + Changes + - + - Fix occasional less data returned to frontend with extended protocol. (bug432) (Tatsuo Ishii) - - - The idea for fix is, use pending message data list. It records - messages from frontend, and it is expected that we will receive same - number of messages. - - - Initial patch is created by Yugo Nagata and fixed by Tatsuo Ishii. + Fix maximum length of hostnames including domain name. (Tatsuo Ishii) - - - - - Fix memory leak when query cache enabled in streaming replication mode + extended query case. (Tatsuo Ishii) + The maximum length of hostnames was 128, but the correct value is 254. + Discussion: [pgpool-hackers: 3903] - + - - - - Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) - - + + - - - - Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) - - - In a explicit transaction, the SELECT results are cached in temporary buffer. - If a write SQL is sent which modifies the table, the temporary buffe should be reset. - - + + Bug fixes + - + - Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) + Fix sending invalid message in SI mode. (Tatsuo Ishii) + + + When a query is aborted by specific reason like serialization error, + Pgpool-II sends error query to abort + transactions running on non main nodes. The message length of the + query was incorrect and it caused "invalid string in message" error on backend. - + - + - Test: Add EXECUTE/DEALLOCATE regression test. (Takuma Hoshiai) + Fix watchdog communication race condition. (Tatsuo Ishii) + + + When watchdog notifies the new message to main process while main process + is executing the process notified by watchdog process, there was a + significant delay before the new message was processing. + Discussion: [pgpool-hackers: 3900] - + - + - - Add missing pgpool_recovery--1.0--1.1.sql file to update - pgpool_recovery() function version to 1.1. (Bo Peng) - - + + Fix watchdog node status not updating after rebooting. + (bug 684) (Muhammad Usama) + + + + + - + + Documents + + + - - Fix kind mismatch error when DEALLOCATE statement is issued. (Bo Peng) - - - PREPARE should be add to pool_add_sent_message, - so that EXECUTE and DEALLOCATE - can be sent to the same node as PREPARE. - - - See [pgpool-general: 6226] for more details. - - - - + + Doc: fix documentation typos. (Bo Peng) + + + + - - Do not update if the password length is incorrect. - (bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - For Pgpool-II 3.7 or before, the password stored in - is MD5 password only. - So check the correctness of by scanning entire file. - - + + Doc: fix typo in in memory query cache document. (Tatsuo Ishii) + + - + - Doc: Change description "new master" to "new primary". (Bo Peng) + Doc: fix description (Masaya Kawamoto) - + + + + + + + Test tools + - + - Fix newer version of gcc warnings. (Tatsuo Ishii) + Fix rsync parameter in pgpool_setup. (Tatsuo Ishii) - + - + - Test: Update clean.sh which clean up regression test results. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - + Fix pgpool_setup in creating base backup script. (Tatsuo Ishii) + + - + - Add .gitignore files. (Bo Peng) + Enhance watchdog_setup script. (Tatsuo Ishii) - Patch provided by Jesper Pedersen. + shutdownall script generated by watchdog_setup caused failover event which is not + necessary in the whole shutdown sequence. - - - - - - Fix segfault when node 0 is in down status in case of both health check - and are disabled. (Tatsuo Ishii) - - - - - - - Doc: Fix typos in documents and scripts. (Tatsuo Ishii) - - - Patch contributed by Jesper Pedersen. - - - - - - - Doc: Fix document mistakes of and . (Bo Peng) - - - - - - - - Release 3.6.12 - - - Release Date - 2018-07-31 - - - - Bug fixes - - - - - Fix "write on backend 0 failed with error :"Success"" error. - (bug 403) (Tatsuo Ishii) - - - Don't treated it as an error if write() returns 0. - - - - - - - Fix for 0000409: worker process is not restarted after failover on standby. - (bug 409) (Muhammad Usama) - - - Patch contributed by Yugo Nagata. - - - - - - - Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) - - - - - - - Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) - - - This led to a segfault issue mentioned on certain platform. - - - - - - - Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) - - - Patch provided by Christian Ehrhardt. - - - - - - - Doc: Improve documents of "MD5 Password Authentication", "Installing Pgpool-II" and "pg_md5".(Bo Peng) - - - Patch provided by Takuma Hoshiai. - - - - - - - Test: Fix 006.memqcache test failure. (Tatsuo Ishii) - - - - - - - - Release 3.6.11 + - - Release Date - 2018-06-12 - + + - Bug fixes - - - - - Fix Pgpool-II hung if replication delay is too much, when query cache enabled in extended query mode. (Tatsuo Ishii) - - - See [pgpool-general-jp: 1534] - for more details. - - - - - - - Doc: Fix document typo of PCP commands option "-U". (Bo Peng) - - + Regression tests + - - - - Delete some debug code. (Bo Peng) - - + + + + Fix 031.connection_life_time. (Tatsuo Ishii) + + - - - - In extended query mode, do not set writing tx flag with SET TRANSACTION READ ONLY. (Tatsuo Ishii) - - - - - - - Doc: Update outdated manual. (Tatsuo Ishii) - - - - - - - Doc: Enhance online recovery document to Clarify - that is only required in native replication mode. (Tatsuo Ishii) - - - - - - - Prevent from recovering "unused" status node. (Tatsuo Ishii) - - - This allowed to try to recovery a node without configuration data, - which leads to variety of problems. - - - See [pgpool-general: 5963] - for more details. - - - Also I fixed pgpool_recovery function so that it quotes an - empty string argument with double quotes. - - - - + + - - Release 3.6.10 - - - Release Date - 2018-04-17 - - - - Bug fixes - + + Release 3.6.26 + + Release Date + 2021-05-20 + - + + Bug fixes + + - Test: Add new regression test for node 0 is down. (Tatsuo Ishii) + Doc: fix description about . (Tatsuo Ishii) - + + It did not mention the parameter can only be used if Pgpool-II started as root. + + - + - Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + Fix to create database cluster entity under pgpool0. (Tatsuo Ishii) - + - + - Doc: Improve watchdog documents. (Tatsuo Ishii) + Fix pgpool crash when query cache enabled. + (bug 700) (Tatsuo Ishii) - + Pgpool-II crashed upon receiving CloseComplete. This only happened in other than streaming and logical replication mode. - + - + - Test: Improve test script 003.failover. (Bo Peng) + Enhance debug message upon receiving startup packet. (Tatsuo Ishii) - + - + - Deal with "unable to bind D cannot get parse message "S1" error. (Tatsuo Ishii) + Doc: enhance documentation. (Tatsuo Ishii, Bo Peng) - + + + + + + + Release 3.6.25 + + Release Date + 2021-02-18 + - + + Changes + + - Doc: Mention that users can avoid failover using backend_flag even PostgreSQL admin shutdown. (Tatsuo Ishii) + Delete any pre-existing watchdog command socket file at startup. (Muhammad Usama) + + + Patch provided by Masaya Kawamoto. - + + + - + + Bug fixes + + - Doc: Fix document typos. (Bo Peng) + Fix the incorrect "weight" displayed in . (Tatsuo Ishii) - + - + - Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) + Fix that DB cluster path was not correct in watchdog_setup installation. (Tatsuo Ishii) - + - + - Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) + Fix pgpool_setup so that it creates separate archive directory for each DB node. (Tatsuo Ishii) - + - + - Doc: Fix pgpool_adm family functions examples. (Tatsuo Ishii) + Fix error while allocating shared memory. (Tatsuo Ishii) - - - - - - - - Release 3.6.9 + - - Release Date - 2018-02-13 - - + + - This release fixed the bug with socket writing added in Pgpool-II 3.7.0, 3.6.6 and 3.5.10. Due to this bug, when the network load is high, an illegal message may be sent to the frontend or backend. All users using 3.7.x, 3.6.6 or later, 3.5.10 or later versions of Pgpool-II should update as soon as possible. + Fix bug is not respected if ERROR occurs. (Tatsuo Ishii) - + - - Changes - - + - Allow to build with libressl. (Tatsuo Ishii) - - - See [pgpool-hackers: 2714] for more details. Patch by Sandino Araico Sanchez. + Fix segfault that may occur when backend_flag = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER' or failover_command = ''. + (bug 672) (Tatsuo Ishii) - + - + - Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) + Doc: fix description. (Tatsuo Ishii) + + + + + + + Release 3.6.24 + + Release Date + 2020-11-19 + + + + Changes + + + - TCP_NODELAY is employed by PostgreSQL, so do we it. + Doc: mention that GSSAPI is not supported. (Tatsuo Ishii) - + - + - Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + Pgpool-II doesn't support GSSAPI. + Allow Pgpool-II to deal with GSSAPI encrypted connection request from frontend instead of responding with an error. (Tatsuo Ishii) + + + Patch is created by me, reviewed and tested by Umar Hayat. - + + + - + + Bug fixes + + - Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + Fix query rewrite syntax error of "INSERT ... ON CONFLICT" in native replication mode. + (bug 654) (Bo Peng) - - - - - - Bug fixes - + - + - Fix writing transaction flag is accidentally set at commit or rollback. (Tatsuo Ishii) + Fix connection counter was not counted down when query is canceled. + (bug 656) (Tatsuo Ishii) - + - + - Doc: Fix document typos. (Bo Peng) + Doc: fix usable versions of PostgreSQL to be 7.4 or later. (Tatsuo Ishii) - + + + + - - + + Release 3.6.23 + + Release Date + 2020-09-17 + - + + Changes + + - Fix bug with socket writing. (Tatsuo Ishii) + Follow the guide line of PostgreSQL 12.4 regarding extensions. (Tatsuo Ishii) - pool_write_flush() is responsible for writing to sockets when pgpool's - write buffer is full (this function was introduced in 3.6.6 etc). When - network write buffer in kernel is full, it does retrying but it forgot - to update the internal buffer pointer. As a result, broken data is - written to the socket. This results in variety of problems including - too large message length. + CREATE OR REPLACE FUNCTION should be avoided. Use CREATE FUNCTION instead. - + - + - Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) + Replace "PGBIN" and "LPATH" in and using PostgreSQL's bin path and lib path. (Bo Peng) + + + - - - + + Bug fixes + + - Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + Doc: fix the incorrect description regarding the running modes of Pgpool-II in which online recovery is available. (Bo Peng) - - - - - - - - Release 3.6.8 - - - Release Date - 2018-01-09 - + - - Bug fixes - + + + + Remove unnecessary checks in some code path. (Tatsuo Ishii) + + + Patch contributed by Hou, Zhijie. + + - + - Doc: Fix document typo and mistakes. (Bo Peng) + Fix relcache query sometimes sent to other than primary. (Tatsuo Ishii) + In streaming replication mode, relcache queries are supposed to be + sent to the primary node. But actually they were not sent to the primary + node if primary node was not the master node. Typically this could + happen when the primary is not node 0. + + + + + + Fix not working when is enabled. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] - + - + - Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) + Display more informative error message in authentication process. (Tatsuo Ishii) - + - + - Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) + Fix segfault in pgpool child process in certain case. (Tatsuo Ishii) - Removeing "Type=forking" and add OPTS=" -n" to - run Pgpool-II with non-daemon mode, because we need to redirect logs. - Using "journalctl" command to see Pgpool-II systemd log. + This issue can be reproduced with the following steps: + + + + Shutdown all backends. + + + + + Connect to pgpool with invalid client. I have used pcp_attach_node with pgpool's port number, not pcp's. + + + - + + + + + + + Release 3.6.22 + + Release Date + 2020-08-20 + - + + Changes + + - Add documentation "Compiling and installing documents" for SGML document build. (Tatsuo Ishii) + Doc: mention that only affects to TLS 1.2 and lower. (Tatsuo Ishii) - + + + + + Doc: Improve the description of . (Bo Peng) + + + Patch is provided by Kenichiro Tanaka. - + - + - Fix timestamp data inconsistency by replication mode. (Bo Peng) + Add mention about hostssl/hostnossl to pool_hba.conf sample file. (Tatsuo Ishii) + + + + - From PostgreSQL10 the column - default value such as 'CURRENT_DATE' changes, - Pgpool-II didn't rewrite - timestamp by the added default values. This caused data inconsistency. + Doc: documentation improvements. (Tatsuo Ishii) - + + + - + + Bug fixes + + - Doc: Fix doc. (Tatsuo Ishii) + At pgpool startup, if pid file exists, truncate pid file to zero length before writing. (Bo Peng) - It lacked to mention that it supports logical replication mode. + Patch is created by maliangzhu. - + - + - Downgrade a log message to debug message. (Tatsuo Ishii) + Doc: fix error in parameter description. (Bo Peng) + + + + - That was mistaken left while last development cycle. + Fix does not work if primary node is not 0 in streaming replication mode. (Tatsuo Ishii) - + - + - Fix for re-sync logic in reading packet from backend. (Tatsuo Ishii) + Fix pgpool_setup problem with -r option and PostgreSQL 12. (Tatsuo Ishii) + + + + - read_kind_from_backend(), which reads message kind - from backend, re-syncs backend nodes when a ready for query message is - received. Unfortunately it forgot to call - pool_pending_message_pull_out() to delete sync - pending message. This leads to random stuck while reading packets - from backend. Fix this to call pool_pending_message_pull_out(). + Change PCP UNIX_DOMAIN_PATH of RPM package to /var/run/postgresql. (Bo Peng) - + - + - Fix Pgpool-II hangs. (bug 370) (Tatsuo Ishii) + Fix query cache bugs. (Tatsuo Ishii) + + + If query cache is enable, when a table is updated, Pgpool-II should delete all the caches related to the table. + However, EXPLAIN ANALYZE and CTE with data-modifying SQLs + were mistakenly treated as normal read only query so that the query caches were not deleted. - If an erroneous query is sent to primary and without a sync message - the next query that requires a catalog cache look up is send, - Pgpool-II hangs in do_query(). + Patch is created by Hou, Zhijie and modified by Tatsuo Ishii. - + - + - Add SL_MODE macro for upper compatibility with Pgpool-II 3.7 or later. (Tatsuo Ishii) + Fix Pgpool-II hang in a corner case. (Tatsuo Ishii) - + - + - Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + If there are parameters other than "user", "database" and "application_name", reading startup packet failed. (Tatsuo Ishii) + + + + - We return primary or master node state of ready for query message to - frontend. In most cases this is good. However if other than primary - node or master node returns an error state (this could happen if load - balance node is other than primary or master node and the query is an - errornous SELECT), this should be returned to frontend, because the - frontend already received an error. + Fix miscount of connections when pg_terminate_backend() is executed. (Takuma Hoshiai) - + - + - Fix pgpool start message printed multiple times. (Tatsuo Ishii) + Fix segmentation fault when application name is included in . (bug 615) (Tatsuo Ishii) - + - + - Add an execute permission bit to the start/stop script in . (Tatsuo Ishii) + Fix incorrectly performing failover when pg_terminate_backend() is executed in native replication mode. (Takuma Hoshiai) - - - + + + - - Release 3.6.7 + + Release 3.6.21 + + Release Date + 2020-05-21 + - - Release Date - 2017-11-01 - + + Bug fixes + + + + + Fix build error on some system (Fedora 32). (Tatsuo Ishii) + + - - Bug fixes - - + - Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) + Fix unnecessary checks. (Tatsuo Ishii) - In RHEL6, the "-n" option is needed to redirect log. + Patch contributed by sherlockcpp. Discussion: [pgpool-general: 7004] - + - + - Fixing an issue in the handling of pg_terminate_backend(). (Muhammad Usama) + Doc: Fix typo. (Tatsuo Ishii) - In some cases pg_terminate_backend() can cause failover even when - the call is properly issued through Pgpool-II. + Patch contributed by Umar Hayat. Discussion: [pgpool-hackers: 3587] - + - + - Fix for bug in watchdog where sometime failover is not reliably performed. (Muhammad Usama) + Fix for segmentation fault in PCP process. (bug 598) (Muhammad Usama) + + + + - Currently watchdog process only considers the node's watchdog state before - deciding if it can handle the failover and failover-locking requests. + Doc: Fix typo. (Tatsuo Ishii, Bo Peng) - But the problem with this technique is that, for the instance when the node has - announced itself as a master/coordinator of the cluster and is waiting for - the standby nodes to recognise it as a Master node. For that period of time - the watchdog state of the node is Master/coordinator, but it is yet not fully - capable of handling the failover and failover-locking requests. + Patch provided by sherlockcpp. + + + + - So sometimes this leads to a situation where a failover is not reliably - performed in case when the failover request arrives while watchdog cluster - is in the process of electing a leader. + Fix possible data inconsistency in native replication mode. (Tatsuo Ishii) - The fix for the above situation is to make sure that the node has fully acquired - the Master status before accepting the failover and failover-locking requests. + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] - + - + - Fix bug with handling of 'H' (flush) message in streaming replication mode. (bug 345) (Tatsuo Ishii) - - - If user expects to read response right after 'H', Pgpool-II hangs. The - cause was, when 'H' received, extended query mode was reset and - pending message was not used. + Fix watchdog ping probes fail with long hostnames due to small buffer. (bug 516) (Bo Peng) - + + + + + + + Release 3.6.20 + + Release Date + 2020-02-20 + - + + Changes + + - Doc: Fix pcp_node_info documents. (Tatsuo Ishii) + Check if socket file exists at startup and remove them if PID file doesn't exist to avoid bind() failure. (Bo Peng) - + + + - + + Bug fixes + + - Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) + Fix incorrect query rewriting in native replication mode. + (bug 551) (Bo Peng) + + + + - See [pgpool-general: 5728] for mor details. + Doc: Update documentation and fix documentation typos. (Takuma Hoshiai, Tatsuo Ishii, Bo Peng) - + - + - Fix exit signal handlers to not call ereport. (Tatsuo Ishii) + Fix to support PostgreSQL 12. (Tatsuo Ishii) + + + - See [pgpool-hackers: 2545] for more details. + Fix occasional regression test failure. (Tatsuo Ishii) - + - + - Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) + Fix replication delay worker segfault when application_name in primary_conninfo is an empty string. + (bug 565) (Tatsuo Ishii) - + - + - Doc: Fix table about replicate_select behavior (Yugo Nagata) + Fix the bug with ignored syslog setting. (Bo Peng) - - - + + + - - Release 3.6.6 - - - Release Date - 2017-09-05 - + + Release 3.6.19 + + Release Date + 2019-10-31 + - - Bug fixes - + + Bug fixes + + + + + Fix incorrect query rewrite in replication mode. (Bo Peng) + + - - - - Fix Pgpool-II hanging when error occurs in streaming replication mode and extended query. (Tatsuo Ishii) - - - If backend returns ERROR, Pgpool-II reads message from frontend until - a sync message is sent. Previous code assumed next message is sync. - However it is possible that more message coming before the sync - message, it's a low probability though. Fix it to continue reading - messages until the sync message is read. - - + + + + Doc: add description when all standby nodes are down. (Takuma Hoshiai) + + - - - - Fix wd_authkey bug in that a request to add new node to the clusetr is rejected by master. (Yugo Nagata) - - - This is a bug due to the implementation of 3.5.6 and 3.6.3. - - - This changed the definition of tv_sec that is used to check wd_authkey so - that this was affected by the clock of OS. So, if there is a lag between - two nodes' clocks, the wd_authkey check fails. - - + + + + Doc: add note not to assign PostgreSQL servers to . (Tatsuo Ishii) + + - - - - Test: Fix load balance test driver. (Tatsuo Ishii) - - - Some tests only for native replication mode was executed in streaming replication mode as well. - - - - - - - Fix not working slony mode in extended query. (Tatsuo Ishii) - - - When response returned from backend, in progress flag was not reset in slony mode, which cause waiting for next message from backend in vain. - - - - - - - Fix ancient bug of stream write modules. (Tatsuo Ishii) - - - Fix bug with pool_write_noerror() when requested length exceeds remaining write buffer size. This could lead to a buffer overrun problem. - - - When write buffer is full, pool_flush_it() is called, which could write data to socket in the middle of message. To fix the problem directly write requested data if the write buffer is going to be full. - - - Enhance performance of pool_unread(). - - - - - - - Test: Some miscellanies small fixes in regression test scripts. (Muhammad Usama) - - - - - - - - - - Doc: Fix documentation about load-balancing. (Yugo Nagata) - - - - - - - - - - Fix core dump and mishandling of temp tables. (Tatsuo Ishii) - - - - - - - Fix ancient bug of pool_unread(). (Tatsuo Ishii) - - - When realloc() is called in pool_unread(), it did not update the - buffer size. This could cause variety of memory corruption and - unexpected data reading from backend. The reason why we did not found - that is, probably recently Pgpool-II starts extensively to use - pool_unread(). - - - - - - - - Fix handling of empty queries. (bug 328) (Tatsuo Ishii) - - - When empty query (empty string or all comment query) is sent, command - complete message was returned to frontend. This is not correct. An - empty query response should be returned to frontend. - - - - - - - Fix query cache bug with streaming replication mode and extended query case. (Tatsuo Ishii) - - - - - - - Fix memory leak with streaming replication mode/extended query case. (bug 324) (Tatsuo Ishii) - - - - - - - Test: Fix Java program in 005.regression test. (Tatsuo Ishii) - - - - - - - Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) - - - This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). - - - - - - - Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) - - - - - - - Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) - - - - - - - Fix Pgpool-II hung up bug or other errors in error case in extended query in replication mode. (Tatsuo Ishii) - - - And other fixes in this commit. - - - 1) Do not send intended error query to backend in streaming replication mode in ErrorResponse3(). - - - 2) Fix pool_virtual_master_db_node_id() to return the virtual_master_node_id only when query is in progress and query context exists. - - - - - - - Doc: Fix Pgpool-II document typo. (Bo Peng) - - - - - - - - - - Allow make dist to include pgpool.service. (Yugo Nagata) - - - - - - - - - Enhancements - - - - - Doc: Add new English and Japanese documents of Pgpoo-II + Watchdog Setup Example. (Bo Peng) - - - - - - - Test: Add more memory leak regression tests. (Tatsuo Ishii) - - - - - - - - - Release 3.6.5 - - - Release Date - 2017-07-11 - - - - Bug fixes - - - + - Fix for [pgpool-hackers: 2400] Garbage output (Muhammad Usama) - - - Mostly the log messages fixes and few code cleanups. + Fix assorted ancient v2 protocol bugs. (Tatsuo Ishii) - + - + - Importing the latest changes in the MemoryManager API from PostgreSQL code. (Muhammad Usama) + Fix problem that doesn't change by reload. + (bug 548) (Takuma Hoshiai) - + - + - Fixing 0000306: Pgpool steals back MASTER status. (bug 306) (Muhammad Usama) + Fix Pgpool-II shutdown failed in certain case. (Tatsuo Ishii) - + - + - Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) + Allow the lost standby node to rejoin the master watchdog node when it gets rediscovered by the lifecheck. + (bug 545) (Muhammad Usama) - + - + - Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) + Fix segfault when executing an erroneous query after DEALLOCATE a named statement. + (bug 546) (Tatsuo Ishii) - - pg_current_wal_location -> pg_current_wal_lsn - pg_last_wal_replay_location -> pg_last_wal_replay_lsn - - + - + - Fix a posible hang with streaming replication and extended protocol. (Yugo Nagata) + Doc: mention that VIP will not be brought up if quorum does not exist. (Tatsuo Ishii) - - This hang occured under a certain condition. The following is an example. + + - - - pgpool.conf is configured so that all read queries are sent to the standby. - - First, issue a writing query in a transaction block - - After commiting the transaction, issue a select query. - - When processing the query, send Describe (statement) message just after Parse. - - + + - Without using JDBC, we can reproduce the problem by pgproto with the followeing messages. + Add "-I" option to command default setting. (Bo Peng) + + + + - - 'Q' "DROP TABLE IF EXISTS test_tbl" - 'Y' - 'Q' "CREATE TABLE test_tbl(i int)" - 'Y' - 'Q' "INSERT INTO test_tbl VALUES(1)" - 'Y' - - 'P' "" "BEGIN" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "" "COMMIT" 0 - 'B' "" "" 0 0 0 - 'E' "" 0 - 'S' - 'Y' - - 'P' "S_1" "SELECT * FROM test_tbl" 0 - 'D' 'S' "S_1" - 'B' "C_1" "S_1" 0 0 0 - 'E' "C_1" 0 - 'S' - 'Y' - - 'X' - - - - To fix it, parse_before_bind() should be called only if we are in a transaction block so that we can send Bind and Execute to the right backend. - - + + Release 3.6.18 + + Release Date + 2019-08-15 + - + + Enhancements + + - Fix Pgpool-II hang when used by erlang applications. (Tatsuo Ishii) - - - Erlang client sends "Describe" message followed by "Flush". So the - backend returns "Row description." However Pgpool-II forgets to reset - the query in progress flag upon receiving "Row description" message, - then Pgpool-II keeps on waiting for response from backend. This is the - cause of erlang client hanging. + Import some of memory manager debug facilities from PostgreSQL. (Tatsuo Ishii) + + + - Fix is, just reset the query in progress flag upon receiving "Row - description" message. Same thing can be said to "no data" message. + Use pg_get_expr() instead of pg_attrdef.adsrc to support for PostgreSQL 12. (Bo Peng) + + + - See [pgpool-general: 5555] for more details. + Enhance shutdown script of . (Tatsuo Ishii) + + + + Make shutdownall to wait for completion of shutdown of Pgpool-II. + + + + + If environment variable CHECK_TIME_WAIT is set to true, use netstat command to confirm usage of the TCP/IP port while executing shutdown script. + + + - - - + + - Fix bug with sending bind message to wrong target node. (bug 314) (Tatsuo Ishii) + Doc: add description to man page how to show pool_passwd hashed string. (Tatsuo Ishii) - + - + - Fix query cache hang when used by node.js. (Tatsuo Ishii) + Doc: add general description about failover. (Tatsuo Ishii) + + + - See [pgpool-general: 5511] for more details. + Deal pgpool_adm extension with PostgreSQL 12. (Tatsuo Ishii) - + + + + + Bug fixes + - + - Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) + Fix "unable to bind. cannot get parse message" error. + (bug 531) (Tatsuo Ishii) - + - + - Fix query cache memory leak. (Tatsuo Ishii) + Fix online-recovery is blocked after a child process exits abnormally with replication mode and watchdog. + (bug 483) (Muhammad Usama) + + + + - Clearing cache buffers in case of no oid queries (like BEGIN, - CHECKPOINT, VACUUM, etc) should have been done, but it did not. + Fix command mode option to work correctly. (Takuma Hoshiai) - + - + - Fix extended query hang in certain case. (Tatsuo Ishii) + Fix to produce correct follow master command. (Tatsuo Ishii) + + + + - errlang PostgreSQL API produces Parse ('P'), Describe ('D'), - Flush ('H'), Bind ('B'), and Execute ('E'). Notice the 'H' message (this - does not happen in JDBC. I suspect that's the reason why this problem - is not popular before). After that, Pgpool-II dropped the extended - query mode, it failed to find which backend to read data. Thus Pgpool-II simply tries to read all of backend which causes hang - because it may have not send a message to some of backends. + Fix query cache module so that it checks oid array's bound. (Tatsuo Ishii) + + + + - Solution is, after receiving the flush message set doing extended query flag. + Fix off-by-one error in query cache module. (Tatsuo Ishii) - + - + - Fix for [pgpool-hackers: 2354] segfault with pg_md5. (Muhammad Usama) + Allow health check process to reload. (Tatsuo Ishii) - + - + - Fix descriptions of white/black_memcache_table_list. (Tatsuo Ishii) + Fix segfault when query cache is enabled. (bug 525) (Tatsuo Ishii) + + + + - They are far from actual implementations. + Down grade LOG "checking zapping sent message ..." to DEBUG5. (Tatsuo Ishii) - See [pgpool-general: 5479] for more details. + Discussion: [pgpool-general: 6620] - + - + - Fix corner case bug in Pgpool-II starting up. (Tatsuo Ishii) + Fix segfault when samenet is specified in pool_hba.conf. (Tatsuo Ishii) - It is possible that a failover request is accepted before primary node - is searched. This leads Pgpool-II to a strange state: there's no - primary node if the failed node was a primary node (even if new - primary node exists as a result of promotion of existing standby). + Discussion: [pgpool-general: 6601]. + + + - See [pgpool-hackers: 2321] for more details. + Doc: Fix document typos. (Bo Peng) - - - - - - - Release 3.6.4 + - - Release Date - 2017-05-11 - - - - Bug fixes - - - - - - - Fixing a few corner cases in the failover request handling of the watchdog. (Muhammad Usama) - - - - + - Tightening up the watchdog cluster membership criteria. (Muhammad Usama) + Fix to deal with backslashes according to the config of standard_conforming_strings in native replication mode. + (bug 467) (Bo Peng) - + - + - Enhance document for load balancing. (Tatsuo Ishii) + Fix compile error on FreeBSD. + (bug 512, + bug 519) (Bo Peng) - + - + - Add node 0 failover test. (Tatsuo Ishii) + Fix memory leaks. (Tatsuo Ishii) - + - + - Fix Pgpool-II child process segfault reported in [pgpool-hackers: 2312]. (Tatsuo Ishii) + Make failover in progress check more aggressively to avoid potential segfault. (Tatsuo Ishii) - - - + + + - - Release 3.6.3 - - - Release Date - 2017-04-28 - - - - Bug fixes + + Release 3.6.17 + + Release Date + 2019-05-16 + - - + + Enhancements + + - Fix "show pool_cache" segfault when memcached is used. - (Bug 301) (Tatsuo Ishii) + Doc: Improve document. (Tatsuo Ishii) - + - + - Fix for some more code warnings. (Muhammad Usama) + Speed up failover when all of backends are down. (Tatsuo Ishii) - - - - - Fixing some annoying compiler warnings. (Muhammad Usama) + If all of the backend are in down status, immediately give up finding + primary node regardless search_primary_node_timeout and promptly + finish the failover process. - - - - - Removing the function defined but not used warnings from pool_config_vatiable.c (Muhammad Usama) + Discussion: [pgpool-hackers: 3321] - + - + - Removing the references of obsolete debug_level configuration parameter. (Muhammad Usama) + pgpool-recovery extension and pgpool_setup is now ready for the next major release PostgreSQL 12. (Tatsuo Ishii) - - - + + - Fixing a mistake in the watchdog code. (Muhammad Usama) - - - commit also adds some debug messages in the watchdog code. + Doc: add entry. (Takuma Hoshiai) - + + + - + + Bug fixes + + - - Fix for 0000299: Errors on the reloading of configuration. - (Bug 299) (Muhammad Usama) + Fix the wrong error message "ERROR: connection cache is full", when all backend nodes are down. + (bug 487) (Bo Peng) - + + When all backend nodes are down, Pgpool-II throws an incorrect + error message "ERROR: connection cache is full". Change the error + message to "all backend nodes are down, pgpool requires at least one valid node". + + - + - Add pgpool_adm English and Japanese docs. (Tatsuo Ishii) + Remove unused .sgml file. (Takuma Hoshiai) - + - + - Fix document indentation. (Tatsuo Ishii) + Avoid exit/fork storm of pool_worker_child process. (Tatsuo Ishii) - + pool_worker_child issues query to get WAL position using do_query(), + which could throws FATAL error. In this case pool_worker_child process + exits and Pgpool-II parent immediately forks new process. This cycle + indefinitely repeats and gives high load to the system. + To avoid the exit/fork storm, sleep sr_check_period. - + - + - Fix for 0000289: Inconsistent backend state. - (Bug 289) (Muhammad Usama) + Fix 's broken default value. (Tatsuo Ishii) - + - + - Enhancing the handling of split-brain scenario by the watchdog. (Muhammad Usama) - - - Previously, the watchdog cluster was used to call for re-election of the - master/coordinator node whenever the split-brain situation was detected. And - consequently every node was required to rejoin the watchdog network, Which was - essentially similar to the re-booting of the whole watchdog cluster. - - - The candidate for the master/coordinator node is selected on the following criteria. - - - - 1-- When two watchdog nodes are claiming to be the cluster master, the master - node that has performed the escalation keeps the master status and the other - node is asked to step down. - - - - 2-- If the conflict could not be resolved by the escalation status of the nodes, - The node which holds the quorum remains the master/coordinator. - - - - 3-- If the quorum status of both contenders is also same. The node with higher - number of connected alive nodes get the preference. + Fix "not enough space in buffer" error. + (bug 499) (Tatsuo Ishii) - - 4-- Finally, if all above three yields no winner, the older master (The node - that has the coordinator status for longer duration) remains the master. + The error occurred while processing error message returned from + backend and the cause is that the query string in question is too + big. Problem is, the buffer is in fixed size (8192 bytes). + Eliminate the fixed size buffer and use palloced buffer + instead. This also saves some memory copy work. - + - + - Enhancing the watchdog internal command mechanism to handle multiple concurrent commands. (Muhammad Usama) + Fix DROP DATABASE failure. (Tatsuo Ishii) - + - + - Fix compiler warnings. (Tatsuo Ishii) + Fix wrong variable in read_status_file() function. + (bug 493) (Takuma Hoshiai) - + - + - Comment out unsupported Java method in new JDBC drivers to prevent regression failure. (Tatsuo Ishii) + Add missing test/watchdog_setup to EXTRA_DIST. (bug 470) (Bo Peng) - + - + - Downgrade parse before bind log message to debug1. (Tatsuo Ishii) + Doc: mention that multi-statement queries are sent to primary node only. (bug 492) (Tatsuo Ishii) - + - + - Fix coverity warnings. (Tatsuo Ishii, Muhammad Usama) + Abort session if failover/failback is ongoing to prevent potential segfault. + (bug 481, + bug 482) (Tatsuo Ishii) - + - + - Fix for [pgpool-general: 5396] pam ldap failure. (Muhammad Usama) + Fix compiler warnings. (Tatsuo Ishii) - + - + - Mention that SQL type commands cannot be used in extended query mode. (Tatsuo Ishii) + Fix memory leak in "batch" mode in extended query. + (bug 468) (Tatsuo Ishii) - + + + + + + + Release 3.6.16 + + Release Date + 2019-03-29 + - + + Enhancements + + - Consider SHOW command as kind of a read query. (Tatsuo Ishii) + Add new configuration option . (Muhammad Usama) - In streaming replication mode, if SHOW is issued then subsequent - SELECTs are sent to the primary node in an explicit transaction. This - is not a reasonable and unnecessary limitation. - - Also fix hang when parse command returns error. - + Add the new setting to let users configure if they + want client's or server's cipher order to take preference. + + + The default for this parameter is off, which prioritize the client's + cipher order as usual. However this is just for keeping backward + compatibility, and it is possible that a malicious client uses weak + ciphers. For this reason we recommend to set this parameter to on at + all times. - + - + - Fix memory leak problem caused by commit adcb636. (Tatsuo Ishii) + Allow to set a client cipher list. (Tatsuo Ishii, Yugo Nagata) - Commit adcb636 introduces "pending message queue". When a message - arrives, the info is added to the queue and a copy of object is - created at the same time, but forgot to free the object. Fix is, - creating a new function pool_pending_message_free_pending_message() - and call it after pool_pending_message_add(), - pool_pending_message_get() and pool_pending_message_pull_out(). - - Problem reported by Sergey Kim. - + For this purpose new parameter , which specifies the cipher + list to be accepted by Pgpool-II, is added. + This is already implemented in PostgreSQL and useful to enhance security when SSL is enabled. - + + + - + + Bug fixes + + - Mega patch to fix "kind mismatch" (or derived) errors in streaming replication mode. - (Bug 271) (Tatsuo Ishii) - - - The errors are caused by wrong prediction in which (or both) database - node will send response to Pgpool-II. Previous implementation using - "sync map" are weak and sometimes fail in the prediction. - - - - This patch introduces new implementation using "pending message - queue", which records all sent message to backends. The element of the - queue stores info regarding messages types - (parse/bind/execute/describe/close/sync), to which database node the - message was sent and so on. It's a simple FIFO queue. When a message - arrives from backend, by looking at the head of the "pending message - queue", it is possible to reliably predict what kind of message and - from which database node it will arrive. After receiving the message, - the element is removed from the queue. + Fix unnecessary fsync() to pgpool_status file. (Tatsuo Ishii) - - I would like to thank to Sergey Kim, who has been helping me in - testing series of patches. - - - - See Bug 271 - and discussion in pgpool-hackers mailing list - [pgpool-hackers: 2043] and - [pgpool-hackers: 2140] - for more details. - + Whenever new connections are created to PostgreSQL backend, fsync() + was issued to pgpool_status file, which could generate excessive I/O + in certain conditions. + So reduce the chance of issuing fsync() so that it is issued only when + backend status is changed. - - - - - Fix for 0000296: PGPool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. - (Bug 296) (Muhammad Usama) + Discussion: [pgpool-general: 6436] - - - - - - + + + - - Release 3.6.2 - - - Release Date - 2017-03-17 - - - - Bug fixes + + Release 3.6.15 + + Release Date + 2019-02-21 + - + + Bug fixes + - + - Add "Wants=network.target" to pgpool.service file. - (bug 294) (Bo Peng) + Test: Fix old JDBC functions and typos in regression test 068.memqcache_bug. (Takuma Hoshiai) - + - + - Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) - - - The master node could not be promoted by pcp_promote_node with - the following error; - - - - FATAL: invalid pgpool mode for process recovery request - DETAIL: specified node is already primary node, can't promote node id 0 - - - - In streaming replication mode, there is a case that Pgpool-II - regards the status of primary node as "standby" for some reasons, - for example, when pg_ctl promote is executed manually during - Pgpool-II is running, in which case, it seems to Pgpool-II - that the primary node doesn't exist. - - - - This status mismatch should be fixe by pcp_promote_node, but when the node - is the master node (the first alive node), it fails as mentioned above. - - - - The reason is as following. before changing the status, pcp_promote_node - checks if the specified node is already primary or not by comparing the - node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from - Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. - Hence, when the master node is specified to be promoted, pcp_promote_node - is confused that this node is already primary and doesn't have to be - promoted, and it exits with the error. - - - - To fix this, pcp_promote_node should check the node id by using - REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, - rather than PRIMARY_NODE_ID. - + Doc: Fix configuration change timing regarding . (Tatsuo Ishii) - + - + - Fix document error. (Tatsuo Ishii, Bo Peng) - - - + Fix online recovery failed due to in certain cases. + (bug 431) (Tatsuo Ishii) - + - + - Pgpool-IIshould not perform ping test after bringing down the VIP. (Muhammad Usama) - - - - This issue was reported by the reporter of - bug:[pgpool-II 0000249]: watchdog sometimes fails de-escalation + Fix corner case bug when strip_quote() handle a empty query string. (bug 458) (Tatsuo Ishii) - + - + - Fix to release shared memory segments when Pgpool-IIexits. (bug 272) (Tatsuo Ishii) + Doc: Mention that schema qualifications cannot be used in white/black_function_list. (Tatsuo Ishii) - + - + - Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) + Fix typo about wd_priority in watchdog_setup. (Takuma Hoshiai) - + - + - Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) + Fix Pgpool child segfault if failover occurs when trying to establish a connection. (Tatsuo Ishii) - + - + - Fix for 281: "segmentation fault" when execute pcp_attach_node. (bug 281) (Muhammad Usama) + Doc: fix typo in logdir description. (bug 453) (Tatsuo Ishii) - + - + - Fix load balancing bug in streaming replication mode. (Tatsuo Ishii) - - - In an explicit transaction, any SELECT will be load balanced until - write query is sent. After writing query is sent, any SELECT should be - sent to the primary node. However if a SELECT is sent before a sync - message is sent, this does not work since the treatment of writing - query is done after ready for query message arrives. - - - Solution is, the treatment for writing query is done in executing the writing query as well. + Fix Pgpool-II hang if a client sends a extended query message such as close after sync message but before next simple query. (Tatsuo Ishii) - - The bug has been there since V3.5. + Discussion: [pgpool-hackers: 3164] - + - + - Fix yet another kind mismatch error in streaming replication mode. (Tatsuo Ishii) + Fix Pgpool-II hang when idle_in_transaction_session_timeout = on. (bug 448) (Tatsuo Ishii) - - - + + - Fix do_query()hangs after close message. (Tatsuo Ishii) + Doc: Fix Japanese document typo in . (Bo Peng) - + + + + + + + Release 3.6.14 + + Release Date + 2018-11-22 + - + + Bug fixes + + + + - Fixing stack smashing detected. (bug 280) (Muhammad Usama) + Fix to sort startup packet's parameters sent by client. + (bug 444)(Takuma Hoshiai) - It was a buffer overflow in wd_get_cmd function - + If order of startup packet's parameters differ between cached connection + pools and connection request, didn't use connection pool ,and created new + connection pool. - - - + + + + - Fixing the issue with the watchdog process restart. (Muhammad Usama) + Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. + (bug 443)(Bo Peng) - When the watchdog process gets abnormally terminated because of some problem - (e.g. Segmentation fault) the new spawned watchdog process fails to start and - produces an error "bind on ... failed with reason: Address already in use". + If the number of parameter format codes is specified to one, but the number + of the original query's parameter is zero, bind_rewrite_timestamp() + will call memcpy with a negative value. + This causes segmentation fault. - Reason is the abnormally terminating watchdog process never gets the time to - clean-up the socket it uses for IPC and the new process gets an error because - the socket address is already occupied. + Patch is provided by Yugo Nagata. + + + + + + + Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + + + + + + Fix segfault in extended query + query cache case. (Tatsuo Ishii) + + + + + + + Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + + + + + + + + Release 3.6.13 + + + Release Date + 2018-10-31 + + + Changes + + + - Fix is, the Pgpool main process sets the flag in shared memory to mark the - watchdog process was abnormally terminated and at startup when the watchdog - process see that the flag is set, it performs the clean up of the socket file and - also performs the de-escalation (If the watchdog process was crashed when it - was master/coordinator node) if required before initializing itself. + Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) - + - + + + Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) + + + + + - Fix query cache bug reported in pgpool-general-jp:1441. (Tatsuo Ishii) + Doc: Add note to online recovery doc. (Tatsuo Ishii) - In streaming replication mode with query cache enabled, SELECT hangs - in the following scenario: + This warns that must be smaller than . + - - 1) a SELECT hits query cache and returns rows from the query cache. - 2) following SELECT needs to search meta data and it hangs. - + + + + Test: Add regression test for SSL connection. (Tatsuo Ishii) + + + + - In #1, while returning the cached result, it misses to call - pool_unset_pending_response(), which leave the pending_response flag - be set. In #2, do_query() checks the flag and tries to read pending - response from backend. Since there's no pending data in backend, it - hangs in reading data from backend. + Doc: Add notes regarding failover script. (Tatsuo Ishii) + + It's not recommended to access against Pgpool-II itself from failover/failback scripts. + + + + + + Doc: Improve docs and error message. (Bo Peng) + - Fix is, just call pool_unset_pending_response() in #1 to reset the - flag. + Patch provided by Jesper Pedersen and modified by me. + + + - Bug report and fix provided by Nobuyuki Nagai. + Test: Add definition of PGLIB in regress.sh. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + - New regression test item (068) added by me. + + + + + Bug fixes + + + + + Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) + + + Patch provided by Phil Ramirez. + - + + + + Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) + + + In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. + + - + - Remove elog/ereport calls from signal handlers. (Tatsuo Ishii) + Fix syntax error when queries including time functions and IN (SELECT ...) in + WHERE clause in native replication mode. + (bug 433) (Bo Peng) - See [pgpool-hackers: 1950] for details. + In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. + However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. - + - + - Fix bug failed to create INET domain socket in FreeBSD if listen_addresses = '*'. - (bug 202) (Bo Peng) + Fix occasional less data returned to frontend with extended protocol. (bug432) (Tatsuo Ishii) + + + The idea for fix is, use pending message data list. It records + messages from frontend, and it is expected that we will receive same + number of messages. + + + Initial patch is created by Yugo Nagata and fixed by Tatsuo Ishii. - + - + - Fix for 0000249: watchdog sometimes fails de-escalation. (bug 249) (Muhammad Usama) + Fix memory leak when query cache enabled in streaming replication mode + extended query case. (Tatsuo Ishii) + + + - The solution is to use the waitpid() system call without WNOHANG option. + Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) + + + + + + Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) + + + In a explicit transaction, the SELECT results are cached in temporary buffer. + If a write SQL is sent which modifies the table, the temporary buffer should be reset. - + - + - Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) + Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) - + - + - Fix authentication timeout that can occur right after client connecttions. (Yugo Nagata) + Test: Add EXECUTE/DEALLOCATE regression test. (Takuma Hoshiai) - + - + + + + Add missing pgpool_recovery--1.0--1.1.sql file to update + pgpool_recovery() function version to 1.1. (Bo Peng) + + - + + + + Fix kind mismatch error when DEALLOCATE statement is issued. (Bo Peng) + + + PREPARE should be add to pool_add_sent_message, + so that EXECUTE and DEALLOCATE + can be sent to the same node as PREPARE. + + + See [pgpool-general: 6226] for more details. + + - + + + + Do not update if the password length is incorrect. + (bug 419) (Takuma Hoshiai, Tatsuo Ishii) + + + For Pgpool-II 3.7 or before, the password stored in + is MD5 password only. + So check the correctness of by scanning entire file. + + - - Release 3.6.1 + + + + Doc: Change description "new master" to "new primary". (Bo Peng) + + - - Release Date - 2016-12-26 - + + + + Fix newer version of gcc warnings. (Tatsuo Ishii) + + - - Bug fixes + + + + Test: Update clean.sh which clean up regression test results. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + - + + + + Add .gitignore files. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + - - - - Tightening up the watchdog security. (Muhammad Usama) + + + + Fix segfault when node 0 is in down status in case of both health check + and are disabled. (Tatsuo Ishii) + + + - Now wd_authkey uses the HMAC SHA-256 hashing. - - + Doc: Fix typos in documents and scripts. (Tatsuo Ishii) + + + Patch contributed by Jesper Pedersen. + + - - - - Add pgpool_adm extension in Pgpool-II RPM. (Bo Peng) - - + + + + Doc: Fix document mistakes of and . (Bo Peng) + + + + + - - - - Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) - - + + Release 3.6.12 - - - - Fix packet kind does not match error in extended protocol. (bug 231) (Tatsuo Ishii) - - - According to the bug231, the bug seem to bite you if all of - following conditions are met: - - - - - Streaming replication mode - - - - - Load balance node is not node 0 - - - - - Extended protocol is used - - - - - SELECT is executed, the statement is closed, then a - transaction command is executed - - - - - The sequence of how the problem bites is: - - - - SELECT executes on statement S1 on the load balance node 1 - - - - - Frontend send Close statement - - - - - Pgool-II forward it to backend 1 - - - - - Frontend sends Parse, Bind, Execute of COMMIT - - - - - Pgool-II forward it to backend 0 & 1 - - - - - Frontend sends sync message - - - - - Pgool-II forward it to backend 0 & 1 - - - - - Backend 0 replies back Parse complete ("1"), while - backend 1 replies back close complete ("3") because of - #3. - - - - - Kind mismatch occurs - - - - - - - The solution is, in #3, let Pgpool-II wait for response from backend - 1, but do not read the response message. Later on Pgpool-II's state - machine will read the response from it before the sync message is sent - in #6. With this, backend 1 will reply back "1" in #8, and the kind - mismatch error does not occur. - - - Also, fix not calling pool_set_doing_extended_query_message() when - receives Close message. (I don't know why it was missed). - - - New regression test "067.bug231" was added. - - + + Release Date + 2018-07-31 + - - - - Fix a race condition in a signal handler. (bug 265) (Tatsuo Ishii) - - - In child.c there's signal handler which calls elog. Since the signal - handler is not blocked against other signals while processing, deadlock - could occur in the system calls in the pgpool shutdown sequence. To - fix the problem, now the signal handler is blocked by using - POOL_SETMASK. - - - Ideally we should avoid calling elog in signal handlers though. - - + + Bug fixes + + + + + Fix "write on backend 0 failed with error :"Success"" error. + (bug 403) (Tatsuo Ishii) + + + Don't treated it as an error if write() returns 0. + + - - - - Fix wrong minimum configuration value for client_idle_limit_in_recovery. (bug 264) (Tatsuo Ishii) - - + + + + Fix for 0000409: worker process is not restarted after failover on standby. + (bug 409) (Muhammad Usama) + + + Patch contributed by Yugo Nagata. + + - - - - Allow to execute "make xslthtml" under doc.ja. (Tatsuo Ishii) - - + + + + Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) + + - - + + + + Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) + + + This led to a segfault issue mentioned on certain platform. + + - + + + + Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) + + + Patch provided by Christian Ehrhardt. + + - + + + + Doc: Improve documents of "MD5 Password Authentication", "Installing Pgpool-II" and "pg_md5".(Bo Peng) + + + Patch provided by Takuma Hoshiai. + + + + + + Test: Fix 006.memqcache test failure. (Tatsuo Ishii) + + + + + + Release 3.6.11 - - Release 3.6 - - - Release Date - 2016-11-21 - - - - Overview + + Release Date + 2018-06-12 + + + Bug fixes + + + + + Fix Pgpool-II hung if replication delay is too much, when query cache enabled in extended query mode. (Tatsuo Ishii) + - Major enhancements in Pgpool-II 3.6 include: + See [pgpool-general-jp: 1534] + for more details. + - + + + + Doc: Fix document typo of PCP commands option "-U". (Bo Peng) + + - + + + + Delete some debug code. (Bo Peng) + + - - - Improve the behavior of failover. In the steaming - replication mode, client sessions will not be disconnected - when a failover occurs any more if the session does not use - the failed standby server. If the primary server goes down, - still all sessions will be disconnected. Also it is possible - to connect to Pgpool-II even if - it is doing health checking retries. Before all attempt of - connecting to Pgpool-II failed - while doing health checking retries. - - + + + + In extended query mode, do not set writing tx flag with SET TRANSACTION READ ONLY. (Tatsuo Ishii) + + - - - New PGPOOL SET command has been introduced. Certain - configuration parameters now can be changed on the fly in a - session. - - + + + + Doc: Update outdated manual. (Tatsuo Ishii) + + - - - Watchdog is significantly enhanced. It becomes more reliable - than previous releases. - - + + + + Doc: Enhance online recovery document to Clarify + that is only required in native replication mode. (Tatsuo Ishii) + + - - - Handling of extended query protocol (e.g. used by Java - applications) in streaming replication mode speeds up if - many rows are returned in a result set. - - + + + + Prevent from recovering "unused" status node. (Tatsuo Ishii) + + + This allowed to try to recovery a node without configuration data, + which leads to variety of problems. + + + See [pgpool-general: 5963] + for more details. + + + Also I fixed pgpool_recovery function so that it quotes an + empty string argument with double quotes. + + + + + - - - Import parser of PostgreSQL 9.6. - - + + Release 3.6.10 - - - In some cases pg_terminate_backend() now does not trigger a - failover. - - + + Release Date + 2018-04-17 + - - - Change documentation format from raw HTML to SGML. - - + + Bug fixes + - + + + + Test: Add new regression test for node 0 is down. (Tatsuo Ishii) + + + + - The above items are explained in more detail in the sections below. + Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + - + + + + Doc: Improve watchdog documents. (Tatsuo Ishii) + + - - Major Enhancements + + - + + + + Test: Improve test script 003.failover. (Bo Peng) + + - - - - Improve the behavior of failover. (Tatsuo Ishii) - - - In the steaming replication mode, client sessions will not - be disconnected when a failover occurs any more if the - session does not use the failed standby server. If the - primary server goes down, still all sessions will be - disconnected. Health check timeout case will also cause the - full session disconnection. Other health check error, - including retry over case does not trigger full session - disconnection. - + + + + Deal with "unable to bind D cannot get parse message "S1" error. (Tatsuo Ishii) + + - - For user's convenience, "show pool_nodes" command shows the - session local load balance node info since this is important - for users in case of failover. If the load balance node is - not the failed node, the session will not be affected by - failover. - + + + + Doc: Mention that users can avoid failover using backend_flag even PostgreSQL admin shutdown. (Tatsuo Ishii) + + - - Also now it is possible to connect - to Pgpool-II even if it is doing - health checking retries. Before all attempt of connecting - to Pgpool-II failed while doing - health checking retries. Before any attempt to connect to - Pgpool-II fails if it is doing a - health check against failed node even if - is off - because Pgpool-II child first - tries to connect to all backend including the failed one and - exits if it fails to connect to a backend (of course it - fails). This is a temporary situation and will be resolved - once pgpool executes failover. However if the health check - is retrying, the temporary situation keeps longer depending - on the setting - of and - . This is not - good. Attached patch tries to mitigate the problem: - - - When an attempt to connect to backend fails, give up - connecting to the failed node and skip to other node, rather - than exiting the process if operating in streaming - replication mode and the node is not primary node. - - - Mark the local status of the failed node to "down". This - will let the primary node be selected as a load balance node - and every queries will be sent to the primary node. If - there's other healthy standby nodes, one of them will be - chosen as the load balance node. - - - After the session is over, the child process will suicide to - not retain the local status. - - + + + + Doc: Fix document typos. (Bo Peng) + + - - - - Add PGPOOL - SHOW, PGPOOL - SET and - PGPOOL RESET - commands. (Muhammad Usama) - - - These are similar to the PostgreSQL's SET and SHOW commands - for GUC variables, adding the functionality - in Pgpool-II to set and reset the - value of config parameters for the current session, and for - that it adds a new syntax - in Pgpool-II which is similar to - PostgreSQL's SET and RESET variable syntax with an addition - of PGPOOL keyword at the start. - - - Currently supported configuration parameters by PGPOOL - SHOW/SET/RESET are: , - , , - , , - , , - , , - . - - + + + + Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) + + - - - - Sync inconsitent status - of PostgreSQL nodes - in Pgpool-II instances after - restart. (bug 218) (Muhammad Usama) - - - Watchdog does not synchronize status. - - + + + + Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) + + - - - - Enhance performance of SELECT when lots of rows involved. - (Tatsuo Ishii) - - - Pgpool-II flushes data to network - (calling write(2)) every time it sends a row data ("Data - Row" message) to frontend. For example, if 10,000 rows - needed to be transfer, 10,000 times write()s are - issued. This is pretty expensive. Since after repeating to - send row data, "Command Complete" message is sent, it's - enough to issue a write() with the command complete - message. Also there are unnecessary flushing are in handling - the command complete message. - - - Quick - testing showed that from 47% to 62% performance - enhancements were achieved in some cases. - - - Unfortunately, performance in workloads where transferring - few rows, will not be enhanced since such rows are needed to - flush to network anyway. - - + + + + Doc: Fix pgpool_adm family functions examples. (Tatsuo Ishii) + + - - - - Import PostgreSQL 9.6's SQL - parser. (Bo Peng) - - - This allows Pgpool-II to fully - understand the newly added SQL syntax such as COPY - INSERT RETURNING. - - + + + - - - - In some cases pg_terminate_backend() now does not trigger a failover. (Muhammad Usama) - - - Because PostgreSQL returns exactly the same error code as postmaster - down case and pg_terminate_backend() case, using - pg_terminate_backend() raises a failover which user might not want. To - fix this, now Pgpool-II finds a pid of backend which is the target of - pg_terminate_backend() and does not trigger failover if so. + + Release 3.6.9 + + + Release Date + 2018-02-13 + + + + This release fixed the bug with socket writing added in Pgpool-II 3.7.0, 3.6.6 and 3.5.10. Due to this bug, when the network load is high, an illegal message may be sent to the frontend or backend. All users using 3.7.x, 3.6.6 or later, 3.5.10 or later versions of Pgpool-II should update as soon as possible. + + + + + Changes + + + + + Allow to build with libressl. (Tatsuo Ishii) - This functions is limited to the case of simple protocol and the pid - is given to pg_terminate_backend() as a constant. So if you call - pg_terminate_backend() via extended protocol (e.g. Java) still - pg_terminate_backend() triggers a failover. + See [pgpool-hackers: 2714] for more details. Patch by Sandino Araico Sanchez. - - - - - - HTML documents are now generated from SGML documents. - (Muhammad Usama, Tatsuo Ishii, Bo Peng) - - - It is intended to have better construction, contents and - maintainability. Also man pages are now generated from SGML. - However, still there's tremendous room to - enhance the SGML documents. Please help us! - - + - - + + + + Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) + + + TCP_NODELAY is employed by PostgreSQL, so do we it. + + - - Other Enhancements + + + + Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + + - + + + + Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + + + + - - + + Bug fixes + - - Make authentication error message more user friendly. (Tatsuo Ishii) - - - When attempt to connect to backend (including health - checking), emit error messages from backend something like - "sorry, too many clients already" instead of "invalid - authentication message response type, Expecting 'R' and - received '%c'" - - + + + + Fix writing transaction flag is accidentally set at commit or rollback. (Tatsuo Ishii) + + - - - - Tighten up health check timer expired condition in pool_check_fd(). (Muhammad Usama) - - + + + + Doc: Fix document typos. (Bo Peng) + + - - - - Add new script called "watchdog_setup". (Tatstuo Ishii) - - - is a command to create a - temporary installation - of Pgpool-II clusters with - watchdog for mainly testings. - - + + - - - - Add "-pg" option to pgpool_setup. (Tatsuo Ishii) - - - This is useful when you want to assign specific port numbers to - PostgreSQL while - using . Also - now pgpool_setup is installed in the - standard bin directory which is same - as pgpool. - - + + + + Fix bug with socket writing. (Tatsuo Ishii) + + + pool_write_flush() is responsible for writing to sockets when pgpool's + write buffer is full (this function was introduced in 3.6.6 etc). When + network write buffer in kernel is full, it does retrying but it forgot + to update the internal buffer pointer. As a result, broken data is + written to the socket. This results in variety of problems including + too large message length. + + - - - - Add "replication delay" column to "show pool_nodes". (Tatsuo Ishii) - - - This column - shows the - replication delay value in bytes if operated in - streaming replication mode. - - + + + + Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) + - - - - Do not update status file if all backend nodes are in down status. (Chris Pacejo, Tatsuo Ishii) - - - This commit tries to remove the data inconsitency in - replication mode found - in [pgpool-general: - 3918] by not recording the status file when all - backend nodes are in down status. This surprisingly simple - but smart solution was provided by Chris Pacejo. - - + - - - - Allow to use multiple SSL cipher protocols. (Muhammad Usama) - - - By replacing TLSv1_method() with SSLv23_method() while - initializing the SSL session, we can use more protocols than - TLSv1 protocol. - - + + + + Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + + - - - - Allow to use arbitrary number of items in the - black_function_list/white_function_list. (Muhammad Usama) - - - Previously there were fixed limits for those. - - + + + - - - - Properly process empty queries (all comments). (Tatsuo Ishii) - - - Pgpool-II now recognizes an empty - query consisted of all comments (for example "/* DBD::Pg - ping test v3.5.3 */") (note that no ';') as an empty query. - - - Before such that query was recognized an error. - - + + Release 3.6.8 - - - - Add some warning messages for wd_authkey hash calculation failure. (Yugo Nagata) - - - Sometimes wd_authkey calculation fails for some reason other - than authkey mismatch. The additional messages make these - distinguishable for each other. - - + + Release Date + 2018-01-09 + - + + Bug fixes + - + + + + Doc: Fix document typo and mistakes. (Bo Peng) + + - - Changes + + - - - - - Fix the broken log_destination = syslog functionality. (Muhammad Usama) - - - Fixing the logging to the syslog destination, which got broken by the - PGPOOL SET/SHOW command commit, and also enhancing the log_destination - configuration parameter to be assigned with the comma separated list of multiple - destinations for the Pgpool-II log. Now, after this commit log_destination can - be set to any combination of 'syslog' and 'stderr' log destinations. - - - - - - Change the default value of - from 10 to 300. (Tatstuo Ishii) - - - Prior default value 10 seconds is sometimes too short for a standby to - be promoted. - - + + + + Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) + + - - - - Change the Makefile under directory - src/sql/, that is proposed by - - [pgpool-hackers: 1611]. (Bo Peng) - + + + + Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) + + + Removing "Type=forking" and add OPTS=" -n" to + run Pgpool-II with non-daemon mode, because we need to redirect logs. + Using "journalctl" command to see Pgpool-II systemd log. + + - - - - - Change the PID length of pcp_proc_count command output to 6 characters long. (Bo Peng) - - - If the Pgpool-II process ID are over 5 characters, the 6th character of each process ID - will be removed. This commit changes the process ID length of pcp_proc_count command - output to 6 characters long. - - - - - - Redirect all user queries to primary server. (Tatsuo Ishii) - - - Up to now some user queries are sent to other than the primary server - even if = off. This commit changes the behavior: if - load_balance_mode = off in streaming replication mode, now all the - user queries are sent to the primary server only. - - - - + + + + Add documentation "Compiling and installing documents" for SGML document build. (Tatsuo Ishii) + + - - Bug fixes + + - - - - - Fixing a potential crash in pool_stream functions. (Muhammad Usama) - - - POOL_CONNECTION->con_info should be checked for null value before de-referencing - when read or write fails on backend socket. - - - - + + + + Fix timestamp data inconsistency by replication mode. (Bo Peng) + + + From PostgreSQL10 the column + default value such as 'CURRENT_DATE' changes, + Pgpool-II didn't rewrite + timestamp by the added default values. This caused data inconsistency. + + + + + + + Doc: Fix doc. (Tatsuo Ishii) + + + It lacked to mention that it supports logical replication mode. + + + + + + + Downgrade a log message to debug message. (Tatsuo Ishii) + + + That was mistaken left while last development cycle. + + + + + + + Fix for re-sync logic in reading packet from backend. (Tatsuo Ishii) + + + read_kind_from_backend(), which reads message kind + from backend, re-syncs backend nodes when a ready for query message is + received. Unfortunately it forgot to call + pool_pending_message_pull_out() to delete sync + pending message. This leads to random stuck while reading packets + from backend. Fix this to call pool_pending_message_pull_out(). + + + + + + + Fix Pgpool-II hangs. (bug 370) (Tatsuo Ishii) + + + If an erroneous query is sent to primary and without a sync message + the next query that requires a catalog cache look up is send, + Pgpool-II hangs in do_query(). + + + + + + + Add SL_MODE macro for upper compatibility with Pgpool-II 3.7 or later. (Tatsuo Ishii) + + + + + + + Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + + + We return primary or master node state of ready for query message to + frontend. In most cases this is good. However if other than primary + node or master node returns an error state (this could happen if load + balance node is other than primary or master node and the query is an + erroneous SELECT), this should be returned to frontend, because the + frontend already received an error. + + + + + + + Fix pgpool start message printed multiple times. (Tatsuo Ishii) + + + + + + + Add an execute permission bit to the start/stop script in . (Tatsuo Ishii) + + + + + + + + Release 3.6.7 + + + Release Date + 2017-11-01 + + + + Bug fixes + + + + + Add different pgpool.sysconfig file for RHEL6 and RHEL7. (bug 343) (Bo Peng) + + + In RHEL6, the "-n" option is needed to redirect log. + + + + + + + Fixing an issue in the handling of pg_terminate_backend(). (Muhammad Usama) + + + In some cases pg_terminate_backend() can cause failover even when + the call is properly issued through Pgpool-II. + + + + + + + Fix for bug in watchdog where sometime failover is not reliably performed. (Muhammad Usama) + + + Currently watchdog process only considers the node's watchdog state before + deciding if it can handle the failover and failover-locking requests. + + + But the problem with this technique is that, for the instance when the node has + announced itself as a master/coordinator of the cluster and is waiting for + the standby nodes to recognise it as a Master node. For that period of time + the watchdog state of the node is Master/coordinator, but it is yet not fully + capable of handling the failover and failover-locking requests. + + + So sometimes this leads to a situation where a failover is not reliably + performed in case when the failover request arrives while watchdog cluster + is in the process of electing a leader. + + + The fix for the above situation is to make sure that the node has fully acquired + the Master status before accepting the failover and failover-locking requests. + + + + + + + Fix bug with handling of 'H' (flush) message in streaming replication mode. (bug 345) (Tatsuo Ishii) + + + If user expects to read response right after 'H', Pgpool-II hangs. The + cause was, when 'H' received, extended query mode was reset and + pending message was not used. + + + + + + + Doc: Fix pcp_node_info documents. (Tatsuo Ishii) + + + + + + + Fix bug mistakenly overriding global backend status right after failover. (Tatsuo Ishii) + + + See [pgpool-general: 5728] for more details. + + + + + + + Fix exit signal handlers to not call ereport. (Tatsuo Ishii) + + + See [pgpool-hackers: 2545] for more details. + + + + + + + Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) + + + + + + + Doc: Fix table about replicate_select behavior (Yugo Nagata) + + + + + + + + Release 3.6.6 + + + Release Date + 2017-09-05 + + + + Bug fixes + + + + + + Fix Pgpool-II hanging when error occurs in streaming replication mode and extended query. (Tatsuo Ishii) + + + If backend returns ERROR, Pgpool-II reads message from frontend until + a sync message is sent. Previous code assumed next message is sync. + However it is possible that more message coming before the sync + message, it's a low probability though. Fix it to continue reading + messages until the sync message is read. + + + + + + + Fix wd_authkey bug in that a request to add new node to the cluster is rejected by master. (Yugo Nagata) + + + This is a bug due to the implementation of 3.5.6 and 3.6.3. + + + This changed the definition of tv_sec that is used to check wd_authkey so + that this was affected by the clock of OS. So, if there is a lag between + two nodes' clocks, the wd_authkey check fails. + + + + + + + Test: Fix load balance test driver. (Tatsuo Ishii) + + + Some tests only for native replication mode was executed in streaming replication mode as well. + + + + + + + Fix not working slony mode in extended query. (Tatsuo Ishii) + + + When response returned from backend, in progress flag was not reset in slony mode, which cause waiting for next message from backend in vain. + + + + + + + Fix ancient bug of stream write modules. (Tatsuo Ishii) + + + Fix bug with pool_write_noerror() when requested length exceeds remaining write buffer size. This could lead to a buffer overrun problem. + + + When write buffer is full, pool_flush_it() is called, which could write data to socket in the middle of message. To fix the problem directly write requested data if the write buffer is going to be full. + + + Enhance performance of pool_unread(). + + + + + + + Test: Some miscellanies small fixes in regression test scripts. (Muhammad Usama) + + + + + + + + + + Doc: Fix documentation about load-balancing. (Yugo Nagata) + + + + + + + + + + Fix core dump and mishandling of temp tables. (Tatsuo Ishii) + + + + + + + Fix ancient bug of pool_unread(). (Tatsuo Ishii) + + + When realloc() is called in pool_unread(), it did not update the + buffer size. This could cause variety of memory corruption and + unexpected data reading from backend. The reason why we did not found + that is, probably recently Pgpool-II starts extensively to use + pool_unread(). + + + + + + + + Fix handling of empty queries. (bug 328) (Tatsuo Ishii) + + + When empty query (empty string or all comment query) is sent, command + complete message was returned to frontend. This is not correct. An + empty query response should be returned to frontend. + + + + + + + Fix query cache bug with streaming replication mode and extended query case. (Tatsuo Ishii) + + + + + + + Fix memory leak with streaming replication mode/extended query case. (bug 324) (Tatsuo Ishii) + + + + + + + Test: Fix Java program in 005.regression test. (Tatsuo Ishii) + + + + + + + Fix for when failover is triggered by worker process, it is possible that wrong DB node could failover. (bug 303) (Tatsuo Ishii) + + + This is due to the db_node_id member in the POLL_CONNECTION structure is not initialized in the process (in child process the member is properly initialized). To solve the problem, add new function pool_set_db_node_id() to set the structure member variable and call it inside make_persistent_db_connection(). + + + + + + + Fix starting unnecessary transaction when SET command is issued. (Tatsuo Ishii) + + + + + + + Fix for [pgpool-general: 5621] Failover() function should be executed with health check alarm disabled. (Muhammad Usama) + + + + + + + Fix Pgpool-II hung up bug or other errors in error case in extended query in replication mode. (Tatsuo Ishii) + + + And other fixes in this commit. + + + 1) Do not send intended error query to backend in streaming replication mode in ErrorResponse3(). + + + 2) Fix pool_virtual_master_db_node_id() to return the virtual_master_node_id only when query is in progress and query context exists. + + + + + + + Doc: Fix Pgpool-II document typo. (Bo Peng) + + + + + + + + + + Allow make dist to include pgpool.service. (Yugo Nagata) + + + + + + + + + Enhancements + + + + + Doc: Add new English and Japanese documents of Pgpool-II + Watchdog Setup Example. (Bo Peng) + + + + + + + Test: Add more memory leak regression tests. (Tatsuo Ishii) + + + + + + + + + Release 3.6.5 + + + Release Date + 2017-07-11 + + + + Bug fixes + + + + + + Fix for [pgpool-hackers: 2400] Garbage output (Muhammad Usama) + + + Mostly the log messages fixes and few code cleanups. + + + + + + + Importing the latest changes in the MemoryManager API from PostgreSQL code. (Muhammad Usama) + + + + + + + Fixing 0000306: Pgpool steals back MASTER status. (bug 306) (Muhammad Usama) + + + + + + + Fixing [pgpool-hackers: 2390]Problems with the relative paths in daemon mode (Muhammad Usama) + + + + + + + Adjust function name change in PostgreSQL 10 dev head. (Tatsuo Ishii) + + + pg_current_wal_location -> pg_current_wal_lsn + pg_last_wal_replay_location -> pg_last_wal_replay_lsn + + + + + + + Fix a possible hang with streaming replication and extended protocol. (Yugo Nagata) + + + + This hang occurred under a certain condition. The following is an example. + + + + - pgpool.conf is configured so that all read queries are sent to the standby. + - First, issue a writing query in a transaction block + - After committing the transaction, issue a select query. + - When processing the query, send Describe (statement) message just after Parse. + + + + Without using JDBC, we can reproduce the problem by pgproto with the following messages. + + + + 'Q' "DROP TABLE IF EXISTS test_tbl" + 'Y' + 'Q' "CREATE TABLE test_tbl(i int)" + 'Y' + 'Q' "INSERT INTO test_tbl VALUES(1)" + 'Y' + + 'P' "" "BEGIN" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "INSERT INTO test_tbl VALUES(1)" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "" "COMMIT" 0 + 'B' "" "" 0 0 0 + 'E' "" 0 + 'S' + 'Y' + + 'P' "S_1" "SELECT * FROM test_tbl" 0 + 'D' 'S' "S_1" + 'B' "C_1" "S_1" 0 0 0 + 'E' "C_1" 0 + 'S' + 'Y' + + 'X' + + + + To fix it, parse_before_bind() should be called only if we are in a transaction block so that we can send Bind and Execute to the right backend. + + + + + + + Fix Pgpool-II hang when used by erlang applications. (Tatsuo Ishii) + + + Erlang client sends "Describe" message followed by "Flush". So the + backend returns "Row description." However Pgpool-II forgets to reset + the query in progress flag upon receiving "Row description" message, + then Pgpool-II keeps on waiting for response from backend. This is the + cause of erlang client hanging. + + + Fix is, just reset the query in progress flag upon receiving "Row + description" message. Same thing can be said to "no data" message. + + + See [pgpool-general: 5555] for more details. + + + + + + + Fix bug with sending bind message to wrong target node. (bug 314) (Tatsuo Ishii) + + + + + + + Fix query cache hang when used by node.js. (Tatsuo Ishii) + + + See [pgpool-general: 5511] for more details. + + + + + + + Deal with PostgreSQL 10 in streaming replication delay checking. (Tatsuo Ishii) + + + + + + + Fix query cache memory leak. (Tatsuo Ishii) + + + Clearing cache buffers in case of no oid queries (like BEGIN, + CHECKPOINT, VACUUM, etc) should have been done, but it did not. + + + + + + + Fix extended query hang in certain case. (Tatsuo Ishii) + + + errlang PostgreSQL API produces Parse ('P'), Describe ('D'), + Flush ('H'), Bind ('B'), and Execute ('E'). Notice the 'H' message (this + does not happen in JDBC. I suspect that's the reason why this problem + is not popular before). After that, Pgpool-II dropped the extended + query mode, it failed to find which backend to read data. Thus Pgpool-II simply tries to read all of backend which causes hang + because it may have not send a message to some of backends. + + + Solution is, after receiving the flush message set doing extended query flag. + + + + + + + Fix for [pgpool-hackers: 2354] segfault with pg_md5. (Muhammad Usama) + + + + + + + Fix descriptions of white/black_memcache_table_list. (Tatsuo Ishii) + + + They are far from actual implementations. + + + See [pgpool-general: 5479] for more details. + + + + + + + Fix corner case bug in Pgpool-II starting up. (Tatsuo Ishii) + + + It is possible that a failover request is accepted before primary node + is searched. This leads Pgpool-II to a strange state: there's no + primary node if the failed node was a primary node (even if new + primary node exists as a result of promotion of existing standby). + + + + See [pgpool-hackers: 2321] for more details. + + + + + + + + Release 3.6.4 + + + Release Date + 2017-05-11 + + + + Bug fixes + + + + + + + Fixing a few corner cases in the failover request handling of the watchdog. (Muhammad Usama) + + + + + + + Tightening up the watchdog cluster membership criteria. (Muhammad Usama) + + + + + + + Enhance document for load balancing. (Tatsuo Ishii) + + + + + + + Add node 0 failover test. (Tatsuo Ishii) + + + + + + + Fix Pgpool-II child process segfault reported in [pgpool-hackers: 2312]. (Tatsuo Ishii) + + + + + + + + Release 3.6.3 + + + Release Date + 2017-04-28 + + + + Bug fixes + + + + + + Fix "show pool_cache" segfault when memcached is used. + (Bug 301) (Tatsuo Ishii) + + + + + + + Fix for some more code warnings. (Muhammad Usama) + + + + + + + Fixing some annoying compiler warnings. (Muhammad Usama) + + + + + + + Removing the function defined but not used warnings from pool_config_variable.c (Muhammad Usama) + + + + + + + Removing the references of obsolete debug_level configuration parameter. (Muhammad Usama) + + + + + + + Fixing a mistake in the watchdog code. (Muhammad Usama) + + + commit also adds some debug messages in the watchdog code. + + + + + + + + Fix for 0000299: Errors on the reloading of configuration. + (Bug 299) (Muhammad Usama) + + + + + + + Add pgpool_adm English and Japanese docs. (Tatsuo Ishii) + + + + + + + Fix document indentation. (Tatsuo Ishii) + + + + + + + + + + Fix for 0000289: Inconsistent backend state. + (Bug 289) (Muhammad Usama) + + + + + + + Enhancing the handling of split-brain scenario by the watchdog. (Muhammad Usama) + + + Previously, the watchdog cluster was used to call for re-election of the + master/coordinator node whenever the split-brain situation was detected. And + consequently every node was required to rejoin the watchdog network, Which was + essentially similar to the re-booting of the whole watchdog cluster. + + + The candidate for the master/coordinator node is selected on the following criteria. + + + + 1-- When two watchdog nodes are claiming to be the cluster master, the master + node that has performed the escalation keeps the master status and the other + node is asked to step down. + + + + 2-- If the conflict could not be resolved by the escalation status of the nodes, + The node which holds the quorum remains the master/coordinator. + + + + 3-- If the quorum status of both contenders is also same. The node with higher + number of connected alive nodes get the preference. + + + + 4-- Finally, if all above three yields no winner, the older master (The node + that has the coordinator status for longer duration) remains the master. + + + + + + + Enhancing the watchdog internal command mechanism to handle multiple concurrent commands. (Muhammad Usama) + + + + + + + Fix compiler warnings. (Tatsuo Ishii) + + + + + + + Comment out unsupported Java method in new JDBC drivers to prevent regression failure. (Tatsuo Ishii) + + + + + + + Downgrade parse before bind log message to debug1. (Tatsuo Ishii) + + + + + + + Fix coverity warnings. (Tatsuo Ishii, Muhammad Usama) + + + + + + + Fix for [pgpool-general: 5396] pam ldap failure. (Muhammad Usama) + + + + + + + Mention that SQL type commands cannot be used in extended query mode. (Tatsuo Ishii) + + + + + + + Consider SHOW command as kind of a read query. (Tatsuo Ishii) + + + In streaming replication mode, if SHOW is issued then subsequent + SELECTs are sent to the primary node in an explicit transaction. This + is not a reasonable and unnecessary limitation. + + Also fix hang when parse command returns error. + + + + + + + + Fix memory leak problem caused by commit adcb636. (Tatsuo Ishii) + + + Commit adcb636 introduces "pending message queue". When a message + arrives, the info is added to the queue and a copy of object is + created at the same time, but forgot to free the object. Fix is, + creating a new function pool_pending_message_free_pending_message() + and call it after pool_pending_message_add(), + pool_pending_message_get() and pool_pending_message_pull_out(). + + Problem reported by Sergey Kim. + + + + + + + + Mega patch to fix "kind mismatch" (or derived) errors in streaming replication mode. + (Bug 271) (Tatsuo Ishii) + + + The errors are caused by wrong prediction in which (or both) database + node will send response to Pgpool-II. Previous implementation using + "sync map" are weak and sometimes fail in the prediction. + + + + This patch introduces new implementation using "pending message + queue", which records all sent message to backends. The element of the + queue stores info regarding messages types + (parse/bind/execute/describe/close/sync), to which database node the + message was sent and so on. It's a simple FIFO queue. When a message + arrives from backend, by looking at the head of the "pending message + queue", it is possible to reliably predict what kind of message and + from which database node it will arrive. After receiving the message, + the element is removed from the queue. + + + + I would like to thank to Sergey Kim, who has been helping me in + testing series of patches. + + + + See Bug 271 + and discussion in pgpool-hackers mailing list + [pgpool-hackers: 2043] and + [pgpool-hackers: 2140] + for more details. + + + + + + + + Fix for 0000296: Pgpool v3.6.2 terminated by systemd because the service Type has been set to 'forking'. + (Bug 296) (Muhammad Usama) + + + + + + + + + + + Release 3.6.2 + + + Release Date + 2017-03-17 + + + + Bug fixes + + + + + + + Add "Wants=network.target" to pgpool.service file. + (bug 294) (Bo Peng) + + + + + + + Fix pcp_promote_node bug that fails promoting node 0. (Yugo Nagata) + + + The master node could not be promoted by pcp_promote_node with + the following error; + + + + FATAL: invalid pgpool mode for process recovery request + DETAIL: specified node is already primary node, can't promote node id 0 + + + + In streaming replication mode, there is a case that Pgpool-II + regards the status of primary node as "standby" for some reasons, + for example, when pg_ctl promote is executed manually during + Pgpool-II is running, in which case, it seems to Pgpool-II + that the primary node doesn't exist. + + + + This status mismatch should be fixed by pcp_promote_node, but when the node + is the master node (the first alive node), it fails as mentioned above. + + + + The reason is as following. before changing the status, pcp_promote_node + checks if the specified node is already primary or not by comparing the + node id with PRIMARY_NODE_ID. However, if the primary doesn't exist from + Pgpool-II's view, PRIMARY_NODE_ID is set to 0, which is same as MASTER_NODE_ID. + Hence, when the master node is specified to be promoted, pcp_promote_node + is confused that this node is already primary and doesn't have to be + promoted, and it exits with the error. + + + + To fix this, pcp_promote_node should check the node id by using + REAL_PRIMARY_NODE_ID, which is set -1 when the primary doesn't exist, + rather than PRIMARY_NODE_ID. + + + + + + + + Fix document error. (Tatsuo Ishii, Bo Peng) + + + + + + + + + + Pgpool-IIshould not perform ping test after bringing down the VIP. (Muhammad Usama) + + + + This issue was reported by the reporter of + bug:[pgpool-II 0000249]: watchdog sometimes fails de-escalation + + + + + + + Fix to release shared memory segments when Pgpool-IIexits. (bug 272) (Tatsuo Ishii) + + + + + + + Fix for [pgpool-general: 5315] pg_terminate_backend (Muhammad Usama) + + + + + + + Adding the missing ExecStop and ExecReload commands to the systemd service configuration file. (Muhammad Usama) + + + + + + + Fix for 281: "segmentation fault" when execute pcp_attach_node. (bug 281) (Muhammad Usama) + + + + + + + Fix load balancing bug in streaming replication mode. (Tatsuo Ishii) + + + In an explicit transaction, any SELECT will be load balanced until + write query is sent. After writing query is sent, any SELECT should be + sent to the primary node. However if a SELECT is sent before a sync + message is sent, this does not work since the treatment of writing + query is done after ready for query message arrives. + + + Solution is, the treatment for writing query is done in executing the writing query as well. + + + + The bug has been there since V3.5. + + + + + + + Fix yet another kind mismatch error in streaming replication mode. (Tatsuo Ishii) + + + + + + + Fix do_query()hangs after close message. (Tatsuo Ishii) + + + + + + + Fixing stack smashing detected. (bug 280) (Muhammad Usama) + + + It was a buffer overflow in wd_get_cmd function + + + + + + + + Fixing the issue with the watchdog process restart. (Muhammad Usama) + + + When the watchdog process gets abnormally terminated because of some problem + (e.g. Segmentation fault) the new spawned watchdog process fails to start and + produces an error "bind on ... failed with reason: Address already in use". + + + Reason is the abnormally terminating watchdog process never gets the time to + clean-up the socket it uses for IPC and the new process gets an error because + the socket address is already occupied. + + + + Fix is, the Pgpool main process sets the flag in shared memory to mark the + watchdog process was abnormally terminated and at startup when the watchdog + process see that the flag is set, it performs the clean up of the socket file and + also performs the de-escalation (If the watchdog process was crashed when it + was master/coordinator node) if required before initializing itself. + + + + + + + Fix query cache bug reported in pgpool-general-jp:1441. (Tatsuo Ishii) + + + In streaming replication mode with query cache enabled, SELECT hangs + in the following scenario: + + + + 1) a SELECT hits query cache and returns rows from the query cache. + 2) following SELECT needs to search meta data and it hangs. + + + + In #1, while returning the cached result, it misses to call + pool_unset_pending_response(), which leave the pending_response flag + be set. In #2, do_query() checks the flag and tries to read pending + response from backend. Since there's no pending data in backend, it + hangs in reading data from backend. + + + + Fix is, just call pool_unset_pending_response() in #1 to reset the + flag. + + + + Bug report and fix provided by Nobuyuki Nagai. + + New regression test item (068) added by me. + + + + + + + + Remove elog/ereport calls from signal handlers. (Tatsuo Ishii) + + + See [pgpool-hackers: 1950] for details. + + + + + + + Fix bug failed to create INET domain socket in FreeBSD if listen_addresses = '*'. + (bug 202) (Bo Peng) + + + + + + + Fix for 0000249: watchdog sometimes fails de-escalation. (bug 249) (Muhammad Usama) + + + + The solution is to use the waitpid() system call without WNOHANG option. + + + + + + + + Fix connection_life_time broken by authentication_timeout. (Yugo Nagata) + + + + + + + Fix authentication timeout that can occur right after client connections. (Yugo Nagata) + + + + + + + + + + + Release 3.6.1 + + + Release Date + 2016-12-26 + + + + Bug fixes + + + + + + + Tightening up the watchdog security. (Muhammad Usama) + + + + Now wd_authkey uses the HMAC SHA-256 hashing. + + + + + + + Add pgpool_adm extension in Pgpool-II RPM. (Bo Peng) + + + + + + + Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii) + + + + + + + Fix packet kind does not match error in extended protocol. (bug 231) (Tatsuo Ishii) + + + According to the bug231, the bug seem to bite you if all of + following conditions are met: + + + + + Streaming replication mode + + + - Fixing the design of failover command propagation on watchdog cluster. (Muhammad Usama) + Load balance node is not node 0 + + - Overhauling the design of how failover, failback and promote node commands are - propagated to the watchdog nodes. Previously the watchdog on pgpool-II node that - needs to perform the node command (failover, failback or promote node) used to - broadcast the failover command to all attached pgpool-II nodes. And this - sometimes makes the synchronization issues, especially when the watchdog cluster - contains a large number of nodes and consequently the failover command sometimes - gets executed by more than one Pgpool-II. + Extended protocol is used + + - Now with this commit all the node commands are forwarded to the - master/coordinator watchdog, which in turn propagates to all standby nodes. - Apart from above the commit also changes the failover command interlocking - mechanism and now only the master/coordinator node can become the lock holder - so the failover commands will only get executed on the master/coordinator node. + SELECT is executed, the statement is closed, then a + transaction command is executed + + + + The sequence of how the problem bites is: + + + + SELECT executes on statement S1 on the load balance node 1 + + + + + Frontend send Close statement + + + + + Pgpool-II forward it to backend 1 + + + + + Frontend sends Parse, Bind, Execute of COMMIT + - - - Fix the case when all backends are down then 1 node attached. (Tatsuo Ishii) - - - When all backends are down, no connection is accepted. Then 1 - PostgreSQL becomes up, and attach the node using pcp_attach_node. It - successfully finishes. However, when a new connection arrives, still - the connection is refused becausePgpool-II child process looks into the - cached status, in which the recovered node is still in down status if - mode is streaming replication mode (native replication and other modes - are fine). Solution is, if all nodes are down, force to restart all - pgpool child. - + + Pgpool-II forward it to backend 0 & 1 + - - - Fix for avoiding downtime when Pgpool-II changes require a restart. (Muhammad Usama) - - - To fix this, the verification mechanism of configuration parameter values is - reversed, previously the standby nodes used to verify their parameter values - against the respective values on the master Pgpool-II node and when the - inconsistency was found the FATAL error was thrown, now with this commit the - verification responsibility is delegated to the master Pgpool-II node. - Now the master node will verify the configuration parameter values of each - joining standby node against its local values and will produce - a WARNING message instead of an error in case of a difference. - This way the nodes having the different configurations will also be allowed to - join the watchdog cluster and the user has to manually look out for the - configuration inconsistency warnings in the master Pgpool-II log to avoid the - surprises at the time of Pgpool-II master switch over. - + + Frontend sends sync message + - - - Fix a problem with the watchdog locking mechanism. (Muhammad Usama) - + + Pgpool-II forward it to backend 0 & 1 + - - - Add compiler flag "-fno-strict-aliasing" in configure.ac to fix compiler error. (Tatsuo Ishii) - + + Backend 0 replies back Parse complete ("1"), while + backend 1 replies back close complete ("3") because of + #3. + - - - Do not use random() while generating MD5 salt. (Tatsuo Ishii) - - - random() should not be used in security related applications. To - replace random(), import PostmasterRandom() from PostgreSQL. Also - store current time at the start up of Pgpool-II main process for later - use. - + + Kind mismatch occurs + + + + + + + The solution is, in #3, let Pgpool-II wait for response from backend + 1, but do not read the response message. Later on Pgpool-II's state + machine will read the response from it before the sync message is sent + in #6. With this, backend 1 will reply back "1" in #8, and the kind + mismatch error does not occur. + + + Also, fix not calling pool_set_doing_extended_query_message() when + receives Close message. (I don't know why it was missed). + + + New regression test "067.bug231" was added. + + + + + + + Fix a race condition in a signal handler. (bug 265) (Tatsuo Ishii) + + + In child.c there's signal handler which calls elog. Since the signal + handler is not blocked against other signals while processing, deadlock + could occur in the system calls in the pgpool shutdown sequence. To + fix the problem, now the signal handler is blocked by using + POOL_SETMASK. + + + Ideally we should avoid calling elog in signal handlers though. + + + + + + + Fix wrong minimum configuration value for client_idle_limit_in_recovery. (bug 264) (Tatsuo Ishii) + + + + + + + Allow to execute "make xslthtml" under doc.ja. (Tatsuo Ishii) + + + + + + + + + + + + + + + Release 3.6 + + + Release Date + 2016-11-21 + + + + Overview + + + Major enhancements in Pgpool-II 3.6 include: + + + + + + + + + Improve the behavior of failover. In the steaming + replication mode, client sessions will not be disconnected + when a failover occurs any more if the session does not use + the failed standby server. If the primary server goes down, + still all sessions will be disconnected. Also it is possible + to connect to Pgpool-II even if + it is doing health checking retries. Before all attempt of + connecting to Pgpool-II failed + while doing health checking retries. + + + + + + New PGPOOL SET command has been introduced. Certain + configuration parameters now can be changed on the fly in a + session. + + + + + + Watchdog is significantly enhanced. It becomes more reliable + than previous releases. + + + + + + Handling of extended query protocol (e.g. used by Java + applications) in streaming replication mode speeds up if + many rows are returned in a result set. + + + + + + Import parser of PostgreSQL 9.6. + + + + + + In some cases pg_terminate_backend() now does not trigger a + failover. + + + + + + Change documentation format from raw HTML to SGML. + + + + + + + The above items are explained in more detail in the sections below. + + + + + + Major Enhancements + + + + + + + Improve the behavior of failover. (Tatsuo Ishii) + + + In the steaming replication mode, client sessions will not + be disconnected when a failover occurs any more if the + session does not use the failed standby server. If the + primary server goes down, still all sessions will be + disconnected. Health check timeout case will also cause the + full session disconnection. Other health check error, + including retry over case does not trigger full session + disconnection. + + + + For user's convenience, "show pool_nodes" command shows the + session local load balance node info since this is important + for users in case of failover. If the load balance node is + not the failed node, the session will not be affected by + failover. + + + + Also now it is possible to connect + to Pgpool-II even if it is doing + health checking retries. Before all attempt of connecting + to Pgpool-II failed while doing + health checking retries. Before any attempt to connect to + Pgpool-II fails if it is doing a + health check against failed node even if + is off + because Pgpool-II child first + tries to connect to all backend including the failed one and + exits if it fails to connect to a backend (of course it + fails). This is a temporary situation and will be resolved + once pgpool executes failover. However if the health check + is retrying, the temporary situation keeps longer depending + on the setting + of and + . This is not + good. Attached patch tries to mitigate the problem: + + + When an attempt to connect to backend fails, give up + connecting to the failed node and skip to other node, rather + than exiting the process if operating in streaming + replication mode and the node is not primary node. + + + Mark the local status of the failed node to "down". This + will let the primary node be selected as a load balance node + and every queries will be sent to the primary node. If + there's other healthy standby nodes, one of them will be + chosen as the load balance node. + + + After the session is over, the child process will suicide to + not retain the local status. + + + + + + + Add PGPOOL + SHOW, PGPOOL + SET and + PGPOOL RESET + commands. (Muhammad Usama) + + + These are similar to the PostgreSQL's SET and SHOW commands + for GUC variables, adding the functionality + in Pgpool-II to set and reset the + value of config parameters for the current session, and for + that it adds a new syntax + in Pgpool-II which is similar to + PostgreSQL's SET and RESET variable syntax with an addition + of PGPOOL keyword at the start. + + + Currently supported configuration parameters by PGPOOL + SHOW/SET/RESET are: , + , , + , , + , , + , , + . + + + + + + + Sync inconsistent status + of PostgreSQL nodes + in Pgpool-II instances after + restart. (bug 218) (Muhammad Usama) + + + Watchdog does not synchronize status. + + + + + + + Enhance performance of SELECT when lots of rows involved. + (Tatsuo Ishii) + + + Pgpool-II flushes data to network + (calling write(2)) every time it sends a row data ("Data + Row" message) to frontend. For example, if 10,000 rows + needed to be transfer, 10,000 times write()s are + issued. This is pretty expensive. Since after repeating to + send row data, "Command Complete" message is sent, it's + enough to issue a write() with the command complete + message. Also there are unnecessary flushing are in handling + the command complete message. + + + Quick + testing showed that from 47% to 62% performance + enhancements were achieved in some cases. + + + Unfortunately, performance in workloads where transferring + few rows, will not be enhanced since such rows are needed to + flush to network anyway. + + + + + + + Import PostgreSQL 9.6's SQL + parser. (Bo Peng) + + + This allows Pgpool-II to fully + understand the newly added SQL syntax such as COPY + INSERT RETURNING. + + + + + + + In some cases pg_terminate_backend() now does not trigger a failover. (Muhammad Usama) + + + Because PostgreSQL returns exactly the same error code as postmaster + down case and pg_terminate_backend() case, using + pg_terminate_backend() raises a failover which user might not want. To + fix this, now Pgpool-II finds a pid of backend which is the target of + pg_terminate_backend() and does not trigger failover if so. + + + This functions is limited to the case of simple protocol and the pid + is given to pg_terminate_backend() as a constant. So if you call + pg_terminate_backend() via extended protocol (e.g. Java) still + pg_terminate_backend() triggers a failover. + + + + + + + HTML documents are now generated from SGML documents. + (Muhammad Usama, Tatsuo Ishii, Bo Peng) + + + It is intended to have better construction, contents and + maintainability. Also man pages are now generated from SGML. + However, still there's tremendous room to + enhance the SGML documents. Please help us! + + + + + + + + Other Enhancements + + + + + + + + Make authentication error message more user friendly. (Tatsuo Ishii) + + + When attempt to connect to backend (including health + checking), emit error messages from backend something like + "sorry, too many clients already" instead of "invalid + authentication message response type, Expecting 'R' and + received '%c'" + + + + + + + Tighten up health check timer expired condition in pool_check_fd(). (Muhammad Usama) + + + + + + + Add new script called "watchdog_setup". (Tatsuo Ishii) + + + is a command to create a + temporary installation + of Pgpool-II clusters with + watchdog for mainly testings. + + + + + + + Add "-pg" option to pgpool_setup. (Tatsuo Ishii) + + + This is useful when you want to assign specific port numbers to + PostgreSQL while + using . Also + now pgpool_setup is installed in the + standard bin directory which is same + as pgpool. + + + + + + + Add "replication delay" column to "show pool_nodes". (Tatsuo Ishii) + + + This column + shows the + replication delay value in bytes if operated in + streaming replication mode. + + + + + + + Do not update status file if all backend nodes are in down status. (Chris Pacejo, Tatsuo Ishii) + + + This commit tries to remove the data inconsistency in + replication mode found + in [pgpool-general: + 3918] by not recording the status file when all + backend nodes are in down status. This surprisingly simple + but smart solution was provided by Chris Pacejo. + + + + + + + Allow to use multiple SSL cipher protocols. (Muhammad Usama) + + + By replacing TLSv1_method() with SSLv23_method() while + initializing the SSL session, we can use more protocols than + TLSv1 protocol. + + + + + + + Allow to use arbitrary number of items in the + black_function_list/white_function_list. (Muhammad Usama) + + + Previously there were fixed limits for those. + + + + + + + Properly process empty queries (all comments). (Tatsuo Ishii) + + + Pgpool-II now recognizes an empty + query consisted of all comments (for example "/* DBD::Pg + ping test v3.5.3 */") (note that no ';') as an empty query. + + + Before such that query was recognized an error. + + + + + + + Add some warning messages for wd_authkey hash calculation failure. (Yugo Nagata) + + + Sometimes wd_authkey calculation fails for some reason other + than authkey mismatch. The additional messages make these + distinguishable for each other. + + + + + + + + + Changes + + + + + + Fix the broken log_destination = syslog functionality. (Muhammad Usama) + + + Fixing the logging to the syslog destination, which got broken by the + PGPOOL SET/SHOW command commit, and also enhancing the log_destination + configuration parameter to be assigned with the comma separated list of multiple + destinations for the Pgpool-II log. Now, after this commit log_destination can + be set to any combination of 'syslog' and 'stderr' log destinations. + + + + + + Change the default value of + from 10 to 300. (Tatsuo Ishii) + + + Prior default value 10 seconds is sometimes too short for a standby to + be promoted. + + + + + + + Change the Makefile under directory + src/sql/, that is proposed by + + [pgpool-hackers: 1611]. (Bo Peng) + + + + + + + Change the PID length of pcp_proc_count command output to 6 characters long. (Bo Peng) + + + If the Pgpool-II process ID are over 5 characters, the 6th character of each process ID + will be removed. This commit changes the process ID length of pcp_proc_count command + output to 6 characters long. + + + + + + Redirect all user queries to primary server. (Tatsuo Ishii) + + + Up to now some user queries are sent to other than the primary server + even if = off. This commit changes the behavior: if + load_balance_mode = off in streaming replication mode, now all the + user queries are sent to the primary server only. + + + + + + + Bug fixes + + + + + + Fixing a potential crash in pool_stream functions. (Muhammad Usama) + + + POOL_CONNECTION->con_info should be checked for null value before de-referencing + when read or write fails on backend socket. + + + + + + Fixing the design of failover command propagation on watchdog cluster. (Muhammad Usama) + + + Overhauling the design of how failover, failback and promote node commands are + propagated to the watchdog nodes. Previously the watchdog on pgpool-II node that + needs to perform the node command (failover, failback or promote node) used to + broadcast the failover command to all attached pgpool-II nodes. And this + sometimes makes the synchronization issues, especially when the watchdog cluster + contains a large number of nodes and consequently the failover command sometimes + gets executed by more than one Pgpool-II. + + + Now with this commit all the node commands are forwarded to the + master/coordinator watchdog, which in turn propagates to all standby nodes. + Apart from above the commit also changes the failover command interlocking + mechanism and now only the master/coordinator node can become the lock holder + so the failover commands will only get executed on the master/coordinator node. + + + + + + Fix the case when all backends are down then 1 node attached. (Tatsuo Ishii) + + + When all backends are down, no connection is accepted. Then 1 + PostgreSQL becomes up, and attach the node using pcp_attach_node. It + successfully finishes. However, when a new connection arrives, still + the connection is refused becausePgpool-II child process looks into the + cached status, in which the recovered node is still in down status if + mode is streaming replication mode (native replication and other modes + are fine). Solution is, if all nodes are down, force to restart all + pgpool child. + + + + + + Fix for avoiding downtime when Pgpool-II changes require a restart. (Muhammad Usama) + + + To fix this, the verification mechanism of configuration parameter values is + reversed, previously the standby nodes used to verify their parameter values + against the respective values on the master Pgpool-II node and when the + inconsistency was found the FATAL error was thrown, now with this commit the + verification responsibility is delegated to the master Pgpool-II node. + Now the master node will verify the configuration parameter values of each + joining standby node against its local values and will produce + a WARNING message instead of an error in case of a difference. + This way the nodes having the different configurations will also be allowed to + join the watchdog cluster and the user has to manually look out for the + configuration inconsistency warnings in the master Pgpool-II log to avoid the + surprises at the time of Pgpool-II master switch over. + + + + + + Fix a problem with the watchdog locking mechanism. (Muhammad Usama) + + + + + + Add compiler flag "-fno-strict-aliasing" in configure.ac to fix compiler error. (Tatsuo Ishii) + + + + + + Do not use random() while generating MD5 salt. (Tatsuo Ishii) + + + random() should not be used in security related applications. To + replace random(), import PostmasterRandom() from PostgreSQL. Also + store current time at the start up of Pgpool-II main process for later + use. + + + + + + + Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) + + + + + + Fix bug that Pgpool-II fails to start if is empty string. (bug 237) (Muhammad Usama) + + + The socket descriptor array (fds[]) was not getting the array end marker + when TCP listen addresses are not used. + + + + + + Create regression log directory if it does not exist yet. (Tatsuo Ishii) + + + + + + Fixing the error messages when the socket operation fails. (Muhammad Usama) + + + + + + Update regression test 003.failover to reflect the changes made to + show pool_nodes. (Tatsuo Ishii) + + + + + + Fix hang when portal suspend received. (bug 230) (Tatsuo Ishii) + + + + + + Fix pgpool doesn't de-escalate IP in case network restored. (bug 228) (Muhammad Usama) + + + set_state function is made to de-escalate, when it is changing the local node's + state from the coordinator state to some other state. + + + + + + SIGUSR1 signal handler should be installed before watchdog initialization. (Muhammad Usama) + + + Since there can be a case where a failover request from other watchdog nodes + arrive at the same time when the watchdog has just been initialized, + and if we wait any longer to install a SIGUSR1 signal handler, it can + result in a potential crash + + + + + + Fix Pgpool-II doesn't escalate ip in case of another node unavailability. (bug 215) (Muhammad Usama) + + + The heartbeat receiver fails to identify the heartbeat sender watchdog node when + the heartbeat destination is specified in terms of an IP address while + wd_hostname is configured as a hostname string or vice versa. + + + + + + Fixing a coding mistake in watchdog code. (Muhammad Usama) + + + wd_issue_failover_lock_command() function is supposed to forward command type + passed in as an argument to the wd_send_failover_sync_command() function instead + it was passing the NODE_FAILBACK_CMD command type. + + + The commit also contains some log message enhancements. + + + + + + Display human readable output for backend node status. (Muhammad Usama) + + + Changed the output of pcp_node_info utility and show commands display human + readable backend status string instead of internal status code. + + + + + + Replace "MAJOR" macro to prevent occasional failure. (Tatsuo Ishii) + + + The macro calls pool_virtual_master_db_node_id() and then access + backend->slots[id]->con using the node id returned. In rare cases, it + could point to 0 (in case when the DB node is not connected), which + gives access to con->major, then it causes a segfault. + + + + + + Fix "kind mismatch" error message in Pgpool-II. (Muhammad Usama) + + + Many of "kind mismatch..." errors are caused by notice/warning + messages produced by one or more of the DB nodes. In this case now + Pgpool-II forwards the messages to frontend, rather than throwing the + "kind mismatch..." error. This would reduce the chance of "kind + mismatch..." errors. + + + + + + Fix handling of config parameter. (Muhammad Usama) + + + + + + Save and restore errno in each signal handler. (Tatsuo Ishii) + + + + + + Fix usage of wait(2) in pgpool main process. (Tatsuo Ishii) + + + The usage of wait(2) in Pgpool-II + main could cause infinite wait in the system call. Solution is, + to use waitpid(2) instead of wait(2). + + + + + + Fix that pool_read() does not emit error messages when read(2) returns -1 if + is off. (Tatsuo Ishii) + + + + + + Fix buffer over run problem in "show pool_nodes". (Tatsuo Ishii) + + + While processing "show pool_nodes", the buffer for hostname was too + short. It should be same size as the buffer used for pgpool.conf. + Problem reported by a twitter user who is using pgpool on AWS (which + could have very long hostname). + + + + + + Fix + [pgpool-hackers: 1638] pgpool-II does not use default configuration. (Muhammad Usama) + + + Configuration file not found should just throw a WARNING message + instead of ERROR or FATAL. + + + + + + Fix bug with load balance node id info on shmem. (Tatsuo Ishii) + + + There are few places where the load balance node was mistakenly put on + wrong place. It should be placed on: + + ConnectionInfo *con_info[child id, connection pool_id, backend id].load_balancing_node]. + + In fact it was placed on: + + *con_info[child id, connection pool_id, 0].load_balancing_node]. + + + + As long as the backend id in question is 0, it is ok. However while + testing Pgpool-II 3.6's enhancement regarding failover, if primary + node is 1 (which is the load balance node) and standby is 0, a client + connecting to node 1 is disconnected when failover happens on node + 0. This is unexpected and the bug was revealed. + + + It seems the bug was there since long time ago but it had not found + until today by the reason above. + + + + + + Fix for bug that pgpool hangs connections to database. (bug 197) (Muhammad Usama) + + + The client connection was getting stuck when backend node and remote Pgpool-II + node becomes unavailable at the same time. The reason was a missing command + timeout handling in the function that sends the IPC commands to watchdog. + + + + + + Fix a possible hang during health checking. (bug 204) (Yugo Nagata) + + + Health checking was hang when any data wasn't sent + from backend after connect(2) succeeded. To fix this, + pool_check_fd() returns 1 when select(2) exits with + EINTR due to SIGALRM while health checking is performed. + + + + + + Deal with the case when the primary is not node 0 in streaming replication mode. (Tatsuo Ishii) + + - - - - - Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii) - - - - - - Fix bug that Pgpool-II fails to start if is empty string. (bug 237) (Muhammad Usama) - - - The socket descriptor array (fds[]) was not getting the array end marker - when TCP listen addresses are not used. - - - - - - Create regression log directory if it does not exist yet. (Tatsuo Ishii) - - - - - - Fixing the error messages when the socket operation fails. (Muhammad Usama) - - - - - - Update regression test 003.failover to reflect the changes made to - show pool_nodes. (Tatsuo Ishii) - - - - - - Fix hang when portal suspend received. (bug 230) (Tatsuo Ishii) - - - - - - Fix pgpool doesn't de-escalate IP in case network restored. (bug 228) (Muhammad Usama) - - - set_state function is made to de-escalate, when it is changing the local node's - state from the coordinator state to some other state. - - - - - - SIGUSR1 signal handler should be installed before watchdog initialization. (Muhammad Usama) - - - Since there can be a case where a failover request from other watchdog nodes - arrive at the same time when the watchdog has just been initialized, - and if we wait any longer to install a SIGUSR1 signal handler, it can - result in a potential crash - - - - - - Fix Pgpool-II doesn't escalate ip in case of another node inavailability. (bug 215) (Muhammad Usama) - - - The heartbeat receiver fails to identify the heartbeat sender watchdog node when - the heartbeat destination is specified in terms of an IP address while - wd_hostname is configured as a hostname string or vice versa. - - - - - - Fixing a coding mistake in watchdog code. (Muhammad Usama) - - - wd_issue_failover_lock_command() function is supposed to forward command type - passed in as an argument to the wd_send_failover_sync_command() function instead - it was passing the NODE_FAILBACK_CMD command type. - - - The commit also contains some log message enhancements. - - - - - - Display human readable output for backend node status. (Muhammad Usama) - - - Changed the output of pcp_node_info utility and show commands display human - readable backend status string instead of internal status code. - - - - - - Replace "MAJOR" macro to prevent occasional failure. (Tatsuo Ishii) - - - The macro calls pool_virtual_master_db_node_id() and then access - backend->slots[id]->con using the node id returned. In rare cases, it - could point to 0 (in case when the DB node is not connected), which - gives access to con->major, then it causes a segfault. - - - - - - Fix "kind mismatch" error message in Pgpool-II. (Muhammad Usama) - - - Many of "kind mismatch..." errors are caused by notice/warning - messages produced by one or more of the DB nodes. In this case now - Pgpool-II forwards the messages to frontend, rather than throwing the - "kind mismatch..." error. This would reduce the chance of "kind - mismatch..." errors. - - - - - - Fix handling of config parameter. (Muhammad Usama) - - - - - - Save and restore errno in each signal handler. (Tatsuo Ishii) - - - - - - Fix usage of wait(2) in pgpool main process. (Tatsuo Ishii) - - - The usage of wait(2) in Pgpool-II - main could cause infinite wait in the system call. Solution is, - to use waitpid(2) instead of wait(2). - - - - - - Fix that pool_read() does not emit error messages when read(2) returns -1 if - is off. (Tatsuo Ishii) - - - - - - Fix buffer over run problem in "show pool_nodes". (Tatsuo Ishii) - - - While processing "show pool_nodes", the buffer for hostname was too - short. It should be same size as the buffer used for pgpool.conf. - Problem reported by a twitter user who is using pgpool on AWS (which - could have very long hostname). - - - - - - Fix - [pgpool-hackers: 1638] pgpool-II does not use default configuration. (Muhammad Usama) - - - Configuration file not found should just throw a WARNING message - instead of ERROR or FATAL. - - - - - - Fix bug with load balance node id info on shmem. (Tatsuo Ishii) - - - There are few places where the load balance node was mistakenly put on - wrong place. It should be placed on: - -ConnectionInfo *con_info[child id, connection pool_id, backend id].load_balancing_node]. - - In fact it was placed on: - -*con_info[child id, connection pool_id, 0].load_balancing_node]. - - - - As long as the backend id in question is 0, it is ok. However while - testing Pgpool-II 3.6's enhancement regarding failover, if primary - node is 1 (which is the load balance node) and standby is 0, a client - connecting to node 1 is disconnected when failover happens on node - 0. This is unexpected and the bug was revealed. - - - It seems the bug was there since long time ago but it had not found - until today by the reason above. - - - - - - Fix for bug that pgpool hangs connections to database. (bug 197) (Muhammad Usama) - - - The client connection was getting stuck when backend node and remote Pgpool-II - node becomes unavailable at the same time. The reason was a missing command - timeout handling in the function that sends the IPC commands to watchdog. - - - - - - Fix a posible hang during health checking. (bug 204) (Yugo Nagata) - - - Helath checking was hang when any data wasn't sent - from backend after connect(2) succeeded. To fix this, - pool_check_fd() returns 1 when select(2) exits with - EINTR due to SIGALRM while health checkking is performed. - - - - - - Deal with the case when the primary is not node 0 in streaming replication mode. (Tatsuo Ishii) - - - - - http://www.pgpool.net/mantisbt/view.php?id=194#c837 reported that if - primary is not node 0, then statement timeout could occur even after - bug194-3.3.diff was applied. After some investigation, it appeared - that MASTER macro could return other than primary or load balance - node, which was not supposed to happen, thus do_query() sends queries - to wrong node (this is not clear from the report but I confirmed it in - my investigation). - - - pool_virtual_master_db_node_id(), which is called in MASTER macro - returns query_context->virtual_master_node_id if query context - exists. This could return wrong node if the variable has not been set - yet. To fix this, the function is modified: if the variable is not - either load balance node or primary node, the primary node id is - returned. - - - - - - If statement timeout is enabled on backend and do_query() sends a query to primary node, and all of following user queries are sent to - standby, it is possible that the next command, for example END, could - cause a statement timeout error on the primary, and a kind mismatch - error on pgpool-II is raised. (bug 194) (Tatsuo Ishii) - - - This fix tries to mitigate the problem by sending sync message instead - of flush message in do_query(), expecting that the sync message reset - the statement timeout timer if we are in an explicit transaction. We - cannot use this technique for implicit transaction case, because the - sync message removes the unnamed portal if there's any. - - - Plus, pg_stat_statement will no longer show the query issued by - do_query() as "running". - - - Plus, pg_stat_statement will no longer show the query issued by - do_query() as "running". - - - - - - Fix extended protocol handling in raw mode. (Tatsuo Ishii) - - - Bug152 reveals that extended protocol handling in raw mode (actually - other than in stream mode) was wrong in Describe() and Close(). - Unlike stream mode, they should wait for backend response. - - - - - - Fix confusing comments in pgpool.conf. (Tatsuo Ishii) - - - - - - Fix Japanese and Chinese documetation bug about raw mode. (Yugo Nagata, Bo Peng) - - - Connection pool is avalilable in raw mode. - - - - - - Fix is_set_transaction_serializable() when - SET default_transaction_isolation TO 'serializable'. (bug 191) (Bo Peng) - - - SET default_transaction_isolation TO 'serializable' is sent to - not only primary but also to standby server in streaming replication mode, - and this causes an error. Fix is, in streaming replication mode, - SET default_transaction_isolation TO 'serializable' is sent only to the - primary server. - - - - - - Fix extended protocol hang with empty query. (bug 190) (Tatsuo Ishii) - - - The fixes related to extended protocol cases in 3.5.1 broke the case - of empty query. In this case backend replies with "empty query - response" which is same meaning as a command complete message. Problem - is, when empty query response is received, pgpool does not reset the - query in progress flag thus keeps on waiting for backend. However, - backend will not send the ready for query message until it receives a - sync message. Fix is, resetting the in progress flag after receiving - the empty query response and reads from frontend expecting it sends a - sync message. - - - - - - Fix for - [pgpool-general: 4569] segfault during trusted_servers check. (Muhammad Usama) - - - PostgreSQL's memory and exception manager APIs adopted by the Pgpool-II 3.4 are not - thread safe and are causing the segmentation fault in the watchdog lifecheck - process, as it uses the threads to ping configured trusted hosts for checking - the upstream connections. - Fix is to remove threads and use the child process approach instead. - - - - - - Validating the PCP packet length. (Muhammad Usama) - - - Without the validation check, a malformed PCP packet can crash the PCP child - and/or can run the server out of memory by sending the packet with a - very large data size. - - - - - - Fix pgpool_setup to not confuse log output. (Tatsuo Ishii) - - - Before it simply redirects the stdout and stderr of pgpool process to - a log file. This could cause log contents being garbled or even - missed because of race condition caused by multiple process being - writing concurrently. I and Usama found this while investigating the - regression failure of 004.watchdog. - - To fix this, pgpool_setup now generates startall script so that pgpool - now sends stdout/stderr to cat command and cat writes to the log file - (It seems the race condition does not occur when writing to a pipe). - - - - - - Fix for - [pgpool-general: 4519] Worker Processes Exit and Are Not Re-spawned. (Muhammad Usama) - - - The problem was due to a logical mistake in the code for checking the exiting - child process type when the watchdog is enabled. - I have also changed the severity of the message from FATAL to LOG, emitted - for child exits due to max connection reached. - - - - - - Fix pgpool hung after receiving error state from backend. (bug #169) (Tatsuo Ishii) - - - This could happend if we execute an extended protocol query and it - fails. - - - - - - Fix query stack problems in extended protocol case. (bug 167, 168) (Tatstuo Ishii) - - - - - - - - Fix - [pgpool-hackers: 1440] yet another reset query stuck problem. (Tatsuo Ishii) - - - After receiving X message from frontend, if Pgpool-II detects EOF on - the connection before sending reset query, Pgpool-II could wait for - backend which had not received the reset query. To fix this, if EOF - received, treat this as FRONTEND_ERROR, rather than ERROR. - - - - - - Fix for - [pgpool-general: 4265] another reset query stuck problem. (Muhammad Usama) - - - The solution is to report FRONTEND_ERROR instead of simple ERROR when - pool_flush on front-end socket fails. - - - - - - Fixing pgpool-recovery module compilation issue with PostgreSQL 9.6. (Muhammad Usama) - - - Incorporating the change of function signature for - GetConfigOption() functions in PostgreSQL 9.6 - - - - - - Fix compile issue on freebsd. (Muhammad Usama) - - - Add missing include files. The patch is contributed by - the bug reporter and enhanced a little by me. - - - - - - Fix regression test to check timeout of each test. (Yugo Nagata) - - - - - - Add some warning messages for hash calculation failure. (Yugo Nagata) - - - Sometimes calculation fails for some reason other than - authkey mismatch. The additional messages make these distingushable - for each other. - - + + http://www.pgpool.net/mantisbt/view.php?id=194#c837 reported that if + primary is not node 0, then statement timeout could occur even after + bug194-3.3.diff was applied. After some investigation, it appeared + that MASTER macro could return other than primary or load balance + node, which was not supposed to happen, thus do_query() sends queries + to wrong node (this is not clear from the report but I confirmed it in + my investigation). + + + pool_virtual_master_db_node_id(), which is called in MASTER macro + returns query_context->virtual_master_node_id if query context + exists. This could return wrong node if the variable has not been set + yet. To fix this, the function is modified: if the variable is not + either load balance node or primary node, the primary node id is + returned. + + + + + + If statement timeout is enabled on backend and do_query() sends a query to primary node, and all of following user queries are sent to + standby, it is possible that the next command, for example END, could + cause a statement timeout error on the primary, and a kind mismatch + error on pgpool-II is raised. (bug 194) (Tatsuo Ishii) + + + This fix tries to mitigate the problem by sending sync message instead + of flush message in do_query(), expecting that the sync message reset + the statement timeout timer if we are in an explicit transaction. We + cannot use this technique for implicit transaction case, because the + sync message removes the unnamed portal if there's any. + + + Plus, pg_stat_statement will no longer show the query issued by + do_query() as "running". + + + Plus, pg_stat_statement will no longer show the query issued by + do_query() as "running". + + + + + + Fix extended protocol handling in raw mode. (Tatsuo Ishii) + + + Bug152 reveals that extended protocol handling in raw mode (actually + other than in stream mode) was wrong in Describe() and Close(). + Unlike stream mode, they should wait for backend response. + + + + + + Fix confusing comments in pgpool.conf. (Tatsuo Ishii) + + + + + + Fix Japanese and Chinese documentation bug about raw mode. (Yugo Nagata, Bo Peng) + + + Connection pool is available in raw mode. + + + + + + Fix is_set_transaction_serializable() when + SET default_transaction_isolation TO 'serializable'. (bug 191) (Bo Peng) + + + SET default_transaction_isolation TO 'serializable' is sent to + not only primary but also to standby server in streaming replication mode, + and this causes an error. Fix is, in streaming replication mode, + SET default_transaction_isolation TO 'serializable' is sent only to the + primary server. + + + + + + Fix extended protocol hang with empty query. (bug 190) (Tatsuo Ishii) + + + The fixes related to extended protocol cases in 3.5.1 broke the case + of empty query. In this case backend replies with "empty query + response" which is same meaning as a command complete message. Problem + is, when empty query response is received, pgpool does not reset the + query in progress flag thus keeps on waiting for backend. However, + backend will not send the ready for query message until it receives a + sync message. Fix is, resetting the in progress flag after receiving + the empty query response and reads from frontend expecting it sends a + sync message. + + + + + + Fix for + [pgpool-general: 4569] segfault during trusted_servers check. (Muhammad Usama) + + + PostgreSQL's memory and exception manager APIs adopted by the Pgpool-II 3.4 are not + thread safe and are causing the segmentation fault in the watchdog lifecheck + process, as it uses the threads to ping configured trusted hosts for checking + the upstream connections. + Fix is to remove threads and use the child process approach instead. + + + + + + Validating the PCP packet length. (Muhammad Usama) + + + Without the validation check, a malformed PCP packet can crash the PCP child + and/or can run the server out of memory by sending the packet with a + very large data size. + + + + + + Fix pgpool_setup to not confuse log output. (Tatsuo Ishii) + + + Before it simply redirects the stdout and stderr of pgpool process to + a log file. This could cause log contents being garbled or even + missed because of race condition caused by multiple process being + writing concurrently. I and Usama found this while investigating the + regression failure of 004.watchdog. - + To fix this, pgpool_setup now generates startall script so that pgpool + now sends stdout/stderr to cat command and cat writes to the log file + (It seems the race condition does not occur when writing to a pipe). + + + + + + Fix for + [pgpool-general: 4519] Worker Processes Exit and Are Not Re-spawned. (Muhammad Usama) + + + The problem was due to a logical mistake in the code for checking the exiting + child process type when the watchdog is enabled. + I have also changed the severity of the message from FATAL to LOG, emitted + for child exits due to max connection reached. + + + + + + Fix pgpool hung after receiving error state from backend. (bug #169) (Tatsuo Ishii) + + + This could happen if we execute an extended protocol query and it + fails. + + + + + + Fix query stack problems in extended protocol case. (bug 167, 168) (Tatsuo Ishii) + + + + + + + + Fix + [pgpool-hackers: 1440] yet another reset query stuck problem. (Tatsuo Ishii) + + + After receiving X message from frontend, if Pgpool-II detects EOF on + the connection before sending reset query, Pgpool-II could wait for + backend which had not received the reset query. To fix this, if EOF + received, treat this as FRONTEND_ERROR, rather than ERROR. + + + + + + Fix for + [pgpool-general: 4265] another reset query stuck problem. (Muhammad Usama) + + + The solution is to report FRONTEND_ERROR instead of simple ERROR when + pool_flush on front-end socket fails. + + + + + + Fixing pgpool-recovery module compilation issue with PostgreSQL 9.6. (Muhammad Usama) + + + Incorporating the change of function signature for + GetConfigOption() functions in PostgreSQL 9.6 + + + + + + Fix compile issue on FreeBSD. (Muhammad Usama) + + + Add missing include files. The patch is contributed by + the bug reporter and enhanced a little by me. + + + + + + Fix regression test to check timeout of each test. (Yugo Nagata) + + + + + + Add some warning messages for hash calculation failure. (Yugo Nagata) + + + Sometimes calculation fails for some reason other than + authkey mismatch. The additional messages make these distinguishable + for each other. + + + + - + diff --git a/doc/src/sgml/release-3.7.sgml b/doc/src/sgml/release-3.7.sgml index 8d7080429..87a13b25a 100644 --- a/doc/src/sgml/release-3.7.sgml +++ b/doc/src/sgml/release-3.7.sgml @@ -1,1806 +1,4532 @@ - - Release 3.7.7 + + Release 3.7.26 Release Date - 2018-11-22 + 2022-12-22 - - Bug fixes + + Changes - - - + - Fix to sort startup packet's parameters sent by client. - (bug 444)(Takuma Hoshiai) + Downgrade LOG messages "new IPC connection received" to DEBUG1. + (bug 775) (Bo Peng) - If order of startup packet's parameters differ between cached connection - pools and connection request, did't use connection pool ,and created new - connection pool. + It is a normal messages and should not be logged as LOG. + Patch is created by pstef and reviewed by Bo Peng. - + + + + + + Bug fixes + + - - + - Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. - (bug 443)(Bo Peng) + Fix rare segfaults in pcp_proc_info, SHOW pool_pools + and SHOW pool_processes. (Tatsuo Ishii) - If the number of parameter format codes is specified to one, but the number - of the original query's parameter is zero, bind_rewrite_timestamp() will call memcpy with a negative value. - This causes segmentation fault. + The segfaults were in get_pools() and get_processes(). They first + extracted pid of particular process info slot on shared memory then + searched the slot again by using pid as the key. Because these steps + were not protected by any locking, it was possible that the search + using the pid failed and returned NULL if the process id is + overwritten by pgpool parent which is responsible for forking new + child process after the process exiting. As a result any subsequent + reference to the NULL pointer generated segfaults. - Patch is provided by Yugo Nagata. + Solution is, first get the pointer to the process info slot then + extract the process id member from the pointer. This way, still + concurrent updating to the shared memory info by the parent process is + possible (which may lead to strange results in the output) but at + least we can avoid segfaults. - + - - + - Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + Fix to not allow Unix-domain socket path with invalid length. (Masaya Kawamoto) - + + + + + + Documents + + - - + - Fix query cache invalidation bug. (Tatsuo Ishii) + Doc: enhance description about memqcache_method. (Tatsuo Ishii) - - - - - - Fix segfault in extended query + query cache case. (Tatsuo Ishii) + Add explanation which method should be used. - + - + - Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + Doc: mention that health check process may use SSL. (Tatsuo Ishii) + + + Also mention that streaming replication check may use SSL too. + This should have been added since 2010. + + + Discussion: [pgpool-hackers: 4187] - - - - - - Release 3.7.6 - - - Release Date - 2018-10-31 - - - - Changes - - - - - Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) - - - - - - - Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) - - - - - - - Doc: Add note to online recovery doc. (Tatsuo Ishii) - - - This warns that must be smaller than . - - - - - - - Test: Add regression test for SSL connection. (Tatsuo Ishii) - - - - - - - Doc: Add notes regarding failover script. (Tatsuo Ishii) - - - It's not recommended to access against Pgpool-II itself from failover/failback scripts. - - - - - - - Doc: Improve docs and error message. (Bo Peng) - - - Patch provided by Jesper Pedersen and modified by me. - - - - - - - Test: Add definition of PGLIB in regress.sh. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - - Bug fixes - - - - - Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) - - - Patch provided by Phil Ramirez. - - - - - - - Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) - - - In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. - - - - - - - Fix syntax error when queries including time functions and IN (SELECT ...) in - WHERE clause in native replication mode. - (bug 433) (Bo Peng) - - - In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. - However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. - - - - - - - Fix occasional less data returned to frontend with extended protocol. (bug432) (Tatsuo Ishii) - - - The idea for fix is, use pending message data list. It records - messages from frontend, and it is expected that we will receive same - number of messages. - - - Initial patch is created by Yugo Nagata and fixed by Tatsuo Ishii. - - - - - - - Fix memory leak when query cache enabled in streaming replication mode + extended query case. (Tatsuo Ishii) - - - - - - - Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) - - - - - - - Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) - - - In a explicit transaction, the SELECT results are cached in temporary buffer. - If a write SQL is sent which modifies the table, the temporary buffe should be reset. - - - - - - - Test: Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) - - - - - - - Test: Add EXECUTE/DEALLOCATE regression test. (Takuma Hoshiai) - - - - - - - Add missing pgpool_recovery--1.0--1.1.sql file to update - pgpool_recovery() function version to 1.1. (Bo Peng) - - - - - - - Fix kind mismatch error when DEALLOCATE statement is issued. (Bo Peng) - - - PREPARE should be add to pool_add_sent_message, - so that EXECUTE and DEALLOCATE - can be sent to the same node as PREPARE. - - - See [pgpool-general: 6226] for more details. - - - - - - - Do not update if the password length is incorrect. - (bug 419) (Takuma Hoshiai, Tatsuo Ishii) - - - For Pgpool-II 3.7 or before, the password stored in - is MD5 password only. - So check the correctness of by scanning entire file. - - - - - - - Doc: Change description "new master" to "new primary". (Bo Peng) - - - - - - - Fix newer version of gcc warnings. (Tatsuo Ishii) - - - - - - - Test: Update clean.sh which clean up regression test results. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Add .gitignore files. (Bo Peng) - - - Patch provided by Jesper Pedersen. - - - - - - - Fix segfault when node 0 is in down status in case of both health check - and are disabled. (Tatsuo Ishii) - - - - - - - Doc: Fix typos in documents and scripts. (Tatsuo Ishii) - - - Patch contributed by Jesper Pedersen. - - - - - - - Doc: Fix document mistakes of and . (Bo Peng) - - - - - + + - - Release 3.7.5 + + Regression Tests + - - Release Date - 2018-07-31 - + + + + Allow to define PGPOOLDIR using environment variable. + (bug 766) (Bo Peng) + + - - Bug fixes - - - - - - Allow not to use pool_passwd in raw mode. - (bug 411) (Tatsuo Ishii) - - - Since in raw there's only 1 backend is actually involved, there's no - need to use pool_passwd with md5 authentication. - - - - - - - Fix "write on backend 0 failed with error :"Success"" error. - (bug 403) (Tatsuo Ishii) - - - Don't treated it as an error if write() returns 0. - - - - - - - Fix for 0000409: worker process is not restarted after failover on standby Pgpool-II. - (bug 409) (Muhammad Usama) - - - Patch contributed by Yugo Nagata. - - - - - - - Fix for 0000406: failover called with wrong old-primary. - (bug 406) (Muhammad Usama) - - - - - - - Fixed that the health check process was not started after failed back. - (bug 407) (Tatsuo Ishii) - - - - - - - Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) - - - - - - - Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) - - - This led to a segfault issue mentioned on certain platform. - - - - - - - Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) - - - Patch provided by Christian Ehrhardt. - - - - - - - Fix for wrong backend roles on standby after the failover. (Muhammad Usama) - - - - - - - Doc: Improve documents of "MD5 Password Authentication", "Installing Pgpool-II" and "pg_md5".(Bo Peng) - - - Patch provided by Takuma Hoshiai. - - - - - - Test: Fix 006.memqcache test failure. (Tatsuo Ishii) - - - - + + - - Release 3.7.4 - + + Release 3.7.25 - Release Date - 2018-06-12 + Release Date + 2022-08-18 - - Bug fixes - - - - - Fix Pgpool-II hung if replication delay is too much, when query cache enabled in extended query mode. (Tatsuo Ishii) - - - See [pgpool-general-jp: 1534] - for more details. - - - - - - - Doc: Fix document typo of PCP commands option "-U". (Bo Peng) - - - - - - - Delete some debug code. (Bo Peng) - - - - - - - In extended query mode, do not set writing tx flag with SET TRANSACTION READ ONLY. (Tatsuo Ishii) - - - - - - - Fix wrong parameter %P (old primary node id) passed to failover script in 3.7.3 and 3.7.2. (Tatsuo Ishii) - - - - - - - Doc: Clarify that requires that health check is enabled. (Tatsuo Ishii) - - - - - - - Doc: Update outdated manual. (Tatsuo Ishii) - - - - - - - Test: Fix test.sh in extended_query_test. (Tatsuo Ishii) - - - - - - - Add missing health_check_timeout in pgpool_setup. (Tatsuo Ishii) - - - - - - - Doc: Enhance online recovery document to Clarify - that is only required in native replication mode. (Tatsuo Ishii) - - - - - - - Prevent from recovering "unused" status node. (Tatsuo Ishii) - - - This allowed to try to recovery a node without configuration data, - which leads to variety of problems. - - - See [pgpool-general: 5963] - for more details. - - - Also I fixed pgpool_recovery function so that it quotes an - empty string argument with double quotes. - - - - - - - - Release 3.7.3 - - - Release Date - 2018-04-17 - + + Bug fixes + - - Bug fixes - - + - Disable health check per node parameters by default. (Bo Peng) + Fix bug in query cache. (Tatsuo Ishii) - - - - - Fix hung when -g option is specified. (bug 391) (Tatsuo Ishii) + Pgpool-II did not cache the query like "Select '2022-02-18 07:00:00.006547'::timestamp". + SELECTs include TIMESTAMP, TIME and DATE are cached, and SELECTs include TIMESTAMPZ + and TIMEZ are not cached because the result can be changed by SET TIME ZONE command etc. + Furthermore, SELECTs having functions with return types are timestamptz or timetz are + not cached too as same reason. + Discussion: [pgpool-general: 8285] - + + + + - + + Documents + + + - Test: Add new regression test for node 0 is down. (Tatsuo Ishii) + Doc: mention that certain SELECTs are not cached. (Tatsuo Ishii) - - - - - Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + certain SELECTs are follows. + + + + SELECTs including TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including CAST to TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including SQLValueFunction (CURRENT_TIME, CURRENT_USER etc.) + + + - + - + - Fix pgpool child process segfault when ALWAYS_MASTER is on. (Tatsuo Ishii) - - - If following conditions are all met pgpool child segfaults: - - - - Streaming replication mode. + Doc: fix description about using PCP password file when connect to Unix domain socket (Masaya Kawamoto) - - - fail_over_on_backend_error is off. + The localhost entry in pcppass matches only for the default PCP socket + directory path, not all Unix socket connections. This behavior is the + same as pgpass. - - + + + + - ALWAYS_MASTER flag is set to the master (writer) node. + Doc: fix wrong explanation on , . (Tatsuo Ishii) - - - pgpool_status file indicates that the node mentioned in #3 is in down status. + Those parameters cannot be changed by reloading config file. Restarting + pgpool is required. + + Discussion: [pgpool-general: 8195] - - + + + + + + Regression Tests + + + + + + Test: print Pgpool-II version in the regression test. (Tatsuo Ishii) - + - + - Doc: Improve watchdog documents. (Tatsuo Ishii) + Test: Fix regression test script to look for pgpool.conf in the proper install directory. (Tatsuo Ishii) - + + + + + + + + + Release 3.7.24 + + Release Date + 2022-05-19 + - + + Changes + + - Doc: Add a document for adding new config parameter. (Tatsuo Ishii) + Enhance in stopping pgpool main process. (Tatsuo Ishii) - + + If "pgpool stop" couldn't terminate the main process within certain period (currently 5 seconds), send the signal again. + + - + - Test: Improve test script 003.failover. (Bo Peng) + Change the PID length of pcp_proc_count command to 7 characters long. (Bo Peng) - + - + - Deal with "unable to bind D cannot get parse message "S1" error. (Tatsuo Ishii) + Enhance error message to include the message kind returned and the backend node id while processing parse message. (Tatsuo Ishii) - + - + - Doc: Mention that users can avoid failover using backend_flag even PostgreSQL admin shutdown. (Tatsuo Ishii) + Downgrade log level of ParameterStatus message from LOG to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] - + - + - Doc: Fix document typos. (Bo Peng) + Change the default value of from '*' to 'localhost'. (Tatsuo Ishii) - + - + - Test: Add new regression test for node 0 not being primary. (Tatsuo Ishii) + Adjust the field name in . (Muhammad Usama) - + - + + + + + Bug fixes + + - Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) + Fix issue that watchdog cluster keeps rejecting the restarted remote node which is lost previously. (Muhammad Usama) - + + Issue report: [pgpool-general: 7896] + + - + - Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) + Fix main process exiting if a backend is failing or shutting down while performing finding primary. (Tatsuo Ishii) - + - + - Revert "Fix pgpool child process segfault when ALWAYS_MASTER is on." (Tatsuo Ishii) + Fix segfaults in watchdog. (Muhammad Usama) - With the commit, - write queries are always sent to node 0 even if the - primary node is not 0 because PRIMARY_NODE_ID macro returns - REAL_MASTER_NODE_ID, which is usually 0. Thus write queries are failed - with: - ERROR: cannot execute INSERT in a read-only transaction + Discussion: [pgpool-general: 8030] - + + + - + + Documents + + - Test: Enhance extended query test. (Tatsuo Ishii) + Doc: update the example output of . (Bo Peng) - + + + + - + + Regression Tests + + - Doc: Fix pgpool_adm family functions examples. (Tatsuo Ishii) + Improve regression test to detect segmentation fault. (Bo Peng) - - - + + + - - Release 3.7.2 - + + Release 3.7.23 - Release Date - 2018-02-13 - - - - This release fixed the bug with socket writing added in Pgpool-II 3.7.0, 3.6.6 and 3.5.10. Due to this bug, when the network load is high, an illegal message may be sent to the frontend or backend. All users using 3.7.x, 3.6.6 or later, 3.5.10 or later versions of Pgpool-II should update as soon as possible. - + Release Date + 2022-02-17 - - Changes - - + + Changes + + - Allow to build with libressl. (Tatsuo Ishii) + Suppress message length log for in_hot_standby. (Tatsuo Ishii) - See [pgpool-hackers: 2714] for more details. Patch by Sandino Araico Sanchez. + PostgreSQL 14 introduced new config parameter in_hot_standby. - - - - - Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) + The value is either "on" for standby servers or "off" for primary + servers. As a result pgpool log is flooded by the messages: - - TCP_NODELAY is employed by PostgreSQL, so do we it. - - - - + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + - Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + To avoid this, only complain if the parameter name is not in_hot_standby. - - - - - Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + Also the message is enhanced to show the parameter name. For example: - - - - - - - Bug fixes - + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + - - - Fix writing transaction flag is accidentally set at commit or rollback. (Tatsuo Ishii) + Discussion: [pgpool-hackers: 4076] - + - + - Throw a warning message when failover consensus settings on watchdog nodes differs. (Muhammad Usama) + Enhance parameter status handling. (Tatsuo Ishii) - + When a parameter status message arrives from backend Pgpool-II + forwards it to frontend not just memorize. - + - + + + + + Bug fixes + + + - Doc: Fix document typo. (Bo Peng) + Fix long standing bug with pcp_node_info. (Tatsuo Ishii) - + Discussion: [pgpool-hackers: 4109] - + - + - Fix bug with socket writing. (Tatsuo Ishii) + Fix health check process issues pointed out by Coverity. (Tatsuo Ishii) + + + + - pool_write_flush() is responsible for writing to sockets when pgpool's - write buffer is full (this function was introduced in 3.6.6 etc). When - network write buffer in kernel is full, it does retrying but it forgot - to update the internal buffer pointer. As a result, broken data is - written to the socket. This results in variety of problems including - too large message length. + Fix memory leak pointed out by Coverity. (Tatsuo Ishii) - + - + - Fix pgpool child process segfault when ALWAYS_MASTER is on. (Tatsuo Ishii) + Fix failover() to deal with the case when no former primary node exists. (Tatsuo Ishii) - If following conditions are all met pgpool child segfaults: - - - - Streaming replication mode. - - - - - fail_over_on_backend_error is off. - - - - - ALWAYS_MASTER flags is set to the master (writer) node. - - - - - pgpool_status file indicates that the node mentioned in #3 is in down status. - - - - - + In case Req_info->primary_node_id is -1 like no primary + node exists when Pgpool-II starts up, + failover() skipped to call + find_primary_node_repeatedly(). Also + follow_master_command was not executed. - See [pgpool-hackers: 2687] and [pgpool-general: 5881] for more details. + Discussion: [pgpool-hackers: 4113] - + - + - Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) + Fixed the streaming replication check process not to retry if it cannot connect to the backend.(bug 742) (Bo Peng) + + + This retry caused a long time failover. + - + + - + + Documents + + - Fix per node health check parameters types. (Tatsuo Ishii) + Add restriction regarding ParameterStatus and in_hot_standby parameter. (Tatsuo Ishii) - + - + - Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + Add restriction about set_config. (Tatsuo Ishii) - + - - - + + - - Release 3.7.1 + + Test tools + - - Release Date - 2018-01-09 - + + + + Fix pgpool_setup in failover script creation. (Tatsuo Ishii) + + + When pgpool_setup creates failover.sh, + it did not consider the case when no primary server existed. + + + + + - - Bug fixes - + + Regression tests + - + - Improve Makefiles. (Bo Peng) + Allow to run regression test against existing installation without recompiling. (Tatsuo Ishii) - Patch provided by Tomoaki Sato. + Discussion: [pgpool-hackers: 4077] - + - + - Doc: Fix document typo and mistakes. (Bo Peng) + Fix pgpool_setup and watchdog_setup binary PATH in noinstall mode. (Bo Peng) - + + + + + + + + Release 3.7.22 + + Release Date + 2021-12-23 + - + + Changes + + + - Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) + Suppress bison warnings regarding yacc incompatibility. (Tatsuo Ishii) - + - + - Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) + Fix redundant code. (Tatsuo Ishii) - Removeing "Type=forking" and add OPTS=" -n" to - run Pgpool-II with non-daemon mode, because we need to redirect logs. - Using "journalctl" command to see Pgpool-II systemd log. + Patch contributed by Lu Chenyang. - + - + + + + + Documents + + + - Add documentation "Compiling and installing documents" for SGML document build. (Tatsuo Ishii) + Doc: fix typo in pcp_watchdog_info manual. (Tatsuo Ishii) - + + + + + Doc: fix typos in release notes. (Bo Peng) - + + + + + + + + Release 3.7.21 + + Release Date + 2021-11-18 + - + + Security release + + - Fix per node health check parameters ignored. (bug 371) (Tatsuo Ishii) + Reject extraneous data after SSL encryption handshake. (Tatsuo Ishii) + + + In the server side implementation of SSL negotiation, it was possible for a + man-in-the-middle attacker to inject arbitrary SQL commands. This is + possible if Pgpool-II is configured to use cert authentication or + hostssl + trust. This resembles PostgreSQL's CVE-2021-23214. - Also is modified to add appropriate - per node health check parameters to pgpool.conf. + Similarly, in the client side implementation of SSL negotiation, it was + possible for a man-in-the-middle attacker to inject arbitrary responses. + This is possible if PostgreSQL is using trust authentication with a + clientcert requirement. It is not possible with cert authentication because + Pgpool-II does not implement the cert authentication between Pgpool-II + and PostgreSQL. This resembles PostgreSQL's CVE-2021-23222. - + + + - + + Changes + + + - Fix health checking process death and forking forever. (Tatsuo Ishii) + Deal with PostgreSQL 14 while processing + pg_terminate_backend(). (Tatsuo Ishii) - - When failed to read from backend socket (this could happen when wrong - health_check_user is specified), the health check process raises a - FATAL error in pool_read(), which causes death of health check - process. And Pgpool-II main forks off - a new health check process. This repeats forever. - - + - + - Fix timestamp data inconsistency by replication mode. (Bo Peng) + Enhance SIGCHLD handler of Pgpool-II main process. (Tatsuo Ishii) - From PostgreSQL10 the column - default value such as 'CURRENT_DATE' changes, - Pgpool-II didn't rewrite - timestamp by the added default values. - This caused data inconsistency. + When Pgpool-II child is killed by SIGKILL signal, + the SIGCHLD handler just emitted LOG level message as other signals. But + SIGKILL is an important event, for example killed by OOM killer. So emit a + WARNING level message instead. + Per suggestion from Michail Alexakis. + Discussion: [pgpool-general: 7750] - + + + + - + + Bug fixes + + + - Doc: Fix doc. (Tatsuo Ishii) + Fix occasional hang in COPY FROM. (Tatsuo Ishii) - It lacked to mention that it supports logical replication mode. + If an error occurs while doing COPY FROM, it was possible the + Pgpool-II waited forever for a response from + backend after COPY end marker was sent from frontend. + The bug was found by Bo Peng. - + - + - Downgrade a log message to debug message. (Tatsuo Ishii) + Fix the incorrect display of load balancing node in raw mode. (Bo Peng) - That was mistaken left while last development cycle. + In raw mode, Pgpool-II sends all queries to main node. + This is harmless, but it may confuse users. - + - + - Test: Add test data for bug 370. (Tatsuo Ishii) + Fix backend_flag* parameter shown twice while executing PGPOOL SHOW ALL. (Tatsuo Ishii) - - + + + + + + + Documents + + + - Fix for re-sync logic in reading packet from backend. (Tatsuo Ishii) + Fix documentation typos. (Bo Peng) - read_kind_from_backend(), which reads message kind - from backend, re-syncs backend nodes when a ready for query message is - received. Unfortunately it forgot to call - pool_pending_message_pull_out() to delete sync - pending message. This leads to random stuck while reading packets - from backend. Fix this to call pool_pending_message_pull_out(). + Patch is created by Kazufumi Noto. - + - + - Fix Pgpool-II hangs. (bug 370) (Tatsuo Ishii) + Doc: Mention that double quotes are required in PGPOOL SHOW command, + if the parameter contains uppercase letters. (Bo Peng) - - If an erroneous query is sent to primary and without a sync message - the next query that requires a catalog cache look up is send, - Pgpool-II hangs in do_query(). - - + + + + - + + Test tools + + + - Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + Fix pgpool_setup to do nothing when no new main node is available. (Tatsuo Ishii) - - We return primary or master node state of ready for query message to - frontend. In most cases this is good. However if other than primary - node or master node returns an error state (this could happen if load - balance node is other than primary or master node and the query is an - errornous SELECT), this should be returned to frontend, because the - frontend already received an error. - - + + + + - + + Regression tests + + + - Test: Fix bug with extended-query-test test driver. (Tatsuo Ishii) + Fix occasional 073.pg_terminate_backend regression test failure. (Tatsuo Ishii) - + - + - Doc: Enhance document "Running mode of Pgpool-II". (Tatsuo Ishii) + Fix psql command path to avoid test failure. (Bo Peng) - - - - + - - Release 3.7 + + + + + Release 3.7.20 - Release Date - 2017-11-22 + Release Date + 2021-08-05 - - Overview + + Changes + + + + - This version improves reliability of failover by using new - watchdog feature and per node health check. Also this version - adapts to changes in PostgreSQL 10: new SQL parser, logical - replication and some admin functions name changes. + Fix maximum length of hostnames including domain name. (Tatsuo Ishii) - Major enhancements in Pgpool-II 3.7 include: + The maximum length of hostnames was 128, but the correct value is 254. + Discussion: [pgpool-hackers: 3903] + - + + - + + Bug fixes + + + + + Fix query cache to not cache SQLValueFunctions. (Tatsuo Ishii) + + + The list of SQLValueFunctions is follow. + - - Quorum aware failover feature. - + + CURRENT_DATE + - - - Allow specifying the hostnames in pool_hba. - + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + - - - Allow to specify per node health check parameters. - + + SESSION_USER + - - - Support AWS Aurora. - + + USER + - - - Import PostgreSQL 10 SQL parser - + + CURRENT_CATALOG + - - Support logical replication. - + + CURRENT_SCHEMA + + + + - - + + + + Fix sending invalid message in SI mode. (Tatsuo Ishii) + + + When a query is aborted by specific reason like serialization error, + Pgpool-II sends error query to abort + transactions running on non main nodes. The message length of the + query was incorrect and it caused "invalid string in message" error on backend. + + - - Major Enhancements + + + + Fix watchdog communication race condition. (Tatsuo Ishii) + + + When watchdog notifies the new message to main process while main process + is executing the process notified by watchdog process, there was a + significant delay before the new message was processing. + Discussion: [pgpool-hackers: 3900] + + - - - - - Quorum and Consensus for backend failover. (Muhammad Usama) - - - Add ability in the Pgpool-II to considers the existence of - quorum and seek the majority node (Pgpool-II nodes part of - the watchdog cluster) consensus to validate the backend node - failover request. This feature helps make failover decision - better and prevent split brain scenarios. - + + + + Fix watchdog node status not updating after rebooting. + (bug 684) (Muhammad Usama) + + - - The addition of this feature also made some modification in - the execution behavior of the failover (failover, failback, - promote-node) command. - + + - - Now only the Master node performs the failover, and the failover - locks are removed. - + + Documents + - - Three new configuration parameters to configure the failover - behavior from user side: failover_when_quorum_exists, - failover_require_consensus, - enable_multiple_failover_requests_from_node. - - + + + + Doc: fix documentation typos. (Bo Peng) + + - - - - Allow specifying the hostnames in pool_hba. (Muhammad Usama) - - - The commit adds the support of hostnames to be used in the - address field of pool_hba records, previously only CIDR - address was supported. - + + + + Doc: fix typo in in memory query cache document. (Tatsuo Ishii) + + - - Along with allowing the hostnames in address field of the - HBA record the commit also made the following enhancements - in the area. - + + + + Doc: fix description (Masaya Kawamoto) + + - - (1) pool_hba records are now completely parsed at the - loading time and we now keep the structured data of records - instead of raw record lines, This saves the parsing at every - new connection time and however little it may be but its a - performance enhancement. - - - (2) Enhanced parsing now gives the better descriptive - error/log messages. - + + - - (3) Better handling of auth-options field. - - + + Test tools + - - - - Supporting per node health check parameters. (Tatsuo Ishii, - Muhammad Usama) - - - Previous implementation of health check is a single serial - processing for all of database nodes. - - - Now pgpool main process forks health check process for each - DB node. This commit enables all health-check related - parameter to be configured for each individual backend - nodes. - - - For example if we have 3 backend nodes and do following - configurations. - - -health_check_period = 10 -health_check_period0 = 5 - + + + + Fix rsync parameter in pgpool_setup. (Tatsuo Ishii) + + - - Then will set the health_check_period for node 0 to 5 while - node-id 1 and 2 will get the value 10 - - + + + + Fix pgpool_setup in creating base backup script. (Tatsuo Ishii) + + - - - - Import PostgreSQL 10 SQL parser. (Bo Peng) - - + + + + Enhance watchdog_setup script. (Tatsuo Ishii) + + + shutdownall script generated by watchdog_setup caused failover event which is not + necessary in the whole shutdown sequence. + + - - + + - - - - Support AWS Aurora. (Tatsuo Ishii) - - - Add new backend flag "ALWAYS_MASTER" to control the primary - node detecting logic. Since we cannot use - pg_is_in_recovery() in Aurora, we assign the new flag to a - backend which is specified as "writer" in Aurora. Since - Aurora always use the same hostname for the master (it's - called "writer"), find_primary_node() just returns the node - id which has ALWAYS_MASTER flag on. - - - See more details about ALWAYS_MASTER - flag . - + + Regression tests + + + + + + Fix 031.connection_life_time. (Tatsuo Ishii) + + + + + + + + + Release 3.7.19 + + Release Date + 2021-05-20 + + + + Bug fixes + + + + + Doc: fix description about . (Tatsuo Ishii) + + + It did not mention the parameter can only be used if Pgpool-II started as root. + + + + + + + Fix to create database cluster entity under pgpool0. (Tatsuo Ishii) + + + + + + + Fix pgpool crash when query cache enabled. + (bug 700) (Tatsuo Ishii) + + + Pgpool-II crashed upon receiving CloseComplete. This only happened in other than streaming and logical replication mode. + + + + + + + Fix that query cache is not created in other than streaming and logical replication mode. (Tatsuo Ishii) + + + + + + + Enhance debug message upon receiving startup packet. (Tatsuo Ishii) + + + + + + + Doc: enhance documentation. (Tatsuo Ishii, Bo Peng) + + + + + + + + Release 3.7.18 + + Release Date + 2021-02-18 + + + + Changes + + + + + Delete any pre-existing watchdog command socket file at startup. (Muhammad Usama) + + + Patch provided by Masaya Kawamoto. + + + + + + + Bug fixes + + + + + Fix the incorrect "weight" displayed in . (Tatsuo Ishii) + + + + + + + Fix watchdog leader sync process to start health check process. (Tatsuo Ishii) + + + + + + + Fix that DB cluster path was not correct in watchdog_setup installation. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup so that it creates separate archive directory for each DB node. (Tatsuo Ishii) + + + + + + + Fix error while allocating shared memory. (Tatsuo Ishii) + + + + + + + Fix bug is not respected if ERROR occurs. (Tatsuo Ishii) + + + + + + + Fix segfault that may occur when backend_flag = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER' or failover_command = ''. + (bug 672) (Tatsuo Ishii) + + + + + + + Doc: fix description. (Tatsuo Ishii) + + + + + + + + Release 3.7.17 + + Release Date + 2020-11-19 + + + + Changes + + + + + Doc: update "Aurora Configuration Example". (Bo Peng) + + + + + + + Doc: mention that GSSAPI is not supported. (Tatsuo Ishii) + + + + + + + Pgpool-II doesn't support GSSAPI. + Allow Pgpool-II to deal with GSSAPI encrypted connection request from frontend instead of responding with an error. (Tatsuo Ishii) + + + Patch is created by me, reviewed and tested by Umar Hayat. + + + + + + + Bug fixes + + + + + Fix query rewrite syntax error of "INSERT ... ON CONFLICT" in native replication mode. + (bug 654) (Bo Peng) + + + + + + + Fix connection counter was not counted down when query is canceled. + (bug 656) (Tatsuo Ishii) + + + + + + + Doc: fix usable versions of PostgreSQL to be 7.4 or later. (Tatsuo Ishii) + + + + + + + + Release 3.7.16 + + Release Date + 2020-09-17 + + + + Changes + + + + + Follow the guide line of PostgreSQL 12.4 regarding extensions. (Tatsuo Ishii) + + + CREATE OR REPLACE FUNCTION should be avoided. Use CREATE FUNCTION instead. + + + + + + + Replace "PGBIN" and "LPATH" in and using PostgreSQL's bin path and lib path. (Bo Peng) + + + + + + + Bug fixes + + + + + Doc: fix the incorrect description regarding the running modes of Pgpool-II in which online recovery is available. (Bo Peng) + + + + + + + Remove unnecessary checks in some code path. (Tatsuo Ishii) + + + Patch contributed by Hou, Zhijie. + + + + + + + Fix relcache query sometimes sent to other than primary. (Tatsuo Ishii) + + + In streaming replication mode, relcache queries are supposed to be + sent to the primary node. But actually they were not sent to the primary + node if primary node was not the master node. Typically this could + happen when the primary is not node 0. + + + + + + + Fix not working when is enabled. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] + + + + + + + Display more informative error message in authentication process. (Tatsuo Ishii) + + + + + + + Fix segfault in pgpool child process in certain case. (Tatsuo Ishii) + + + This issue can be reproduced with the following steps: + + + + Shutdown all backends. + + + + + Connect to pgpool with invalid client. I have used pcp_attach_node with pgpool's port number, not pcp's. + + + + + + + + + + + Release 3.7.15 + + Release Date + 2020-08-20 + + + + Changes + + + + + Doc: mention that only affects to TLS 1.2 and lower. (Tatsuo Ishii) + + + + + + + Doc: Improve the description of . (Bo Peng) + + + Patch is provided by Kenichiro Tanaka. + + + + + + + Add mention about hostssl/hostnossl to pool_hba.conf sample file. (Tatsuo Ishii) + + + + + + + Doc: documentation improvements. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + At pgpool startup, if pid file exists, truncate pid file to zero length before writing. (Bo Peng) + + + Patch is created by maliangzhu. + + + + + + + Doc: fix error in parameter description. (Bo Peng) + + + + + + + Fix does not work if primary node is not 0 in streaming replication mode. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup problem with -r option and PostgreSQL 12. (Tatsuo Ishii) + + + + + + + Change PCP UNIX_DOMAIN_PATH of RPM package to /var/run/postgresql. (Bo Peng) + + + + + + + Fix query cache bugs. (Tatsuo Ishii) + + + If query cache is enable, when a table is updated, Pgpool-II should delete all the caches related to the table. + However, EXPLAIN ANALYZE and CTE with data-modifying SQLs + were mistakenly treated as normal read only query so that the query caches were not deleted. + + + Patch is created by Hou, Zhijie and modified by Tatsuo Ishii. + + + + + + + Fix Pgpool-II hang in a corner case. (Tatsuo Ishii) + + + + + + + If there are parameters other than "user", "database" and "application_name", reading startup packet failed. (Tatsuo Ishii) + + + + + + + Fix miscount of connections when pg_terminate_backend() is executed. (Takuma Hoshiai) + + + + + + + Fix segmentation fault when application name is included in . (bug 615) (Tatsuo Ishii) + + + + + + + Fix incorrectly performing failover when pg_terminate_backend() is executed in native replication mode. (Takuma Hoshiai) + + + + + + + Fix 004.watchdog test crash on IBM Z hardware. (bug 614) (Tatsuo Ishii) + + + Patch is provided by gregn123, slightly modified by Tatsuo Ishii. + + + + + + + + Release 3.7.14 + + Release Date + 2020-05-21 + + + + Bug fixes + + + + + Fix build error on some system (Fedora 32). (Tatsuo Ishii) + + + + + + + Fix unnecessary checks. (Tatsuo Ishii) + + + Patch contributed by sherlockcpp. Discussion: [pgpool-general: 7004] + + + + + + + Doc: Fix typo. (Tatsuo Ishii) + + + Patch contributed by Umar Hayat. Discussion: [pgpool-hackers: 3587] + + + + + + + Fix for segmentation fault in PCP process. (bug 598) (Muhammad Usama) + + + + + + + Doc: Fix typo. (Tatsuo Ishii, Bo Peng) + + + Patch provided by sherlockcpp. + + + + + + + Fix Pgpool-II hangs when an Execute message is issued right after Sync message and query cache hits. (Tatsuo Ishii) + + + + + + + Fix problems in watchdog source code processing json data. (bug 596) (Tatsuo Ishii) + + + Patch is provided by Greg Nancarrow (Fujitsu Australia). + + + + + + + Fix possible data inconsistency in native replication mode. (Tatsuo Ishii) + + + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] + + + + + + + Fix watchdog ping probes fail with long hostnames due to small buffer. (bug 516) (Bo Peng) + + + + + + + + Release 3.7.13 + + Release Date + 2020-02-20 + + + + Changes + + + + + + Disallowing the quorum aware failover option for the native replication mode. (Muhammad Usama) + + + In native replication mode, Pgpool-II. is responsible for replicating the data + on all backend nodes, and if a node becomes quarantined then Pgpool-II stops + sending the writes to that node. This is dangerous since it can cause data inconsistency. + + + So as per the discussion, we reached the conclusion to disallow + with the native replication mode so that backend + node should never get into quarantine when Pgpool-II is configured in the replication mode. + + + + + + Check if socket file exists at startup and remove them if PID file doesn't exist to avoid bind() failure. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect query rewriting in native replication mode. + (bug 551) (Bo Peng) + + + + + + + Doc: Update documentation and fix documentation typos. (Takuma Hoshiai, Tatsuo Ishii, Bo Peng) + + + + + + Fix child process segfault after reload if is empty. + (bug 571) (Bo Peng) + + + + + + Fix to support PostgreSQL 12. (Tatsuo Ishii) + + + + + + Fix occasional regression test failure. (Tatsuo Ishii) + + + + + + Fix replication delay worker segfault when application_name in primary_conninfo is an empty string. + (bug 565) (Tatsuo Ishii) + + + + + + Fix command doesn't display ALWAYS_MASTER, + when = 'ALWAYS_MASTER'. (Takuma Hoshiai) + + + + + + Fix the bug with ignored syslog setting. (Bo Peng) + + + + + + + + Release 3.7.12 + + Release Date + 2019-10-31 + + + + Bug fixes + + + + + Fix incorrect query rewrite in replication mode. (Bo Peng) + + + + + + + Fix that health check timeout does work in certain case. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 3458], [pgpool-hackers: 3459] + + + + + + + Doc: add description when all standby nodes are down. (Takuma Hoshiai) + + + + + + + Doc: add note not to assign PostgreSQL servers to . (Tatsuo Ishii) + + + + + + + Fix for miscellaneous watchdog issues. (Muhammad Usama) + + + The lost nodes reported by life-check are treated as hard failures even when the node + is reachable from the watchdog core. + + + In the case of network partitioning or partial life-check failure, + the kicked out standby node was too aggressive in trying to connect + to the master or become a master itself so that potentially put the + unnecessary burden on the network and the cluster nodes. + Fix is to make the isolated node a bit calm and wait between trying to connect to + master or become a master. + + + See details: + (bug 547), + [pgpool-general: 6672] + + + + + + + Fix assorted ancient v2 protocol bugs. (Tatsuo Ishii) + + + + + + + Fix problem that doesn't change by reload. + (bug 548) (Takuma Hoshiai) + + + + + + + Fix Pgpool-II shutdown failed in certain case. (Tatsuo Ishii) + + + + + + + Allow the lost standby node to rejoin the master watchdog node when it gets rediscovered by the lifecheck. + (bug 545) (Muhammad Usama) + + + + + + + Overhaul health check debug facility. (Tatsuo Ishii) + + + + + + + Fix segfault when executing an erroneous query after DEALLOCATE a named statement. + (bug 546) (Tatsuo Ishii) + + + + + + + Doc: mention that VIP will not be brought up if quorum does not exist. (Tatsuo Ishii) + + + + + + + + + + Add "-I" option to command default setting. (Bo Peng) + + + + + + + + Release 3.7.11 + + Release Date + 2019-08-15 + + + Enhancements + + + + + Import some of memory manager debug facilities from PostgreSQL. (Tatsuo Ishii) + + + + + + Use pg_get_expr() instead of pg_attrdef.adsrc to support for PostgreSQL 12. (Bo Peng) + + + + + + + Enhance shutdown script of . (Tatsuo Ishii) + + - Other than that, user can use the streaming replication mode - with Aurora. Notice that replication delay cannot be - performed in Aurora, sr_check_period should be always 0. + Make shutdownall to wait for completion of shutdown of Pgpool-II. + + - Also add English/Japanese Aurora setting example. + If environment variable CHECK_TIME_WAIT is set to true, use netstat command to confirm usage of the TCP/IP port while executing shutdown script. + + + + + + + + + Doc: add description to man page how to show pool_passwd hashed string. (Tatsuo Ishii) + + + + + + + Doc: add general description about failover. (Tatsuo Ishii) + + + + + + Deal pgpool_adm extension with PostgreSQL 12. (Tatsuo Ishii) + + + + + + + + + + Bug fixes + + + + + + Fix "unable to bind. cannot get parse message" error. + (bug 531) (Tatsuo Ishii) + + + + + + + Fix online-recovery is blocked after a child process exits abnormally with replication mode and watchdog. + (bug 483) (Muhammad Usama) + + + + + + + Fix for keep the backend health check running on quarantined nodes. (Muhammad Usama) + + + Pgpool should keep the backend health check running on quarantined nodes so + that when the connectivity resumes, they should automatically get removed + from the quarantine. + + + See [pgpool-hackers: 3295] for more details. + + + + + + + Fix for no primary on standby pgpool when primary is quarantined on master. (Muhammad Usama) + + + Master watchdog Pgpool sends the backend status sync message if the primary node is quarantined on it. + So standby watchdog pgpool must not update its status when the status of current primary node + is not DOWN. + + + + + + + Fix command mode option to work correctly. (Takuma Hoshiai) + + + + + + + Fix to produce correct follow master command. (Tatsuo Ishii) + + + + + + + Fix query cache module so that it checks oid array's bound. (Tatsuo Ishii) + + + + + + + Fix off-by-one error in query cache module. (Tatsuo Ishii) + + + + + + + Allow health check process to reload. (Tatsuo Ishii) + + + + + + + Fix segfault when query cache is enabled. (bug 525) (Tatsuo Ishii) + + + + + + + Down grade LOG "checking zapping sent message ..." to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 6620] + + + + + + + Fix segfault when samenet is specified in pool_hba.conf. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 6601]. + + + + + + + Doc: Fix documentation mistakes in follow_master.sh script and typos. (Bo Peng) + + + + + + + Fix health check process is not shutting down in certain cases. (Tatsuo Ishii) + + + + + + + Fix to deal with backslashes according to the config of standard_conforming_strings in native replication mode. + (bug 467) (Bo Peng) + + + + + + + Fix compile error on FreeBSD. + (bug 512, + bug 519) (Bo Peng) + + + + + + + Fix memory leaks. (Tatsuo Ishii) + + + + + + + Make failover in progress check more aggressively to avoid potential segfault. (Tatsuo Ishii) + + + + + + + + + Release 3.7.10 + + Release Date + 2019-05-16 + + + + Enhancements + + + + + Doc: Improve document. (Tatsuo Ishii) + + + + + + + Speed up failover when all of backends are down. (Tatsuo Ishii) + + + If all of the backend are in down status, immediately give up finding + primary node regardless search_primary_node_timeout and promptly + finish the failover process. + + + Discussion: [pgpool-hackers: 3321] + + + + + + + pgpool-recovery extension and pgpool_setup is now ready for the next major release PostgreSQL 12. (Tatsuo Ishii) + + + + + + Doc: add entry. (Takuma Hoshiai) + + + + + + + Bug fixes + + + + + Fix the wrong error message "ERROR: connection cache is full", when all backend nodes are down. + (bug 487) (Bo Peng) + + + When all backend nodes are down, Pgpool-II throws an incorrect + error message "ERROR: connection cache is full". Change the error + message to "all backend nodes are down, pgpool requires at least one valid node". + + + + + + + Remove unused .sgml file. (Takuma Hoshiai) + + + + + + + Avoid exit/fork storm of pool_worker_child process. (Tatsuo Ishii) + + + pool_worker_child issues query to get WAL position using do_query(), + which could throws FATAL error. In this case pool_worker_child process + exits and Pgpool-II parent immediately forks new process. This cycle + indefinitely repeats and gives high load to the system. + To avoid the exit/fork storm, sleep sr_check_period. + + + + + + + Fix 's broken default value. (Tatsuo Ishii) + + + + + + + Fix "not enough space in buffer" error. + (bug 499) (Tatsuo Ishii) + + + The error occurred while processing error message returned from + backend and the cause is that the query string in question is too + big. Problem is, the buffer is in fixed size (8192 bytes). + Eliminate the fixed size buffer and use palloced buffer + instead. This also saves some memory copy work. + + + + + + + Fix DROP DATABASE failure. (Tatsuo Ishii) + + + + + + + Fix wrong variable in read_status_file() function. + (bug 493) (Takuma Hoshiai) + + + + + + + Add missing test/watchdog_setup to EXTRA_DIST. (bug 470) (Bo Peng) + + + + + + + Doc: mention that multi-statement queries are sent to primary node only. (bug 492) (Tatsuo Ishii) + + + + + + + Test: Fix occasional regression test failure of 014.watchdog_test_quorum_bypass. (Tatsuo Ishii) + + + + + + + Abort session if failover/failback is ongoing to prevent potential segfault. + (bug 481, + bug 482) (Tatsuo Ishii) + + + + + + + Fix compiler warnings. (Tatsuo Ishii) + + + + + + + Fix memory leak in "batch" mode in extended query. + (bug 468) (Tatsuo Ishii) + + + + + + + + Release 3.7.9 + + Release Date + 2019-03-29 + + + + Enhancements + + + + + Add new configuration option . (Muhammad Usama) + + + Add the new setting to let users configure if they + want client's or server's cipher order to take preference. + + + The default for this parameter is off, which prioritize the client's + cipher order as usual. However this is just for keeping backward + compatibility, and it is possible that a malicious client uses weak + ciphers. For this reason we recommend to set this parameter to on at + all times. + + + + + + + Allow to set a client cipher list. (Tatsuo Ishii, Yugo Nagata) + + + For this purpose new parameter , which specifies the cipher + list to be accepted by Pgpool-II, is added. + This is already implemented in PostgreSQL and useful to enhance security when SSL is enabled. + + + + + + + Bug fixes + + + + + Fix unnecessary fsync() to pgpool_status file. (Tatsuo Ishii) + + + Whenever new connections are created to PostgreSQL backend, fsync() + was issued to pgpool_status file, which could generate excessive I/O + in certain conditions. + So reduce the chance of issuing fsync() so that it is issued only when + backend status is changed. + + + Discussion: [pgpool-general: 6436] + + + + + + + + Release 3.7.8 + + Release Date + 2019-02-21 + + + + Bug fixes + + + + + Test: Fix old JDBC functions and typos in regression test 068.memqcache_bug. (Takuma Hoshiai) + + + + + + + Doc: Fix configuration change timing regarding . (Tatsuo Ishii) + + + + + + + Fix online recovery failed due to in certain cases. + (bug 431) (Tatsuo Ishii) + + + + + + + Reduce memory usage when large data set is returned from backend. + (bug 462) (Tatsuo Ishii) + + + + + + + Test: Fix syntax error in extended query test script. (Tatsuo Ishii) + + + + + + + Fix corner case bug when strip_quote() handle a empty query string. (bug 458) (Tatsuo Ishii) + + + + + + + Doc: Mention that schema qualifications cannot be used in white/black_function_list. (Tatsuo Ishii) + + + + + + + Fix typo about wd_priority in watchdog_setup. (Takuma Hoshiai) + + + + + + + Fix Pgpool child segfault if failover occurs when trying to establish a connection. (Tatsuo Ishii) + + + + + + + Doc: fix typo in logdir description. (bug 453) (Tatsuo Ishii) + + + + + + + Fix Pgpool-II hang if a client sends a extended query message such as close after sync message but before next simple query. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 3164] + + + + + + + Fix Pgpool-II hang when idle_in_transaction_session_timeout = on. (bug 448) (Tatsuo Ishii) + + + + + + Doc: Fix Japanese document typo in . (Bo Peng) + + + + + + + + Release 3.7.7 + + Release Date + 2018-11-22 + + + + Bug fixes + + + + + + + Fix to sort startup packet's parameters sent by client. + (bug 444)(Takuma Hoshiai) + + + If order of startup packet's parameters differ between cached connection + pools and connection request, didn't use connection pool ,and created new + connection pool. + + + + + + + + Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. + (bug 443)(Bo Peng) + + + If the number of parameter format codes is specified to one, but the number + of the original query's parameter is zero, bind_rewrite_timestamp() will call memcpy with a negative value. + This causes segmentation fault. + + + Patch is provided by Yugo Nagata. + + + + + + + + Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + + + + + + Fix segfault in extended query + query cache case. (Tatsuo Ishii) + + + + + + + Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + + + + + + + + Release 3.7.6 + + + Release Date + 2018-10-31 + + + + Changes + + + + + Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) + + + + + + + Change pgpool.spec file to install extension to DB server which supports LLVM JIT. (Bo Peng) + + + + + + + Doc: Add note to online recovery doc. (Tatsuo Ishii) + + + This warns that must be smaller than . + + + + + + + Test: Add regression test for SSL connection. (Tatsuo Ishii) + + + + + + + Doc: Add notes regarding failover script. (Tatsuo Ishii) + + + It's not recommended to access against Pgpool-II itself from failover/failback scripts. + + + + + + + Doc: Improve docs and error message. (Bo Peng) + + + Patch provided by Jesper Pedersen and modified by me. + + + + + + + Test: Add definition of PGLIB in regress.sh. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + + Bug fixes + + + + + Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) + + + Patch provided by Phil Ramirez. + + + + + + + Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) + + + In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. + + + + + + + Fix syntax error when queries including time functions and IN (SELECT ...) in + WHERE clause in native replication mode. + (bug 433) (Bo Peng) + + + In native replication mode, queries including time functions (e.g. now(), CURRENT_TIMESTAMP etc.) are rewritten to a timestamp constant value. + However, Pgpool-II doesn't support queries including time functions and IN (SELECT ...) in WHERE clause. + + + + + + + Fix occasional less data returned to frontend with extended protocol. (bug432) (Tatsuo Ishii) + + + The idea for fix is, use pending message data list. It records + messages from frontend, and it is expected that we will receive same + number of messages. + + + Initial patch is created by Yugo Nagata and fixed by Tatsuo Ishii. + + + + + + + Fix memory leak when query cache enabled in streaming replication mode + extended query case. (Tatsuo Ishii) + + + + + + + Fix memory leak in trigger_failover_command(). (Tatsuo Ishii) + + + + + + + Fix memory leak when memory_cache_enabled = on and write SQLs are sent. (Bo Peng) + + + In a explicit transaction, the SELECT results are cached in temporary buffer. + If a write SQL is sent which modifies the table, the temporary buffer should be reset. + + + + + + + Test: Fix occasional failure in regression 065.bug152. (Tatsuo Ishii) + + + + + + + Test: Add EXECUTE/DEALLOCATE regression test. (Takuma Hoshiai) + + + + + + + Add missing pgpool_recovery--1.0--1.1.sql file to update + pgpool_recovery() function version to 1.1. (Bo Peng) + + + + + + + Fix kind mismatch error when DEALLOCATE statement is issued. (Bo Peng) + + + PREPARE should be add to pool_add_sent_message, + so that EXECUTE and DEALLOCATE + can be sent to the same node as PREPARE. + + + See [pgpool-general: 6226] for more details. + + + + + + + Do not update if the password length is incorrect. + (bug 419) (Takuma Hoshiai, Tatsuo Ishii) + + + For Pgpool-II 3.7 or before, the password stored in + is MD5 password only. + So check the correctness of by scanning entire file. + + + + + + + Doc: Change description "new master" to "new primary". (Bo Peng) + + + + + + + Fix newer version of gcc warnings. (Tatsuo Ishii) + + + + + + + Test: Update clean.sh which clean up regression test results. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Add .gitignore files. (Bo Peng) + + + Patch provided by Jesper Pedersen. + + + + + + + Fix segfault when node 0 is in down status in case of both health check + and are disabled. (Tatsuo Ishii) + + + + + + + Doc: Fix typos in documents and scripts. (Tatsuo Ishii) + + + Patch contributed by Jesper Pedersen. + + + + + + + Doc: Fix document mistakes of and . (Bo Peng) + + + + + + + + + Release 3.7.5 + + + Release Date + 2018-07-31 + + + + Bug fixes + + + + + + Allow not to use pool_passwd in raw mode. + (bug 411) (Tatsuo Ishii) + + + Since in raw there's only 1 backend is actually involved, there's no + need to use pool_passwd with md5 authentication. + + + + + + + Fix "write on backend 0 failed with error :"Success"" error. + (bug 403) (Tatsuo Ishii) + + + Don't treated it as an error if write() returns 0. + + + + + + + Fix for 0000409: worker process is not restarted after failover on standby Pgpool-II. + (bug 409) (Muhammad Usama) + + + Patch contributed by Yugo Nagata. + + + + + + + Fix for 0000406: failover called with wrong old-primary. + (bug 406) (Muhammad Usama) + + + + + + + Fixed that the health check process was not started after failed back. + (bug 407) (Tatsuo Ishii) + + + + + + + Fix memory leaks related to pool_extract_error_message(). (Tatsuo Ishii) + + + + + + + Fix an incorrect declare as bool, rather than int in pool_extract_error_message(). (Tatsuo Ishii) + + + This led to a segfault issue mentioned on certain platform. + + + + + + + Fix segfault in per_node_error_log() on armhf architecture. (Tatsuo Ishii) + + + Patch provided by Christian Ehrhardt. + + + + + + + Fix for wrong backend roles on standby after the failover. (Muhammad Usama) + + + + + + + Doc: Improve documents of "MD5 Password Authentication", "Installing Pgpool-II" and "pg_md5".(Bo Peng) + + + Patch provided by Takuma Hoshiai. + + + + + + Test: Fix 006.memqcache test failure. (Tatsuo Ishii) + + + + + + + + Release 3.7.4 + + + Release Date + 2018-06-12 + + + + Bug fixes + + + + + Fix Pgpool-II hung if replication delay is too much, when query cache enabled in extended query mode. (Tatsuo Ishii) + + + See [pgpool-general-jp: 1534] + for more details. + + + + + + + Doc: Fix document typo of PCP commands option "-U". (Bo Peng) + + + + + + + Delete some debug code. (Bo Peng) + + + + + + + In extended query mode, do not set writing tx flag with SET TRANSACTION READ ONLY. (Tatsuo Ishii) + + + + + + + Fix wrong parameter %P (old primary node id) passed to failover script in 3.7.3 and 3.7.2. (Tatsuo Ishii) + + + + + + + Doc: Clarify that requires that health check is enabled. (Tatsuo Ishii) + + + + + + + Doc: Update outdated manual. (Tatsuo Ishii) + + + + + + + Test: Fix test.sh in extended_query_test. (Tatsuo Ishii) + + + + + + + Add missing health_check_timeout in pgpool_setup. (Tatsuo Ishii) + + + + + + + Doc: Enhance online recovery document to Clarify + that is only required in native replication mode. (Tatsuo Ishii) + + + + + + + Prevent from recovering "unused" status node. (Tatsuo Ishii) + + + This allowed to try to recovery a node without configuration data, + which leads to variety of problems. + + + See [pgpool-general: 5963] + for more details. + + + Also I fixed pgpool_recovery function so that it quotes an + empty string argument with double quotes. + + + + + + + + Release 3.7.3 + + + Release Date + 2018-04-17 + + + + Bug fixes + + + + + Disable health check per node parameters by default. (Bo Peng) + + + + + + + Fix hung when -g option is specified. (bug 391) (Tatsuo Ishii) + + + + + + + Test: Add new regression test for node 0 is down. (Tatsuo Ishii) + + + + + + + Make calls to to_regclass fully schema qualified. (Tatsuo Ishii) + + + + + + + Fix pgpool child process segfault when ALWAYS_MASTER is on. (Tatsuo Ishii) + + + If following conditions are all met pgpool child segfaults: + + + + Streaming replication mode. + + + + + fail_over_on_backend_error is off. + + + + + ALWAYS_MASTER flag is set to the master (writer) node. + + + + + pgpool_status file indicates that the node mentioned in #3 is in down status. + + + + + + + + + + + Doc: Improve watchdog documents. (Tatsuo Ishii) + + + + + + + Doc: Add a document for adding new config parameter. (Tatsuo Ishii) + + + + + + + Test: Improve test script 003.failover. (Bo Peng) + + + + + + + Deal with "unable to bind D cannot get parse message "S1" error. (Tatsuo Ishii) + + + + + + + Doc: Mention that users can avoid failover using backend_flag even PostgreSQL admin shutdown. (Tatsuo Ishii) + + + + + + + Doc: Fix document typos. (Bo Peng) + + + + + + + Test: Add new regression test for node 0 not being primary. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup failure in replication mode. (Tatsuo Ishii) + + + + + + + Allow to support pgpool_switch_xlog PostgreSQL 10. (Tatsuo Ishii) + + + + + + + Revert "Fix pgpool child process segfault when ALWAYS_MASTER is on." (Tatsuo Ishii) + + + With the commit, + write queries are always sent to node 0 even if the + primary node is not 0 because PRIMARY_NODE_ID macro returns + REAL_MASTER_NODE_ID, which is usually 0. Thus write queries are failed + with: + ERROR: cannot execute INSERT in a read-only transaction + + + + + + + Test: Enhance extended query test. (Tatsuo Ishii) + + + + + + + Doc: Fix pgpool_adm family functions examples. (Tatsuo Ishii) + + + + + + + + Release 3.7.2 + + + Release Date + 2018-02-13 + + + + This release fixed the bug with socket writing added in Pgpool-II 3.7.0, 3.6.6 and 3.5.10. Due to this bug, when the network load is high, an illegal message may be sent to the frontend or backend. All users using 3.7.x, 3.6.6 or later, 3.5.10 or later versions of Pgpool-II should update as soon as possible. + + + + + Changes + + + + + Allow to build with libressl. (Tatsuo Ishii) + + + See [pgpool-hackers: 2714] for more details. Patch by Sandino Araico Sanchez. + + + + + + + Set TCP_NODELAY and non blocking to frontend socket. (Tatsuo Ishii) + + + TCP_NODELAY is employed by PostgreSQL, so do we it. + + + + + + + Change systemd service file to use STOP_OPTS=" -m fast". (Bo Peng) + + + + + + + Change pgpool_setup to add restore_command in recovery.conf. (Bo Peng) + + + + + + + + + Bug fixes + + + + + + Fix writing transaction flag is accidentally set at commit or rollback. (Tatsuo Ishii) + + + + + + + Throw a warning message when failover consensus settings on watchdog nodes differs. (Muhammad Usama) + + + + + + + + + + Doc: Fix document typo. (Bo Peng) + + + + + + + + + + Fix bug with socket writing. (Tatsuo Ishii) + + + pool_write_flush() is responsible for writing to sockets when pgpool's + write buffer is full (this function was introduced in 3.6.6 etc). When + network write buffer in kernel is full, it does retrying but it forgot + to update the internal buffer pointer. As a result, broken data is + written to the socket. This results in variety of problems including + too large message length. + + + + + + + Fix pgpool child process segfault when ALWAYS_MASTER is on. (Tatsuo Ishii) + + + If following conditions are all met pgpool child segfaults: + + + + Streaming replication mode. + + + + + fail_over_on_backend_error is off. + + + + + ALWAYS_MASTER flags is set to the master (writer) node. + + + + + pgpool_status file indicates that the node mentioned in #3 is in down status. + + + + + + + See [pgpool-hackers: 2687] and [pgpool-general: 5881] for more details. + + + + + + + Fix segfault when %a is in log_line_prefix and debug message is on. (bug 376) (Tatsuo Ishii) + + + + + + + + Fix per node health check parameters types. (Tatsuo Ishii) + + + + + + + Fix queries hanging in parse_before_bind with extended protocol and replication + load-balancing. (bug 377) (Tatsuo Ishii) + + + + + + + + + Release 3.7.1 + + + Release Date + 2018-01-09 + + + + Bug fixes + + + + + + Improve Makefiles. (Bo Peng) + + + Patch provided by Tomoaki Sato. + + + + + + + Doc: Fix document typo and mistakes. (Bo Peng) + + + + + + + Replace /bin/ed with /bin/sed in , because /bin/sed is included in most distribution's base packages. (Tatsuo Ishii) + + + + + + + Change the pgpool.service and sysconfig files to output Pgpool-II log. (Bo Peng) + + + Removing "Type=forking" and add OPTS=" -n" to + run Pgpool-II with non-daemon mode, because we need to redirect logs. + Using "journalctl" command to see Pgpool-II systemd log. + + + + + + + Add documentation "Compiling and installing documents" for SGML document build. (Tatsuo Ishii) + + + + + - - - - Support logical replication. (Tatsuo Ishii) - - - The logical replication mode can be used - with PostgreSQL servers operating - logical replication. In this - mode, PostgreSQL is responsible - for synchronizing tables. - - - Load balancing is possible in the mode. Since logical - replication does not replicate all tables, it's user's - responsibility to replicate the table which could be load - balanced. - - - The sample configuration file - is $prefix/etc/pgpool.conf.sample-logical. - - - And add support for logical replication mode - to pgpool_setup. - - + + + + Fix per node health check parameters ignored. (bug 371) (Tatsuo Ishii) + + + Also is modified to add appropriate + per node health check parameters to pgpool.conf. + + - - + + + + Fix health checking process death and forking forever. (Tatsuo Ishii) + + + When failed to read from backend socket (this could happen when wrong + health_check_user is specified), the health check process raises a + FATAL error in pool_read(), which causes death of health check + process. And Pgpool-II main forks off + a new health check process. This repeats forever. + + - - Other Enhancements - - - - - Test: Add some watchdog test cases. (Muhammad Usama) - - + + + + Fix timestamp data inconsistency by replication mode. (Bo Peng) + + + From PostgreSQL10 the column + default value such as 'CURRENT_DATE' changes, + Pgpool-II didn't rewrite + timestamp by the added default values. + This caused data inconsistency. + + + + + + + Doc: Fix doc. (Tatsuo Ishii) + + + It lacked to mention that it supports logical replication mode. + + + + + + + Downgrade a log message to debug message. (Tatsuo Ishii) + + + That was mistaken left while last development cycle. + + + + + + + Test: Add test data for bug 370. (Tatsuo Ishii) + + + + + + + Fix for re-sync logic in reading packet from backend. (Tatsuo Ishii) + + + read_kind_from_backend(), which reads message kind + from backend, re-syncs backend nodes when a ready for query message is + received. Unfortunately it forgot to call + pool_pending_message_pull_out() to delete sync + pending message. This leads to random stuck while reading packets + from backend. Fix this to call pool_pending_message_pull_out(). + + + + + + + Fix Pgpool-II hangs. (bug 370) (Tatsuo Ishii) + + + If an erroneous query is sent to primary and without a sync message + the next query that requires a catalog cache look up is send, + Pgpool-II hangs in do_query(). + + + + + + + Fix returning transaction state when "ready for query" message received. (Tatsuo Ishii) + + + We return primary or master node state of ready for query message to + frontend. In most cases this is good. However if other than primary + node or master node returns an error state (this could happen if load + balance node is other than primary or master node and the query is an + erroneous SELECT), this should be returned to frontend, because the + frontend already received an error. + + + + + + + Test: Fix bug with extended-query-test test driver. (Tatsuo Ishii) + + + + + + + Doc: Enhance document "Running mode of Pgpool-II". (Tatsuo Ishii) + + + + + + + + Release 3.7 + + + Release Date + 2017-11-22 + + + + Overview + + This version improves reliability of failover by using new + watchdog feature and per node health check. Also this version + adapts to changes in PostgreSQL 10: new SQL parser, logical + replication and some admin functions name changes. + + + Major enhancements in Pgpool-II 3.7 include: + + + + + + + + + Quorum aware failover feature. + + + + + + Allow specifying the hostnames in pool_hba. + + + + + + Allow to specify per node health check parameters. + + + + + + Support AWS Aurora. + + + + + + Import PostgreSQL 10 SQL parser + + + + + Support logical replication. + + + + + + + + Major Enhancements + + + + + + Quorum and Consensus for backend failover. (Muhammad Usama) + + + Add ability in the Pgpool-II to considers the existence of + quorum and seek the majority node (Pgpool-II nodes part of + the watchdog cluster) consensus to validate the backend node + failover request. This feature helps make failover decision + better and prevent split brain scenarios. + + + + The addition of this feature also made some modification in + the execution behavior of the failover (failover, failback, + promote-node) command. + + + + Now only the Master node performs the failover, and the failover + locks are removed. + + + + Three new configuration parameters to configure the failover + behavior from user side: failover_when_quorum_exists, + failover_require_consensus, + enable_multiple_failover_requests_from_node. + + + + + + + Allow specifying the hostnames in pool_hba. (Muhammad Usama) + + + The commit adds the support of hostnames to be used in the + address field of pool_hba records, previously only CIDR + address was supported. + + + + Along with allowing the hostnames in address field of the + HBA record the commit also made the following enhancements + in the area. + + + + (1) pool_hba records are now completely parsed at the + loading time and we now keep the structured data of records + instead of raw record lines, This saves the parsing at every + new connection time and however little it may be but its a + performance enhancement. + + + (2) Enhanced parsing now gives the better descriptive + error/log messages. + + + + (3) Better handling of auth-options field. + + + + + + + Supporting per node health check parameters. (Tatsuo Ishii, + Muhammad Usama) + + + Previous implementation of health check is a single serial + processing for all of database nodes. + + + Now pgpool main process forks health check process for each + DB node. This commit enables all health-check related + parameter to be configured for each individual backend + nodes. + + + For example if we have 3 backend nodes and do following + configurations. + + + health_check_period = 10 + health_check_period0 = 5 + + + + Then will set the health_check_period for node 0 to 5 while + node-id 1 and 2 will get the value 10 + + + + + + + Import PostgreSQL 10 SQL parser. (Bo Peng) + + + + + + + + + + Support AWS Aurora. (Tatsuo Ishii) + + + Add new backend flag "ALWAYS_MASTER" to control the primary + node detecting logic. Since we cannot use + pg_is_in_recovery() in Aurora, we assign the new flag to a + backend which is specified as "writer" in Aurora. Since + Aurora always use the same hostname for the master (it's + called "writer"), find_primary_node() just returns the node + id which has ALWAYS_MASTER flag on. + + + See more details about ALWAYS_MASTER + flag . + + + Other than that, user can use the streaming replication mode + with Aurora. Notice that replication delay cannot be + performed in Aurora, sr_check_period should be always 0. + + + Also add English/Japanese Aurora setting example. + + + + + + + Support logical replication. (Tatsuo Ishii) + + + The logical replication mode can be used + with PostgreSQL servers operating + logical replication. In this + mode, PostgreSQL is responsible + for synchronizing tables. + + + Load balancing is possible in the mode. Since logical + replication does not replicate all tables, it's user's + responsibility to replicate the table which could be load + balanced. + + + The sample configuration file + is $prefix/etc/pgpool.conf.sample-logical. + + + And add support for logical replication mode + to pgpool_setup. + + + + + + + + Other Enhancements + + + + + Test: Add some watchdog test cases. (Muhammad Usama) + + - - - - Test: Add new test case "node_js.data" to extended-query-test. (Tatsuo Ishii) - - + + + + Test: Add new test case "node_js.data" to extended-query-test. (Tatsuo Ishii) + + - - - - Doc: Documentation updates for pool_hba enhancements. (Muhammad Usama) - - + + + + Doc: Documentation updates for pool_hba enhancements. (Muhammad Usama) + + - - - - Add "slony mode" to pgpool_setup. (Tatsuo Ishii) - - - - - - Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) - - + + + + Add "slony mode" to pgpool_setup. (Tatsuo Ishii) + + + + + + Deal with OpenSSL 1.1. (Tatsuo Ishii, Muhammad Usama) + + - - - - Test: Add new regression test "069.memory_leak_extended". (Tatsuo Ishii) - - + + + + Test: Add new regression test "069.memory_leak_extended". (Tatsuo Ishii) + + - - - - Doc: Enhance query cache documents. (Tatsuo Ishii) - - - - - - Doc: Add "Tips for Installation" section. (Tatsuo Ishii) - - + + + + Doc: Enhance query cache documents. (Tatsuo Ishii) + + + + + + Doc: Add "Tips for Installation" section. (Tatsuo Ishii) + + - - - - Test: Add new test 011.watchdoc_quorum_failover. (Tatsuo Ishii) - - + + + + Test: Add new test 011.watchdog_quorum_failover. (Tatsuo Ishii) + + - - - - Test: Add new test suits. (Tatsuo Ishii) - - - The new test suit "extended-query-test" is intended to test extended - queries using pgproto command. - - + + + + Test: Add new test suits. (Tatsuo Ishii) + + + The new test suit "extended-query-test" is intended to test extended + queries using pgproto command. + + - - - - Add debugging aid to check pending message and backend - response. (Tatsuo Ishii) - - - New function pool_check_pending_message_and_reply() added. - If pending message kind and backend reply message kind is - not inconsistent, it prints a debug message. Currently the - only client of the function is read_kind_from_backend(). - - + + + + Add debugging aid to check pending message and backend + response. (Tatsuo Ishii) + + + New function pool_check_pending_message_and_reply() added. + If pending message kind and backend reply message kind is + not inconsistent, it prints a debug message. Currently the + only client of the function is read_kind_from_backend(). + + - - - - Add debugging/testing aid for health check. (Tatsuo Ishii) - - + + + + Add debugging/testing aid for health check. (Tatsuo Ishii) + + - - + + - - Changes - - - - - Add "role" field to pcp_node_info command. (Tatsuo Ishii) - - - Role is the server role: one of "primary", "standby", - "master" or "slave". - - - - - - Change master_slave_sub_mode default to 'stream'. (Tatsuo Ishii) - - - This is necessary since the default value for the - pool_config_variable.c is STREAM_MODE. - - + + Changes + + + + + Add "role" field to pcp_node_info command. (Tatsuo Ishii) + + + Role is the server role: one of "primary", "standby", + "master" or "slave". + + + + + + Change master_slave_sub_mode default to 'stream'. (Tatsuo Ishii) + + + This is necessary since the default value for the + pool_config_variable.c is STREAM_MODE. + + - - - - Allow to fork new health check process when it exits. (Tatsuo Ishii) - - + + + + Allow to fork new health check process when it exits. (Tatsuo Ishii) + + - - + + - - - - Add new group "health_check" to PGPOOL SHOW command doc. (Tatsuo Ishii) - - + + + + Add new group "health_check" to PGPOOL SHOW command doc. (Tatsuo Ishii) + + - - + + - - - - Remove old html docs and related files. (Tatsuo Ishii) - - - - + + + + Remove old html docs and related files. (Tatsuo Ishii) + + + + - - Bug fix - + + Bug fix + - - - - Fix Pgpool-II hanging after receiving 'H' (flush) message in streaming replication mode. (bug 345) (Tatsuo Ishii) - - + + + + Fix Pgpool-II hanging after receiving 'H' (flush) message in streaming replication mode. (bug 345) (Tatsuo Ishii) + + - - - - Fix exit signal handlers to not call ereport. (Tatsuo Ishii) - - - There could be a race condition in the exit signal handlers. - - - See [pgpool-hackers:2545] for more details. - - + + + + Fix exit signal handlers to not call ereport. (Tatsuo Ishii) + + + There could be a race condition in the exit signal handlers. + + + See [pgpool-hackers:2545] for more details. + + - - - - Doc: Fix table about replicate_select behavior. (Yugo Nagata) - - + + + + Doc: Fix table about replicate_select behavior. (Yugo Nagata) + + - - + + - - - - Test: Fix bug with memory leak tests and add new memory leak - test. (Tatsuo Ishii) - - + + + + Test: Fix bug with memory leak tests and add new memory leak + test. (Tatsuo Ishii) + + - - - - Add log after health check retrying succeeds. (Tatsuo Ishii) - - - Previously only health check retry logs were produced. So it was not - clear if the retry succeeded or not in the end. + + + + Add log after health check retrying succeeds. (Tatsuo Ishii) + + + Previously only health check retry logs were produced. So it was not + clear if the retry succeeded or not in the end. - - + + - - - - Add necessary setting for health check retry in the Aurora - example. (Tatsuo Ishii) - - + + + + Add necessary setting for health check retry in the Aurora + example. (Tatsuo Ishii) + + - - + + - + - + diff --git a/doc/src/sgml/release-4.0.sgml b/doc/src/sgml/release-4.0.sgml index 7bba7853c..62439b143 100644 --- a/doc/src/sgml/release-4.0.sgml +++ b/doc/src/sgml/release-4.0.sgml @@ -1,798 +1,4544 @@ - - Release 4.0.2 + + Release 4.0.25 Release Date - 2018-11-22 + 2023-11-30 - - Bug fixes + + Documents - - - - - Fix to sort startup packet's parameters sent by client. - (bug 444)(Takuma Hoshiai) - + - If order of startup packet's parameters differ between cached connection - pools and connection request, did't use connection pool ,and created new - connection pool. + Modify "Pgpool-II + Watchdog Setup Example" to mention that + pcp_listen_addresses = '*' is required to + allow PCP to listen on all addresses. - + + + + + + Release 4.0.24 + + Release Date + 2023-08-17 + + + + Changes + - - - - Fix broken authentication for Pgpool-II's internal connections. (Muhammad Usama) - + - The issue is caused by a mistake in "SCRAM and Certificate authentication - support" commit. The problem is while authenticating against backend in - connection_do_auth(), it returns to caller as soon as backend returns auth - ok response. So authentication itself established fine. However - connection_do_auth() does not proceed until it receives "Ready for query". - The fix is to keep processing the data after receiving auth_ok response until we get - "Ready for query". + Install system exit callback only after initialization of shared memory. (Muhammad Usama) - Patch provided by Tatsuo Ishii and a tiny modification made by Muhammad Usama. + When the on-exit callback gets called because of a failure to acquire + shared memory. The cleanup function can produce a segfault while accessing + process_info, that lives in shared memory. + Although we can also fix this by bailing out from the exit callback when + process_info is NULL but installing the function after successful initialization + of shared memory is a better approach as the rest of the system always assumes + the process_info can never be NULL, and also, there is nothing to + clean up before child processes are spawned. - + - + - Fix compiler warnings with gcc 8.x. (Takuma Hoshiai) + Add schema qualification to some system catalog inquiry functions. (Tatsuo Ishii) - + + + + + Bug fixes + - - + - Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. - (bug 443)(Bo Peng) + Fix find_primary_node_repeatedly doesn't terminate within . (Bo Peng) + + + + - If the number of parameter format codes is specified to one, but the number - of the original query's parameter is zero, bind_rewrite_timestamp() - will call memcpy with a negative value. - This causes segmentation fault. + Fix pgproto to work with bind message using params. (Tatsuo Ishii) - Patch is provided by Yugo Nagata. + Previously pgproto can only process bind messages without params. - + + + + + Documents + - - + - Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + Clarify the meaning of stop mode. (Tatsuo Ishii) - + - - + - Fix query cache invalidation bug. (Tatsuo Ishii) + Enhance online recovery documentation. (Bo Peng) - - - - - - Fix segfault in extended query + query cache case. (Tatsuo Ishii) + Mention that 2nd stage of online recovery does not work properly only for multiple pgpool nodes without watchdog enabled. - + + + + + Regression Tests + - + - Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + Fix occasional 069.memory_leak_extended test failure. (Tatsuo Ishii) + + + It turned out that reason of the occasional test failure is, pgpool + child process is gone before running ps command after pgbench + finishes. The cause is a kind mismatch FATAL error, "DISCARD ALL + cannot be executed within a pipeline". To fix this, run pgbench in + background and get the process size before pgbench finishes. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html - - - + + + - - Release 4.0.1 + + Release 4.0.23 Release Date - 2018-10-31 + 2023-05-18 - - Changes - - - - - Allow ssl key files to be owned by users other than Pgpool-II user and root. (Muhammad Usama) - - - - - - - Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) - - - - - - - Bug fixes - - - - - - Fix corruption of file due to the different lengths of md5, AES and text type passwords. (Muhammad Usama) - - - The patch was provided by Takuma Hoshiai and modified by Muhammad Usama. - - - - - - - Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) - - - Patch provided by Phil Ramirez. - - - - - - - Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) - - - In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. - - - - - + + Changes + + + + + Use schema qualification for internal queries. (Tatsuo Ishii) + + + Some of objects such as function and cast did not use "pg_catalog." + schema qualification. This does not lead to immediate security + concern but using the schema qualification is always good practice. + + + + - - Release 4.0 - - Release Date - 2018-10-19 - + + Bug fixes + + + + + Fix compile error on systems using musl libc. + (bug 790) (Tatsuo Ishii) + + + Patch provided by leimaohui. + + - - Overview + + - This version addes support for SCRAM and CERT authentication, - improves load balancing control and import PostgreSQL 11 - new SQL parser. + Fix multiple query cache bug. (Tatsuo Ishii) - Major enhancements in Pgpool-II 4.0 include: + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + - + + + + Fix sr worker to not send wrong query to standby server in corner case. (Tatsuo Ishii) + + + When ALWAYS_PRIMARY flag is set, PRIMARY_NODE_ID macro returns node + id, rather than -1 even if the primary is down. + In this case streaming replication delay check worker + sends SELECT pg_current_wal_lsn() or + SELECT pg_current_xlog_location() + depending on PostgreSQL's version to + standby which of course raises an error. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + - + + + + Fix kind mismatch error with DEALLOCATE. + (bug 780) (Tatsuo Ishii) + + + Kind mismatch error occurs when conditions below are all met: + - - Add SCRAM and Certificate authentication support. - + + streaming replication mode + + + - - Detecting "false" primary server of PostgreSQL. - + + load balance node is other than primary + - + + - - Improvement of load balancing: - - - - More load balancing fine control after write queries. - - - - - Load balancing control for specific queries. - - - - - Allow to specify load balance weight ratio for load balance parameters. - - - - + + PREPARE is used in a multi-statement query + + + + + + - - - Add last state change timestamp to . - - - - - Import PostgreSQL 11 SQL parser. - - - - - Logging client messages. - - - - - - - Migration to Version 4.0 - - Version 4.0 contains a number of changes that may affect compatibility with - previous releases. Observe the following incompatibilities: - - - - - - Add 1st/2nd stage online recovery commands parameter to get the node number to be recovered. (Tatsuo Ishii) - - - Online recovery script now accepts 5 parameters, rather than 4 (the 5th - parameter is node number to be recovered). - Run ALTER EXTENSION pgpool_recovery UPDATE TO '1.2' - to update pgpool_recovery version. - Existing 4-parameter-style recovery scripts can be used if you don't care - about information provided by the 5th parameter. - - - See and - for more details. - - - - - - fail_over_on_backend_error parameter is renamed to - . (Muhammad Usama) - - - Now we throw a warning message when old config name fail_over_on_backend_error - is used instead of . - Using the old config variable name will have no effect. - - - - - - Allow to specify the AES encrypted password in the pgpool.conf. (Muhammad Usama) - - - Since 4.0, you can specify the AES encrypted password in the - pgpool.conf file for , - , and - . - - - To specify the unencrypted clear text password, prefix the password string with TEXT. - In the absence of a valid prefix, Pgpool-II will consider the string as a plain text password. - - - The empty password string specified in the - pgpool.conf file for , - , and - will only be used when the - does not contain the password for that specific user. - If these parameters are left blank, Pgpool-II will first try to - get the password for that specific user from file before - using the empty password. - - - - - - - Major Enhancements - - - - - Add support for SCRAM and Certificate - based authentication methods. (Muhammad Usama) - - - - Add support for SCRAM authentication method. - - - SCRAM authentication is supported using the pool_passwd authentication file. - - - See for more details. - - - - - Allow to use CERT authentication between Pgpool-II and frontend. - - - To use this authentication method, Pgpool-II will require that the client provide a valid certificate. - - - See for more details. - - - - - Able to use different auth methods for frontend and backend. - - - Now it is possible to use different authentication methods between - client to Pgpool-II and Pgpool-II to backend. - - - - - - - Now can store three format passwords. AES256 encrypted format, plain text format and md5 format. - - - Pgpool-II identifies the password format type by it's prefix, - so each password entry in the pool_passwd must be prefixed as per the password format. - - - md5 hashed passwords will be prefixed with md5 and AES256 encrypted password types - will be stored using AES prefix. - To store the password in the plain text format TEXT prefix can be used. - - - In the absence of a valid prefix, Pgpool-II will be considered the string as a plain text password. - - - For example: - -username1:AESIFwI86k+ZbVdf6C+t3qpGA== -username2:md59c6583185ba6a85bdcd1f129ec8cabb4 -username3:TEXTmypassword - - - - - - - - Able to use MD5 and SCRAM authentication methods - to connect to database without . - - - A new configuration parameter is added. - This parameter enables this config allows the Pgpool-II - to use clear-text-password authentication with frontend clients when - file does not contain the password for the connecting user, - and use that password (provided by client) to authenticate with the backend - using MD5 and/or SCRAM authentication. - - - - - - - New utility to create encrypted passwords. - - - A new utility is added to create AES encrypted passwords. - - - - - - See for more details. - - + + Documents + + + + + Add explanation for . (Chen Ningwei) + + - - - - Add new parameter . (Tatsuo Ishii) - - - If set detach_false_primary = on, detach false primary node. - The default is off. This parameter is only valid in streaming replication mode - and for PostgreSQL 9.6 or after since this feature - uses pg_stat_wal_receiver. - If PostgreSQL 9.5.x or older version is used, no - error is raised, just the feature is ignored. - - - - - - Add parameter to specify - load balance behavior after write queries appear. (Tatsuo Ishii) - - - This parameter allows to specify the behavior when a write query issued. - - + + + + Add restriction regarding PREPARE/EXECUTE/DEALLOCATE. (Tatsuo Ishii) + + - - - - Allow to specify load balance weight ratio for load balance parameters. (Bo Peng) - - - Add a new feature to allow to specify load balance weight ratio for - and - parameters. - - - You can specify the list of "database-name:node id(ratio)" pairs to - send SELECT queries to a particular backend node for a particular - database connection at a specified load balance ratio. - - - Also you can specify list of "application-name:node id(ratio)" pairs to - send SELECT queries to a particular backend node for a particular client - application connection at a specified load balance ratio. - - - This load balance ratio specifies a value between 0 and 1, - and the default is 1.0. - - + + + + Add caution to use -D option with pgpool. (Tatsuo Ishii) + + - - - - Add new parameter to enable - specifying SQL patterns lists that should not be load-balanced. (Bo Peng) - - - Specify a semicolon separated list of SQL patterns that - should be sent to primary node only. Regular expression can be - used in SQL patterns. Only Maste Slave mode is supported. - - + + + + Enhancing "Installation from RPM" section. (Bo Peng) + + - - - - Add new parameter to allow logging client message. (Takuma Hoshiai, Tatsuo Ishii) - - - Set log_client_messages = on, any client messages will be logged without debugging messages. - - - - - - Add last_status_change column to command. (Tatsuo Ishii) - - - The new column indicates the time when status or role has been changed. - - - See - [pgpool-hackers: 2822] for the reasoning to add the column. - - - - - - Import PostgreSQL 11's SQL parser. (Bo Peng) - - - Now Pgpool-II can fully understand the newly added SQL syntax - in PostgreSQL 11, - such as CREATE/ALTER/DROP PROCEDURE, - { RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ], etc. - - - - + + + + Remove the configuration of "-D" start OPTS from "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + - - Other Enhancements - - - - - Add "-r" option to pgpool_setup to allow use of pg_rewind. (Tatsuo Ishii) - - - With this option, pgpool_setup creates basebackup.sh which tries - pg_rewind first. If it fails, falls back to rsync. - - - Also a new environment variable "USE_PG_REWIND" to pgpool_setup is added. - This brings the same effect as "-r" option is specified. - - + + + + Mention that AES256 support requires option. (Tatsuo Ishii) + + - - - - Add "-s" option to pgpool_setup to support for replication slot. (Tatsuo Ishii) - - - This eliminates the problem when standby is promoted. When a standby - is promoted, it changes the time line in PITR archive, which will stop - other standby if any because of shared archive directory. - - - Also a new environment variable "USE_REPLICATION_SLOT" to pgpool_setup is added. - This brings the same effect as "-s" option is specified. - - - If "USE_REPLICATION_SLOT=true", in streaming replication mode, - use replication slot instead of archive. - - - By setting USE_REPLICATION_SLOT environment variable, - now pgpool_setup in all tests uses replication slots. - This reduces disk space under src/test/regression from - 6.3GB to 5,1GB (1.2GB savings). - - - - - - Introduce to Pgpool-II. (Takuma Hoshiai) - - - A new utility is added to test PostgreSQL - or any other servers that understand the frontend/backend protocol. - - - - - - Allow to display Pgpool-II child process id and - PostgreSQL backend id in . (Tatsuo Ishii) - - - Add --all option to display all child processes and their available connection slots. - - - - - - Add replication_delay and last_status_change to - . (Tatsuo Ishii) - - - - - - Add role, replication_delay and last_status_change columns to pgpool_adm's - . (Tatsuo Ishii) - - - - + + + + Explicitly stat that it is -w option of pcp command is needed to use .pcppass. (Tatsuo Ishii) + + - - Changes - - - - - Downgrade most of DEBUG1 messages to DEBUG5. (Tatsuo Ishii) - - - This significantly reduces the size of pgpool log when pgpool starts - with -d option (this is equivalent to setting to - debug1). - - - Per discussion - [pgpool-hackers: 2794]. - - - - + + + + Enhance . (Tatsuo Ishii) + + + + - - Bug fixes - - - - - Fix syntax error in native replication, when queries including time functions - (now(), etc.) and IN (SELECT ...) - in WHERE clause. - (bug 433) (Bo Peng) - - + + Regression Tests + + + + + Refactor 071.execute_and_deallocate/test.sh. (Tatsuo Ishii) + + - - - - Fix compiler error if HAVE_ASPRINTF is not defined. (Tatsuo Ishii) - - + + + + Enhance regression tests. (Tatsuo Ishii) + + - - - - Fix configure.ac to remove generating src/sql/pgpool_adm/Makefile.in. (Tatsuo Ishii) - - + + + + Fix occasional 005.jdbc test failure. (Tatsuo Ishii) + + + + + - - - - Fix pgpool main process segfault when PostgreSQL 9.5 is used. (Tatsuo Ishii) - - - pgpool_setup -n 3 (or greater) triggers the bug. While recovering node - 2, pgpool main process tried to retrieve version info from backend #2 - even if it's not running. This causes the sefault because connection - was not established yet. The reason why PostgreSQL 9.6 - or later was not suffered from the bug was, PostgreSQL - exited the loop as soon as the server version is higher than 9.5. To fix this, - call to VALID_BACKEND macro was added. - - + + Release 4.0.22 + + Release Date + 2023-01-23 + - - - - Add missing in pgpool_setup. (Tatsuo Ishii) - - - Per node health_check_timeout was missing and this should had been - there since the per node health check parameter support was added. - - + + Overview + + This release contains a security fix. + + + If following conditions are all met, the password of is + exposed by command. + The command can be executed by any user who can + connect to Pgpool-II. (CVE-2023-22332) + - - - - Test: Try to reduce the chance of regression 006.memcache failure. (Tatsuo Ishii) - - - It seems the occasional failure of the test is caused by replication - lag. The script tries to read tables from standby but it returns a - table not existing error. So insert pg_sleep() after creation of - tables. - - + + + + Version 3.3 or later. + + - - - - Test: Fix regression test 055.backend_all_down error. (Bo Peng) - - + + + is on. + + - - - - Doc: Enhance online recovery document. (Tatsuo Ishii) - - - Clarify that 2nd stage command is only required in native replication mode. - - + + + is query. + + - - - - Test: Add new regression test 017.node_0_is_down for node 0 not being primary. (Tatsuo Ishii) - - - - + + + A plain text password is set + to . + + + + + + In this case it is strongly recommended to upgrade to this version + (we do not expose in + show pool_status command any more), or use one of following + workarounds. + + + + Workarounds for 4.0.x to 4.4.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + Set an empty string + to . This will use + password in the pool_passwd file. + + + + + + Set an AES encrypted password + to . + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Workarounds for 3.0.x to 3.7.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Please note that Pgpool-II 3.7.x or + before are end of life and no minor updates are provided for those + versions. + + + + + Changes + + + + + + Do not expose in + , + and + commands. (CVE-2023-22332) (Bo Peng) + + + + + + + Change the default value + for to empty string as + documented. (Bo Peng) + + + + + + + + Bug fixes + + + + + + Fix compiler warning + in pgpool-regclass.c. (Florian Weimer, + Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: Enhance and fix some mistakes + in Configurations + to use shared memory chapter. (Tatsuo Ishii) + + + + + + + + + Release 4.0.21 + + Release Date + 2022-12-22 + + + + Changes + + + + + Downgrade LOG messages "new IPC connection received" to DEBUG1. + (bug 775) (Bo Peng) + + + It is a normal messages and should not be logged as LOG. + Patch is created by pstef and reviewed by Bo Peng. + + + + + + + + Bug fixes + + + + + + Fix issue with . (Muhammad Usama) + + + The fix is to dynamically set the failover command timeout based on the maximum + value of health check parameters across the watchdog cluster. + + + Reviewed and tested by Tatsuo Ishii. + Discussion: [pgpool-hackers: 4227] + + + + + + + Fix not to print warnings of use of backslashes in parser. (Tatsuo Ishii) + + + When standard_conforming_strings = off and escape_string_warning = on, + PostgreSQL prints warnings if backslashes are used in string + literal. This is fine. But previously Pgpool-II's parser printed the + same message too. This is redundant. + + + + + + + Deal with idle_session_timeout. (Tatsuo Ishii) + + + If idle_session_timeout (added in PostgreSQL 14) is enabled and the + timeout fires, followings happen: + + + + If failover_on_backend_error is on (the default), Pgpool-II will trigger failover. + + + + + + + If only one of PostgreSQL servers enables idle_session_timeout, Pgpool-II could hang. + + + + + + To deal with idle_session_timeout detect_idle_session_timeout_error() + is added to detect the error code for idle_session_timeout. If the + error is detected, Pgpool-II returns the error code to frontend as a + fatal error and disconnects the session. This is a similar fix + implemented for idle_in_transaction_session_timeout. + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + Discussion: [pgpool-hackers: 4208] + + + + + + + Deal with SSL error SSL_ERROR_ZERO_RETURN. (Tatsuo Ishii) + + + Previously this caused failover, which was actually unnecessary because + it means the server is just going to close the connection. + + + Discussion: [pgpool-general: 8366] + Discussion: [pgpool-hackers: 4193] + + + + + + + Fix: Setting memory cache size greater than 2GB causes a segfault. (Muhammad Usama) + + + The problem was in the block_address() function that returns the memory address + for a given cache block, It was using 32bit integers to calculate the offset of + the block within the shared memory space that is only good until the 2GB limit. + + + + + + + Fix rare segfaults in pcp_proc_info, SHOW pool_pools + and SHOW pool_processes. (Tatsuo Ishii) + + + The segfaults were in get_pools() and get_processes(). They first + extracted pid of particular process info slot on shared memory then + searched the slot again by using pid as the key. Because these steps + were not protected by any locking, it was possible that the search + using the pid failed and returned NULL if the process id is + overwritten by pgpool parent which is responsible for forking new + child process after the process exiting. As a result any subsequent + reference to the NULL pointer generated segfaults. + + + Solution is, first get the pointer to the process info slot then + extract the process id member from the pointer. This way, still + concurrent updating to the shared memory info by the parent process is + possible (which may lead to strange results in the output) but at + least we can avoid segfaults. + + + + + + + Fix to not allow Unix-domain socket path with invalid length. (Masaya Kawamoto) + + + + + + + + Documents + + + + + + Doc: enhance description about memqcache_method. (Tatsuo Ishii) + + + Add explanation which method should be used. + + + + + + + Doc: mention that health check process may use SSL. (Tatsuo Ishii) + + + Also mention that streaming replication check may use SSL too. + This should have been added since 2010. + + + Discussion: [pgpool-hackers: 4187] + + + + + + + + Regression Tests + + + + + + Allow to define PGPOOLDIR using environment variable. + (bug 766) (Bo Peng) + + + + + + + + + Release 4.0.20 + + Release Date + 2022-08-18 + + + + Bug fixes + + + + + + Fix bug in query cache. (Tatsuo Ishii) + + + Pgpool-II did not cache the query like "Select '2022-02-18 07:00:00.006547'::timestamp". + SELECTs include TIMESTAMP, TIME and DATE are cached, and SELECTs include TIMESTAMPZ + and TIMEZ are not cached because the result can be changed by SET TIME ZONE command etc. + Furthermore, SELECTs having functions with return types are timestamptz or timetz are + not cached too as same reason. + Discussion: [pgpool-general: 8285] + + + + + + + + Documents + + + + + + Doc: mention that certain SELECTs are not cached. (Tatsuo Ishii) + + + certain SELECTs are follows. + + + + SELECTs including TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including CAST to TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including SQLValueFunction (CURRENT_TIME, CURRENT_USER etc.) + + + + + + + + + + Doc: fix description about using PCP password file when connect to Unix domain socket (Masaya Kawamoto) + + + The localhost entry in pcppass matches only for the default PCP socket + directory path, not all Unix socket connections. This behavior is the + same as pgpass. + + + + + + + Doc: fix wrong explanation on , . (Tatsuo Ishii) + + + Those parameters cannot be changed by reloading config file. Restarting + pgpool is required. + + Discussion: [pgpool-general: 8195] + + + + + + + + Test Tools + + + + + + Allow to run pgpool_setup on PostgreSQL 15. (Tatsuo Ishii) + + + Per ticket 757 + + + + + + + + Regression Tests + + + + + + Test: print Pgpool-II version in the regression test. (Tatsuo Ishii) + + + + + + + Test: Fix regression test script to look for pgpool.conf in the proper install directory. (Tatsuo Ishii) + + + + + + + + + + Release 4.0.19 + + Release Date + 2022-05-19 + + + + Changes + + + + + Enhance in stopping pgpool main process. (Tatsuo Ishii) + + + If "pgpool stop" couldn't terminate the main process within certain period (currently 5 seconds), send the signal again. + + + + + + + Change the PID length of pcp_proc_count command to 7 characters long. (Bo Peng) + + + + + + + Enhance error message to include the message kind returned and the backend node id while processing parse message. (Tatsuo Ishii) + + + + + + + Downgrade log level of ParameterStatus message from LOG to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + Change the default value of from '*' to 'localhost'. (Tatsuo Ishii) + + + + + + + Adjust the field name in . (Muhammad Usama) + + + + + + + + Bug fixes + + + + + Fix issue that watchdog cluster keeps rejecting the restarted remote node which is lost previously. (Muhammad Usama) + + + Issue report: [pgpool-general: 7896] + + + + + + + Fix exit_handler in pgpool main process to avoid possible infinite wait. (Tatsuo Ishii) + + + + + + + Fix main process exiting if a backend is failing or shutting down while performing finding primary. (Tatsuo Ishii) + + + + + + + Fix segfaults in watchdog. (Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + Documents + + + + + Doc: update configuration example. (Masaya Kawamoto) + + + + + + + Doc: update the example output of . (Bo Peng) + + + + + + + Doc: mention that escaping is required if you are providing the password as an argument to pg_enc and the password contains a "$" character. (Bo Peng) + + + + + + + + + Regression Tests + + + + + Enhance regression test 074.bug700_memqcache_segfault to avoid the timeout error. (Tatsuo Ishii) + + + + + + + Improve regression test to detect segmentation fault. (Bo Peng) + + + + + + + + Release 4.0.18 + + Release Date + 2022-02-17 + + + + Changes + + + + + + Suppress message length log for in_hot_standby. (Tatsuo Ishii) + + + PostgreSQL 14 introduced new config parameter in_hot_standby. + + + The value is either "on" for standby servers or "off" for primary + servers. As a result pgpool log is flooded by the messages: + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + To avoid this, only complain if the parameter name is not in_hot_standby. + + + Also the message is enhanced to show the parameter name. For example: + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + Enhance parameter status handling. (Tatsuo Ishii) + + + When a parameter status message arrives from backend Pgpool-II + forwards it to frontend not just memorize. + + + + + + + + Bug fixes + + + + + + Fix long standing bug with pcp_node_info. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Fix health check process issues pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix memory leak pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix failover() to deal with the case when no former primary node exists. (Tatsuo Ishii) + + + In case Req_info->primary_node_id is -1 like no primary + node exists when Pgpool-II starts up, + failover() skipped to call + find_primary_node_repeatedly(). Also + follow_master_command was not executed. + + + Discussion: [pgpool-hackers: 4113] + + + + + + + Fixed the streaming replication check process not to retry if it cannot connect to the backend.(bug 742) (Bo Peng) + + + This retry caused a long time failover. + + + + + + + + Documents + + + + + + Fix documentation typos. (pengbo) + + + Patch is created by Umar Hayat. + + + + + + + Add "exclude" settings to /etc/yum.repos.d/pgdg-redhat-all.repo so + that Pgpool-II is not installed from + PostgreSQL YUM repository. (Bo Peng) + + + + + + + Add restriction regarding ParameterStatus and in_hot_standby parameter. (Tatsuo Ishii) + + + + + + + Add restriction about set_config. (Tatsuo Ishii) + + + + + + + + Test tools + + + + + + Fix pgpool_setup in failover script creation. (Tatsuo Ishii) + + + When pgpool_setup creates failover.sh, + it did not consider the case when no primary server existed. + + + + + + + + Regression tests + + + + + + Allow to run regression test against existing installation without recompiling. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + Fix pgpool_setup and watchdog_setup binary PATH in noinstall mode. (Bo Peng) + + + + + + + + + Release 4.0.17 + + Release Date + 2021-12-23 + + + + Changes + + + + + + Suppress bison warnings regarding yacc incompatibility. (Tatsuo Ishii) + + + + + + + Fix redundant code. (Tatsuo Ishii) + + + Patch contributed by Lu Chenyang. + + + + + + + + Documents + + + + + + Doc: fix typo in pcp_watchdog_info manual. (Tatsuo Ishii) + + + + + + + Doc: fix typos in release notes. (Bo Peng) + + + + + + + + + Release 4.0.16 + + Release Date + 2021-11-18 + + + + Security release + + + + + Reject extraneous data after SSL encryption handshake. (Tatsuo Ishii) + + + In the server side implementation of SSL negotiation, it was possible for a + man-in-the-middle attacker to inject arbitrary SQL commands. This is + possible if Pgpool-II is configured to use cert authentication or + hostssl + trust. This resembles PostgreSQL's CVE-2021-23214. + + + Similarly, in the client side implementation of SSL negotiation, it was + possible for a man-in-the-middle attacker to inject arbitrary responses. + This is possible if PostgreSQL is using trust authentication with a + clientcert requirement. It is not possible with cert authentication because + Pgpool-II does not implement the cert authentication between Pgpool-II + and PostgreSQL. This resembles PostgreSQL's CVE-2021-23222. + + + + + + + Changes + + + + + + Deal with PostgreSQL 14 while processing + pg_terminate_backend(). (Tatsuo Ishii) + + + + + + + Enhance SIGCHLD handler of Pgpool-II main process. (Tatsuo Ishii) + + + When Pgpool-II child is killed by SIGKILL signal, + the SIGCHLD handler just emitted LOG level message as other signals. But + SIGKILL is an important event, for example killed by OOM killer. So emit a + WARNING level message instead. + Per suggestion from Michail Alexakis. + Discussion: [pgpool-general: 7750] + + + + + + + + Bug fixes + + + + + + Fix occasional hang in COPY FROM. (Tatsuo Ishii) + + + If an error occurs while doing COPY FROM, it was possible the + Pgpool-II waited forever for a response from + backend after COPY end marker was sent from frontend. + The bug was found by Bo Peng. + + + + + + + Fix the incorrect display of load balancing node in raw mode. (Bo Peng) + + + In raw mode, Pgpool-II sends all queries to main node. + This is harmless, but it may confuse users. + + + + + + + Fix backend_flag* parameter shown twice while executing PGPOOL SHOW ALL. (Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: fix documentation typos. (Bo Peng) + + + + + + + Fix documentation typos. (Bo Peng) + + + Patch is created by Kazufumi Noto. + + + + + + + Doc: Mention that double quotes are required in PGPOOL SHOW command, + if the parameter contains uppercase letters. (Bo Peng) + + + + + + + + Test tools + + + + + Fix pgpool_setup to do nothing when no new main node is available. (Tatsuo Ishii) + + + + + + + + Regression tests + + + + + + Fix occasional 073.pg_terminate_backend regression test failure. (Tatsuo Ishii) + + + + + + + Rename regression test 074. (Bo Peng) + + + + + + + Fix psql command path to avoid test failure. (Bo Peng) + + + + + + + + + Release 4.0.15 + + Release Date + 2021-08-05 + + + + Changes + + + + + + Fix maximum length of hostnames including domain name. (Tatsuo Ishii) + + + The maximum length of hostnames was 128, but the correct value is 254. + Discussion: [pgpool-hackers: 3903] + + + + + + + + Bug fixes + + + + + + Fix query cache to not cache SQLValueFunctions. (Tatsuo Ishii) + + + The list of SQLValueFunctions is follow. + + + + CURRENT_DATE + + + + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + + + + + SESSION_USER + + + + + USER + + + + + CURRENT_CATALOG + + + + + CURRENT_SCHEMA + + + + + + + + + + Fix sending invalid message in SI mode. (Tatsuo Ishii) + + + When a query is aborted by specific reason like serialization error, + Pgpool-II sends error query to abort + transactions running on non main nodes. The message length of the + query was incorrect and it caused "invalid string in message" error on backend. + + + + + + + Fix watchdog communication race condition. (Tatsuo Ishii) + + + When watchdog notifies the new message to main process while main process + is executing the process notified by watchdog process, there was a + significant delay before the new message was processing. + Discussion: [pgpool-hackers: 3900] + + + + + + + Fix watchdog node status not updating after rebooting. + (bug 684) (Muhammad Usama) + + + + + + + + Documents + + + + + + Doc: fix documentation typos. (Bo Peng) + + + + + + + Doc: fix typo in in memory query cache document. (Tatsuo Ishii) + + + + + + + Doc: fix wd_life_point description (Masaya Kawamoto) + + + + + + + + Test tools + + + + + + Fix rsync parameter in pgpool_setup. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup in creating base backup script. (Tatsuo Ishii) + + + + + + + Enhance watchdog_setup script. (Tatsuo Ishii) + + + shutdownall script generated by watchdog_setup caused failover event which is not + necessary in the whole shutdown sequence. + + + + + + + + Regression tests + + + + + + Fix 031.connection_life_time. (Tatsuo Ishii) + + + + + + + + + Release 4.0.14 + + Release Date + 2021-05-20 + + + + Bug fixes + + + + + Doc: fix description about . (Tatsuo Ishii) + + + It did not mention the parameter can only be used if Pgpool-II started as root. + + + + + + + Fix broken database/app redirect preference in statement level load balancing mode. + (bug 707) (Bo Peng) + + + + + + + Fix to create database cluster entity under pgpool0. (Tatsuo Ishii) + + + + + + + Fix pgpool crash when query cache enabled. + (bug 700) (Tatsuo Ishii) + + + Pgpool-II crashed upon receiving CloseComplete. This only happened in other than streaming and logical replication mode. + + + + + + + Fix that query cache is not created in other than streaming and logical replication mode. (Tatsuo Ishii) + + + + + + + Enhance debug message upon receiving startup packet. (Tatsuo Ishii) + + + + + + + Doc: enhance documentation. (Tatsuo Ishii, Bo Peng) + + + + + + + + Release 4.0.13 + + Release Date + 2021-02-18 + + + + Changes + + + + + Delete any pre-existing watchdog command socket file at startup. (Muhammad Usama) + + + Patch provided by Masaya Kawamoto. + + + + + + + Bug fixes + + + + + Fix the incorrect "weight" displayed in . (Tatsuo Ishii) + + + + + + + Fix watchdog leader sync process to start health check process. (Tatsuo Ishii) + + + + + + + Fix that DB cluster path was not correct in watchdog_setup installation. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup so that it creates separate archive directory for each DB node. (Tatsuo Ishii) + + + + + + + Fix messages when health check process starts. (Tatsuo Ishii) + + + + + + + Doc: mention that the sample scripts doesn't support tablespaces in "Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix error while allocating shared memory. (Tatsuo Ishii) + + + + + + + Fix bug is not respected if ERROR occurs. (Tatsuo Ishii) + + + + + + + Fix segfault that may occur when backend_flag = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER' or failover_command = ''. + (bug 672) (Tatsuo Ishii) + + + + + + + Fix file swapping race condition in pool_passwd. (Tatsuo Ishii) + + + Patch is provided by Masaya Kawamoto. + + + + + + + Doc: fix description. (Tatsuo Ishii) + + + + + + + + Release 4.0.12 + + Release Date + 2020-11-19 + + + + Changes + + + + + Doc: update "Aurora Configuration Example". (Bo Peng) + + + + + + + Doc: mention that GSSAPI is not supported. (Tatsuo Ishii) + + + + + + + Pgpool-II doesn't support GSSAPI. + Allow Pgpool-II to deal with GSSAPI encrypted connection request from frontend instead of responding with an error. (Tatsuo Ishii) + + + Patch is created by me, reviewed and tested by Umar Hayat. + + + + + + + Bug fixes + + + + + Fix query rewrite syntax error of "INSERT ... ON CONFLICT" in native replication mode. + (bug 654) (Bo Peng) + + + + + + + Fix connection counter was not counted down when query is canceled. + (bug 656) (Tatsuo Ishii) + + + + + + + Doc: fix usable versions of PostgreSQL to be 7.4 or later. (Tatsuo Ishii) + + + + + + + + Release 4.0.11 + + Release Date + 2020-09-17 + + + + Changes + + + + + Follow the guide line of PostgreSQL 12.4 regarding extensions. (Tatsuo Ishii) + + + CREATE OR REPLACE FUNCTION should be avoided. Use CREATE FUNCTION instead. + + + + + + + Replace "PGBIN" and "LPATH" in and using PostgreSQL's bin path and lib path. (Bo Peng) + + + + + + + Bug fixes + + + + + Doc: fix the incorrect description regarding the running modes of Pgpool-II in which online recovery is available. (Bo Peng) + + + + + + + Remove unnecessary checks in some code path. (Tatsuo Ishii) + + + Patch contributed by Hou, Zhijie. + + + + + + + Fix relcache query sometimes sent to other than primary. (Tatsuo Ishii) + + + In streaming replication mode, relcache queries are supposed to be + sent to the primary node. But actually they were not sent to the primary + node if primary node was not the master node. Typically this could + happen when the primary is not node 0. + + + + + + + Fix not working when is enabled. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] + + + + + + + Display more informative error message in authentication process. (Tatsuo Ishii) + + + + + + + Fix segfault in pgpool child process in certain case. (Tatsuo Ishii) + + + This issue can be reproduced with the following steps: + + + + Shutdown all backends. + + + + + Connect to pgpool with invalid client. I have used pcp_attach_node with pgpool's port number, not pcp's. + + + + + + + + + + + Release 4.0.10 + + Release Date + 2020-08-20 + + + + Changes + + + + + Doc: mention that only affects to TLS 1.2 and lower. (Tatsuo Ishii) + + + + + + + Doc: Improve the description of . (Bo Peng) + + + Patch is provided by Kenichiro Tanaka. + + + + + + + Add mention about hostssl/hostnossl to pool_hba.conf sample file. (Tatsuo Ishii) + + + + + + + Doc: documentation improvements. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + At pgpool startup, if pid file exists, truncate pid file to zero length before writing. (Bo Peng) + + + Patch is created by maliangzhu. + + + + + + + Doc: fix error in parameter description. (Bo Peng) + + + + + + + Fix does not work if primary node is not 0 in streaming replication mode. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup problem with -r option and PostgreSQL 12. (Tatsuo Ishii) + + + + + + + Change PCP UNIX_DOMAIN_PATH of RPM package to /var/run/postgresql. (Bo Peng) + + + + + + + Fix query cache bugs. (Tatsuo Ishii) + + + If query cache is enable, when a table is updated, Pgpool-II should delete all the caches related to the table. + However, EXPLAIN ANALYZE and CTE with data-modifying SQLs + were mistakenly treated as normal read only query so that the query caches were not deleted. + + + Patch is created by Hou, Zhijie and modified by Tatsuo Ishii. + + + + + + + Fix Pgpool-II hang in a corner case. (Tatsuo Ishii) + + + + + + + If there are parameters other than "user", "database" and "application_name", reading startup packet failed. (Tatsuo Ishii) + + + + + + + Fix miscount of connections when pg_terminate_backend() is executed. (Takuma Hoshiai) + + + + + + + Fix segmentation fault when application name is included in . (bug 615) (Tatsuo Ishii) + + + + + + + Fix incorrectly performing failover when pg_terminate_backend() is executed in native replication mode. (Takuma Hoshiai) + + + + + + + Fix 004.watchdog test crash on IBM Z hardware. (bug 614) (Tatsuo Ishii) + + + Patch is provided by gregn123, slightly modified by Tatsuo Ishii. + + + + + + + + Release 4.0.9 + + Release Date + 2020-05-21 + + + + Bug fixes + + + + + Fix build error on some system (Fedora 32). (Tatsuo Ishii) + + + + + + + Fix pgpool ssl front end accept all ciphers. (bug 608) (Muhammad Usama) + + + + + + + Downgrade too verbose authentication logs. (Tatsuo Ishii) + + + + + + + Fix unnecessary checks. (Tatsuo Ishii) + + + Patch contributed by sherlockcpp. Discussion: [pgpool-general: 7004] + + + + + + + Doc: Fix typo. (Tatsuo Ishii) + + + Patch contributed by Umar Hayat. Discussion: [pgpool-hackers: 3587] + + + + + + + Fix for segmentation fault in PCP process. (bug 598) (Muhammad Usama) + + + + + + + Fix a warning message is never output in watchdog. (Tatsuo Ishii) + + + Patch provided by sherlockcpp. Discussion: ([pgpool-general: 6956] + + + + + + + Doc: Fix typo. (Tatsuo Ishii, Bo Peng) + + + Patch provided by sherlockcpp. + + + + + + + Fix Pgpool-II hangs when an Execute message is issued right after Sync message and query cache hits. (Tatsuo Ishii) + + + + + + + Fix problems in watchdog source code processing json data. (bug 596) (Tatsuo Ishii) + + + Patch is provided by Greg Nancarrow (Fujitsu Australia). + + + + + + + Fix SCRAM auth handling bug. (bug 596) (Tatsuo Ishii) + + + Patch is provided by Greg Nancarrow (Fujitsu Australia). + + + + + + + Fix possible data inconsistency in native replication mode. (Tatsuo Ishii) + + + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] + + + + + + + Fix watchdog ping probes fail with long hostnames due to small buffer. (bug 516) (Bo Peng) + + + + + + + Doc: Enhance documents. (Tatsuo Ishii) + + + + + + + Fix "last status change" timestamp is not set properly. (Tatsuo Ishii) + + + + + + + + Release 4.0.8 + + Release Date + 2020-02-20 + + + + Changes + + + + + + Disallowing the quorum aware failover option for the native replication mode. (Muhammad Usama) + + + In native replication mode, Pgpool-II. is responsible for replicating the data + on all backend nodes, and if a node becomes quarantined then Pgpool-II stops + sending the writes to that node. This is dangerous since it can cause data inconsistency. + + + So as per the discussion, we reached the conclusion to disallow + with the native replication mode so that backend + node should never get into quarantine when Pgpool-II is configured in the replication mode. + + + + + + Check if socket file exists at startup and remove them if PID file doesn't exist to avoid bind() failure. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect query rewriting in native replication mode. + (bug 551) (Bo Peng) + + + + + + + Doc: Update documentation and fix documentation typos. (Takuma Hoshiai, Tatsuo Ishii, Bo Peng) + + + + + + + Fix child process segfault after reload if is empty. + (bug 571) (Bo Peng) + + + + + + + Fix to support PostgreSQL 12. (Tatsuo Ishii) + + + + + + Doc: Change the sample follow_master_command script %M %H parameter's order. (Bo Peng) + + + + + + + + + + Fix occasional regression test failure. (Tatsuo Ishii) + + + + + + + Fix replication delay worker segfault when application_name in primary_conninfo is an empty string. + (bug 565) (Tatsuo Ishii) + + + + + + + Fix command doesn't display ALWAYS_MASTER, + when = 'ALWAYS_MASTER'. (Takuma Hoshiai) + + + + + + + Fix the bug with ignored syslog setting. (Bo Peng) + + + + + + + + Release 4.0.7 + + Release Date + 2019-10-31 + + + + Bug fixes + + + + + Fix incorrect query rewrite in replication mode. (Bo Peng) + + + + + + + Fix that health check timeout does work in certain case. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 3458], [pgpool-hackers: 3459] + + + + + + + Doc: add description when all standby nodes are down. (Takuma Hoshiai) + + + + + + + Doc: add note not to assign PostgreSQL servers to . (Tatsuo Ishii) + + + + + + + Fix for miscellaneous watchdog issues. (Muhammad Usama) + + + The lost nodes reported by life-check are treated as hard failures even when the node + is reachable from the watchdog core. + + + In the case of network partitioning or partial life-check failure, + the kicked out standby node was too aggressive in trying to connect + to the master or become a master itself so that potentially put the + unnecessary burden on the network and the cluster nodes. + Fix is to make the isolated node a bit calm and wait between trying to connect to + master or become a master. + + + See details: + (bug 547), + [pgpool-general: 6672] + + + + + + + Fix assorted ancient v2 protocol bugs. (Tatsuo Ishii) + + + + + + + Fix problem that doesn't change by reload. + (bug 548) (Takuma Hoshiai) + + + + + + + Fix Pgpool-II shutdown failed in certain case. (Tatsuo Ishii) + + + + + + + Allow the lost standby node to rejoin the master watchdog node when it gets rediscovered by the lifecheck. + (bug 545) (Muhammad Usama) + + + + + + + Overhaul health check debug facility. (Tatsuo Ishii) + + + + + + + Fix segfault when executing an erroneous query after DEALLOCATE a named statement. + (bug 546) (Tatsuo Ishii) + + + + + + + Doc: clarify that certificate authentication works between only client and Pgpool-II. (Tatsuo Ishii) + + + + + + + Doc: update configuration Examples "Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Doc: mention that VIP will not be brought up if quorum does not exist. (Tatsuo Ishii) + + + + + + + + + + Fix pgpool_setup to deal with PostgreSQL 9.1. (Tatsuo Ishii) + + + + + + + Fix for password authentication does not work when the password for + the connecting user is not found in the pool_passwd file. + (bug 534) (Muhammad Usama) + + + + + + + Add "-I" option to command default setting. (Bo Peng) + + + + + + + + Release 4.0.6 + + Release Date + 2019-08-15 + + + + Enhancements + + + + + Doc: Update "Pgpool-II + Watchdog Setup Example" to support PostgreSQL 12. (Bo Peng) + + + + + + Import some of memory manager debug facilities from PostgreSQL. (Tatsuo Ishii) + + + + + + Use pg_get_expr() instead of pg_attrdef.adsrc to support for PostgreSQL 12. (Bo Peng) + + + + + + Enhance shutdown script of . (Tatsuo Ishii) + + + + Make shutdownall to wait for completion of shutdown of Pgpool-II. + + + + + If environment variable CHECK_TIME_WAIT is set to true, use netstat command to confirm usage of the TCP/IP port while executing shutdown script. + + + + + + + + + Deal pgpool_adm extension with PostgreSQL 12. (Tatsuo Ishii) + + + + + + Doc: add description to man page how to show pool_passwd hashed string. (Tatsuo Ishii) + + + + + + + Doc: add general description about failover. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + Test: Fix test failure of extended-query-test when disable_load_balance_on_write = off/transaction/always. (Tatsuo Ishii) + + + + + + + Fix "unable to bind. cannot get parse message" error. + (bug 531) (Tatsuo Ishii) + + + + + + + Fix online-recovery is blocked after a child process exits abnormally with replication mode and watchdog. + (bug 483) (Muhammad Usama) + + + + + + + Fix for keep the backend health check running on quarantined nodes. (Muhammad Usama) + + + Pgpool should keep the backend health check running on quarantined nodes so + that when the connectivity resumes, they should automatically get removed + from the quarantine. + + + See [pgpool-hackers: 3295] for more details. + + + + + + + Fix for no primary on standby pgpool when primary is quarantined on master. (Muhammad Usama) + + + Master watchdog Pgpool sends the backend status sync message if the primary node is quarantined on it. + So standby watchdog pgpool must not update its status when the status of current primary node + is not DOWN. + + + + + + + Fix command mode option to work correctly. (Takuma Hoshiai) + + + + + + + Fix to produce correct follow master command. (Tatsuo Ishii) + + + + + + + Fix in native replication mode Pgpool-II rewriting query error when the queries include GROUPS and EXCLUDE in frame clauses. (Bo Peng) + + + + + + + Fix query cache module so that it checks oid array's bound. (Tatsuo Ishii) + + + + + + + Fix off-by-one error in query cache module. (Tatsuo Ishii) + + + + + + + Allow health check process to reload. (Tatsuo Ishii) + + + + + + + Fix segfault when query cache is enabled. (bug 525) (Tatsuo Ishii) + + + + + + + Down grade LOG "checking zapping sent message ..." to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 6620] + + + + + + + Fix segfault when samenet is specified in pool_hba.conf. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 6601]. + + + + + + + Doc: Fix documentation mistakes in follow_master.sh script and typos. (Bo Peng) + + + + + + + Fix health check process is not shutting down in certain cases. (Tatsuo Ishii) + + + + + + + Fix to deal with backslashes according to the config of standard_conforming_strings in native replication mode. + (bug 467) (Bo Peng) + + + + + + + Fix compile error on FreeBSD. + (bug 512, + bug 519) (Bo Peng) + + + + + + + Fix memory leaks. (Tatsuo Ishii) + + + + + + + Make failover in progress check more aggressively to avoid potential segfault. (Tatsuo Ishii) + + + + + + + + Release 4.0.5 + + Release Date + 2019-05-16 + + + + Enhancements + + + + + Doc: Improve document. (Tatsuo Ishii) + + + + + + + Speed up failover when all of backends are down. (Tatsuo Ishii) + + + If all of the backend are in down status, immediately give up finding + primary node regardless search_primary_node_timeout and promptly + finish the failover process. + + + Discussion: [pgpool-hackers: 3321] + + + + + + + pgpool-recovery extension and pgpool_setup is now ready for the next major release PostgreSQL 12. (Tatsuo Ishii) + + + + + + Doc: add entry. (Takuma Hoshiai) + + + + + + + Bug fixes + + + + + Fix the wrong error message "ERROR: connection cache is full", when all backend nodes are down. + (bug 487) (Bo Peng) + + + When all backend nodes are down, Pgpool-II throws an incorrect + error message "ERROR: connection cache is full". Change the error + message to "all backend nodes are down, pgpool requires at least one valid node". + + + + + + + Remove unused .sgml file. (Takuma Hoshiai) + + + + + + + Avoid exit/fork storm of pool_worker_child process. (Tatsuo Ishii) + + + pool_worker_child issues query to get WAL position using do_query(), + which could throws FATAL error. In this case pool_worker_child process + exits and Pgpool-II parent immediately forks new process. This cycle + indefinitely repeats and gives high load to the system. + To avoid the exit/fork storm, sleep sr_check_period. + + + + + + + Fix 's broken default value. (Tatsuo Ishii) + + + + + + + Fix "not enough space in buffer" error. + (bug 499) (Tatsuo Ishii) + + + The error occurred while processing error message returned from + backend and the cause is that the query string in question is too + big. Problem is, the buffer is in fixed size (8192 bytes). + Eliminate the fixed size buffer and use palloced buffer + instead. This also saves some memory copy work. + + + + + + + Fix DROP DATABASE failure. (Tatsuo Ishii) + + + + + + + Fix wrong variable in read_status_file() function. + (bug 493) (Takuma Hoshiai) + + + + + + + Add missing test/watchdog_setup to EXTRA_DIST. (bug 470) (Bo Peng) + + + + + + + Doc: mention that multi-statement queries are sent to primary node only. (bug 492) (Tatsuo Ishii) + + + + + + + Fix md5 auth broken in raw mode with more than 1 backends. + (bug 491) (Tatsuo Ishii) + + + + + + + Test: Fix occasional regression test failure of 014.watchdog_test_quorum_bypass. (Tatsuo Ishii) + + + + + + + Abort session if failover/failback is ongoing to prevent potential segfault. + (bug 481, + bug 482) (Tatsuo Ishii) + + + + + + + Fix compiler warnings. (Tatsuo Ishii) + + + + + + + Fix memory leak in "batch" mode in extended query. + (bug 468) (Tatsuo Ishii) + + + + + + + + Release 4.0.4 + + Release Date + 2019-03-29 + + + + Enhancements + + + + + Add new configuration option . (Muhammad Usama) + + + Add the new setting to let users configure if they + want client's or server's cipher order to take preference. + + + The default for this parameter is off, which prioritize the client's + cipher order as usual. However this is just for keeping backward + compatibility, and it is possible that a malicious client uses weak ciphers. + For this reason we recommend to set this parameter to on at all times. + + + + + + + Allow to set a client cipher list. (Tatsuo Ishii, Yugo Nagata) + + + For this purpose new parameter , which specifies the cipher + list to be accepted by Pgpool-II, is added. + This is already implemented in PostgreSQL and useful to enhance security when SSL is enabled. + + + + + + + Bug fixes + + + + + Fix unnecessary fsync() to pgpool_status file. (Tatsuo Ishii) + + + Whenever new connections are created to PostgreSQL backend, fsync() + was issued to pgpool_status file, which could generate excessive I/O + in certain conditions. + So reduce the chance of issuing fsync() so that it is issued only when + backend status is changed. + + + Discussion: [pgpool-general: 6436] + + + + + + + Doc: add more explanation to . (Tatsuo Ishii) + + + Add description how is executed etc. + + + + + + + Doc: add note to configuration parameter. + (bug 469) (Tatsuo Ishii) + + + To use this feature, must be super user or in pg_monitor group. + + + + + + + + Release 4.0.3 + + Release Date + 2019-02-21 + + + + Changes + + + + + Doc: Update configuration example . (Bo Peng) + + + + + + + Bug fixes + + + + + Skip over "host=" when getting info from conninfo string. (Bo Peng) + + + Patch provided by Nathan Ward. + + + + + + + Test: Fix old JDBC functions and typos in regression test 068.memqcache_bug. (Takuma Hoshiai) + + + + + + + Doc: Fix configuration change timing regarding . (Tatsuo Ishii) + + + + + + + Fix online recovery failed due to in certain cases. + (bug 431) (Tatsuo Ishii) + + + + + + + Reduce memory usage when large data set is returned from backend. + (bug 462) (Tatsuo Ishii) + + + + + + + Test: Fix syntax error in extended query test script. (Tatsuo Ishii) + + + + + + + Fix corner case bug when strip_quote() handle a empty query string. (bug 458) (Tatsuo Ishii) + + + + + + + Doc: Mention that schema qualifications cannot be used in white/black_function_list. (Tatsuo Ishii) + + + + + + + Fix typo about wd_priority in watchdog_setup. (Takuma Hoshiai) + + + + + + + Fixed segfault when wd_lifecheck_method = 'query'. (bug 455) (Muhammad Usama) + + + The fix was proposed by Muhammad Usama and some adjustments to the patch and testing is done by Yugo Nagata. + + + + + + + Fix Pgpool child segfault if failover occurs when trying to establish a connection. (Tatsuo Ishii) + + + + + + + Doc: fix typo in logdir description. (bug 453) (Tatsuo Ishii) + + + + + + + Fix PAM authentication failed. (Takuma Hoshiai) + + + See [pgpool-general: 6353] for more details. + + + + + + + Fix Pgpool-II hang if a client sends a extended query message such as close after sync message but before next simple query. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 3164] + + + + + + + Fix Pgpool-II hang when idle_in_transaction_session_timeout = on. (bug 448) (Tatsuo Ishii) + + + + + + + + Release 4.0.2 + + Release Date + 2018-11-22 + + + + Bug fixes + + + + + + + Fix to sort startup packet's parameters sent by client. + (bug 444)(Takuma Hoshiai) + + + If order of startup packet's parameters differ between cached connection + pools and connection request, didn't use connection pool and created new + connection pool. + + + + + + + + Fix broken authentication for Pgpool-II's internal connections. (Muhammad Usama) + + + The issue is caused by a mistake in "SCRAM and Certificate authentication + support" commit. The problem is while authenticating against backend in + connection_do_auth(), it returns to caller as soon as backend returns auth + ok response. So authentication itself established fine. However + connection_do_auth() does not proceed until it receives "Ready for query". + The fix is to keep processing the data after receiving auth_ok response until we get + "Ready for query". + + + Patch provided by Tatsuo Ishii and a tiny modification made by Muhammad Usama. + + + + + + + Fix compiler warnings with gcc 8.x. (Takuma Hoshiai) + + + + + + + + Fix segmentation fault occurs when a certain Bind message is sent in native replication mode. + (bug 443)(Bo Peng) + + + If the number of parameter format codes is specified to one, but the number + of the original query's parameter is zero, bind_rewrite_timestamp() + will call memcpy with a negative value. + This causes segmentation fault. + + + Patch is provided by Yugo Nagata. + + + + + + + + Fix a query passed to relcache so that it uses schema qualified table name. (Tatsuo Ishii) + + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + + + + + + Fix segfault in extended query + query cache case. (Tatsuo Ishii) + + + + + + + Fix memory leak in extended query + query cache enabled. (Tatsuo Ishii) + + + + + + + + Release 4.0.1 + + Release Date + 2018-10-31 + + + + Changes + + + + + Allow ssl key files to be owned by users other than Pgpool-II user and root. (Muhammad Usama) + + + + + + + Allow PCP[attach/detach/promote] commands during failover. (Muhammad Usama) + + + + + + + Bug fixes + + + + + + Fix corruption of file due to the different lengths of md5, AES and text type passwords. (Muhammad Usama) + + + The patch was provided by Takuma Hoshiai and modified by Muhammad Usama. + + + + + + + Fix typo in child_max_connections description of SHOW POOL_STATUS output. (Tatsuo Ishii) + + + Patch provided by Phil Ramirez. + + + + + + + Fix segmentation fault when error query and Sync message are sent in native replication mode. (bug 434) (Takuma Hoshiai) + + + In native replication mode, segmentation fault occurs when Sync messages is sent just after a query error. + + + + + + + + Release 4.0 + + Release Date + 2018-10-19 + + + + Overview + + This version adds support for SCRAM and CERT authentication, + improves load balancing control and import PostgreSQL 11 + new SQL parser. + + + Major enhancements in Pgpool-II 4.0 include: + + + + + + + + Add SCRAM and Certificate authentication support. + + + + + Detecting "false" primary server of PostgreSQL. + + + + + + Improvement of load balancing: + + + + More load balancing fine control after write queries. + + + + + Load balancing control for specific queries. + + + + + Allow to specify load balance weight ratio for load balance parameters. + + + + + + + + + Add last state change timestamp to . + + + + + Import PostgreSQL 11 SQL parser. + + + + + Logging client messages. + + + + + + + Migration to Version 4.0 + + Version 4.0 contains a number of changes that may affect compatibility with + previous releases. Observe the following incompatibilities: + + + + + + Add 1st/2nd stage online recovery commands parameter to get the node number to be recovered. (Tatsuo Ishii) + + + Online recovery script now accepts 5 parameters, rather than 4 (the 5th + parameter is node number to be recovered). + Run ALTER EXTENSION pgpool_recovery UPDATE TO '1.2' + to update pgpool_recovery version. + Existing 4-parameter-style recovery scripts can be used if you don't care + about information provided by the 5th parameter. + + + See and + for more details. + + + + + + fail_over_on_backend_error parameter is renamed to + . (Muhammad Usama) + + + Now we throw a warning message when old config name fail_over_on_backend_error + is used instead of . + Using the old config variable name will have no effect. + + + + + + Allow to specify the AES encrypted password in the pgpool.conf. (Muhammad Usama) + + + Since 4.0, you can specify the AES encrypted password in the + pgpool.conf file for , + , and + . + + + To specify the unencrypted clear text password, prefix the password string with TEXT. + In the absence of a valid prefix, Pgpool-II will consider the string as a plain text password. + + + The empty password string specified in the + pgpool.conf file for , + , and + will only be used when the + does not contain the password for that specific user. + If these parameters are left blank, Pgpool-II will first try to + get the password for that specific user from file before + using the empty password. + + + + + + + Major Enhancements + + + + + Add support for SCRAM and Certificate + based authentication methods. (Muhammad Usama) + + + + Add support for SCRAM authentication method. + + + SCRAM authentication is supported using the pool_passwd authentication file. + + + See for more details. + + + + + Allow to use CERT authentication between Pgpool-II and frontend. + + + To use this authentication method, Pgpool-II will require that the client provide a valid certificate. + + + See for more details. + + + + + Able to use different auth methods for frontend and backend. + + + Now it is possible to use different authentication methods between + client to Pgpool-II and Pgpool-II to backend. + + + + + + + Now can store three format passwords. AES256 encrypted format, plain text format and md5 format. + + + Pgpool-II identifies the password format type by it's prefix, + so each password entry in the pool_passwd must be prefixed as per the password format. + + + md5 hashed passwords will be prefixed with md5 and AES256 encrypted password types + will be stored using AES prefix. + To store the password in the plain text format TEXT prefix can be used. + + + In the absence of a valid prefix, Pgpool-II will be considered the string as a plain text password. + + + For example: + + username1:AESIFwI86k+ZbVdf6C+t3qpGA== + username2:md59c6583185ba6a85bdcd1f129ec8cabb4 + username3:TEXTmypassword + + + + + + + + Able to use MD5 and SCRAM authentication methods + to connect to database without . + + + A new configuration parameter is added. + This parameter enables this config allows the Pgpool-II + to use clear-text-password authentication with frontend clients when + file does not contain the password for the connecting user, + and use that password (provided by client) to authenticate with the backend + using MD5 and/or SCRAM authentication. + + + + + + + New utility to create encrypted passwords. + + + A new utility is added to create AES encrypted passwords. + + + + + + See for more details. + + + + + + + Add new parameter . (Tatsuo Ishii) + + + If set detach_false_primary = on, detach false primary node. + The default is off. This parameter is only valid in streaming replication mode + and for PostgreSQL 9.6 or after since this feature + uses pg_stat_wal_receiver. + If PostgreSQL 9.5.x or older version is used, no + error is raised, just the feature is ignored. + + + + + + Add parameter to specify + load balance behavior after write queries appear. (Tatsuo Ishii) + + + This parameter allows to specify the behavior when a write query issued. + + + + + + + Allow to specify load balance weight ratio for load balance parameters. (Bo Peng) + + + Add a new feature to allow to specify load balance weight ratio for + and + parameters. + + + You can specify the list of "database-name:node id(ratio)" pairs to + send SELECT queries to a particular backend node for a particular + database connection at a specified load balance ratio. + + + Also you can specify list of "application-name:node id(ratio)" pairs to + send SELECT queries to a particular backend node for a particular client + application connection at a specified load balance ratio. + + + This load balance ratio specifies a value between 0 and 1, + and the default is 1.0. + + + + + + + Add new parameter to enable + specifying SQL patterns lists that should not be load-balanced. (Bo Peng) + + + Specify a semicolon separated list of SQL patterns that + should be sent to primary node only. Regular expression can be + used in SQL patterns. Only Master Slave mode is supported. + + + + + + + Add new parameter to allow logging client message. (Takuma Hoshiai, Tatsuo Ishii) + + + Set log_client_messages = on, any client messages will be logged without debugging messages. + + + + + + Add last_status_change column to command. (Tatsuo Ishii) + + + The new column indicates the time when status or role has been changed. + + + See + [pgpool-hackers: 2822] for the reasoning to add the column. + + + + + + Import PostgreSQL 11's SQL parser. (Bo Peng) + + + Now Pgpool-II can fully understand the newly added SQL syntax + in PostgreSQL 11, + such as CREATE/ALTER/DROP PROCEDURE, + { RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ], etc. + + + + + + + Other Enhancements + + + + + Add "-r" option to pgpool_setup to allow use of pg_rewind. (Tatsuo Ishii) + + + With this option, pgpool_setup creates basebackup.sh which tries + pg_rewind first. If it fails, falls back to rsync. + + + Also a new environment variable "USE_PG_REWIND" to pgpool_setup is added. + This brings the same effect as "-r" option is specified. + + + + + + + Add "-s" option to pgpool_setup to support for replication slot. (Tatsuo Ishii) + + + This eliminates the problem when standby is promoted. When a standby + is promoted, it changes the time line in PITR archive, which will stop + other standby if any because of shared archive directory. + + + Also a new environment variable "USE_REPLICATION_SLOT" to pgpool_setup is added. + This brings the same effect as "-s" option is specified. + + + If "USE_REPLICATION_SLOT=true", in streaming replication mode, + use replication slot instead of archive. + + + By setting USE_REPLICATION_SLOT environment variable, + now pgpool_setup in all tests uses replication slots. + This reduces disk space under src/test/regression from + 6.3GB to 5,1GB (1.2GB savings). + + + + + + Introduce to Pgpool-II. (Takuma Hoshiai) + + + A new utility is added to test PostgreSQL + or any other servers that understand the frontend/backend protocol. + + + + + + Allow to display Pgpool-II child process id and + PostgreSQL backend id in . (Tatsuo Ishii) + + + Add --all option to display all child processes and their available connection slots. + + + + + + Add replication_delay and last_status_change to + . (Tatsuo Ishii) + + + + + + Add role, replication_delay and last_status_change columns to pgpool_adm's + . (Tatsuo Ishii) + + + + + + + Changes + + + + + Downgrade most of DEBUG1 messages to DEBUG5. (Tatsuo Ishii) + + + This significantly reduces the size of pgpool log when pgpool starts + with -d option (this is equivalent to setting to + debug1). + + + Per discussion + [pgpool-hackers: 2794]. + + + + + + + Bug fixes + + + + + Fix syntax error in native replication, when queries including time functions + (now(), etc.) and IN (SELECT ...) + in WHERE clause. + (bug 433) (Bo Peng) + + + + + + + Fix compiler error if HAVE_ASPRINTF is not defined. (Tatsuo Ishii) + + + + + + + Fix configure.ac to remove generating src/sql/pgpool_adm/Makefile.in. (Tatsuo Ishii) + + + + + + + Fix pgpool main process segfault when PostgreSQL 9.5 is used. (Tatsuo Ishii) + + + pgpool_setup -n 3 (or greater) triggers the bug. While recovering node + 2, pgpool main process tried to retrieve version info from backend #2 + even if it's not running. This causes the segfault because connection + was not established yet. The reason why PostgreSQL 9.6 + or later was not suffered from the bug was, PostgreSQL + exited the loop as soon as the server version is higher than 9.5. To fix this, + call to VALID_BACKEND macro was added. + + + + + + + Add missing in pgpool_setup. (Tatsuo Ishii) + + + Per node health_check_timeout was missing and this should had been + there since the per node health check parameter support was added. + + + + + + + Test: Try to reduce the chance of regression 006.memcache failure. (Tatsuo Ishii) + + + It seems the occasional failure of the test is caused by replication + lag. The script tries to read tables from standby but it returns a + table not existing error. So insert pg_sleep() after creation of + tables. + + + + + + + Test: Fix regression test 055.backend_all_down error. (Bo Peng) + + + + + + + Doc: Enhance online recovery document. (Tatsuo Ishii) + + + Clarify that 2nd stage command is only required in native replication mode. + + + + + + + Test: Add new regression test 017.node_0_is_down for node 0 not being primary. (Tatsuo Ishii) + + + + diff --git a/doc/src/sgml/release-4.1.sgml b/doc/src/sgml/release-4.1.sgml new file mode 100644 index 000000000..d98786ca9 --- /dev/null +++ b/doc/src/sgml/release-4.1.sgml @@ -0,0 +1,5204 @@ + + + + + Release 4.1.23 + + Release Date + 2024-11-28 + + + + Bug fixes + + + + + + Abort SSL negotiation if backend sends an error message. (Tatsuo Ishii) + + + In the client side implementation of SSL negotiation + (pool_ssl_negotiate_clientserver()), it was possible for a + man-in-the-middle attacker to send a long error message to confuse + Pgpool-II or client while in the SSL negotiation phase. This commit + rejects the negotiation immediately (issue a FATAL error) and exits + the session to prevent such an attack. + + + This resembles PostgreSQL's CVE-2024-10977. + + + + + + + Fix the watchdog process not reloading configurations. (Bo Peng) + + + The reload_config() function + in Pgpool-II should send + a SIGHUP signal to the watchdog process. + + + + + + + Fix bug in do_query. (Tatsuo Ishii) + + + Fix do_query to use ntohs/ntohl instead of htons/htonl. + + + + + + + Fix authentication failure after updating pool_passwd and reload. (Tatsuo Ishii) + + + If pool_hba.conf is disabled, + updating pool_passwd was not recognized + by Pgpool-II child process even + if Pgpool-II reload was performed. + The reload processing function check_config_reload() mistakenly assumed + that reopening pool_passwd was only necessary when + is on. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html" + + + + + + + Fix COPY hangs. (#79) (Tatsuo Ishii) + + + During COPY IN state (i.e. COPY FROM STDIN), frontend can send Flush + or Sync messages. According to the F/B protocol specification, they + should be ignored but Pgpool-II treated as an invalid message and this + causes COPY hung. + + + Also a regression test is added for this issue. + + + + + + + Fix sporadic health check failures due to authentication failure. (Tatsuo Ishii) + + + When is empty string, + health check process looks for the password from pool_passwd file. + Problem is, the file descriptor for the file is inherited from + parent pgpool process. + This means that pgpool main and health check process (possibly multiple + process) share the same descriptor, which causes various problem + including the issue reported here. To fix the problem, re-open the + file when health check process starts so that each health check + process owns its own file descriptor. + + + Note that pgpool child process (responsible for frontend sessions) + already re-opens the file descriptor and they are not related to the + issue. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + Optimize query cache invalidation for ALTER ROLE. (Tatsuo Ishii) + + + Commit 6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89 invalidates query + cache if any ALTER ROLE/USER statement is used. + Actually this is an overkill. + Because following queries do not affect the privilege of the role. + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + So do not invalidate query cache if those commands are used. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Fix bug in replication/snapshot isolation mode. (#69) (Tatsuo Ishii) + + + When INSERT command is received, + pgpool automatically issues table LOCK command to the + target table but it forgot to send the command to + other than main nodes. This only happened in extended query mode. + + + + + + + Fix another bug in native replication/snapshot isolation mode. (Tatsuo Ishii) + + + insert_lock() forgot to send row lock command (lock_kind == 3 case) to + other than main node. + + + + + + + Fix resource leaks in pool_memqcache.c. (Tatsuo Ishii) + + + These leaks were brought in by commit 6fdba5c33. + + + + + + + + Documents + + + + + Fix typos in the documentation and sample configuration files. (Bo Peng) + + + + + + + + Release 4.1.22 + + Release Date + 2024-09-09 + + + + Overview + + This release contains a security fix. + + + When the query cache () feature is enabled, + it was possible that a database user can read rows from tables that should + not be visible for the user through query cache (CVE-2024-45624). + + + All versions of Pgpool-II older than + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22, and all older + versions that has the query cache feature (the query cache feature was + implemented in 3.2) are affected by the vulnerability. + + + + + + If query cache is created for a table for a user, and then the + access right of the table is revoked from the user by + REVOKE command, still it was possible for the + user to access the table which the user does not have the access + right through the query + cache. + + + + + + If query cache is created for a table for user A, and then other + user B accesses the table via SET ROLE or + SET SESSION_AUTHORIZATION in the same session, + still it was possible for the user B to access the table which B + does not have the access right through the query + cache. + + + + + + If query cache is created for a row security enabled table for user + A, and then other user B accesses the table via SET ROLE + or SET SESSION_AUTHORIZATION in the same session, + it was possible for the user B to retrieve rows which should not be + visible from the user B through the query cache. + + + + + + It is strongly recommend to upgrade to Pgpool-II + 4.5.4, 4.4.9, 4.3.12, 4.2.19 and 4.1.22 or later. Or you should better turn + off the query cache feature. + + + + Note that to fix the vulnerability, some commands (ALTER DATABASE, + ALTER ROLE, ALTER TABLE, REVOKE) now invalidate whole query cache + data. This may affect the performance when using the query cache + feature. + + + + + Changes + + + + + Back port . (Tatsuo Ishii) + + + This is mainly for testing. Backpatch-through: v4.1 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + Bug fixes + + + + + + Fix bugs in replication mode and snapshot isolation mode. (Tatsuo Ishii) + + + The following bugs was fixed: + + + + + In replication mode and snapshot isolation mode when a command finishes, + Pgpool-II waits for a ready for query message + but forgot that some commands (for example SET ROLE) + produces a parameter status message. As a result + Pgpool-II errors + out that other message arrives before the ready for query message. + + + + + + If previous query produces parameter status message, subsequent + parse() needs to read and process it because + it wants to read Ready for query message which is supposed to follow + the parameter status message. + However when ParameterStatus() gets called, + the query in progress flag was set and it was possible that only + one of parameter status message from backend was processed if the + query processed in this parse() call is load + balanced. It is likely that the parameter status message comes from + all live backend because they are generated by SET + command, and SET command are sent to all live backend + in replication mode and snapshot isolation mode. So unset the query in + progress flag before calling ParameterStatus(). + + + + + + + + + + + Release 4.1.21 + + Release Date + 2024-08-15 + + + + Changes + + + + + + Use psql -V instead of initdb -V + in sample scripts. (Bo Peng) + + + Use psql -V instead of initdb -V + in the sample scripts because in some cases postgresqlxx-server may not + be installed. + + + + + + + + Bug fixes + + + + + + Fix hang after a flush message received. (#59) (Tatsuo Ishii) + + + + + + + Fix segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool child segfaulted in pool_do_auth. The cause + was MAIN_CONNECTION() returns NULL. It seems my_main_node_id was set + to incorrect node id 0, which was actually in down status. thus there + was no connection in cp->slots[0]. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9175] + + + + + + + Fix segfault to not use MAIN_NODE macro. (Tatsuo Ishii) + + + Some functions (close_idle_connection(), new_connection() and + pool_create_cp()) used MAIN* and VALID_BACKEND where they are not + appropriate. MAIN* and VALID_BACKEND are only useful against current + connections to backend, not for pooled connections since in pooled + connections which backend is the main node or up and running is + necessarily same as the current connections to backend. + The misuses of those macros sometimes leads to segfault. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9114] + + + + + + + Fix MAIN_NODE macro (actually pool_virtual_main_db_node_id()). (Tatsuo Ishii) + + + The macro used to return REAL_MAIN_NODE_ID if there's no session context. + This is wrong since REAL_MAIN_NODE_ID can be changed any time when + failover/failback happens. + + + Suppose REAL_MAIN_NODE_ID == my_main_node_id == 1. + Then due to failback, REAL_MAIN_NODE_ID is changed to 0. + Then MAIN_CONNECTION(cp) will return NULL and any + reference to it will cause segmentation fault. To prevent the issue we + should return my_main_node_id instead. + + + + + + + Fix segfault in a child process. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + Watchdog dies and kills pgpool2 when network gets shortly interrupted. (#823) (Muhammad Usama) + + + With network monitoring enabled, a Pgpool-II + node would shut down immediately if it lost all network interfaces or + assigned IP addresses, providing extra protection by quickly removing + a non-communicative node from the cluster. + + + The issue was that Pgpool-II responded to network blackout events even when network + monitoring was disabled. This fix ensures that the network monitoring socket is + not opened when network monitoring is not enabled, preventing unnecessary shutdowns. + + + + + + + Fix psql_scan crash. (#54) (Tatsuo Ishii) + + + It was reported that psql_scan crashes while determining whether a + string in a long query is psql variable (i.e. starting with ":") or not. + + + + + + + + Documents + + + + + + Mega typo fix for docs and program source codes. (Tatsuo Ishii) + + + Patch is created by Umar Hayat. + + + + + + + Add the missing default values for virtual IP related parameters. (Bo Peng) + + + + + + + + + Release 4.1.20 + + Release Date + 2024-05-16 + + + + Bug fixes + + + + + + Fix assorted causes of segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool and its child process segfault in certain + cases when failover involved. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + Fix uninitialized memory error. (Tatsuo Ishii) + + + It was reported that valgrind found several errors including an + uninitialized memory error in read_startup_packet. It allocates memory + for user name in a startup packet in case cancel or SSL request using + palloc, and later on the memory is used by pstrdup. Since memory + allocated by palloc is undefined, this should have been palloc0. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + Fix errors/hung up when load_balance_mode is off. (Tatsuo Ishii) + + + Commit 3f3c1656 + brought errors/hung up when load_balance_mode is off, primary node id + is not 0 and queries are BEGIN etc. + + + Bug found and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + Fix compile errors with certain CFLAGS. (Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42 + reported that with CFLAGS + -flto=4 -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing + gcc emits errors. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + Fix comments in sample pgpool.conf. (Bo Peng) + + + The default value for sr_check_period should be 10 seconds. + Also fixed some typos in comments. + + + Patch is created by hiroin and modified by Bo Peng. + + + + + + + Allow reset queries to run even if extended queries do not end. (Tatsuo Ishii) + + + Commit 240c668d + caused reset queries fail if extended query messages do not end. This commit + fix that by checking whether we are running reset queries in + SimpleQuery(). Also add the test case for this. + + + + + + + Guard against inappropriate protocol data. (Tatsuo Ishii) + + + If a simple query message arrives before a sequence of extended query + messages ends pgpool could hang. This is because the query context in + the session context for the simple query is overwritten by the query + contexts of the extended query messages. + + + This commit implements a guard in SimpleQuery() by checking whether + extended query protocol messages ended. If they do not end, raise a + FATAL error. A known example detected by this checking is JDBC + driver's "autosave=always" option. This means pgpool will not accept + the option after this commit until the issue (sending a simple + protocol message before ending extended query message protocol) is + fixed by the JDBC driver side. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + Documents + + + + + + Enhance "Upstream server connection" documentation. (Bo Peng) + + + + + + + Language cleanup in Japanese document. (Masaya Kawamoto) + + + + + + + + Regression Tests + + + + + + Fixed regression test 005.jdbc to avoid Java 21 deprecation warnings. (Bo Peng) + + + Replace Runtime.exec(String) with Runtime.exec(String[]) to avoid Java 21 deprecation warnings. + Patch is created by Vladimir Petko and modified by Bo Peng. + + + + + + + + + Release 4.1.19 + + Release Date + 2024-02-29 + + + + Changes + + + + + Remove restore_command from sample scripts. (Bo Peng) + + + Restore_command is not required because replication slot is enabled. + It causes occasional failover failure. + + + + + + + Bug fixes + + + + + Fixed the default values of . (Bo Peng) + + + Because the default value of recovery_user + should be same as and + , I changed the default value + from '' to 'nobody'. + + + + + + + Fixed with BEGIN etc. (Tatsuo Ishii) + + + When statement_level_load_balance is enabled, + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE + ALL/DISCARD were sent to primary node and all standby nodes even if + is off. + This is not only plain wrong but caused slow + down if one of the standby nodes are in remote network. + + + Fix this in that pgpool sends such queries to primary node only when + load_balance_mode is off. + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + Documents + + + + + Fix Japanese watchdog document. (Tatsuo Ishii) + + + It mistakenly used "master" watchdog node instead of "leader". + + + + + + + Fix English watchdog document. (Tatsuo Ishii) + + + It mistakenly used "main" PostgreSQL node instead of "primary". + + + + + + + + Release 4.1.18 + + Release Date + 2023-11-30 + + + + Changes + + + + + Modify the replication slot name conversion in sample scripts + to support for the hostname in uppercase. (Bo Peng) + + + Replication slots are automatically created or deleted in the scripts + which are executed during failover or online recovery. + Since uppercase can't be used for a replication slot name, modify these scripts + to convert the hostname to lowercase. + + + Patch is created by Sheikh Wasiu Al Hasib and modified by Bo Peng. + + + + + + + Bug fixes + + + + + Remove unnecessary logging line. (Tatsuo Ishii) + + + Debug message "unset_tx_started_by_multi_statement_query is called in CommandComplete" was accidentally left. + + + + + + + Fix Describe() so that it does not abort with portal created by DECLARE. (Tatsuo Ishii) + + + When DECLARE foo CURSOR FOR is executed, + a portal named "foo" is automatically created by PostgreSQL. + As the portal is not managed by Pgpool-II, + "Describe foo" message failed with "unable to execute Describe. + unable to get the bind message" error. + + + To fix this, make Describe() create a dummy write query + context so that the describe message is sent to primary (streaming replication + mode) or all nodes (replication/snapshot isolation mode). + + + Also add test case 080 for this commit. + + + This problem was reported and analyzed by Heather Lapointe. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + Remove duplication definitions of NAMEDATALEN. (Tatsuo Ishii) + + + The definition for NAMEDATALEN is now in + src/include/pg_config_manual.h only. + Also replace POOL_NAMEDATALEN with + NAMEDATALEN in + src/utils/pool_select_walker.c. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + Documents + + + + + Modify "Pgpool-II + Watchdog Setup Example" to mention that + pcp_listen_addresses = '*' is required to + allow PCP to listen on all addresses. + + + + + + + + Release 4.1.17 + + Release Date + 2023-08-17 + + + + Changes + + + + + Install system exit callback only after initialization of shared memory. (Muhammad Usama) + + + When the on-exit callback gets called because of a failure to acquire + shared memory. The cleanup function can produce a segfault while accessing + process_info, that lives in shared memory. + Although we can also fix this by bailing out from the exit callback when + process_info is NULL but installing the function after successful initialization + of shared memory is a better approach as the rest of the system always assumes + the process_info can never be NULL, and also, there is nothing to + clean up before child processes are spawned. + + + + + + + Add schema qualification to some system catalog inquiry functions. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + Fix coverity warning. (Tatsuo Ishii) + + + Fix query cache module assigned time_t value to int32 variable. Change + the variable type to int64. Per Coverity. Also use difftime() to + calculate time_t difference. This is a recommended practice. + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + Fix find_primary_node_repeatedly doesn't terminate within . (Bo Peng) + + + + + + + Fix PREPARE in multi-statement case. (Tatsuo Ishii) + + + If multi-statement query includes PREPARE in the second or latter + position, and subsequent bind message uses the prepared statement, it + fails with "unable to bind" error because the prepared statement is not + saved in sent messages. + + + To fix this if such a case found after parsing the statement, create a + query context for the named statement and add it to the sent message list. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + For this new regression test 079..multi_prepare is added. + + + + + + + Fix pgproto to work with bind message using params. (Tatsuo Ishii) + + + Previously pgproto can only process bind messages without params. + + + + + + + Documents + + + + + Clarify the meaning of stop mode. (Tatsuo Ishii) + + + + + + + Enhance SSH public key authentication setting section in "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Enhance online recovery documentation. (Bo Peng) + + + Mention that 2nd stage of online recovery does not work properly only for multiple pgpool nodes without watchdog enabled. + + + + + + + Regression Tests + + + + + Fix occasional 069.memory_leak_extended test failure. (Tatsuo Ishii) + + + It turned out that reason of the occasional test failure is, pgpool + child process is gone before running ps command after pgbench + finishes. The cause is a kind mismatch FATAL error, "DISCARD ALL + cannot be executed within a pipeline". To fix this, run pgbench in + background and get the process size before pgbench finishes. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + Release 4.1.16 + + Release Date + 2023-05-18 + + + + Changes + + + + + Import psqlscan source code into Pgpool-II to judge multi statement query. (Tatsuo Ishii) + + + Psqlscan is a module in the PostgreSQL source tree. + It is essentially subset of PostgreSQL SQL scanner + but it is specialized for detecting + the end of each SQL statement. Therefore we can count the number of + SQL statements in a query string by using it. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + Allow to use multiple statements extensively. (Tatsuo Ishii) + + + This commit tries to eliminate pgpool's long standing limitations + regarding multiple statements (multi-statements). + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + Use schema qualification for internal queries. (Tatsuo Ishii) + + + Some of objects such as function and cast did not use "pg_catalog." + schema qualification. This does not lead to immediate security + concern but using the schema qualification is always good practice. + + + + + + + Bug fixes + + + + + Fix possible dead lock with shared relation cache. (Tatsuo Ishii) + + + When a user defined function obtains table locking, call to the + function using extended query protocol could lead to dead lock. Here's + a scenario: + + + + (1) In session A client sends parse, bind, execute request for the function to pgpool. + + + + + + + (2) Pgpool-II in session A forwards + the request to PostgreSQL. + + + + + + + (3) PostgreSQL in session A performs execute, resulting in a table lock. + + + + + + + (4) In session B client sends parse, bind, execute request for the + function to pgpool. + + + + + + + (5) Pgpool in session B forwards the request to PostgreSQL. + + + + + + + (6) PostgreSQL in session B performs bind but the table was already + locked by PostgreSQL in session A, and it waits for release of the + lock. + + + + + + + (7) After pgpool in session B forwards the execute to PostgreSQL, it + acquires semaphore to search shared relation cache to check the + volatility of the function. Then it calls do_query and sends flush + message to PostgreSQL to obtain the response from PostgreSQL up to + this point. But since PostgreSQL is waiting for table lock in #6, + pgpool has to wait for messages beyond bind complete. + + + + + + + (8) After pgpool in session A forwards the execute to PostgreSQL, it + tries to acquire semaphore to search shared relation cache to check + the volatility of the function but the semaphore was already + acquired by pgpool in session B, it waits for the release of the + semaphore. + + + + + + + (9) Session A and session B wait for each other, resulting in a dead lock. + + + + + + To fix this, modify pool_search_relcache() so that it releases + semaphore before calling do_query() (but acquires semaphore after + do_query()). By this, session A in #8 above can get semaphore, and go + forward. It receives sync message from client and forwards it to + PostgreSQL. Upon receiving sync, the user defined function will finish + the execution and releases the table lock. This makes PostgreSQL in + session B move forward because now it can obtain the table lock. + + + + + + + Fix compile error on systems using musl libc. + (bug 790) (Tatsuo Ishii) + + + Patch provided by leimaohui. + + + + + + + Fix multiple query cache bug. (Tatsuo Ishii) + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + Fix sr worker to not send wrong query to standby server in corner case. (Tatsuo Ishii) + + + When ALWAYS_PRIMARY flag is set, PRIMARY_NODE_ID macro returns node + id, rather than -1 even if the primary is down. + In this case streaming replication delay check worker + sends SELECT pg_current_wal_lsn() or + SELECT pg_current_xlog_location() + depending on PostgreSQL's version to + standby which of course raises an error. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + Fix kind mismatch error with DEALLOCATE. + (bug 780) (Tatsuo Ishii) + + + Kind mismatch error occurs when conditions below are all met: + + + + streaming replication mode + + + + + + + load balance node is other than primary + + + + + + + PREPARE is used in a multi-statement query + + + + + + + + + + Documents + + + + + Add explanation for . (Chen Ningwei) + + + + + + + Add restriction regarding PREPARE/EXECUTE/DEALLOCATE. (Tatsuo Ishii) + + + + + + + Add caution to use -D option with pgpool. (Tatsuo Ishii) + + + + + + + Enhancing "Installation from RPM" section. (Bo Peng) + + + + + + + Remove the configuration of "-D" start OPTS from "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Mention that AES256 support requires option. (Tatsuo Ishii) + + + + + + + Explicitly stat that it is -w option of pcp command is needed to use .pcppass. (Tatsuo Ishii) + + + + + + + Enhance . (Tatsuo Ishii) + + + + + + + Regression Tests + + + + + Refactor 071.execute_and_deallocate/test.sh. (Tatsuo Ishii) + + + + + + + Enhance regression tests. (Tatsuo Ishii) + + + + + + + Fix occasional 005.jdbc test failure. (Tatsuo Ishii) + + + + + + + + Release 4.1.15 + + Release Date + 2023-01-23 + + + + Overview + + This release contains a security fix. + + + If following conditions are all met, the password of is + exposed by command. + The command can be executed by any user who can + connect to Pgpool-II. (CVE-2023-22332) + + + + + + Version 3.3 or later. + + + + + + is on. + + + + + + is query. + + + + + + A plain text password is set + to . + + + + + + In this case it is strongly recommended to upgrade to this version + (we do not expose in + show pool_status command any more), or use one of following + workarounds. + + + + Workarounds for 4.0.x to 4.4.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + Set an empty string + to . This will use + password in the pool_passwd file. + + + + + + Set an AES encrypted password + to . + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Workarounds for 3.0.x to 3.7.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Please note that Pgpool-II 3.7.x or + before are end of life and no minor updates are provided for those + versions. + + + + + Changes + + + + + + Do not expose in + , + and + commands. (CVE-2023-22332) (Bo Peng) + + + + + + + Change the default value + for to empty string as + documented. (Bo Peng) + + + + + + + + Bug fixes + + + + + + Fix compiler warning + in pgpool-regclass.c. (Florian Weimer, + Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: Enhance and fix some mistakes + in Configurations + to use shared memory chapter. (Tatsuo Ishii) + + + + + + + + + Release 4.1.14 + + Release Date + 2022-12-22 + + + + Changes + + + + + Downgrade LOG messages "new IPC connection received" to DEBUG1. + (bug 775) (Bo Peng) + + + It is a normal messages and should not be logged as LOG. + Patch is created by pstef and reviewed by Bo Peng. + + + + + + + + Bug fixes + + + + + + Fix issue with . (Muhammad Usama) + + + The fix is to dynamically set the failover command timeout based on the maximum + value of health check parameters across the watchdog cluster. + + + Reviewed and tested by Tatsuo Ishii. + Discussion: [pgpool-hackers: 4227] + + + + + + + Fix not to print warnings of use of backslashes in parser. (Tatsuo Ishii) + + + When standard_conforming_strings = off and escape_string_warning = on, + PostgreSQL prints warnings if backslashes are used in string + literal. This is fine. But previously Pgpool-II's parser printed the + same message too. This is redundant. + + + + + + + Deal with idle_session_timeout. (Tatsuo Ishii) + + + If idle_session_timeout (added in PostgreSQL 14) is enabled and the + timeout fires, followings happen: + + + + If failover_on_backend_error is on (the default), Pgpool-II will trigger failover. + + + + + + + If only one of PostgreSQL servers enables idle_session_timeout, Pgpool-II could hang. + + + + + + To deal with idle_session_timeout detect_idle_session_timeout_error() + is added to detect the error code for idle_session_timeout. If the + error is detected, Pgpool-II returns the error code to frontend as a + fatal error and disconnects the session. This is a similar fix + implemented for idle_in_transaction_session_timeout. + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + Discussion: [pgpool-hackers: 4208] + + + + + + + Deal with SSL error SSL_ERROR_ZERO_RETURN. (Tatsuo Ishii) + + + Previously this caused failover, which was actually unnecessary because + it means the server is just going to close the connection. + + + Discussion: [pgpool-general: 8366] + Discussion: [pgpool-hackers: 4193] + + + + + + + Fix: Setting memory cache size greater than 2GB causes a segfault. (Muhammad Usama) + + + The problem was in the block_address() function that returns the memory address + for a given cache block, It was using 32bit integers to calculate the offset of + the block within the shared memory space that is only good until the 2GB limit. + + + + + + + Fix rare segfaults in pcp_proc_info, SHOW pool_pools + and SHOW pool_processes. (Tatsuo Ishii) + + + The segfaults were in get_pools() and get_processes(). They first + extracted pid of particular process info slot on shared memory then + searched the slot again by using pid as the key. Because these steps + were not protected by any locking, it was possible that the search + using the pid failed and returned NULL if the process id is + overwritten by pgpool parent which is responsible for forking new + child process after the process exiting. As a result any subsequent + reference to the NULL pointer generated segfaults. + + + Solution is, first get the pointer to the process info slot then + extract the process id member from the pointer. This way, still + concurrent updating to the shared memory info by the parent process is + possible (which may lead to strange results in the output) but at + least we can avoid segfaults. + + + + + + + Fix to not allow Unix-domain socket path with invalid length. (Masaya Kawamoto) + + + + + + + + Documents + + + + + + Doc: enhance description about memqcache_method. (Tatsuo Ishii) + + + Add explanation which method should be used. + + + + + + + Doc: mention that health check process may use SSL. (Tatsuo Ishii) + + + Also mention that streaming replication check may use SSL too. + This should have been added since 2010. + + + Discussion: [pgpool-hackers: 4187] + + + + + + + + Regression Tests + + + + + + Allow to define PGPOOLDIR using environment variable. + (bug 766) (Bo Peng) + + + + + + + + + Release 4.1.13 + + Release Date + 2022-08-18 + + + + Changes + + + + + + Add ssh options to restore_command in sample scripts. (Bo Peng) + + + Patch is created by Jon SCHEWE and updated by Bo Peng. + + + + + + + When CloseComplete is received, forward to frontend without buffering. (Tatsuo Ishii) + + + It seems this caused occasional timeout error in 074.bug700_memqcache_segfault. + + + + + + + + Bug fixes + + + + + + Fix bug in query cache. (Tatsuo Ishii) + + + Pgpool-II did not cache the query like "Select '2022-02-18 07:00:00.006547'::timestamp". + SELECTs include TIMESTAMP, TIME and DATE are cached, and SELECTs include TIMESTAMPZ + and TIMEZ are not cached because the result can be changed by SET TIME ZONE command etc. + Furthermore, SELECTs having functions with return types are timestamptz or timetz are + not cached too as same reason. + Discussion: [pgpool-general: 8285] + + + + + + + + Documents + + + + + + Doc: mention that certain SELECTs are not cached. (Tatsuo Ishii) + + + certain SELECTs are follows. + + + + SELECTs including TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including CAST to TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including SQLValueFunction (CURRENT_TIME, CURRENT_USER etc.) + + + + + + + + + + Doc: fix description about using PCP password file when connect to Unix domain socket (Masaya Kawamoto) + + + The localhost entry in pcppass matches only for the default PCP socket + directory path, not all Unix socket connections. This behavior is the + same as pgpass. + + + + + + + Doc: enhance and fix memory requirement section. (Tatsuo Ishii) + + + + + + Add explanation about memory usage while pgpool child process is running. + + + + + Enhance the formula to calculate shared memory requirement so that it computes more accurate result. + + + + + Fix shared memory requirement for shared rel cache. The old value 64MB was simply wrong. + + + + + Fix process memory requirement. Previously the formula was based on + RSS. However PSS should be used because RSS includes shared memory + such as the memory used for libraries. This results in lot smaller + memory requirement than before. + + + + + + + + + + Doc: fix wrong explanation on , . (Tatsuo Ishii) + + + Those parameters cannot be changed by reloading config file. Restarting + pgpool is required. + + Discussion: [pgpool-general: 8195] + + + + + + + + Test Tools + + + + + + Allow to run pgpool_setup on PostgreSQL 15. (Tatsuo Ishii) + + + Per ticket 757 + + + + + + + + Regression Tests + + + + + + Test: print Pgpool-II version in the regression test. (Tatsuo Ishii) + + + + + + + Test: Fix regression test script to look for pgpool.conf in the proper install directory. (Tatsuo Ishii) + + + + + + + + + Release 4.1.12 + + Release Date + 2022-05-19 + + + + Changes + + + + + Enhance in stopping pgpool main process. (Tatsuo Ishii) + + + If "pgpool stop" couldn't terminate the main process within certain period (currently 5 seconds), send the signal again. + + + + + + + Change the PID length of pcp_proc_count command to 7 characters long. (Bo Peng) + + + + + + + Enhance error message to include the message kind returned and the backend node id while processing parse message. (Tatsuo Ishii) + + + + + + + Downgrade log level of ParameterStatus message from LOG to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + Change the default value of from '*' to 'localhost'. (Tatsuo Ishii) + + + + + + + Adjust the field name in . (Muhammad Usama) + + + + + + + + Bug fixes + + + + + Fix issue that watchdog cluster keeps rejecting the restarted remote node which is lost previously. (Muhammad Usama) + + + Issue report: [pgpool-general: 7896] + + + + + + + Fix exit_handler in pgpool main process to avoid possible infinite wait. (Tatsuo Ishii) + + + + + + + Fix main process exiting if a backend is failing or shutting down while performing finding primary. (Tatsuo Ishii) + + + + + + + Fix segfaults in watchdog. (Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + Fixed follow_primary.sh.sample script to check the status of PostgreSQL using pg_isready. (Bo Peng) + + + + + + + + Documents + + + + + Doc: update configuration example. (Masaya Kawamoto) + + + + + + + Doc: update the example output of . (Bo Peng) + + + + + + + Doc: mention that escaping is required if you are providing the password as an argument to pg_enc and the password contains a "$" character. (Bo Peng) + + + + + + + + + Regression Tests + + + + + Enhance regression test 018.detach_primary to avoid the timeout error. (Tatsuo Ishii) + + + + + + + Enhance regression test 074.bug700_memqcache_segfault to avoid the timeout error. (Tatsuo Ishii) + + + + + + + Improve regression test to detect segmentation fault. (Bo Peng) + + + + + + + + Release 4.1.11 + + Release Date + 2022-02-17 + + + + Changes + + + + + + Suppress message length log for in_hot_standby. (Tatsuo Ishii) + + + PostgreSQL 14 introduced new config parameter in_hot_standby. + + + The value is either "on" for standby servers or "off" for primary + servers. As a result pgpool log is flooded by the messages: + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + To avoid this, only complain if the parameter name is not in_hot_standby. + + + Also the message is enhanced to show the parameter name. For example: + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + Add validations of and format (Masaya Kawamoto) + + + wd_lifecheck_password and recovery_password + are not allowed to be md5 hashed password format but pgpool just reported + authentication failure and did not check them. + + + + + + + Enhance parameter status handling. (Tatsuo Ishii) + + + When a parameter status message arrives from backend Pgpool-II + forwards it to frontend not just memorize. + + + + + + + + Bug fixes + + + + + + Fix long standing bug with pcp_node_info. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Fix health check process issues pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix memory leak pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix failover() to deal with the case when no former primary node exists. (Tatsuo Ishii) + + + In case Req_info->primary_node_id is -1 like no primary + node exists when Pgpool-II starts up, + failover() skipped to call + find_primary_node_repeatedly(). Also + follow_master_command was not executed. + + + Discussion: [pgpool-hackers: 4113] + + + + + + + Fixed sample failover script. (Bo Peng) + + + This script did not consider the case when the old primary node id is "-1". + + + + + + + Fixed the streaming replication check process not to retry if it cannot connect to the backend. (bug 742)(Bo Peng) + + + This retry caused a long time failover. + + + + + + + + Documents + + + + + + Fix documentation typos. (pengbo) + + + Patch is created by Umar Hayat. + + + + + + + Add "exclude" settings to /etc/yum.repos.d/pgdg-redhat-all.repo so + that Pgpool-II is not installed from + PostgreSQL YUM repository. (Bo Peng) + + + + + + + Add restriction regarding ParameterStatus and in_hot_standby parameter. (Tatsuo Ishii) + + + + + + + Add restriction about set_config. (Tatsuo Ishii) + + + + + + + + Test tools + + + + + + Fix pgpool_setup in failover script creation. (Tatsuo Ishii) + + + When pgpool_setup creates failover.sh, + it did not consider the case when no primary server existed. + + + + + + + + Regression tests + + + + + + Allow to run regression test against existing installation without recompiling. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + Fix regression test 075. (Tatsuo Ishii) + + + The test reported success even if pgpool does not start up. + Problem reported and patch provided by Qiang Lingjie. + Discussion: [pgpool-hackers: 4085] + + + + + + + Fix pgpool_setup and watchdog_setup binary PATH in noinstall mode. (Bo Peng) + + + + + + + + + Release 4.1.10 + + Release Date + 2021-12-23 + + + + Changes + + + + + + Suppress bison warnings regarding yacc incompatibility. (Tatsuo Ishii) + + + + + + + Fix redundant code. (Tatsuo Ishii) + + + Patch contributed by Lu Chenyang. + + + + + + + + Documents + + + + + + Doc: fix typo in pcp_watchdog_info manual. (Tatsuo Ishii) + + + + + + + Doc: fix typos in configuration example. (Bo Peng) + + + Patch is created by Lu Chenyang. + + + + + + + Doc: fix typos in release notes. (Bo Peng) + + + + + + + + + Release 4.1.9 + + Release Date + 2021-11-18 + + + + Security release + + + + + Reject extraneous data after SSL encryption handshake. (Tatsuo Ishii) + + + In the server side implementation of SSL negotiation, it was possible for a + man-in-the-middle attacker to inject arbitrary SQL commands. This is + possible if Pgpool-II is configured to use cert authentication or + hostssl + trust. This resembles PostgreSQL's CVE-2021-23214. + + + Similarly, in the client side implementation of SSL negotiation, it was + possible for a man-in-the-middle attacker to inject arbitrary responses. + This is possible if PostgreSQL is using trust authentication with a + clientcert requirement. It is not possible with cert authentication because + Pgpool-II does not implement the cert authentication between Pgpool-II + and PostgreSQL. This resembles PostgreSQL's CVE-2021-23222. + + + + + + + Changes + + + + + + Deal with PostgreSQL 14 while processing + pg_terminate_backend(). (Tatsuo Ishii) + + + + + + + Enhance SIGCHLD handler of Pgpool-II main process. (Tatsuo Ishii) + + + When Pgpool-II child is killed by SIGKILL signal, + the SIGCHLD handler just emitted LOG level message as other signals. But + SIGKILL is an important event, for example killed by OOM killer. So emit a + WARNING level message instead. + Per suggestion from Michail Alexakis. + Discussion: [pgpool-general: 7750] + + + + + + + + Bug fixes + + + + + + Fix connection counter issue when is 0. (Tatsuo Ishii) + + + If reserved_connections is 0, we don't need to manage + the connection counter. This will prevent unwanted "Sorry, too many clients + already" error by accidental counter leak. + Discussion: [pgpool-general: 7750] + + + + + + + Fix for bug 732: Segmentation fault at failover ... (Muhammad Usama) + + + + + + + Fix occasional hang in COPY FROM. (Tatsuo Ishii) + + + If an error occurs while doing COPY FROM, it was possible the + Pgpool-II waited forever for a response from + backend after COPY end marker was sent from frontend. + The bug was found by Bo Peng. + + + + + + + Fix the incorrect display of load balancing node in raw mode. (Bo Peng) + + + In raw mode, Pgpool-II sends all queries to main node. + This is harmless, but it may confuse users. + + + + + + + Fix backend_flag* parameter shown twice while executing PGPOOL SHOW ALL. (Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: fix documentation typos. (Bo Peng) + + + + + + + Fix typos in documentation and sample scripts. (Bo Peng) + + + Patch is created by Kazufumi Noto. + + + + + + + Doc: Mention that double quotes are required in PGPOOL SHOW command, + if the parameter contains uppercase letters. (Bo Peng) + + + + + + + + Test tools + + + + + + Fix pgpool_setup to do nothing when no new main node is available. (Tatsuo Ishii) + + + + + + + + Regression tests + + + + + + Fix occasional 073.pg_terminate_backend regression test failure. (Tatsuo Ishii) + + + + + + + Rename regression test 074. (Bo Peng) + + + + + + + Fix psql command path to avoid test failure. (Bo Peng) + + + + + + + + + Release 4.1.8 + + Release Date + 2021-08-05 + + + + Changes + + + + + + Fix maximum length of hostnames including domain name. (Tatsuo Ishii) + + + The maximum length of hostnames was 128, but the correct value is 254. + Discussion: [pgpool-hackers: 3903] + + + + + + + + Bug fixes + + + + + + Fix query cache to not cache SQLValueFunctions. (Tatsuo Ishii) + + + The list of SQLValueFunctions is follow. + + + + CURRENT_DATE + + + + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + + + + + SESSION_USER + + + + + USER + + + + + CURRENT_CATALOG + + + + + CURRENT_SCHEMA + + + + + + + + + + Fix client side hang when describe message is followed by NoData response. (Tatsuo Ishii) + + + Problem reported and patch provided by Daniel van de Giessen. + Discussion: [pgpool-hackers: 3950] + + + + + + + Fix sending invalid message in SI mode. (Tatsuo Ishii) + + + When a query is aborted by specific reason like serialization error, + Pgpool-II sends error query to abort + transactions running on non main nodes. The message length of the + query was incorrect and it caused "invalid string in message" error on backend. + + + + + + + Fix orphan process is left when pgpool is going down. (Tatsuo Ishii) + + + When pgpool is going down while follow primary command is ongoing, + some process started by follow primary child process could be left. + + + + + + + Fix pcp_detach_node leaves down node. (Tatsuo Ishii) + + + As detaching primary node using pcp_detach_node, a + standby node is kept down status after follow primary command was executed. + Discussion: [pgpool-hackers: 3915] + + + + + + + Fix cannot be changed by reloading. (Tatsuo Ishii) + + + + + + + Fix watchdog communication race condition. (Tatsuo Ishii) + + + When watchdog notifies the new message to main process while main process + is executing the process notified by watchdog process, there was a + significant delay before the new message was processing. + Discussion: [pgpool-hackers: 3900] + + + + + + + Fix watchdog node status not updating after rebooting. + (bug 684) (Muhammad Usama) + + + + + + + + Documents + + + + + + Doc: add more explanation about . (Tatsuo Ishii) + + + + + + + Doc: fix documentation typos. (Bo Peng) + + + + + + + Doc: fix typo in in memory query cache document. (Tatsuo Ishii) + + + + + + + Doc: fix wd_life_point description (Masaya Kawamoto) + + + + + + + + Test tools + + + + + + Fix pgpool_setup to generate portable follow_primary.sh. (Tatsuo Ishii) + + + + + + + Fix rsync parameter in pgpool_setup. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup in creating base backup script. (Tatsuo Ishii) + + + + + + + Enhance watchdog_setup script. (Tatsuo Ishii) + + + shutdownall script generated by watchdog_setup caused failover event which is not + necessary in the whole shutdown sequence. + + + + + + + + Regression tests + + + + + + Fix 075.detach_primary_left_down_node. (Tatsuo Ishii) + + + + + + + Fix 031.connection_life_time. (Tatsuo Ishii) + + + + + + + Fix 018.detach_primary error in the log. (Tatsuo Ishii) + + + + + + + Fix occasional failure of 028.watchdog_enable_consensus_with_half_votes test. (Tatsuo Ishii) + + + + + + + Fix occasional regression test 018.detach_primary error. (Tatsuo Ishii) + + + + + + + + + Release 4.1.7 + + Release Date + 2021-05-20 + + + + Bug fixes + + + + + Improve sample scripts. (Bo Peng) + + + + + + + Fix regression test 018.detach_primary. (Tatsuo Ishii) + + + + + + + Fix race condition between and . (Tatsuo Ishii) + + + If and are running concurrently, many problem occurred. + Typical problem is, no primary node is found at the end. + + + + + + + Doc: fix description about . (Tatsuo Ishii) + + + It did not mention the parameter can only be used if Pgpool-II started as root. + + + + + + + Doc: enhance description on . (Tatsuo Ishii) + + + + + + + + + Doc: remove incorrect description about . (Tatsuo Ishii) + + + + + + + + + Fix broken database/app redirect preference in statement level load balancing mode. + (bug 707) (Bo Peng) + + + + + + + Fix to create database cluster entity under pgpool0. (Tatsuo Ishii) + + + + + + + Fix pgpool crash when query cache enabled. + (bug 700) (Tatsuo Ishii) + + + Pgpool-II crashed upon receiving CloseComplete. This only happened in other than streaming and logical replication mode. + + + + + + + Improve follow_primary.sh sample scripts. + (bug 694) (Bo Peng) + + + Empty pg_replslot directory of the standby node after running pg_rewind, because pg_replslot directory may be copied from the primary node in old PostgreSQL versions. + + + + + + + Fix that query cache is not created in other than streaming and logical replication mode. (Tatsuo Ishii) + + + + + + + Fix hang with asyncpg. (Tatsuo Ishii) + + + + + + + Enhance debug message upon receiving startup packet. (Tatsuo Ishii) + + + + + + + Doc: enhance documentation. (Tatsuo Ishii, Bo Peng) + + + + + + + + Release 4.1.6 + + Release Date + 2021-02-18 + + + + Changes + + + + + Delete any pre-existing watchdog command socket file at startup. (Muhammad Usama) + + + Patch provided by Masaya Kawamoto. + + + + + + + Bug fixes + + + + + Fix the incorrect "weight" displayed in . (Tatsuo Ishii) + + + + + + + Fix follow_primary.sh.sample to avoid removing recovery.conf after executing pg_rewind. (Bo Peng) + + + + + + + Fix watchdog leader sync process to start health check process. (Tatsuo Ishii) + + + + + + + Fix that DB cluster path was not correct in watchdog_setup installation. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup so that it creates separate archive directory for each DB node. (Tatsuo Ishii) + + + + + + + Fix messages when health check process starts. (Tatsuo Ishii) + + + + + + + Doc: mention that the sample scripts doesn't support tablespaces in "Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Doc: add explanation about the shared memory required by shared relation cache. (Tatsuo Ishii) + + + + + + + Fix error while allocating shared memory. (Tatsuo Ishii) + + + + + + + Fix bug is not respected if ERROR occurs. (Tatsuo Ishii) + + + + + + Doc: fix usage of firewall-cmd in the installation tips section. (Tatsuo Ishii) + + + firewall-cmd opened unnecessary ports in the example. + + + + + + + Fix segfault that may occur when backend_flag = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER' or failover_command = ''. + (bug 672) (Tatsuo Ishii) + + + + + + Fix file swapping race condition in pool_passwd. (Tatsuo Ishii) + + + Patch is provided by Masaya Kawamoto. + + + + + + Doc: fix description. (Tatsuo Ishii) + + + + + + + + Release 4.1.5 + + Release Date + 2020-11-19 + + + + Changes + + + + + Doc: update "Aurora Configuration Example". (Bo Peng) + + + + + + + Doc: mention that GSSAPI is not supported. (Tatsuo Ishii) + + + + + + + Pgpool-II doesn't support GSSAPI. + Allow Pgpool-II to deal with this issue and expects that the frontend falls back to other connections + instead of responding with an error. (Tatsuo Ishii) + + + Patch is created by me, reviewed and tested by Umar Hayat. + + + + + + + Doc: update "Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Bug fixes + + + + + Fix query rewrite syntax error of "INSERT ... ON CONFLICT" in native replication mode. + (bug 654) (Bo Peng) + + + + + + + Fix connection counter was not counted down when query is canceled. + (bug 656) (Tatsuo Ishii) + + + + + + + Doc: fix usable versions of PostgreSQL to be 7.4 or later. (Tatsuo Ishii) + + + + + + + + + Release 4.1.4 + + Release Date + 2020-09-17 + + + + Changes + + + + + Follow the guide line of PostgreSQL 12.4 regarding extensions. (Tatsuo Ishii) + + + CREATE OR REPLACE FUNCTION should be avoided. Use CREATE FUNCTION instead. + + + + + + + Replace "PGBIN" and "LPATH" in and using PostgreSQL's bin path and lib path. (Bo Peng) + + + + + + + Bug fixes + + + + + Doc: fix the incorrect description regarding the running modes of Pgpool-II in which online recovery is available. (Bo Peng) + + + + + + + Remove unnecessary checks in some code path. (Tatsuo Ishii) + + + Patch contributed by Hou, Zhijie. + + + + + + + Fix relcache query sometimes sent to other than primary. (Tatsuo Ishii) + + + In streaming replication mode, relcache queries are supposed to be + sent to the primary node. But actually they were not sent to the primary + node if primary node was not the master node. Typically this could + happen when the primary is not node 0. + + + + + + + Fix not working when is enabled. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 7175] + + + + + + + Display more informative error message in authentication process. (Tatsuo Ishii) + + + + + + + Test: Fix occasional 073.pg_terminate_backend test failure. (Tatsuo Ishii) + + + + + + + Fix segfault in pgpool child process in certain case. (Tatsuo Ishii) + + + This issue can be reproduced with the following steps: + + + + Shutdown all backends. + + + + + Connect to pgpool with invalid client. I have used pcp_attach_node with pgpool's port number, not pcp's. + + + + + + + + + + + Release 4.1.3 + + Release Date + 2020-08-20 + + + + Changes + + + + + Doc: mention that only affects to TLS 1.2 and lower. (Tatsuo Ishii) + + + + + + + Doc: add sample script links in configuration example . (Bo Peng) + + + + + + + Doc: Improve the description of . (Bo Peng) + + + Patch is provided by Kenichiro Tanaka. + + + + + + + Add mention about hostssl/hostnossl to pool_hba.conf sample file. (Tatsuo Ishii) + + + + + + + Doc: documentation improvements. (Tatsuo Ishii) + + + + + + + Doc: add note about . (Takuma Hoshiai) + + + If user uses replication_slot, the replication slot may be deleted by when standby node is down. + In this case, may not work because replication stopped. + + + + + + + Bug fixes + + + + + At pgpool startup, if pid file exists, truncate pid file to zero length before writing. (Bo Peng) + + + Patch is created by maliangzhu. + + + + + + + Doc: fix error in parameter description. (Bo Peng) + + + + + + + Fix does not work if primary node is not 0 in streaming replication mode. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup problem with -r option and PostgreSQL 12. (Tatsuo Ishii) + + + + + + + Change PCP UNIX_DOMAIN_PATH of RPM package to /var/run/postgresql. (Bo Peng) + + + + + + + Fix query cache bugs. (Tatsuo Ishii) + + + If query cache is enable, when a table is updated, Pgpool-II should delete all the caches related to the table. + However, EXPLAIN ANALYZE and CTE with data-modifying SQLs + were mistakenly treated as normal read only query so that the query caches were not deleted. + + + Patch is created by Hou, Zhijie and modified by Tatsuo Ishii. + + + + + + + Fix Pgpool-II hang in a corner case. (Tatsuo Ishii) + + + + + + + If there are parameters other than "user", "database" and "application_name", reading startup packet failed. (Tatsuo Ishii) + + + + + + + Fix miscount of connections when pg_terminate_backend() is executed. (Takuma Hoshiai) + + + + + + + Fix segmentation fault when application name is included in . (bug 615) (Tatsuo Ishii) + + + + + + + Fix incorrectly performing failover when pg_terminate_backend() is executed in native replication mode. (Takuma Hoshiai) + + + + + + + Fix 004.watchdog test crash on IBM Z hardware. (bug 614) (Tatsuo Ishii) + + + Patch is provided by gregn123, slightly modified by Tatsuo Ishii. + + + + + + + + Release 4.1.2 + + Release Date + 2020-05-21 + + + + Bug fixes + + + + + Fix build error on some system (Fedora 32). (Tatsuo Ishii) + + + + + + + Doc: Add note about and command. (Bo Peng) + + + + + + + Fix pgpool ssl front end accept all ciphers. (bug 608) (Muhammad Usama) + + + + + + + Downgrade too verbose authentication logs. (Tatsuo Ishii) + + + + + + + Fix unnecessary checks. (Tatsuo Ishii) + + + Patch contributed by sherlockcpp. Discussion: [pgpool-general: 7004] + + + + + + + Doc: Fix typo. (Tatsuo Ishii) + + + Patch contributed by Umar Hayat. Discussion: [pgpool-hackers: 3587] + + + + + + + Fix for segmentation fault in PCP process. (bug 598) (Muhammad Usama) + + + + + + + Fix a warning message is never output in watchdog. (Tatsuo Ishii) + + + Patch provided by sherlockcpp. Discussion: ([pgpool-general: 6956] + + + + + + + Doc: Fix typo. (Tatsuo Ishii, Bo Peng) + + + Patch provided by sherlockcpp. + + + + + + + Fix Pgpool-II hangs when an Execute message is issued right after Sync message and query cache hits. (Tatsuo Ishii) + + + + + + + Fix problems in watchdog source code processing json data. (bug 596) (Tatsuo Ishii) + + + Patch is provided by Greg Nancarrow (Fujitsu Australia). + + + + + + + Fix SCRAM auth handling bug. (bug 595) (Tatsuo Ishii) + + + Patch is provided by Greg Nancarrow (Fujitsu Australia). + + + + + + + Fix possible data inconsistency in native replication mode. (Tatsuo Ishii) + + + Discussions: + [pgpool-general: 6896] + [pgpool-hackers: 3540] + + + + + + + Fix watchdog ping probes fail with long hostnames due to small buffer. (bug 516) (Bo Peng) + + + + + + + Doc: Enhance documents. (Tatsuo Ishii) + + + + + + + Fix "last status change" timestamp is not set properly. (Tatsuo Ishii) + + + + + + + + Release 4.1.1 + + Release Date + 2020-02-20 + + + + Changes + + + + + + Disallowing the quorum aware failover option for the native replication mode. (Muhammad Usama) + + + In native replication mode, Pgpool-II. is responsible for replicating the data + on all backend nodes, and if a node becomes quarantined then Pgpool-II stops + sending the writes to that node. This is dangerous since it can cause data inconsistency. + + + So as per the discussion, we reached the conclusion to disallow + with the native replication mode so that backend + node should never get into quarantine when Pgpool-II is configured in the replication mode. + + + + + + Check if socket file exists at startup and remove them if PID file doesn't exist to avoid bind() failure. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect query rewriting in native replication mode. + (bug 551) (Bo Peng) + + + + + + + Doc: Update documentation and fix documentation typos. (Takuma Hoshiai, Tatsuo Ishii, Bo Peng) + + + + + + + Update pgpool-recovery function definitions. (Tatsuo Ishii) + + + + + + + Fix child process segfault after reload if is empty. + (bug 571) (Bo Peng) + + + + + + + Suppress unnecessary error message when there's no standby server. (Tatsuo Ishii) + + + + + + + Fix to support PostgreSQL 12. (Tatsuo Ishii) + + + + + + + Doc: Change the sample follow_master_command script %M %H parameter's order. (Bo Peng) + + + + + + + Fix occasional regression test failure. (Tatsuo Ishii) + + + + + + + Unbreak notification response message treatment in 4.1. + (bug 573) (Tatsuo Ishii) + + + + + + + Fix replication delay worker segfault when application_name in primary_conninfo is an empty string. + (bug 565) (Tatsuo Ishii) + + + + + + + Fix command doesn't display ALWAYS_MASTER, + when = 'ALWAYS_MASTER'. (Takuma Hoshiai) + + + + + + + Fix the bug with ignored syslog setting. (Bo Peng) + + + + + + + + Release 4.1.0 + + Release Date + 2019-10-31 + + + + Overview + + This version implements long awaited features including + + and . Also it enhances number + of areas related to performance. Finally it + imports PostgreSQL 12's new SQL + parser. + + + Major enhancements in Pgpool-II 4.1 include: + + + + + + + + Statement level load + balancing. Previously Pgpool-II + only allows session level load balancing. This version + allows to use statement level load + balancing, which is useful for frontends + permanently connecting + to Pgpool-II but want to use + existing standby server resources. + + + + + + Auto failback allows to automatically attach streaming + replication standby servers, which are considered safe + enough to failback. + + + + + + Enhance performance in number of areas. + + + + Shared relation cache allows to reuse relation cache + among sessions to reduce internal queries + against PostgreSQL system + catalogs. + + + + + Have separate SQL parser for DML statements to + eliminate unnecessary parsing effort. + + + + + Load balancing control for specific queries. + + + + + + + + + Import PostgreSQL 12 SQL parser. + + + + + + + Migration to Version 4.1 + + Version 4.1 contains some changes that may affect compatibility + with previous releases. Observe the following incompatibilities: + + + + + + + Add replication_state and + replication_sync_state columns + of and friends. (Tatsuo + Ishii) + + + This allows to show important information from + pg_stat_replication, which is available + from PostgreSQL 9.1 (also with + replication_state_sync. it's only + available since 9.2 however). For this purpose + new parameter is + added to each backend_host configuration parameters. + pg_stat_replication is called from + streaming replication delay checking process. So + if is 0, those new columns + are not available. + + + Also + and function are + modified. + + + + + + + Add parameter to configure + majority rule calculations. (Muhammad Usama, Tatsuo Ishii) + + + This changes the behavior of the decision of quorum existence and + failover consensus on even number (i.e. 2, 4, 6...) of watchdog + clusters. Odd number of clusters (3, 5, 7...) are not + affected. When this parameter is off (the default), a 2 node + watchdog cluster needs to have both 2 nodes are alive to have a + quorum. If the quorum does not exist and 1 node goes down, then + 1) VIP will be lost, 2) failover script is not executed and 3) + no watchdog master exists. Especially #2 could be troublesome + because no new primary PostgreSQL + exists if existing primary goes down. Probably 2 node watchdog + cluster users want to turn on this parameter to keep the existing + behavior. On the other hand 4 or more even number of watchdog + cluster users will benefit from this parameter is off because now + it prevents possible split brain when a half of watchdog nodes go + down. + + + + + + + If installing from RPMs, by default Pgpool-II + is started by postgres user. (Bo Peng) + + + Because of the security reason, the Pgpool-II default + startup user is changed to postgres user. + + + If installing from RPMs, postgres user will be allowed to + run if_up/down_cmd and arping_cmd + with sudo without a password. + If if_up/down_cmd or arping_cmd starts with "/", + the setting specified in if_cmd_path or arping_path + will be ignored. + + + + + + + Down grade LOG to DEBUG5 in sent message module. (Tatsuo Ishii) + + + + + + + + + Major Enhancements + + + + + + Allow to use statement level load balancing. (Bo Peng) + + + This feature enables selecting load balancing node per + statement. The current feature for load balancing, the load + balancing node is decided at the session start time and will + not be changed until the session ends. When set to + = on, + the load balancing node is decided for each read query. For + example, in applications that use connection pooling remain + connections open to the backend server, because the session + may be held for a long time, the load balancing node does + not change until the session ends. In such applications, + when statement_level_load_balance is enabled, it is possible + to decide load balancing node per query, not per session. + + + + + + + Add (Takuma Hoshiai). + + + This allows to reattach backend node automatically that is + in DOWN status but actually it is running normally. + + + To use this feature it is required + that PostgreSQL is 9.1 or later + and new configuration + variable auto_failback is + enabled. Also Pgpool-II must be + operating in streaming-replication mode, with sr_check and + health_check are + enabled. Pgpool-II calls + pg_stat_replication on + the PostgreSQL primary server to + make sure that the standby node in question is running and + receiving replication stream from the primary server. + + + This feature is useful in the case that a standby server + fails over due to a temporary network failure. + + + + + + + Add new + parameter. (Takuma Hoshiai) + + + The relation cache were stored in local cache of child + processes, so all child processes executed same query to get + relation cache. If + is on, the relation cache is stored in memory cache and all + child process share it. It will expect to reduce the load + that same query is executed. + + + + + + + Add new parameter to + check temporary tables. (Tatsuo Ishii) + + + Checking temporary tables is slow because it needs to lookup + system catalogs. To eliminate the lookup, new method to + trace CREATE TEMP TABLE/DROP TABLE is + added. To use the new method, + set + to trace. + + + Note that it is impossible to trace tables created in + functions and triggers. In this case existing method should + be used. + + + + + + + Reduce internal queries against system catalogs. (Tatsuo Ishii) + + + Currently the relcache module issues 7+ queries to obtain + various info from PostgreSQL + system catalogs. Some of them are necessary for + Pgpool-II to work with multiple + version of PostgreSQL. To reduce + such internal queries, + get PostgreSQL version to know + what kind of queries are needed. For example, we need to + know if pg_namespace exists and for this purpose we send a + query against pg_class. But if we know that pg_namespace was + introduced in PostgreSQL 7.3, we + do not need to inquire pg_class. + + + + + + + Performance enhancements for the large INSERT and UPDATE + statements. (Muhammad Usama) + + + Pgpool-II only needs very little + information, especially for the INSERT and UPDATE statements + to decide where it needs to send the query. For example: In + master-slave mode, for the INSERT + statements Pgpool-II only + requires the relation name referenced in the statement while + it doesn't care much about the column values and other + parameters. But since the parser we use + in Pgpool-II is taken + from PostgreSQL source which + parses the complete query including the value lists which + seems harmless for smaller statements but in case of INSERT + and UPDATE with lots of column values and large data in + value items, consumes significant time. + + + So the idea here is to short circuit the INSERT and UPDATE + statement parsing as soon as we have the required + information. For that purpose, the commit adds the second + minimal parser that gets invoked in master-slave mode and + tries to extract the performance for large INSERT and UPDATE + statements. + + + Apart from the second parser addition, changes aiming + towards the performance enhancements are also part of the + commit. See + the commit + log for more details. + + + + + + + Import PostgreSQL 12 beta2 new parser. (Bo Peng) + + + Major changes of PostgreSQL 12 parser include: + + + + + Add new VACUUM options:SKIP_LOCKED, INDEX_CLEANUP and TRUNCATE. + + + + + Add COMMIT AND CHAIN and ROLLBACK AND CHAIN commands. + + + + + Add a WHERE clause to COPY FROM. + + + + + Allow to use CREATE OR REPLACE AGGREGATE command. + + + + + Allow to use mcv (most-common-value) in CREATE STATISTICS. + + + + + ADD REINDEX option CONCURRENTLY. + + + + + Add EXPLAIN option SETTINGS. + + + + + + + + + + Allow to route relcache queries to load balance node. (Tatsuo Ishii) + + + Queries to build relcache entries were always sent to master (primary) + node. This is usually good because we could eliminate the bad effect + of replication delay. However if users want to lower the load of + master node, it would be nice if we could route the queries to other + than master node. This patch introduces new parameter + . If it is set to + load_balance_node, relcache queries will + be routed to load balance node. If it is set + to master, the queries are routed to + master node, which is same as before (this is the default). + + + + + + + Disable load balance after a SELECT having functions + specified in black function list or not specified in white + function list. (Bo Peng) + + + In Pgpool-II 4.0 or earlier, if + we set = + transaction, when a write query is issued + inside an explicit truncation, subsequent queries should be + sent to primary only until the end of this transaction in + order to avoid the replication delay. However, the SELECTs + having write functions specified + in or not specified + in are not regarded + as a write query and the subsequent read queries are still + load balanced. This commit will disable load balance after + a SELECT having functions specified in black function list + or not specified in white function list. + + + + + + + Implement new feature to not accept incoming + connections. (Tatsuo Ishii) + + + Pgpool-II accepts up to + frontends and queues + up more connection requests until one of child process + becomes free. This mostly works well, but if each session + takes long time, the queue grows longer and the whole system + does not work smoothly. To overcome the problem, a new way + to deal with many connection requests from frontend is + implemented: When + is set to 1 or greater, incoming connections from clients + are not accepted with error message "Sorry, too many clients + already", rather than blocked if the number of current + connections from clients is more than + (num_init_children - + reserved_connections). This is exactly + the same behavior as PostgreSQL. + + + + + + + Enhance performance by eliminating select(2) system calls + when they are not necessary. (Tatsuo Ishii, Jesper Pedersen) + + + + + + + Enhance performance while sending message to + frontend. (Tatsuo Ishii) + + + SimpleForwardToFrontend(), which is responsible for sending + message to frontend, does write buffering only if it is + either 'D' (DataRow) or 'd' (CopyData). Other message types + were immediately written to socket. But actually this was + not necessary. So if the messages are not critical, just + write to buffer. With this 10-17% performance enhance was + observed. + + + + + + + Avoid error or notice message analysis if it's not + necessary. (Tatsuo Ishii) + + + After sending query to + backend, Pgpool-II always calls + pool_extract_error_message() via per_node_error_log(). In + the function memory allocation is performed even if error or + notice message is returned from backend. To avoid the waste + of CPU cycle, check message kind and avoid calling + pool_extract_error_message() if it's not error or notice + message. + + + + + + + Enhance performance of CopyData message handling. (Tatsuo Ishii) + + + When COPY XX FROM STDIN gets executed (typical client is + pg_dump), each copy row data is sent + from Pgpool-II to frontend using + CopyData message. Previously, one CopyData message was + followed by a flush, which costed a lot. Instead, now flush + is done in subsequent Command Complete, Notice message or + Error message. A quick test reveals that this change brings + x2.5 speed up. + + + + + + + Allow to use MD5 hashed password + in and + sr_. (Tatsuo Ishii) + + + + + + + Support ECDH key exchange with SSL (Takuma Hoshiai) + + + + + + + Add backend_application_name to "pgpool show backend" group. (Tatsuo Ishii) + + + + + + + + + + Deal with PostgreSQL 12. (Tatsuo Ishii) + + + recovery.conf cannot be used anymore. Standby's recovery configuration + is now in postgresql.conf. Also "standby.signal" file is needed in + PostgreSQL database cluster directory to start postmaster as a standby + server. + + + HeapTupleGetOid() is not available any more in PostgreSQL 12. Use + GETSTRUCT() and refer to oid column of Form_pg_proc. + + + Change pgpool_adm extension. Now that oid + is gone, the signature of CreateTemplateTupleDesc() has been + changed. + + + + + + + Speed up failover when all of backends are down. (Tatsuo + Ishii) + + + Pgpool-II tries to find primary + node till + expires even if all of the backend are in down status. This + is not only a waste of time but + makes Pgpool-II looked like + hanged because while searching primary node failover process + is suspended and all of + the Pgpool-II child process are + in defunct state, thus there's no process which accepts + connection requests from clients. Since the default value of + searching primary is 300 seconds, typically this keeps on + for 300 seconds. This is not comfortable for users. + + + To fix this immediately give up finding primary node + regardless + and + promptly finish the failover process if all of the backend + are in down status. + + + + + + + Resign the master watchdog node from master responsibilities if + the primary backend node gets into quarantine state on that. (Muhammad Usama) + + + By doing this, we could avoid the situation on which there's no + primary PostgreSQL server exists. To + implement this, make the master/coordinator watchdog node resign + from its status if it fails to get the consensus for the + quarantined primary node failover, within + FAILOVER_COMMAND_FINISH_TIMEOUT(15) seconds. + + + When the watchdog master resigns, because of quarantined primary + node its wd_priority is decreased to (-1), so that it should get + the least preference in the next election for the + master/coordinator node selection. And once the election is + concluded the wd_priority for the node gets restored to the + original configured value. + + + In case of failed consensus for standby node failover no action + is taken. + + + + + + + Add parameter to configure + majority rule calculations. (Muhammad Usama, Tatsuo Ishii) + + + Pgpool-II takes the decision of quorum + existence and failover consensus after receiving the exact 50% of + votes when the watchdog cluster is configured with an even number + of nodes. With parameter, users + can tell Pgpool-II, whether the + distributed consensus in an even number of nodes cluster requires + (n/2) or ((n/2) +1) votes to decide the majority. Odd number of + clusters (3, 5, 7...) are not affected. Extra caution is needed + for 2 node watchdog cluster users. See for more details. + + + + + + + Allow to specify absolute path in . (Bo Peng) + + + Patch is provided by Danylo Hlynskyi. + + + + + + + Add various sample scripts. (Bo Peng) + + + Allow failover.sh.sample, follow_master.sh.sample, recovery_1st_stage.sample, recovery_2nd_stage.sample, + pgpool_remote_start.sample scripts to be included in distributions. + + + + + + + Documentation enhancements: + + + + + Add performance chapter (). (Tatsuo Ishii) + + + + + + Enhance 'getting started' of 'tutorial' chapter, + 'watchdog' of 'tutorial' and some sections of 'server + administration'(takuma hoshiai) + + + + + + Update configuration example "Pgpool-II + watchdog + setup example". (bo peng) + + + + + + Mention that schema qualifications cannot be used in + white/black_function_list. (tatsuo Ishii) + + + + + + Enhance explanation + about + and . (tatsuo + ishii) + + + + + + Add note to detach_false_primary configuration + parameter. (tatsuo ishii) + + + + + + Add more explanation to follow_master_command. (tatsuo + ishii) + + + + + + Enhance watchdog/pgpool-ii example so that it mentions + about pg_monitor role. (tatsuo ishii) + + + + + + Mention that multi-statement queries are sent to + primary node only. (tatsuo ishii) + + + + + + Add load balancing description. (tatsuo ishii) + + + + + + Add useful link how to create pcp.conf in the pcp + reference page. (tatsuo ishii) + + + + + + Add more description to pcp_node_info manual. (tatsuo + ishii) + + + + + + Add description to pg_md5 man page how to show + pool_passwd ready string. (tatsuo ishii) + + + + + + Enhance client authentication docs. (tatsuo ishii) + + + + + + Enhance watchdog documents regarding quorum + failover. (tatsuo ishii) + + + + + + + Mention that in raw mode or load_balance_mode = off + case for relation cache. (tatsuo ishii) + + + + + + Add general description about failover. (tatsuo ishii) + + + + + + + + + + + + Bug fixes + + + + In this release same bug fixes as Pgpool-II 4.0.7 are + already applied. See for more details of those fixes. + + + + + diff --git a/doc/src/sgml/release-4.2.sgml b/doc/src/sgml/release-4.2.sgml new file mode 100644 index 000000000..054315ba3 --- /dev/null +++ b/doc/src/sgml/release-4.2.sgml @@ -0,0 +1,6309 @@ + + + + + Release 4.2.24 + + Release Date + 2025-11-25 + + + + Changes + + + + + Remove unnecessary application_name treatment. (Tatsuo Ishii) + + + A previous commit added a step to set application_name when reusing existing connections. + However, this is unnecessary because DISCARD ALL automatically resets application_name, + and send_params() already sends all necessary parameter status messages, including application_name, to the frontend. + Removing this redundant step also improves performance, particularly for backend nodes that are geographically distant. + + + Discussion: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + Bug fixes + + + + + Fix segfault with CopyOut. (Tatsuo Ishii) + + + When COPY relname TO STDOUT is executed in the extended query + protocol mode, pgpool segfaulted. + + + This problem is reported by https://github.com/tetesh. + + + Discussion: datanymizer and pg-pool segmentation fault + + + + + + Prevent watchdog split-brain scenario in some corner cases. (Tatsuo Ishii) + + + Watchdog uses both beacon messages and heartbeat for communication. + If the heartbeat is not yet active, missing beacon messages + for over 30 seconds can cause a split-brain scenario, + where the old leader remains active while a new leader is elected. + This change prevents two leaders from existing simultaneously by revoking the old leader. + When a node detects that it has missed beacon messages from the leader more than twice, + the leader is set to LOST and a new leader election is triggered via set_state(WD_JOINING). + + + + + + + Prevent FATAL error when non-existing prepared statement is given. (Tatsuo Ishii) + + + Previously, Bind() raised a FATAL error when a non-existing prepared statement was used, unlike PostgreSQL. + This change changes Bind() to check for the statement's existence and send an ERROR message to the frontend if it does not exist. + Note that no log is written, as logging this is not currently possible. + + + + + + + Fix not working if both -p and -P are provided. (Tatsuo Ishii) + + + The original report showed that running pg_enc -p -P prompted for a password and encryption key, + but failed if the key was not provided. + + + Discussion: pg_enc + + + + + + + Fix compiling issue on 32-bit environments. (Tatsuo Ishii) + + + On 32-bit systems, compiling src/parser/snprintf.c fails due to undefined functions isnan() and isinf(), which come from math.h. + This change includes math.h and also reorders the include files for clarity. + The file was originally imported from PostgreSQL, where math.h was already included. + This fix was provided via pull request: https://github.com/pgpool/pgpool2/pull/128 + + + Discussion: Compiling issues for 32-bit targets + + + + + + + Fix safer directory deletion in Bash in recovery_1st_stage.sample. (Taiki Koshino) + + + Quote variables in rm commands to avoid accidental deletion: + rm -rf "${DEST_NODE_PGDATA}" + + If the variable is empty, rm could delete unexpected files or directories. + + + + + + + Fix the compilation error when building without the option. (Tatsuo Ishii) + + + A compiler error occurred when configuring without . + The issue arose because the compiler could not determine that ptr would only be freed when memcached is enabled. + To fix this, the relevant code block was wrapped with #ifdef USE_MEMCACHED. + + + Problem reported by Bo Peng. + + + + + + + Documents + + + + + Update doc about "Setting up PostgreSQL standby" in 8.2. Pgpool-II + Watchdog Setup Example. (Taiki Koshino) + + + Add a note that when setting up a standby without online recovery, do not write primary_conninfo to postgresql.auto.conf. + + + Discussion: Follow primary command not fixing postgresql.auto.conf + + + + + + + Fix watchdog_setup manual. (Tatsuo Ishii) + + + It mistakenly stated that heartbeart is not setup in watchdog_setup. + + + + + + + Regression Tests + + + + + Adapt 023.ssl_connection to PostgreSQL 18. (Tatsuo Ishii) + + + PostgreSQL 18 heavily changed psql's \conninfo output format, which + made the test fail because the test relies on \conninfo. This change + makes the test script aware the PostgreSQL version to fix the issue. + + + + + + + Fix ruby script in 010.rewrite_timestamp. (Tatsuo Ishii) + + + The ruby script used "File.exists", which is said to be obsoleted in + newer version of Ruby. Replace it with "File.exist". + + + + + + + Tweak timeout in 034 and 075 tests. (Tatsuo Ishii) + + + 034.promote_node and 075.detach_primary_left_down_node set the timeout + 60 seconds for finishing follow primary script. It turns out that + these timeout values are not long enough, and sometimes caused false + errors. So make them from 60 seconds to 120 seconds. + + + + + + + Add ssl_ecdh_curve test to 023.ssl_connection. (Tatsuo Ishii) + + + 023.ssl_connection did not cover the test for ssl_ecdh_curve. This + commit tests it using bad ssl_ecdh_curve parameter to see if connection + between frontend and pgpool fails. + + + + + + + + Release 4.2.23 + + Release Date + 2025-08-21 + + + + Bug fixes + + + + + Fix watchdog to print inappropriate NOTICE message. (Tatsuo Ishii) + + + read_ipc_socket_and_process() printed a notice message every time when + it wrote commands to IPC socket even if it was successful. Fix this to + print the notice message only when the write failed. + + The reason why this bug was not recognized is, the message appears + only when log_min_messages is set to notice or higher. + + + Discussion: pgpool IPC socket connection issue + + + + + + + + Fix resource leak while reading startup packet. (Tatsuo Ishii) + + + Fix resource leak in pool_push_pending_data. + + + + + + + Fix broken scram-sha-256 authentication on big-endian machines. (Tatsuo Ishii) + + + When scram-sha-256 authentication is performed, a hash function + pg_sha_256_final is used. It was imported from PostgreSQL and it uses + preprocessor define WORDS_BIGENDIAN to judge host machine's + endianness. Although WORDS_BIGENDIAN should be defined while + configure, this part was missed when pg_sha_256_final (and others) was + imported from PostgreSQL. As a result, scram-sha-256 worked only in + little endian machines. Fixed the issue by adding + AC_C_BIGENDIAN macro to configure.ac. + + + Problem reported by Christoph Berg and analyzed by pranavkaruvally. + + + Discussion: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + Fix source code typos. (Bo Peng) + + + + + + + Fix heartbeat device treatment. (Tatsuo Ishii) + + + While processing pgpool.conf, heartbeat_device was mistakenly treated + and the first device was ignored. + + + Problem analyzed by Bo Peng. + + + + + + + Documents + + + + + Fix documentation for parameters that are not reflected by reload. (Taiki Koshino) + + + "authentication_timeout" and "memqcache_oiddir" is not reflected by reload. + The documentation is changed to "This parameter can only be set at server start.". + + + + + + + + Unify watchdog leader terms (followup). (Tatsuo Ishii) + + + + + + + + Fix example script link. (Taiki Koshino) + + + Modified the sample script in the section "8.2. Pgpool-II + Watchdog Setup Example" + + + + + + + Fix load balance explanation missed logical replication mode and Slony mode. (Tatsuo Ishii) + + + + + + + Add section of kernel resources. (Tatsuo Ishii) + + + Pgpool-II uses System V shared memory and semaphores. It's better to + describe the requirements in the docs. + + + + + + + Add description for option of configure. (Tatsuo Ishii) + + + It was missed when LDAP support was introduced in v4.2 + + + + + + + Clarify supported platforms for Pgpool-II. (Tatsuo Ishii) + + + + + + + Enhance document. (Tatsuo Ishii) + + + + + + + Regression Tests + + + + + Stabilize 029.cert_passphrase regression test. (Tatsuo Ishii) + + + When ssl_passphrase_command is not valid, the error message is + typically "bad decrypt" but it seems sometimes "wrong tag". + + + + + + + + Release 4.2.22 + + Release Date + 2025-05-15 + + + + Overview + + This release contains a security fix. + + + An authentication bypass vulnerability exists in the client authentication + mechanism of Pgpool-II. + In Pgpool-II, authentication may be bypassed even + when it is supposed to be enforced. As a result, an attacker could log in as + any user, potentially leading to information disclosure, data tampering, or + even a complete shutdown of the database. (CVE-2025-46801) + + + This vulnerability affects systems where the authentication configuration + matches one of the following patterns: + + + + + Pattern 1: This vulnerability occurs when all of the following conditions are met: + + + + + The password authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is not set in pool_passwd + + + + + The scram-sha-256 or md5 authentication + method is used in pg_hba.conf + + + + + + + + Pattern 2: This vulnerability occurs when all of the following conditions are met: + + + + + enable_pool_hba = off + + + + + One of the following authentication methods is used in pg_hba.conf: + password, pam, or ldap + + + + + + + + Pattern 3: This vulnerability occurs when all of the following conditions are met: + + + + + Raw mode is used (backend_clustering_mode = 'raw') + + + + + The md5 authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is registered in pool_passwd in plain + text or AES format + + + + + One of the following authentication methods is used in + pg_hba.conf: + password, pam, or ldap + + + + + + + All versions of Pgpool-II 4.0 and 4.1 series, 4.2.0 to 4.2.21, 4.3.0 to 4.3.14, + 4.4.0 to 4.4.11, 4.5.0 to 4.5.6 and 4.6.0 are affected by this vulnerability. + It is strongly recommended to upgrade to Pgpool-II + 4.6.1, 4.5.7, 4.4.12, 4.3.15 and 4.2.22 or later. + Alternatively, you can modify your settings so that they do not match any of + the vulnerable configuration patterns. + + + + + Changes + + + + + Add major version information to the configuration file. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect client authentication in some cases. (Tatsuo Ishii) + + + If enable_pool_hba = on, it's auth method is "password", no + password is registered in pool_passwd, and auth method in + pg_hba.conf is "scram-sha-256" or "md5", for the first time when + a client connects to pgpool, authentication is performed as + expected. But if a client connects to the cached connection, any + password from the client is accepted. + + + Also if enable_pool_hba = off, in some cases a client is not + asked password for the first time, or when a client connects to + cached connection, even if it should be. + + + In addition to fixing above, following changes are made: + + + + + Remove single PostgreSQL code path to simplify the authentication code. + + + + + Remove crypt authentication support for frontend and + backend. The feature had not been documented and never + tested. Moreover crypt authentication was removed long time + ago in PostgreSQL (8.4, 2009). + + + + + Add new regression test "040.client_auth". The test performs + exhaustive client authentication tests using a test + specification file formatted in CSV. + + + + + + + + Fix long standing bind bug with query cache. (Tatsuo Ishii) + + + When a named statement is prepared, it is possible to bind then execute without a parse message. + Problem is, table oids which are necessary to invalidate query cache at execute or COMMIT was + collected only in parse messages process (Parse()). Thus if bind is executed + without parse after previous execute, no table oids were collected, and pgpool failed to invalidate query cache. + Fix is collecting table oids at bind time too. + Add regression test to 006.memqcache. + + + Problem reported by and test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + When an execute message is received, pgpool checks its max number of rows paramter. If it's not zero, + pgpool sets "partial_fetch" flag to instruct pool_handle_query_cache() to not create query cache. + Problem is, commit 2a99aa5d1 missed that even INSERT/UPDATE/DELETE sets the execute message parameter to non 0 (mostly 1) + and pgpool set the flag for even none SELECTs. This resulted in failing to invalidate query cache because if the flag is true, + subsequent code in pool_handle_query_cache() skips cache invalidation. + To fix this change Execute() to check if the query is read only SELECT before setting the flag. + Also add test to 006.memqcache. + + + Problem reported by and a test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix portability to OpenBSD. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + The patch was created by Martijn van Duren. + + + + + + Fix json_writer did not properly encode special characters. (Bo Peng) + + + Pgpool-II would crash when the watchdog was enabled if contained special characters (e.g., a backslash). + + + The patch was created by Martijn van Duren and slightly modified by Bo Peng. + + + + + + Fix sr check and health check to reopen upon reload. (Tatsuo Ishii) + + + The streaming replication check and health check process forgot to + reopen upon reload. If or + is empty string, the password is obtained from + . Thus those process read outdated content of + upon reload. + + + + + + + Documents + + + + + Enhance the description on (Tatsuo Ishii) + + + is a config value to determine the life time of + cached connections to PostgreSQL backend. Current document lacks a + description that the expiration calculation is actually done at the + time when the client disconnects to the process which holds the cached + connections. + + + Discussion: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + Enhance the explanation on . (Tatsuo Ishii) + + + It must be a superuser or in the pg_monitor group. + + + + + + + + Release 4.2.21 + + Release Date + 2025-02-28 + + + + Changes + + + + + Remove pg_basebackup from the sample follow primary script. (Bo Peng) + + + If pg_rewind fails, the safest way for users is to recover manually. + + + + + + + Bug fixes + + + + + Fix per_node_error_log() error message that is printed with two colons. (Bo Peng) + + + Patch is created by Umar Hayat. + + + + + + + Fix pool_signal. (Tatsuo Ishii) + + + Previously pool_signal did not set SA_RESTART flag. Thus any system + calls interrupted by a signal does not restart. Some of our code are + prepared so that they restart if a system call is interrupted by a + signal. But not sure all places are prepared too. So add the + flag. Note, PostgreSQL always uses the flag. + + + + + + + Fixed an issue where pg_md5 and + pg_enc would not update the password + file if a file other than the default value was specified + in the parameter. (Bo Peng) + + + This issue is reported by Sadhuprasad Patro. + + + + + + + Fix several query cache bugs in streaming replication mode. (Tatsuo Ishii) + + + + + When query cache is enabled and an execute message is sent from + frontend, Pgpool-II injects query cache + data into backend message buffer if query cache data is available. + But it was possible that the cached message is inserted at + inappropriate position and Pgpool-II + mistakenly raised "kind mismatch" error. + + + + + If query cache is enabled and query is operated in extended query mode + and pgpool is running in streaming replication mode, an execute + message could return incorrect results. + + + + + Another trouble is when multiple execute messages are sent + consecutively. In this case Pgpool-II returned exactly the same + results from query cache for each execute message. This is wrong since + the second or subsequent executes should return 0 rows. + + + Discussion: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + Documents + + + + + Enhance client authentication chapter. (Tatsuo Ishii) + + + Add intro about pool_passwd. Previously there was only description on + pool_hba.conf in the overview page. A general guide to + + will help users to understand this chapter. + + + + + + + Regression Tests + + + + + Stabilize 032.dml_adaptive_loadbalance (Tatsuo Ishii) + + + + + + + + Release 4.2.20 + + Release Date + 2024-11-28 + + + + Bug fixes + + + + + + Abort SSL negotiation if backend sends an error message. (Tatsuo Ishii) + + + In the client side implementation of SSL negotiation + (pool_ssl_negotiate_clientserver()), it was possible for a + man-in-the-middle attacker to send a long error message to confuse + Pgpool-II or client while in the SSL negotiation phase. This commit + rejects the negotiation immediately (issue a FATAL error) and exits + the session to prevent such an attack. + + + This resembles PostgreSQL's CVE-2024-10977. + + + + + + + Fix the watchdog process not reloading configurations. (Bo Peng) + + + The reload_config() function + in Pgpool-II should send + a SIGHUP signal to the watchdog process. + + + + + + + Fix bug in do_query. (Tatsuo Ishii) + + + Fix do_query to use ntohs/ntohl instead of htons/htonl. + + + + + + + Fix authentication failure after updating pool_passwd and reload. (Tatsuo Ishii) + + + If pool_hba.conf is disabled, + updating pool_passwd was not recognized + by Pgpool-II child process even + if Pgpool-II reload was performed. + The reload processing function check_config_reload() mistakenly assumed + that reopening pool_passwd was only necessary when + is on. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html" + + + + + + + Fix COPY hangs. (#79) (Tatsuo Ishii) + + + During COPY IN state (i.e. COPY FROM STDIN), frontend can send Flush + or Sync messages. According to the F/B protocol specification, they + should be ignored but Pgpool-II treated as an invalid message and this + causes COPY hung. + + + Also a regression test is added for this issue. + + + + + + + Fix Pgpool-II child process crash during shutdown. (Tatsuo Ishii) + + + The actual crash was in close_all_backend_connections(). + close_all_backend_connections() was + called because on_system_exit registers + child_will_go_down(). + At the moment it seems pgpool child had just started up and doing + pool_init_cp(). The connection pool + object had not been completely initialized, that's cause of the crash. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + Fix sporadic health check failures due to authentication failure. (Tatsuo Ishii) + + + When is empty string, + health check process looks for the password from pool_passwd file. + Problem is, the file descriptor for the file is inherited from + parent pgpool process. + This means that pgpool main and health check process (possibly multiple + process) share the same descriptor, which causes various problem + including the issue reported here. To fix the problem, re-open the + file when health check process starts so that each health check + process owns its own file descriptor. + + + Note that pgpool child process (responsible for frontend sessions) + already re-opens the file descriptor and they are not related to the + issue. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + Optimize query cache invalidation for ALTER ROLE. (Tatsuo Ishii) + + + Commit 6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89 invalidates query + cache if any ALTER ROLE/USER statement is used. + Actually this is an overkill. + Because following queries do not affect the privilege of the role. + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + So do not invalidate query cache if those commands are used. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Fix Pgpool-II crash when pgpool child process exits. (Tatsuo Ishii) + + + When a pgpool child process exits, + close_all_backend_connections() is + called, which is responsible for closing all connections to backend in + the connection pool. It used mistakenly MAIN_CONNECTION macro, which + is fine for current active connections but is not good for pooled + connections because a main node could be different at the time when + the connection pool was created. + Fix is using in_use_backend() instead. + + + Reported-by: Emond Papegaaij + + + + + + + Fix bug in replication/snapshot isolation mode. (#69) (Tatsuo Ishii) + + + When INSERT command is received, + pgpool automatically issues table LOCK command to the + target table but it forgot to send the command to + other than main nodes. This only happened in extended query mode. + + + + + + + Fix another bug in native replication/snapshot isolation mode. (Tatsuo Ishii) + + + insert_lock() forgot to send row lock command (lock_kind == 3 case) to + other than main node. + + + + + + + Fix resource leaks in pool_memqcache.c. (Tatsuo Ishii) + + + These leaks were brought in by commit 6fdba5c33. + + + + + + + + Documents + + + + + Fix typos in the documentation and sample configuration files. (Bo Peng) + + + + + + + Regression Tests + + + + + Adapt 024.cert_auth test to OpenSSL 3.2. (Tatsuo Ishii) + + + + + + + + Release 4.2.19 + + Release Date + 2024-09-09 + + + + Overview + + This release contains a security fix. + + + When the query cache () feature is enabled, + it was possible that a database user can read rows from tables that should + not be visible for the user through query cache (CVE-2024-45624). + + + All versions of Pgpool-II older than + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22, and all older + versions that has the query cache feature (the query cache feature was + implemented in 3.2) are affected by the vulnerability. + + + + + + If query cache is created for a table for a user, and then the + access right of the table is revoked from the user by + REVOKE command, still it was possible for the + user to access the table which the user does not have the access + right through the query + cache. + + + + + + If query cache is created for a table for user A, and then other + user B accesses the table via SET ROLE or + SET SESSION_AUTHORIZATION in the same session, + still it was possible for the user B to access the table which B + does not have the access right through the query + cache. + + + + + + If query cache is created for a row security enabled table for user + A, and then other user B accesses the table via SET ROLE + or SET SESSION_AUTHORIZATION in the same session, + it was possible for the user B to retrieve rows which should not be + visible from the user B through the query cache. + + + + + + It is strongly recommend to upgrade to Pgpool-II + 4.5.4, 4.4.9, 4.3.12, 4.2.19 and 4.1.22 or later. Or you should better turn + off the query cache feature. + + + + Note that to fix the vulnerability, some commands (ALTER DATABASE, + ALTER ROLE, ALTER TABLE, REVOKE) now invalidate whole query cache + data. This may affect the performance when using the query cache + feature. + + + + + Changes + + + + + Back port . (Tatsuo Ishii) + + + This is mainly for testing. Backpatch-through: v4.1 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + Bug fixes + + + + + + Fix bugs in replication mode and snapshot isolation mode. (Tatsuo Ishii) + + + The following bugs was fixed: + + + + + In replication mode and snapshot isolation mode when a command finishes, + Pgpool-II waits for a ready for query message + but forgot that some commands (for example SET ROLE) + produces a parameter status message. As a result + Pgpool-II errors + out that other message arrives before the ready for query message. + + + + + + If previous query produces parameter status message, subsequent + parse() needs to read and process it because + it wants to read Ready for query message which is supposed to follow + the parameter status message. + However when ParameterStatus() gets called, + the query in progress flag was set and it was possible that only + one of parameter status message from backend was processed if the + query processed in this parse() call is load + balanced. It is likely that the parameter status message comes from + all live backend because they are generated by SET + command, and SET command are sent to all live backend + in replication mode and snapshot isolation mode. So unset the query in + progress flag before calling ParameterStatus(). + + + + + + + + + + + Release 4.2.18 + + Release Date + 2024-08-15 + + + + Changes + + + + + + Use psql -V instead of initdb -V + in sample scripts. (Bo Peng) + + + Use psql -V instead of initdb -V + in the sample scripts because in some cases postgresqlxx-server may not + be installed. + + + + + + + + Bug fixes + + + + + + Fix hang after a flush message received. (#59) (Tatsuo Ishii) + + + + + + + Fix segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool child segfaulted in pool_do_auth. The cause + was MAIN_CONNECTION() returns NULL. It seems my_main_node_id was set + to incorrect node id 0, which was actually in down status. thus there + was no connection in cp->slots[0]. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9175] + + + + + + + Fix segfault to not use MAIN_NODE macro. (Tatsuo Ishii) + + + Some functions (close_idle_connection(), new_connection() and + pool_create_cp()) used MAIN* and VALID_BACKEND where they are not + appropriate. MAIN* and VALID_BACKEND are only useful against current + connections to backend, not for pooled connections since in pooled + connections which backend is the main node or up and running is + necessarily same as the current connections to backend. + The misuses of those macros sometimes leads to segfault. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9114] + + + + + + + Fix MAIN_NODE macro (actually pool_virtual_main_db_node_id()). (Tatsuo Ishii) + + + The macro used to return REAL_MAIN_NODE_ID if there's no session context. + This is wrong since REAL_MAIN_NODE_ID can be changed any time when + failover/failback happens. + + + Suppose REAL_MAIN_NODE_ID == my_main_node_id == 1. + Then due to failback, REAL_MAIN_NODE_ID is changed to 0. + Then MAIN_CONNECTION(cp) will return NULL and any + reference to it will cause segmentation fault. To prevent the issue we + should return my_main_node_id instead. + + + + + + + Fix show pool_processes to not show row description twice. (Tatsuo Ishii) + + + processes_reporting() accidentaly called both send_row_description() + and send_row_description_and_data_rows(). + + + Discussion: [pgpool-hackers: 4471] + + + + + + + Fix segfault in a child process. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + Watchdog dies and kills pgpool2 when network gets shortly interrupted. (#823) (Muhammad Usama) + + + With network monitoring enabled, a Pgpool-II + node would shut down immediately if it lost all network interfaces or + assigned IP addresses, providing extra protection by quickly removing + a non-communicative node from the cluster. + + + The issue was that Pgpool-II responded to network blackout events even when network + monitoring was disabled. This fix ensures that the network monitoring socket is + not opened when network monitoring is not enabled, preventing unnecessary shutdowns. + + + + + + + Fix pgpool reset command not working if watchdog is enabled. (Tatsuo Ishii) + + + Bug reported and problem analysis by keiseo. + Discussion: [pgpool-hackers: 4465] + + + + + + + Fix psql_scan crash. (#54) (Tatsuo Ishii) + + + It was reported that psql_scan crashes while determining whether a + string in a long query is psql variable (i.e. starting with ":") or not. + + + + + + + + Documents + + + + + + Mega typo fix for docs and program source codes. (Tatsuo Ishii) + + + Patch is created by Umar Hayat. + + + + + + + Add the missing default values for virtual IP related parameters. (Bo Peng) + + + + + + + + + Release 4.2.17 + + Release Date + 2024-05-16 + + + + Bug fixes + + + + + Fix compiler error with -Werror=implicit-function-declaration. (Bo Peng) + + + Add LDAP_DEPRECATED to include prototypes for deprecated ldap functions. + Also Add missing header files in autoconf check. + + + Patch is created by Vladimir Petko. + + + + + + + Fix assorted causes of segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool and its child process segfault in certain + cases when failover involved. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + Fix uninitialized memory error. (Tatsuo Ishii) + + + It was reported that valgrind found several errors including an + uninitialized memory error in read_startup_packet. It allocates memory + for user name in a startup packet in case cancel or SSL request using + palloc, and later on the memory is used by pstrdup. Since memory + allocated by palloc is undefined, this should have been palloc0. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + Fix errors/hung up when load_balance_mode is off. (Tatsuo Ishii) + + + Commit 3f3c1656 + brought errors/hung up when load_balance_mode is off, primary node id + is not 0 and queries are BEGIN etc. + + + Bug found and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + Fix compile errors with certain CFLAGS. (Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42 + reported that with CFLAGS + -flto=4 -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing + gcc emits errors. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + Fix comments in sample pgpool.conf. (Bo Peng) + + + The default value for sr_check_period should be 10 seconds. + Also fixed some typos in comments. + + + Patch is created by hiroin and modified by Bo Peng. + + + + + + + Allow reset queries to run even if extended queries do not end. (Tatsuo Ishii) + + + Commit 240c668d + caused reset queries fail if extended query messages do not end. This commit + fix that by checking whether we are running reset queries in + SimpleQuery(). Also add the test case for this. + + + + + + + Guard against inappropriate protocol data. (Tatsuo Ishii) + + + If a simple query message arrives before a sequence of extended query + messages ends pgpool could hang. This is because the query context in + the session context for the simple query is overwritten by the query + contexts of the extended query messages. + + + This commit implements a guard in SimpleQuery() by checking whether + extended query protocol messages ended. If they do not end, raise a + FATAL error. A known example detected by this checking is JDBC + driver's "autosave=always" option. This means pgpool will not accept + the option after this commit until the issue (sending a simple + protocol message before ending extended query message protocol) is + fixed by the JDBC driver side. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + Documents + + + + + + Enhance "Upstream server connection" documentation. (Bo Peng) + + + + + + + Language cleanup in Japanese document. (Masaya Kawamoto) + + + + + + + + Regression Tests + + + + + + Fixed regression test 005.jdbc to avoid Java 21 deprecation warnings. (Bo Peng) + + + Replace Runtime.exec(String) with Runtime.exec(String[]) to avoid Java 21 deprecation warnings. + Patch is created by Vladimir Petko and modified by Bo Peng. + + + + + + + + + Release 4.2.16 + + Release Date + 2024-02-29 + + + + Changes + + + + + Remove restore_command from sample scripts. (Bo Peng) + + + Restore_command is not required because replication slot is enabled. + It causes occasional failover failure. + + + + + + + Bug fixes + + + + + Fixed the default values of . (Bo Peng) + + + Because the default value of recovery_user + should be same as and + , I changed the default value + from '' to 'nobody'. + + + + + + + Fixed with BEGIN etc. (Tatsuo Ishii) + + + When statement_level_load_balance is enabled, + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE + ALL/DISCARD were sent to primary node and all standby nodes even if + is off. + This is not only plain wrong but caused slow + down if one of the standby nodes are in remote network. + + + Fix this in that pgpool sends such queries to primary node only when + load_balance_mode is off. + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + Documents + + + + + Fix Japanese watchdog document. (Tatsuo Ishii) + + + It mistakenly used "master" watchdog node instead of "leader". + + + + + + + Fix English watchdog document. (Tatsuo Ishii) + + + It mistakenly used "main" PostgreSQL node instead of "primary". + + + + + + + + Release 4.2.15 + + Release Date + 2023-11-30 + + + + Changes + + + + + Modify the replication slot name conversion in sample scripts + to support for the hostname in uppercase. (Bo Peng) + + + Replication slots are automatically created or deleted in the scripts + which are executed during failover or online recovery. + Since uppercase can't be used for a replication slot name, modify these scripts + to convert the hostname to lowercase. + + + Patch is created by Sheikh Wasiu Al Hasib and modified by Bo Peng. + + + + + + + Add SSH timeout in sample script escalation.sh.sample + which is set in parameter. (Bo Peng) + + + + + + + Bug fixes + + + + + Remove unnecessary logging line. (Tatsuo Ishii) + + + Debug message "unset_tx_started_by_multi_statement_query is called in CommandComplete" was accidentally left. + + + + + + + Fix Describe() so that it does not abort with portal created by DECLARE. (Tatsuo Ishii) + + + When DECLARE foo CURSOR FOR is executed, + a portal named "foo" is automatically created by PostgreSQL. + As the portal is not managed by Pgpool-II, + "Describe foo" message failed with "unable to execute Describe. + unable to get the bind message" error. + + + To fix this, make Describe() create a dummy write query + context so that the describe message is sent to primary (streaming replication + mode) or all nodes (replication/snapshot isolation mode). + + + Also add test case 080 for this commit. + + + This problem was reported and analyzed by Heather Lapointe. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + Remove duplication definitions of NAMEDATALEN. (Tatsuo Ishii) + + + The definition for NAMEDATALEN is now in + src/include/pg_config_manual.h only. + Also replace POOL_NAMEDATALEN with + NAMEDATALEN in + src/utils/pool_select_walker.c. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + Documents + + + + + Modify "Pgpool-II + Watchdog Setup Example" to mention that + pcp_listen_addresses = '*' is required to + allow PCP to listen on all addresses. + + + + + + + Enhance manual. (Tatsuo Ishii) + + + Mention that it is necessary to run if + is not used. + + + + + + + Regression Tests + + + + + Enhance pgpool_setup. (Tatsuo Ishii) + + + Enhance failover script generation and follow primary script + generation so that they create better logging. + + + + + + + + Release 4.2.14 + + Release Date + 2023-08-17 + + + + Changes + + + + + Install system exit callback only after initialization of shared memory. (Muhammad Usama) + + + When the on-exit callback gets called because of a failure to acquire + shared memory. The cleanup function can produce a segfault while accessing + process_info, that lives in shared memory. + Although we can also fix this by bailing out from the exit callback when + process_info is NULL but installing the function after successful initialization + of shared memory is a better approach as the rest of the system always assumes + the process_info can never be NULL, and also, there is nothing to + clean up before child processes are spawned. + + + + + + + Add schema qualification to some system catalog inquiry functions. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + Fix coverity warning. (Tatsuo Ishii) + + + Fix query cache module assigned time_t value to int32 variable. Change + the variable type to int64. Per Coverity. Also use difftime() to + calculate time_t difference. This is a recommended practice. + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + Fix find_primary_node_repeatedly doesn't terminate within . (Bo Peng) + + + + + + + Fix crash when v2 protocol is used.(bug 807)(Tatsuo Ishii) + + + When read_kind_from_backend() accumulates statistics data, it was not prepared for v2 protocol case. + + + Bug report and patch from MCanivez.Slightly modified by me. + + + + + + + Fix PREPARE in multi-statement case. (Tatsuo Ishii) + + + If multi-statement query includes PREPARE in the second or latter + position, and subsequent bind message uses the prepared statement, it + fails with "unable to bind" error because the prepared statement is not + saved in sent messages. + + + To fix this if such a case found after parsing the statement, create a + query context for the named statement and add it to the sent message list. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + For this new regression test 079..multi_prepare is added. + + + + + + + Fix pgproto to work with bind message using params. (Tatsuo Ishii) + + + Previously pgproto can only process bind messages without params. + + + + + + + Fix sample script log messages. (Bo Peng) + + + + + + + Documents + + + + + Fix the missing "logger" application name. (Bo Peng) + + + + + + + Clarify the meaning of stop mode. (Tatsuo Ishii) + + + + + + + Remove the incorrect information from release note 4.2.10. (Bo Peng) + + + Remove "Fix pgpool_recovery extension script. (Tatsuo Ishii)" from release note 4.2.10. + + + + + + + Enhance SSH public key authentication setting section in "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix load balance mode chapter. (Tatsuo Ishii) + + + In some places "streaming replication mode" was written as "native + replication mode". Also enhance description regarding additional + requirements for load balancing in the streaming replication mode. + Add some indexes. + + + + + + + Enhance online recovery documentation. (Bo Peng) + + + Mention that 2nd stage of online recovery does not work properly only for multiple pgpool nodes without watchdog enabled. + + + + + + + Regression Tests + + + + + Fix occasional 069.memory_leak_extended test failure. (Tatsuo Ishii) + + + It turned out that reason of the occasional test failure is, pgpool + child process is gone before running ps command after pgbench + finishes. The cause is a kind mismatch FATAL error, "DISCARD ALL + cannot be executed within a pipeline". To fix this, run pgbench in + background and get the process size before pgbench finishes. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + Release 4.2.13 + + Release Date + 2023-05-18 + + + + Changes + + + + + Import psqlscan source code into Pgpool-II to judge multi statement query. (Tatsuo Ishii) + + + Psqlscan is a module in the PostgreSQL source tree. + It is essentially subset of PostgreSQL SQL scanner + but it is specialized for detecting + the end of each SQL statement. Therefore we can count the number of + SQL statements in a query string by using it. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + Allow to use multiple statements extensively. (Tatsuo Ishii) + + + This commit tries to eliminate pgpool's long standing limitations + regarding multiple statements (multi-statements). + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + Use schema qualification for internal queries. (Tatsuo Ishii) + + + Some of objects such as function and cast did not use "pg_catalog." + schema qualification. This does not lead to immediate security + concern but using the schema qualification is always good practice. + + + + + + + Bug fixes + + + + + Fix possible dead lock with shared relation cache. (Tatsuo Ishii) + + + When a user defined function obtains table locking, call to the + function using extended query protocol could lead to dead lock. Here's + a scenario: + + + + (1) In session A client sends parse, bind, execute request for the function to pgpool. + + + + + + + (2) Pgpool-II in session A forwards + the request to PostgreSQL. + + + + + + + (3) PostgreSQL in session A performs execute, resulting in a table lock. + + + + + + + (4) In session B client sends parse, bind, execute request for the + function to pgpool. + + + + + + + (5) Pgpool in session B forwards the request to PostgreSQL. + + + + + + + (6) PostgreSQL in session B performs bind but the table was already + locked by PostgreSQL in session A, and it waits for release of the + lock. + + + + + + + (7) After pgpool in session B forwards the execute to PostgreSQL, it + acquires semaphore to search shared relation cache to check the + volatility of the function. Then it calls do_query and sends flush + message to PostgreSQL to obtain the response from PostgreSQL up to + this point. But since PostgreSQL is waiting for table lock in #6, + pgpool has to wait for messages beyond bind complete. + + + + + + + (8) After pgpool in session A forwards the execute to PostgreSQL, it + tries to acquire semaphore to search shared relation cache to check + the volatility of the function but the semaphore was already + acquired by pgpool in session B, it waits for the release of the + semaphore. + + + + + + + (9) Session A and session B wait for each other, resulting in a dead lock. + + + + + + To fix this, modify pool_search_relcache() so that it releases + semaphore before calling do_query() (but acquires semaphore after + do_query()). By this, session A in #8 above can get semaphore, and go + forward. It receives sync message from client and forwards it to + PostgreSQL. Upon receiving sync, the user defined function will finish + the execution and releases the table lock. This makes PostgreSQL in + session B move forward because now it can obtain the table lock. + + + + + + + Fix compile error on systems using musl libc. + (bug 790) (Tatsuo Ishii) + + + Patch provided by leimaohui. + + + + + + + Fix multiple query cache bug. (Tatsuo Ishii) + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + Fix sr worker to not send wrong query to standby server in corner case. (Tatsuo Ishii) + + + When ALWAYS_PRIMARY flag is set, PRIMARY_NODE_ID macro returns node + id, rather than -1 even if the primary is down. + In this case streaming replication delay check worker + sends SELECT pg_current_wal_lsn() or + SELECT pg_current_xlog_location() + depending on PostgreSQL's version to + standby which of course raises an error. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + Fix kind mismatch error with DEALLOCATE. + (bug 780) (Tatsuo Ishii) + + + Kind mismatch error occurs when conditions below are all met: + + + + streaming replication mode + + + + + + + load balance node is other than primary + + + + + + + PREPARE is used in a multi-statement query + + + + + + + + + + Fix compile error of regression test (Takuma Hoshiai) + + + The error occurred by timestamp test using gcc10. + + + + + + + Fix that show pool_version shows row description twice. (Tatsuo Ishii) + + + + + + + Documents + + + + + Add explanation for . (Chen Ningwei) + + + + + + + Add restriction regarding PREPARE/EXECUTE/DEALLOCATE. (Tatsuo Ishii) + + + + + + + Add caution to use -D option with pgpool. (Tatsuo Ishii) + + + + + + + Enhancing "Installation from RPM" section. (Bo Peng) + + + + + + + Add "Backing up PostgreSQL database" section to "Server Setup and Operation" chapter. (Tatsuo Ishii) + + + + + + + Remove the configuration of "-D" start OPTS from "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix restrictions section. (Tatsuo Ishii) + + + + + + Add mention about SCRAM-SHA-256 authentication + + + + + + + Add mention about snapshot isolation mode + + + + + + + + + + Mention that AES256 support requires option. (Tatsuo Ishii) + + + + + + + Explicitly stat that it is -w option of pcp command is needed to use .pcppass. (Tatsuo Ishii) + + + + + + + Enhance . (Tatsuo Ishii) + + + + + + + Regression Tests + + + + + Refactor 071.execute_and_deallocate/test.sh. (Tatsuo Ishii) + + + + + + + Enhance regression tests. (Tatsuo Ishii) + + + + + + + Fix occasional 005.jdbc test failure. (Tatsuo Ishii) + + + + + + + + Release 4.2.12 + + Release Date + 2023-01-23 + + + + Overview + + This release contains a security fix. + + + If following conditions are all met, the password of is + exposed by command. + The command can be executed by any user who can + connect to Pgpool-II. (CVE-2023-22332) + + + + + + Version 3.3 or later. + + + + + + is on. + + + + + + is query. + + + + + + A plain text password is set + to . + + + + + + In this case it is strongly recommended to upgrade to this version + (we do not expose in + show pool_status command any more), or use one of following + workarounds. + + + + Workarounds for 4.0.x to 4.4.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + Set an empty string + to . This will use + password in the pool_passwd file. + + + + + + Set an AES encrypted password + to . + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Workarounds for 3.0.x to 3.7.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Please note that Pgpool-II 3.7.x or + before are end of life and no minor updates are provided for those + versions. + + + + + Changes + + + + + + Do not expose in + , + and + commands. (CVE-2023-22332) (Bo Peng) + + + + + + + Change the default value + for to empty string as + documented. (Bo Peng) + + + + + + + + Bug fixes + + + + + + Fix compiler warning + in pgpool-regclass.c. (Florian Weimer, + Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: Enhance and fix some mistakes + in Configurations + to use shared memory chapter. (Tatsuo Ishii) + + + + + + + + + Release 4.2.11 + + Release Date + 2022-12-22 + + + + Changes + + + + + Downgrade LOG messages "new IPC connection received" to DEBUG1. + (bug 775) (Bo Peng) + + + It is a normal messages and should not be logged as LOG. + Patch is created by pstef and reviewed by Bo Peng. + + + + + + + + Bug fixes + + + + + + Fix issue with . (Muhammad Usama) + + + The fix is to dynamically set the failover command timeout based on the maximum + value of health check parameters across the watchdog cluster. + + + Reviewed and tested by Tatsuo Ishii. + Discussion: [pgpool-hackers: 4227] + + + + + + + Fix not to print warnings of use of backslashes in parser. (Tatsuo Ishii) + + + When standard_conforming_strings = off and escape_string_warning = on, + PostgreSQL prints warnings if backslashes are used in string + literal. This is fine. But previously Pgpool-II's parser printed the + same message too. This is redundant. + + + + + + + Deal with idle_session_timeout. (Tatsuo Ishii) + + + If idle_session_timeout (added in PostgreSQL 14) is enabled and the + timeout fires, followings happen: + + + + If failover_on_backend_error is on (the default), Pgpool-II will trigger failover. + + + + + + + If only one of PostgreSQL servers enables idle_session_timeout, Pgpool-II could hang. + + + + + + To deal with idle_session_timeout detect_idle_session_timeout_error() + is added to detect the error code for idle_session_timeout. If the + error is detected, Pgpool-II returns the error code to frontend as a + fatal error and disconnects the session. This is a similar fix + implemented for idle_in_transaction_session_timeout. + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + Discussion: [pgpool-hackers: 4208] + + + + + + + Deal with SSL error SSL_ERROR_ZERO_RETURN. (Tatsuo Ishii) + + + Previously this caused failover, which was actually unnecessary because + it means the server is just going to close the connection. + + + Discussion: [pgpool-general: 8366] + Discussion: [pgpool-hackers: 4193] + + + + + + + Fix: Setting memory cache size greater than 2GB causes a segfault. (Muhammad Usama) + + + The problem was in the block_address() function that returns the memory address + for a given cache block, It was using 32bit integers to calculate the offset of + the block within the shared memory space that is only good until the 2GB limit. + + + + + + + Fix rare segfaults in pcp_proc_info, SHOW pool_pools + and SHOW pool_processes. (Tatsuo Ishii) + + + The segfaults were in get_pools() and get_processes(). They first + extracted pid of particular process info slot on shared memory then + searched the slot again by using pid as the key. Because these steps + were not protected by any locking, it was possible that the search + using the pid failed and returned NULL if the process id is + overwritten by pgpool parent which is responsible for forking new + child process after the process exiting. As a result any subsequent + reference to the NULL pointer generated segfaults. + + + Solution is, first get the pointer to the process info slot then + extract the process id member from the pointer. This way, still + concurrent updating to the shared memory info by the parent process is + possible (which may lead to strange results in the output) but at + least we can avoid segfaults. + + + + + + + Fix to not allow Unix-domain socket path with invalid length. (Masaya Kawamoto) + + + + + + + + Documents + + + + + + Doc: fix typo in Aurora example. (Tatsuo Ishii) + + + + + + + Doc: enhance description about memqcache_method. (Tatsuo Ishii) + + + Add explanation which method should be used. + + + + + + + Doc: mention that health check process may use SSL. (Tatsuo Ishii) + + + Also mention that streaming replication check may use SSL too. + This should have been added since 2010. + + + Discussion: [pgpool-hackers: 4187] + + + + + + + + Regression Tests + + + + + + Allow to define PGPOOLDIR using environment variable. + (bug 766) (Bo Peng) + + + + + + + + + Release 4.2.10 + + Release Date + 2022-08-18 + + + + Changes + + + + + + Add ssh options to restore_command in sample scripts. (Bo Peng) + + + Patch is created by Jon SCHEWE and updated by Bo Peng. + + + + + + + Update sample scripts. (Bo Peng) + + + + Update PSQL connection information to use postgres database when creating or dropping replication slots. + + + + + + + Allow setting ssh login user and ssh key file using variables. + + + + + + + + + + When CloseComplete is received, forward to frontend without buffering. (Tatsuo Ishii) + + + It seems this caused occasional timeout error in 074.bug700_memqcache_segfault. + + + + + + + + Bug fixes + + + + + + Fix bug in query cache. (Tatsuo Ishii) + + + Pgpool-II did not cache the query like "Select '2022-02-18 07:00:00.006547'::timestamp". + SELECTs include TIMESTAMP, TIME and DATE are cached, and SELECTs include TIMESTAMPZ + and TIMEZ are not cached because the result can be changed by SET TIME ZONE command etc. + Furthermore, SELECTs having functions with return types are timestamptz or timetz are + not cached too as same reason. + Discussion: [pgpool-general: 8285] + + + + + + + Fix internal transaction handling bug in snapshot isolation mode. (Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: mention that certain SELECTs are not cached. (Tatsuo Ishii) + + + certain SELECTs are follows. + + + + SELECTs including TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including CAST to TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including SQLValueFunction (CURRENT_TIME, CURRENT_USER etc.) + + + + + + + + + + Doc: fix description about using PCP password file when connect to Unix domain socket (Masaya Kawamoto) + + + The localhost entry in pcppass matches only for the default PCP socket + directory path, not all Unix socket connections. This behavior is the + same as pgpass. + + + + + + + Doc: enhance and fix memory requirement section. (Tatsuo Ishii) + + + + + + Add explanation about memory usage while pgpool child process is running. + + + + + Enhance the formula to calculate shared memory requirement so that it computes more accurate result. + + + + + Fix shared memory requirement for shared rel cache. The old value 64MB was simply wrong. + + + + + Fix process memory requirement. Previously the formula was based on + RSS. However PSS should be used because RSS includes shared memory + such as the memory used for libraries. This results in lot smaller + memory requirement than before. + + + + + + + + + + Doc: fix wrong explanation on , . (Tatsuo Ishii) + + + Those parameters cannot be changed by reloading config file. Restarting + pgpool is required. + + Discussion: [pgpool-general: 8195] + + + + + + + + Test Tools + + + + + + Allow to run pgpool_setup on PostgreSQL 15. (Tatsuo Ishii) + + + Per ticket 757 + + + + + + + Allow pgpool_setup to test sample scripts and sample config files contained in RPMs. (Bo Peng) + + + + + + + + Regression Tests + + + + + + Test: print Pgpool-II version in the regression test. (Tatsuo Ishii) + + + + + + + Test: Fix regression test script to look for pgpool.conf in the proper install directory. (Tatsuo Ishii) + + + + + + + + + + Release 4.2.9 + + Release Date + 2022-05-19 + + + + Changes + + + + + Enhance in stopping pgpool main process. (Tatsuo Ishii) + + + If "pgpool stop" couldn't terminate the main process within certain period (currently 5 seconds), send the signal again. + + + + + + + Change the PID length of pcp_proc_count command to 7 characters long. (Bo Peng) + + + + + + + Enhance error message to include the message kind returned and the backend node id while processing parse message. (Tatsuo Ishii) + + + + + + + Downgrade log level of ParameterStatus message from LOG to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + Change the default value of from '*' to 'localhost'. (Tatsuo Ishii) + + + + + + + Adjust the field name in . (Muhammad Usama) + + + + + + + Enable parameters related to by default in RPM packages. (Bo Peng) + + + + + + + + Bug fixes + + + + + Fix issue that watchdog cluster keeps rejecting the restarted remote node which is lost previously. (Muhammad Usama) + + + Issue report: [pgpool-general: 7896] + + + + + + + Fix exit_handler in pgpool main process to avoid possible infinite wait. (Tatsuo Ishii) + + + + + + + Fix a potential issue in shared memory allocation function. (Tatsuo Ishii) + + + + + + + Fix bug with pg_enc and pg_md5 when using "-i" option. (bug 747)(Tatsuo Ishii) + + + + + + + Fix main process exiting if a backend is failing or shutting down while performing finding primary. (Tatsuo Ishii) + + + + + + + Fix segfaults in watchdog. (Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + Fixed follow_primary.sh.sample script to check the status of PostgreSQL using pg_isready. (Bo Peng) + + + + + + + + Documents + + + + + Doc: move the example of "Pgpool-II on Kubernetes" to github repository. (Bo Peng) + + + + + + + Doc: update configuration example. (Masaya Kawamoto) + + + + + + + Doc: update the example output of . (Bo Peng) + + + + + + + Doc: mention that escaping is required if you are providing the password as an argument to pg_enc and the password contains a "$" character. (Bo Peng) + + + + + + + + + Regression Tests + + + + + Enhance regression test 018.detach_primary to avoid the timeout error. (Tatsuo Ishii) + + + + + + + Enhance regression test 074.bug700_memqcache_segfault to avoid the timeout error. (Tatsuo Ishii) + + + + + + + Improve regression test to detect segmentation fault. (Bo Peng) + + + + + + + + + Release 4.2.8 + + Release Date + 2022-02-17 + + + + Changes + + + + + + Suppress message length log for in_hot_standby. (Tatsuo Ishii) + + + PostgreSQL 14 introduced new config parameter in_hot_standby. + + + The value is either "on" for standby servers or "off" for primary + servers. As a result pgpool log is flooded by the messages: + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + To avoid this, only complain if the parameter name is not in_hot_standby. + + + Also the message is enhanced to show the parameter name. For example: + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + Add validations of and format (Masaya Kawamoto) + + + wd_lifecheck_password and recovery_password + are not allowed to be md5 hashed password format but pgpool just reported + authentication failure and did not check them. + + + + + + + Enhance parameter status handling. (Tatsuo Ishii) + + + When a parameter status message arrives from backend Pgpool-II + forwards it to frontend not just memorize. + + + + + + + + Bug fixes + + + + + + Fix long standing bug with pcp_node_info. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Fix health check process issues pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix memory leak pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix failover() to deal with the case when no former primary node exists. (Tatsuo Ishii) + + + In case Req_info->primary_node_id is -1 like no primary + node exists when Pgpool-II starts up, + failover() skipped to call + find_primary_node_repeatedly(). Also + follow_master_command was not executed. + + + Discussion: [pgpool-hackers: 4113] + + + + + + + Fixed sample failover script. (Bo Peng) + + + This script did not consider the case when the old primary node id is "-1". + + + + + + + Fixed the streaming replication check process not to retry if it cannot connect to the backend.(bug 742) (Bo Peng) + + + This retry caused a long time failover. + + + + + + + + Documents + + + + + + Fix documentation typos. (pengbo) + + + Patch is created by Umar Hayat. + + + + + + + Add "exclude" settings to /etc/yum.repos.d/pgdg-redhat-all.repo so + that Pgpool-II is not installed from + PostgreSQL YUM repository. (Bo Peng) + + + + + + + Add restriction regarding ParameterStatus and in_hot_standby parameter. (Tatsuo Ishii) + + + + + + + Add restriction about set_config. (Tatsuo Ishii) + + + + + + + + Test tools + + + + + + Fix pgpool_setup in failover script creation. (Tatsuo Ishii) + + + When pgpool_setup creates failover.sh, + it did not consider the case when no primary server existed. + + + + + + + + Regression tests + + + + + + Allow to run regression test against existing installation without recompiling. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + Fix regression test 075. (Tatsuo Ishii) + + + The test reported success even if pgpool does not start up. + Problem reported and patch provided by Qiang Lingjie. + Discussion: [pgpool-hackers: 4085] + + + + + + + Fix pgpool_setup and watchdog_setup binary PATH in noinstall mode. (Bo Peng) + + + + + + + + + Release 4.2.7 + + Release Date + 2021-12-23 + + + + Changes + + + + + + Suppress bison warnings regarding yacc incompatibility. (Tatsuo Ishii) + + + + + + + Fix redundant code. (Tatsuo Ishii) + + + Patch contributed by Lu Chenyang. + + + + + + + + Documents + + + + + + Doc: fix typo in pcp_watchdog_info manual. (Tatsuo Ishii) + + + + + + + Doc: fix typos in configuration example. (Bo Peng) + + + Patch is created by Lu Chenyang. + + + + + + + Doc: fix typos in release notes. (Bo Peng) + + + + + + + + + Release 4.2.6 + + Release Date + 2021-11-18 + + + + Security release + + + + + Reject extraneous data after SSL encryption handshake. (Tatsuo Ishii) + + + In the server side implementation of SSL negotiation, it was possible for a + man-in-the-middle attacker to inject arbitrary SQL commands. This is + possible if Pgpool-II is configured to use cert authentication or + hostssl + trust. This resembles PostgreSQL's CVE-2021-23214. + + + Similarly, in the client side implementation of SSL negotiation, it was + possible for a man-in-the-middle attacker to inject arbitrary responses. + This is possible if PostgreSQL is using trust authentication with a + clientcert requirement. It is not possible with cert authentication because + Pgpool-II does not implement the cert authentication between Pgpool-II + and PostgreSQL. This resembles PostgreSQL's CVE-2021-23222. + + + + + + + Changes + + + + + + Deal with PostgreSQL 14 while processing + pg_terminate_backend(). (Tatsuo Ishii) + + + + + + + Enhance SIGCHLD handler of Pgpool-II main process. (Tatsuo Ishii) + + + When Pgpool-II child is killed by SIGKILL signal, + the SIGCHLD handler just emitted LOG level message as other signals. But + SIGKILL is an important event, for example killed by OOM killer. So emit a + WARNING level message instead. + Per suggestion from Michail Alexakis. + Discussion: [pgpool-general: 7750] + + + + + + + + Bug fixes + + + + + + Fix application_name array lacking an entry for logger process. (Tatsuo Ishii) + + + + + + + Fix connection counter issue when is 0. (Tatsuo Ishii) + + + If reserved_connections is 0, we don't need to manage + the connection counter. This will prevent unwanted "Sorry, too many clients + already" error by accidental counter leak. + Discussion: [pgpool-general: 7750] + + + + + + + Fix for bug 732: Segmentation fault at failover ... (Muhammad Usama) + + + + + + + Fix occasional hang in COPY FROM. (Tatsuo Ishii) + + + If an error occurs while doing COPY FROM, it was possible the + Pgpool-II waited forever for a response from + backend after COPY end marker was sent from frontend. + The bug was found by Bo Peng. + + + + + + + + Documents + + + + + + Doc: fix documentation typos. (Bo Peng) + + + + + + + Fix typos in documentation and sample scripts. (Bo Peng) + + + Patch is created by Kazufumi Noto. + + + + + + + Doc: fix yum install command typo in configuration example. (Bo Peng) + + + + + + + + Regression tests + + + + + + Fix occasional 073.pg_terminate_backend regression test failure. (Tatsuo Ishii) + + + + + + + Rename regression test 074. (Bo Peng) + + + + + + + Fix pg_config command path to avoid test failure. (Bo Peng) + + + + + + + Fix psql command path to avoid test failure. (Bo Peng) + + + + + + + + + Release 4.2.5 + + Release Date + 2021-09-14 + + + + Changes + + + + + Change PGPOOL SHOW option other_pgpool to watchdog. (Bo Peng) + + + Since 4.2 other_pgpool parameter is removed, + other_pgpool option should be changed to watchdog. + + + + + + + Bug fixes + + + + + Fix bug-731: Fails to execute follow_primary_command when watchdog is enabled. + (bug 731) (Muhammad Usama) + + + It was a segmentation fault happening because of a silly coding mistake in + parse_wd_exec_cluster_command_json() function. + This bug was introduced in 4.2.4 and does not affect 4.2.3 and earlier. + + + + + + + Fix bug of PGPOOL SHOW heartbeat and PGPOOL SHOW ALL command. (Bo Peng) + + + + + + + Fix to allow to be set to 0. (Tatsuo Ishii) + + + According to the docs, it is possible to set 0 to log_rotation_age + so that the log rotation feature is disabled. But the allowed minimum + value for it was mistakenly set to 10, which made it impossible to set + log_rotation_age to 0. + + + + + + + Fix the incorrect display of load balancing node in raw mode. (Bo Peng) + + + In raw mode, Pgpool-II sends all queries to main node. + This is harmless, but it may confuse users. + + + + + + + Fix pgpool logger process eats 100% cpu. (Tatsuo Ishii) + + + Problem reported and patch provided by Fang Jun. + Discussion: [pgpool-hackers: 3992] + + + + + + + Fix SI mode to acquire a snapshot with an internal transaction. (Tatsuo Ishii) + + + + + + + Fix backend_flag* parameter shown twice while executing PGPOOL SHOW ALL. (Tatsuo Ishii) + + + + + + + Documents + + + + + Doc: Mention that double quotes are required in PGPOOL SHOW command, + if the parameter contains uppercase letters. (Bo Peng) + + + + + + + Test tools + + + + + Fix pgpool_setup to do nothing when no new main node is available. (Tatsuo Ishii) + + + + + + + + Release 4.2.4 + + Release Date + 2021-08-05 + + + + Changes + + + + + + Fix maximum length of hostnames including domain name. (Tatsuo Ishii) + + + The maximum length of hostnames was 128, but the correct value is 254. + Discussion: [pgpool-hackers: 3903] + + + + + + + + Bug fixes + + + + + + Fix query cache to not cache SQLValueFunctions. (Tatsuo Ishii) + + + The list of SQLValueFunctions is follow. + + + + CURRENT_DATE + + + + + CURRENT_TIME + + + + + CURRENT_TIMESTAMP + + + + + LOCALTIME + + + + + LOCALTIMESTAMP + + + + + CURRENT_ROLE + + + + + CURRENT_USER + + + + + SESSION_USER + + + + + USER + + + + + CURRENT_CATALOG + + + + + CURRENT_SCHEMA + + + + + + + + + + Implementing the follow_primary command-locking over the watchdog channel. (Muhammad Usama) + + + This is supplementary fix for "Fix race condition between detach_false_primary and follow_primary_command". + The design is good enough for most cases, but has the potential to fail in some case. + + + + + + + Fix client side hang when describe message is followed by NoData response. (Tatsuo Ishii) + + + Problem reported and patch provided by Daniel van de Giessen. + Discussion: [pgpool-hackers: 3950] + + + + + + + Fix typo in pgpool.conf samples. (Tatsuo Ishii) + + + + + + + Fix sending invalid message in SI mode. (Tatsuo Ishii) + + + When a query is aborted by specific reason like serialization error, + Pgpool-II sends error query to abort + transactions running on non main nodes. The message length of the + query was incorrect and it caused "invalid string in message" error on backend. + + + + + + + Fix orphan process is left when pgpool is going down. (Tatsuo Ishii) + + + When pgpool is going down while follow primary command is ongoing, + some process started by follow primary child process could be left. + + + + + + + Fix pcp_detach_node leaves down node. (Tatsuo Ishii) + + + As detaching primary node using pcp_detach_node, a + standby node is kept down status after follow primary command was executed. + Discussion: [pgpool-hackers: 3915] + + + + + + + Fix cannot be changed by reloading pgpool.pgpool.conf. (Tatsuo Ishii) + + + + + + + Fix watchdog communication race condition. (Tatsuo Ishii) + + + When watchdog notifies the new message to main process while main process + is executing the process notified by watchdog process, there was a + significant delay before the new message was processing. + Discussion: [pgpool-hackers: 3900] + + + + + + + Fix watchdog node status not updating after rebooting. + (bug 684) (Muhammad Usama) + + + + + + + + Documents + + + + + + Doc: Update configuration example "Pgpool-II on Kubernetes". (Bo Peng) + + + + + + + Doc: add more explanation about . (Tatsuo Ishii) + + + + + + + Doc: fix documentation typos. (Bo Peng) + + + + + + + Doc: fix typo in in memory query cache document. (Tatsuo Ishii) + + + + + + + Doc: fix parameter name typo in ldap option (Takuma Hoshiai) + + + + + + + Doc: fix description (Masaya Kawamoto) + + + + + + + + Test tools + + + + + + Fix pgpool_setup to generate portable follow_primary.sh. (Tatsuo Ishii) + + + + + + + Fix rsync parameter in pgpool_setup. (Tatsuo Ishii) + + + + + + + Fix follow primary script creation in pgpool_setup. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup in creating base backup script. (Tatsuo Ishii) + + + + + + + Enhance watchdog_setup script. (Tatsuo Ishii) + + + shutdownall script generated by watchdog_setup caused failover event which is not + necessary in the whole shutdown sequence. + + + + + + + + Regression tests + + + + + + Fix 075.detach_primary_left_down_node. (Tatsuo Ishii) + + + + + + + Fix 031.connection_life_time. (Tatsuo Ishii) + + + + + + + Fix 018.detach_primary error in the log. (Tatsuo Ishii) + + + + + + + Fix occasional failure of 028.watchdog_enable_consensus_with_half_votes test. (Tatsuo Ishii) + + + + + + + Fix occasional regression test 018.detach_primary error. (Tatsuo Ishii) + + + + + + + + + Release 4.2.3 + + Release Date + 2021-05-20 + + + + Bug fixes + + + + + Improve sample scripts. (Bo Peng) + + + + + + + Fix regression test 018.detach_primary. (Tatsuo Ishii) + + + + + + + Fix race condition between and . (Tatsuo Ishii) + + + If and are running concurrently, many problem occurred. + Typical problem is, no primary node is found at the end. + + + + + + + Doc: fix description about . (Tatsuo Ishii) + + + It did not mention the parameter can only be used if Pgpool-II started as root. + + + + + + + Doc: enhance description on . (Tatsuo Ishii) + + + + + + + + + Doc: remove incorrect description about . (Tatsuo Ishii) + + + + + + + + + Fix broken database/app redirect preference in statement level load balancing mode. + (bug 707) (Bo Peng) + + + + + + + Fix to create database cluster entity under pgpool0. (Tatsuo Ishii) + + + + + + + Fix default value of . (Tatsuo Ishii) + + + Patch contributed by KAWAMOTO Masaya. + + + + + + + Set application name "pgproto" to pgproto. (Tatsuo Ishii) + + + + + + + Fix pgpool crash when query cache enabled. + (bug 700) (Tatsuo Ishii) + + + Pgpool-II crashed upon receiving CloseComplete. This only happened in other than streaming and logical replication mode. + + + + + + + Improve follow_primary.sh sample scripts. + (bug 694) (Bo Peng) + + + Empty pg_replslot directory of the standby node after running pg_rewind, because pg_replslot directory may be copied from the primary node in old PostgreSQL versions. + + + + + + + Fix that query cache is not created in other than streaming and logical replication mode. (Tatsuo Ishii) + + + + + + + Fix so that it fail back to full restore if failed in restarting. (Tatsuo Ishii) + + + + + + + Fix hang with asyncpg. (Tatsuo Ishii) + + + + + + + Enhance debug message upon receiving startup packet. (Tatsuo Ishii) + + + + + + + Doc: enhance documentation. (Tatsuo Ishii, Bo Peng) + + + + + + + + Release 4.2.2 + + Release Date + 2021-02-18 + + + + Bug fixes + + + + + Fix the incorrect "weight" displayed in . (Tatsuo Ishii) + + + + + + + Fix follow_primary.sh.sample to avoid removing recovery.conf after executing pg_rewind. (Bo Peng) + + + + + + + Fix watchdog leader sync process to start health check process. (Tatsuo Ishii) + + + + + + + Doc: fix the missing description of snapshot isolation mode in manual. (Tatsuo Ishii) + + + + + + + Fix watchdog_setup to support for snapshot isolation mode. (Tatsuo Ishii) + + + + + + + Fix that DB cluster path was not correct in watchdog_setup installation. (Tatsuo Ishii) + + + + + + + Fix follow_primary.sh creation in pgpool_setup. (Tatsuo Ishii) + + + + + + + Enhance shutdownall script used by pgpool_setup. (Tatsuo Ishii) + + + + + + + Fix pgpool_setup so that it creates separate archive directory for each DB node. (Tatsuo Ishii) + + + + + + + Fix missing display of in "show pool_status" command. (Bo Peng) + + + + + + + Fix messages when health check process starts. (Tatsuo Ishii) + + + + + + + Doc: mention that the sample scripts doesn't support tablespaces in "Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix segfault in snapshot isolation mode. (Tatsuo Ishii) + + + + + + + Doc: enhance online recovery document about recovery first stage and second stage. (Tatsuo Ishii) + + + + + + + Doc: add explanation about the shared memory required by shared relation cache. (Tatsuo Ishii) + + + + + + + Adjusting the allowed range and default value for . (Muhammad Usama) + + + + + + + Fix error while allocating shared memory. (Tatsuo Ishii) + + + + + + + Fix bug is not respected if ERROR occurs. (Tatsuo Ishii) + + + + + + + + Release 4.2.1 + + Release Date + 2020-12-23 + + + + Changes + + + + + Change the socket path to "/var/run/postgresql" in all of the pgpool.conf samples. (Bo Peng) + + + + + + Use single shared memory segment for all shared variables in Pgpool parent process (Muhammad Usama) + + + Shared memory segments is a limited resource and opening too many segments should be avoided. + + + + + + Delete any pre-existing watchdog command socket file at startup (Muhammad Usama) + + + Patch provided by Masaya Kawamoto + + + + + + + Bug fixes + + + + + Doc: Add missing raw mode to "5.3. Clustering mode" and fix typos. (Bo Peng) + + + + + + + Fix incorrect heartbeat related results of pcp_pool_status and SHOW POOL_STATUS commands. (Bo Peng) + + + + + + + Doc: fix usage of firewall-cmd in the installation tips section. (Tatsuo Ishii) + + + firewall-cmd opened unnecessary ports in the example. + + + + + + + Fix segfault that may occur when backend_flag = 'ALWAYS_PRIMARY|ALLOW_TO_FAILOVER' or failover_command = ''. + (bug 672) (Tatsuo Ishii) + + + + + + + Fix for inconsistent watchdog node_id problem in and watchdog lifecheck mechanism. (Muhammad Usama) + + + When pgpool node 0 (leader watchdog) is shutdown, all of the pgpool nodes terminate abnormally. + This commit fixed this issue. + + + + + + + Fix error if watchdog is disabled and wd_port is not defined. (Tatsuo Ishii) + + + + + + + Fix compiler error on FreeBSD. + (bug 670) (Tatsuo Ishii) + + + Patch is provided by ajs. + + + + + + + Fix file swapping race condition in pool_passwd. (Tatsuo Ishii) + + + Patch is provided by Masaya Kawamoto. + + + + + + + + Release 4.2.0 + + Release Date + 2020-11-26 + + + + Overview + + Many enhancements are added to this version for easier + configuration and administration. Moreover new clustering mode + which allows not only write consistency but read consistency in + multiple PostgreSQL servers. Also SSL + is improved to allow more secure operation. New + PostgreSQL 13 SQL + parse is imported. + + + + Please be warned that in this version some configuration parameters + are changed to use more appropriate language. Also some words used + in reporting are changed accordingly. See "Migration" section for + more details. + + + + Below are major enhancements. + + + + + + Some items in the configuration file + pgpool.conf are vastly enhanced for easier + configuration and administration. + + + + + + Implement for easier log + management. + + + + + + Implement to collect + disconnection logs. + + + + + + Implement and to + allow to register multiple passwords at once. + + + + + + Allow to show statistics of health check by using command, and also + allow to show statistics of issued SQL by using command. + + + + + + New PCP command is added. + + + + + + Now it is possible to omit and by looking at system catalog + information. + + + + + + Add new clustering mode which guarantees not only + data modifications to multiple + PostgreSQL but read consistency. + + + + + + Support LDAP authentication between clients and + Pgpool-II. + + + + + + Add and to SSL configuration. + + + + + + Import PostgreSQL 13's SQL parser. + + + + + + + + Migration to Version 4.2 + + + + + + + master_slave_mode, master_slave_sub_mode and replication_mode are + deprecated and replaced by . Please change them as + follows. + + + + + master_slave_mode = 'on', master_slave_sub_mode = 'stream' → backend_clustering_mode = 'streaming_replication' + + + + + + master_slave_mode = 'on', master_slave_sub_mode = 'logical' → backend_clustering_mode = 'logical_replication' + + + + + + master_slave_mode = 'on', master_slave_sub_mode = 'slony' → backend_clustering_mode = 'slony' + + + + + + replication_mode = 'on' → backend_clustering_mode = 'native_replication' + + + + + + replication_mode = 'off', master_slave_mode = 'off' → backend_clustering_mode = 'raw' + + + + + + + + + + + Cleanup language. (Umar Hayat) + + + Following changes are made in pgpool.conf. + + + + + black_function_list → write_function_list + + + + + + white_function_list → read_only_function_list + + + + + + black_query_pattern → primary_routing_query_pattern + + + + + + black_memcache_table_list → cache_unsafe_table_list + + + + + + white_memcache_table_list → cache_safe_table_list + + + + + + ALWAYS_MASTER flag → ALWAYS_PRIMARY flag + + + + + + follow_master_command → follow_primary_command + + + + + + Replace relcache_query_target option value 'master' to 'primary'. + + + + + + + + Some words used in reporting are changed. + + + + + master → main + + + slave → replica + + + + + + + Some parameter names used in scripts are changed. + + + + + master → main + + + + + + + Some names used in watchdog are changed. + + + + + master → leader + + + + + + + + + + + Watchdog parameters below are deprecated. + + - wd_hostname + - wd_port + - wd_heartbeat_port + - heartbeat_device + - heartbeat_destination0 + - heartbeat_destination_port0 + - heartbeat_destination1 + - heartbeat_destination_port1 + - other_pgpool_hostname0 + - other_pgpool_port0 + - other_wd_port0 + - other_pgpool_hostname1 + - other_pgpool_port1 + - other_wd_port1 + + Use below parameters instead. + See for more details. + + hostname0 = 'server1' + wd_port0 = 9000 + pgpool_port0 = 9999 + + hostname1 = 'server2' + wd_port1 = 9000 + pgpool_port1 = 9999 + + hostname2 = 'server3' + wd_port2 = 9000 + pgpool_port2 = 9999 + + heartbeat_hostname0 = 'server1' + heartbeat_port0 = 9694 + heartbeat_device0 = '' + + heartbeat_hostname1 = 'server2' + heartbeat_port1 = 9694 + heartbeat_device1 = '' + + heartbeat_hostname2 = 'server3' + heartbeat_port2 = 9694 + heartbeat_device2 = '' + + Unlike 4.1 or before, now all watchdog parameters are identical + on all hosts. To distinguish which host is which, create a file + pgpool_node_id and put number 0, 1, 2 + etc. to identify host. + + + + + + and are now both empty. + + + + + + + + + Bug fixes + + + + In this release same bug fixes as Pgpool-II 4.1.4 are + already applied. See for more details of those fixes. + + + + + + + Major Enhancements + + + + + + Removing strerror() call from ereports. (Muhammad Usama) + + + Call to ereport() resets the errno value and using the "strerror(errno)" emits the wrong error message. + The right way is to use %m format specifier instead. + + + + + + + Unify master_slave_mode, master_slave_sub_mode and + replication_mode into . (Tatsuo Ishii) + + + + + + + Simplify Watchdog related configuration parameters. (Bo Peng) + + + + + + + Allow units to be specified with configuration settings. (Muhammad Usama) + + + + + + + Add . (Muhammad Usama, Japanese doc by Tatsuo Ishii) + + + Import PostgreSQL's logging collector. + + + + + + + Allow to collect disconnection log by . (Takuma Hoshiai) + + + + + + + Allow to set application name parameter of in more cases. (Tatsuo Ishii) + + + %a in was only be set if + application_name is specified in startup message. Now it is + possible to set application_name if it is set in the connection + parameter or SET command. + + + Also set hard coded application_name in various internal process so + that admins can easily recognize each log line belonging to which + process. + + + + + + + Change so that includes application name. (Tatsuo + Ishii) + + + + + + + Add support for an user/password input file to . (Umar Hayat, Japanese doc by Tatsuo Ishii) + + + + + + + Add support for an user/password input file to . (Umar Hayat, Japanese doc by Bo Peng) + + + + + + + Add . (Tatsuo Ishii) + + + The new command shows the number of SQL commands executed and + errors returned from backend since + Pgpool-II started. + + + + + + + Add to show + health check statistics (Tatsuo Ishii) + + + + + + + Add new PCP command . (Tatsuo Ishii) + + + + + + + Add new pgpool_adm function . (Tatsuo Ishii) + + + + + + + New PCP command for reloading + the pgpool configuration (Jianshen Zhou, Muhammad Usama, Japanese + doc by Tatsuo Ishii) + + + + + + + Allow to stop whole pgpool cluster by using command. (Muhammad Usama, Japanese doc + by Tatsuo Ishii) + + + + + + + Add wd_cli utility (Muhammad Usama, Japanese doc by Tatsuo Ishii) + + + makes it easier to integrate the external health check systems with the + Pgpool-II. + + + + + + + Implement automatic writing function detection by checking volatile property. (Tatsuo Ishii, Hou, Zhijie) + + + If a function included in SELECT/WITH has volatile property by + checking system catalog, regard it a writing function. This + feature is available only when the and the are both empty. The default of + the black_function_list and the white_function_list are now empty + string so that this feature is enabled by default. + + + + + + + Enhance the way getting function names in multiple places. (Hou, Zhijie) + + + With query cache enabled, Pgpool-II + examines function calls in SELECTs. However if a function were + called with schema qualification, it was not recognized. This + commit fix to allow schema qualifications in the case. + + + Also now schema qualified function names in and are allowed. Note that if you + want to register schema qualified function names, you have to + register function names without schema qualification as well. + + + + + + + Add dml object level load balance support in .(Subiao, Muhammad + Usama) + + + + + + + Allow to use argument names in pgpool_adm functions. (Hou, Zhijie) + + + Example: + + SELECT * FROM pcp_node_count(host => 'localhost', port => 11001, username => 't-ishii', password => 't-ishii'); + + + + + + + + Add public API to invalidate query cache by table/database oid. (Tatsuo Ishii) + + + + + + + Add support for LDAP authentication between client and pgpool. (Takuma Hoshiai) + See for more details. + + + + + + + Enhance scram/md5 auth regression test to use AES256 encrypted password. (Tatsuo Ishii) + + + + + + + Add new "snapshot + isolation mode". (Tatsuo Ishii) + + + This mode is similar to existing native replication mode except + it provides more strict read consistency among backends (so + called "atomic visibility") and will give a illusion that a + cluster consisting with multiple backends seems to be a single + PostgreSQL server. + + + + + + + Add mention about hostssl/hostnossl to + pool_hba.conf sample file. (Tatsuo Ishii) + + + Although hostssl/hostnossl are supported, + pool_hba.conf comment did not mention about + it. + + + + + + Add support for . (Umar Hayat, Japanese doc + by Tatsuo Ishii) + + + + + + + Add support for (CRL: + Certificate Revocation List). (Umar Hayat, Japanese doc by Tatsuo + Ishii) + + + + + + + Change relative path of SSL files to configuration + directory. (Umar Hayat, Japanese doc by Bo Peng) + + + + + + + Allow to show appropriate process status by ps command with + extend queries. (Takuma Hoshiai) + + + + + + + Downgrade too verbose authentication logs. (Tatsuo Ishii) + + + + + + + Display more informative error message in authentication process. (Tatsuo Ishii) + + + + + + + Suppress unnecessary error message when there's no standby + server. (Tatsuo Ishii) + + + + + + + Check if socket file exists at startup and remove them if PID + file doesn't exist. (Bo Peng) + + + + + + + Teach pgproto notification response message. (Tatsuo Ishii) + + + + + + + Import PostgreSQL 13 beta3 new parser. + Major changes of PostgreSQL 13 parser include: + + + + Remove an object's dependency on an extension + + ALTER TRIGGER ... NO DEPENDS ON EXTENSION ... + ALTER FUNCTION ... NO DEPENDS ON EXTENSION ... + + + + + + + Allow FETCH FIRST to use WITH TIES. + + FETCH FIRST ... WITH TIES + + + + + + + + Allow ALTER VIEW to rename view columns + + ALTER VIEW ... RENAME COLUMN ... TO ... + + + + + + + Add VACUUM clause PARALLEL option + + VACUUM (PARALLEL 1) ... + + + + + + + + + + + and watchdog_setup with PostgreSQL's bin path + and lib path. (Bo Peng) + + + + + + + Use pg_config to get + PostgreSQL lib path and add this path + to LD_LIBRARY_PATH environment parameter in regress.sh. (Bo Peng) + + + + + + + + + + Make RPMs to include pcp.conf and + pool_hba.conf sample files. (Bo Peng) + + + + + + + Change PCP UNIX_DOMAIN_PATH of RPM package to "/var/run/postgresql". (Bo Peng) + + + + + + + Rename src/redhat/pgpool_rhel7.sysconfig to + src/redhat/pgpool_rhel.sysconfig to make this file available on + RHEL8/CentOS8. (Bo Peng) + + + + + + + + Major Documentation Enhancements + + + + + + Add new documentation "Pgpool-II on Kubernetes". (Bo Peng) + + + + + + + Add escalation.sh sample script executed by . (Masaya Kawamoto) + + + + + + + Remove "8.2. Watchdog Configuration Example". (Bo Peng) + + + See of "Pgpool-II + Watchdog Setup Example" for watchdog configuration. + + + + + + + Add Pgpool-II/PostgreSQL start/stop etc. documents. (Tatsuo Ishii) + + + See etc. for more details. + + + + + + + Mention that needs to be configured + to log into localhost using ssh without password. (Tatsuo Ishii) + + + + + + + Change sample scripts and yum repository urls. (Bo Peng) + + + + + + + Clarify what actually does. (Tatsuo Ishii) + + + + + + + Update "Installation from RPM" section. (Bo Peng) + + + + + + + Add note about . (Takuma Hoshiai) + + + + + + + Add explanation about .pgpoolkey. (Tatsuo + Ishii) + + + + + + + Improve the description of . (Kenichiro Tanaka) + + + + + + + Add note about and + command. (Bo Peng) + + + + + + + Enhance installation documents. (Tatsuo Ishii) + + + Add "Planning" section (see ) so that + users can grasp a big picture of installation. + + + + + + + Explicitly mention that Pgpool-II + needs 3 nodes to avoid split brain. (Tatsuo Ishii) + + + See for more details. + + + + + + + Enhance description of failover. (Tatsuo Ishii) + + + See for more details. + + + + + + + Clarify the session disconnection conditions while + failover. (Tatsuo Ishii) + + + See for more details. + + + + + + + Enhance description of parameter. (Tatsuo Ishii) + + + + + + + Add sample script links in configuration example. (Bo Peng) + + + See for more details. + + + + + + + Mention about environment variable PGPOOLKEYFILE in command. (Tatsuo Ishii) + + + pg_enc command actually recognizes the + environment variable. + + + + + + diff --git a/doc/src/sgml/release-4.3.sgml b/doc/src/sgml/release-4.3.sgml new file mode 100644 index 000000000..d7d8d1830 --- /dev/null +++ b/doc/src/sgml/release-4.3.sgml @@ -0,0 +1,5134 @@ + + + + + Release 4.3.20 + + Release Date + 2026-06-04 + + + + Bug fixes + + + + + Allow pgproto to accept new line data. (Tatsuo Ishii) + + + Now "\n" is recognized as a new line. This is necessary for COPY command. + + + + + + + Keep local primary_node_id when leader watchdog reports the initial -2 sentinel. (Tatsuo Ishii) + + + Fix a watchdog synchronization issue after simultaneous restart of all pgpool nodes, + where standby nodes could overwrite a valid primary_node_id with the initial -2 sentinel + value and remain stuck in an uninitialized state indefinitely. Fix is, keep the local + primary_node_id when the leader reports the initial -2 sentinel. + + + Problem reported by Emond Papegaaij and Claude Code. + + + Discussion: Primary node detection race at clean startup + + + + + + + Fix empty query case in aborted transaction. (Tatsuo Ishii) + + + Fix empty queries in aborted transactions incorrectly raising errors. + Empty queries should be allowed in aborted transactions, + but a previous commit caused check_transaction_state_and_abort() to reject them. + Fix is, detect empty queries in SimpleQuery() and bypass the check. + + + Problem reported by Ronaldo Raivil. + + + Discussion: pgpool >= 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + Fix description about ssl_dh_params_file. (Tatsuo Ishii) + + + It actually falls back to compiled-in default not only when the + parameter is empty (the default), but when specified parameter is + incorrect one. + + + + + + + Fix PCP main process to remember child pids upon restarting. (Tatsuo Ishii) + + + Upon failover/failback, pgpool main process sends a signal to PCP main + process to request restarting, and PCP main restarts. Problem is, when + PCP main restarts, it forgets the list of pids of its child PCP worker + process. + + As a result, commands such as pcp_promote_node could hang indefinitely. + Fix is, store PCP worker PIDs in shared memory so they survive PCP main restart. + + + Problem reported by Taiki Koshino. + + + Discussion: Problem with pcp process + + + + + + + Fix version mismatch: regenerate configure for 4.3.19. (Bo Peng) + + + + + + + Fix memory leak in a SSL module. (Tatsuo Ishii) + + + Fix a memory leak in load_dh_file() when invalid DH parameters are supplied. + The function failed to free memory returned by PEM_read_DHparams(). + Also update the copyright notice in the same file to retain the original PostgreSQL copyright. + + + Discussion: Memory leak in SSL module + + + + + + + Fix incorrect routing of SET transaction_read_only = 0. (Bo Peng) + + + Fix incorrect routing of SET transaction_read_only = 0 to standby node, which caused query errors. + Also replace incorrect bool ret = POOL_BOTH with the proper enum type. + + + Problem reported by liujinyang-highgo. + + + Discussion: set command 'set transaction_read_only = 0;' routed to standby node and execute failed. + + + + + + + Documents + + + + + Doc: fix ignore_leading_white_space and allow_sql_comments docs. (Tatsuo Ishii) + + + They lacked a description on the default values. + + + + + + + + Release 4.3.19 + + Release Date + 2026-02-26 + + + + Changes + + + + + Allow parallel make. (Tatsuo Ishii) + + + Previously a parallel make failed with: + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + Patch is created by anthonyroussel and reviewed by Tatsuo Ishii. + + + Discussion: Fix parallel build + + + + + + + Add detail log about mismatch between and primary_conninfo host. (Taiki Koshino) + + + If the set in pgpool.conf does not match + the host setting in PostgreSQL's primary_conninfo, + the following log message will be output. + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + Explicitly stat supported minimum OpenSSL version. (Tatsuo Ishii) + + + That can be done in configure.ac by using + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + The supported minimum version is 1.0.2, which is identical to + PostgreSQL at this point. (Actually the AC_DEFINE is brought in from + PostgreSQL). Also this could avoid OpenSSL deprecation warnings if + your installed OpenSSL is new, like 3.0. + Moreover, add mention to installation document that required minimum + version of OpenSSL is 1.0.2. + + + + + + + Bug fixes + + + + + Fix oversight in check_transaction_state_and_abort(). (Tatsuo Ishii) + + + The function does not take the case when frontend is NULL into account. + + + Problem pointed out by Coverity. + + + + + + + Fix walker() functions to return earlier. (Tatsuo Ishii) + + + Previously walker() functions returned false once it found target + objects. But it is possible to short-circuit the traverse and it + should have been. + + Also import comments from PostgreSQL to clarify walker function + design. + + + Problem reported by liujinyang-highgo and reviewed by Tatsuo Ishii. + + + Discussion: Improper handling in the function view_walker(). + + + + + + + Fix memory leak in scram-sha-256 authentication. (Tatsuo Ishii) + + + Problem pointed out by Coverity. + + + + + + + Fix to check the return value of malloc(). (Tatsuo Ishii) + + + create_inet_domain_sockets() forgot to check the return value of + malloc() while allocating memory for socket fds. + + + + + + + Fix possible integer overflow. (Tatsuo Ishii) + + + In pool_write_flush() and pool_flus_it() write(2) is used. write(2) + returns ssize_t and in the code there are some places where the return + value was assigned to an int variable. As a result it was possible + that the return value was evaluated to negative value, which led to an + error. + + + + + + + + Release 4.3.18 + + Release Date + 2025-12-15 + + + + Changes + + + + + Use "grep -E" instead of deprecated "egrep" in pgpool_setup. (Bo Peng) + + + Replace "egrep" with "grep -E" to avoid obsolescence warnings on newer GNU grep versions. + + + + + + + Bug fixes + + + + + Fix buffer overflow error in show pool_status. (Tatsuo Ishii) + + + "show pool_status", "pgpool show" and pcp_pool_status could cause a + buffer overflow error. If backend_flag is set to "ALWAYS_PRIMARY", + pool_flag_to_str(), which is responsible to produce printable format + of backend_flag, wrote data past to the end of static buffer. + + + Problem reported by zam bak and reviewed by Bo Peng. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + Fix memqcache_stats_start_time shown in "show pool_status". (Tatsuo Ishii) + + + get_config() uses ctime() to generate printable form of + memqcache_stats_start_time. But it did not take into account that + ctime() adds newline at the end of result. As a result, not only the + output of memqcache_stats_start_time was with unnecessary newline but + next row printed empty items. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + + Release 4.3.17 + + Release Date + 2025-11-25 + + + + Changes + + + + + Remove unnecessary application_name treatment. (Tatsuo Ishii) + + + A previous commit added a step to set application_name when reusing existing connections. + However, this is unnecessary because DISCARD ALL automatically resets application_name, + and send_params() already sends all necessary parameter status messages, including application_name, to the frontend. + Removing this redundant step also improves performance, particularly for backend nodes that are geographically distant. + + + Discussion: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + Bug fixes + + + + + Fix segfault with CopyOut. (Tatsuo Ishii) + + + When COPY relname TO STDOUT is executed in the extended query + protocol mode, pgpool segfaulted. + + + This problem is reported by https://github.com/tetesh. + + + Discussion: datanymizer and pg-pool segmentation fault + + + + + + Prevent watchdog split-brain scenario in some corner cases. (Tatsuo Ishii) + + + Watchdog uses both beacon messages and heartbeat for communication. + If the heartbeat is not yet active, missing beacon messages + for over 30 seconds can cause a split-brain scenario, + where the old leader remains active while a new leader is elected. + This change prevents two leaders from existing simultaneously by revoking the old leader. + When a node detects that it has missed beacon messages from the leader more than twice, + the leader is set to LOST and a new leader election is triggered via set_state(WD_JOINING). + + + + + + + Prevent FATAL error when non-existing prepared statement is given. (Tatsuo Ishii) + + + Previously, Bind() raised a FATAL error when a non-existing prepared statement was used, unlike PostgreSQL. + This change changes Bind() to check for the statement's existence and send an ERROR message to the frontend if it does not exist. + Note that no log is written, as logging this is not currently possible. + + + + + + + Fix not working if both -p and -P are provided. (Tatsuo Ishii) + + + The original report showed that running pg_enc -p -P prompted for a password and encryption key, + but failed if the key was not provided. + + + Discussion: pg_enc + + + + + + + Fix compiling issue on 32-bit environments. (Tatsuo Ishii) + + + On 32-bit systems, compiling src/parser/snprintf.c fails due to undefined functions isnan() and isinf(), which come from math.h. + This change includes math.h and also reorders the include files for clarity. + The file was originally imported from PostgreSQL, where math.h was already included. + This fix was provided via pull request: https://github.com/pgpool/pgpool2/pull/128 + + + Discussion: Compiling issues for 32-bit targets + + + + + + + Fix safer directory deletion in Bash in recovery_1st_stage.sample. (Taiki Koshino) + + + Quote variables in rm commands to avoid accidental deletion: + rm -rf "${DEST_NODE_PGDATA}" + + If the variable is empty, rm could delete unexpected files or directories. + + + + + + + Fix the compilation error when building without the option. (Tatsuo Ishii) + + + A compiler error occurred when configuring without . + The issue arose because the compiler could not determine that ptr would only be freed when memcached is enabled. + To fix this, the relevant code block was wrapped with #ifdef USE_MEMCACHED. + + + Problem reported by Bo Peng. + + + + + + + Documents + + + + + Update doc about "Setting up PostgreSQL standby" in 8.2. Pgpool-II + Watchdog Setup Example. (Taiki Koshino) + + + Add a note that when setting up a standby without online recovery, do not write primary_conninfo to postgresql.auto.conf. + + + Discussion: Follow primary command not fixing postgresql.auto.conf + + + + + + + Fix watchdog_setup manual. (Tatsuo Ishii) + + + It mistakenly stated that heartbeart is not setup in watchdog_setup. + + + + + + + Regression Tests + + + + + Adapt 023.ssl_connection to PostgreSQL 18. (Tatsuo Ishii) + + + PostgreSQL 18 heavily changed psql's \conninfo output format, which + made the test fail because the test relies on \conninfo. This change + makes the test script aware the PostgreSQL version to fix the issue. + + + + + + + Fix ruby script in 010.rewrite_timestamp. (Tatsuo Ishii) + + + The ruby script used "File.exists", which is said to be obsoleted in + newer version of Ruby. Replace it with "File.exist". + + + + + + + Tweak timeout in 034 and 075 tests. (Tatsuo Ishii) + + + 034.promote_node and 075.detach_primary_left_down_node set the timeout + 60 seconds for finishing follow primary script. It turns out that + these timeout values are not long enough, and sometimes caused false + errors. So make them from 60 seconds to 120 seconds. + + + + + + + Add ssl_ecdh_curve test to 023.ssl_connection. (Tatsuo Ishii) + + + 023.ssl_connection did not cover the test for ssl_ecdh_curve. This + commit tests it using bad ssl_ecdh_curve parameter to see if connection + between frontend and pgpool fails. + + + + + + + + Release 4.3.16 + + Release Date + 2025-08-21 + + + + Bug fixes + + + + + Fix watchdog to print inappropriate NOTICE message. (Tatsuo Ishii) + + + read_ipc_socket_and_process() printed a notice message every time when + it wrote commands to IPC socket even if it was successful. Fix this to + print the notice message only when the write failed. + + The reason why this bug was not recognized is, the message appears + only when log_min_messages is set to notice or higher. + + + Discussion: pgpool IPC socket connection issue + + + + + + + + Fix resource leak while reading startup packet. (Tatsuo Ishii) + + + Fix resource leak in pool_push_pending_data. + + + + + + + Fix broken scram-sha-256 authentication on big-endian machines. (Tatsuo Ishii) + + + When scram-sha-256 authentication is performed, a hash function + pg_sha_256_final is used. It was imported from PostgreSQL and it uses + preprocessor define WORDS_BIGENDIAN to judge host machine's + endianness. Although WORDS_BIGENDIAN should be defined while + configure, this part was missed when pg_sha_256_final (and others) was + imported from PostgreSQL. As a result, scram-sha-256 worked only in + little endian machines. Fixed the issue by adding + AC_C_BIGENDIAN macro to configure.ac. + + + Problem reported by Christoph Berg and analyzed by pranavkaruvally. + + + Discussion: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + Fix source code typos. (Bo Peng) + + + + + + + Fix heartbeat device treatment. (Tatsuo Ishii) + + + While processing pgpool.conf, heartbeat_device was mistakenly treated + and the first device was ignored. + + + Problem analyzed by Bo Peng. + + + + + + + Fix typo in the comments of pgpool.conf. (Tatsuo Ishii) + + + + + + + Documents + + + + + Enhance "8.3. Replication Mode and Snapshot Isolation Mode Configuration Example" Document. (Taiki Koshino) + + + Updated the link to the example script and the explanation in the "8.3.3. Before you begin" section. + + + + + + + Fix documentation for parameters that are not reflected by reload. (Taiki Koshino) + + + "authentication_timeout" and "memqcache_oiddir" is not reflected by reload. + The documentation is changed to "This parameter can only be set at server start.". + + + + + + + + Unify watchdog leader terms (followup). (Tatsuo Ishii) + + + + + + + + Fix example script link. (Taiki Koshino) + + + Modified the sample script in the section "8.2. Pgpool-II + Watchdog Setup Example" + + + + + + + Fix load balance explanation missed logical replication mode and Slony mode. (Tatsuo Ishii) + + + + + + + Enhance document. (Bo Peng) + + + Clarify that each backend_application_nameX must match the value specified + in the application_name of primary_conninfo to correctly display + "replication_state" and "replication_sync_state". + + + + + + + Add section of kernel resources. (Tatsuo Ishii) + + + Pgpool-II uses System V shared memory and semaphores. It's better to + describe the requirements in the docs. + + + + + + + Add description for option of configure. (Tatsuo Ishii) + + + It was missed when LDAP support was introduced in v4.2 + + + + + + + Clarify supported platforms for Pgpool-II. (Tatsuo Ishii) + + + + + + + Enhance document. (Tatsuo Ishii) + + + + + + + Regression Tests + + + + + Stabilize 029.cert_passphrase regression test. (Tatsuo Ishii) + + + When ssl_passphrase_command is not valid, the error message is + typically "bad decrypt" but it seems sometimes "wrong tag". + + + + + + + + Release 4.3.15 + + Release Date + 2025-05-15 + + + + Overview + + This release contains a security fix. + + + An authentication bypass vulnerability exists in the client authentication + mechanism of Pgpool-II. + In Pgpool-II, authentication may be bypassed even + when it is supposed to be enforced. As a result, an attacker could log in as + any user, potentially leading to information disclosure, data tampering, or + even a complete shutdown of the database. (CVE-2025-46801) + + + This vulnerability affects systems where the authentication configuration + matches one of the following patterns: + + + + + Pattern 1: This vulnerability occurs when all of the following conditions are met: + + + + + The password authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is not set in pool_passwd + + + + + The scram-sha-256 or md5 authentication + method is used in pg_hba.conf + + + + + + + + Pattern 2: This vulnerability occurs when all of the following conditions are met: + + + + + enable_pool_hba = off + + + + + One of the following authentication methods is used in pg_hba.conf: + password, pam, or ldap + + + + + + + + Pattern 3: This vulnerability occurs when all of the following conditions are met: + + + + + Raw mode is used (backend_clustering_mode = 'raw') + + + + + The md5 authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is registered in pool_passwd in plain + text or AES format + + + + + One of the following authentication methods is used in + pg_hba.conf: + password, pam, or ldap + + + + + + + All versions of Pgpool-II 4.0 and 4.1 series, 4.2.0 to 4.2.21, 4.3.0 to 4.3.14, + 4.4.0 to 4.4.11, 4.5.0 to 4.5.6 and 4.6.0 are affected by this vulnerability. + It is strongly recommended to upgrade to Pgpool-II + 4.6.1, 4.5.7, 4.4.12, 4.3.15 and 4.2.22 or later. + Alternatively, you can modify your settings so that they do not match any of + the vulnerable configuration patterns. + + + + + Changes + + + + + Add major version information to the configuration file. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect client authentication in some cases. (Tatsuo Ishii) + + + If enable_pool_hba = on, it's auth method is "password", no + password is registered in pool_passwd, and auth method in + pg_hba.conf is "scram-sha-256" or "md5", for the first time when + a client connects to pgpool, authentication is performed as + expected. But if a client connects to the cached connection, any + password from the client is accepted. + + + Also if enable_pool_hba = off, in some cases a client is not + asked password for the first time, or when a client connects to + cached connection, even if it should be. + + + In addition to fixing above, following changes are made: + + + + + Remove single PostgreSQL code path to simplify the authentication code. + + + + + Remove crypt authentication support for frontend and + backend. The feature had not been documented and never + tested. Moreover crypt authentication was removed long time + ago in PostgreSQL (8.4, 2009). + + + + + Add new regression test "040.client_auth". The test performs + exhaustive client authentication tests using a test + specification file formatted in CSV. + + + + + + + + Fix long standing bind bug with query cache. (Tatsuo Ishii) + + + When a named statement is prepared, it is possible to bind then execute without a parse message. + Problem is, table oids which are necessary to invalidate query cache at execute or COMMIT was + collected only in parse messages process (Parse()). Thus if bind is executed + without parse after previous execute, no table oids were collected, and pgpool failed to invalidate query cache. + Fix is collecting table oids at bind time too. + Add regression test to 006.memqcache. + + + Problem reported by and test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + When an execute message is received, pgpool checks its max number of rows paramter. If it's not zero, + pgpool sets "partial_fetch" flag to instruct pool_handle_query_cache() to not create query cache. + Problem is, commit 2a99aa5d1 missed that even INSERT/UPDATE/DELETE sets the execute message parameter to non 0 (mostly 1) + and pgpool set the flag for even none SELECTs. This resulted in failing to invalidate query cache because if the flag is true, + subsequent code in pool_handle_query_cache() skips cache invalidation. + To fix this change Execute() to check if the query is read only SELECT before setting the flag. + Also add test to 006.memqcache. + + + Problem reported by and a test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix portability to OpenBSD. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + The patch was created by Martijn van Duren. + + + + + + Fix json_writer did not properly encode special characters. (Bo Peng) + + + Pgpool-II would crash when the watchdog was enabled if contained special characters (e.g., a backslash). + + + The patch was created by Martijn van Duren and slightly modified by Bo Peng. + + + + + + Fix sr check and health check to reopen upon reload. (Tatsuo Ishii) + + + The streaming replication check and health check process forgot to + reopen upon reload. If or + is empty string, the password is obtained from + . Thus those process read outdated content of + upon reload. + + + + + + + Documents + + + + + Enhance the description on (Tatsuo Ishii) + + + is a config value to determine the life time of + cached connections to PostgreSQL backend. Current document lacks a + description that the expiration calculation is actually done at the + time when the client disconnects to the process which holds the cached + connections. + + + Discussion: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + Enhance the explanation on . (Tatsuo Ishii) + + + It must be a superuser or in the pg_monitor group. + + + + + + + + Release 4.3.14 + + Release Date + 2025-02-28 + + + + Changes + + + + + Remove pg_basebackup from the sample follow primary script. (Bo Peng) + + + If pg_rewind fails, the safest way for users is to recover manually. + + + + + + + Bug fixes + + + + + Fix per_node_error_log() error message that is printed with two colons. (Bo Peng) + + + Patch is created by Umar Hayat. + + + + + + + Fix pool_signal. (Tatsuo Ishii) + + + Previously pool_signal did not set SA_RESTART flag. Thus any system + calls interrupted by a signal does not restart. Some of our code are + prepared so that they restart if a system call is interrupted by a + signal. But not sure all places are prepared too. So add the + flag. Note, PostgreSQL always uses the flag. + + + + + + + Fixed an issue where pg_md5 and + pg_enc would not update the password + file if a file other than the default value was specified + in the parameter. (Bo Peng) + + + This issue is reported by Sadhuprasad Patro. + + + + + + + Fix several query cache bugs in streaming replication mode. (Tatsuo Ishii) + + + + + When query cache is enabled and an execute message is sent from + frontend, Pgpool-II injects query cache + data into backend message buffer if query cache data is available. + But it was possible that the cached message is inserted at + inappropriate position and Pgpool-II + mistakenly raised "kind mismatch" error. + + + + + If query cache is enabled and query is operated in extended query mode + and pgpool is running in streaming replication mode, an execute + message could return incorrect results. + + + + + Another trouble is when multiple execute messages are sent + consecutively. In this case Pgpool-II returned exactly the same + results from query cache for each execute message. This is wrong since + the second or subsequent executes should return 0 rows. + + + Discussion: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + Documents + + + + + Enhance client authentication chapter. (Tatsuo Ishii) + + + Add intro about pool_passwd. Previously there was only description on + pool_hba.conf in the overview page. A general guide to + + will help users to understand this chapter. + + + + + + + Regression Tests + + + + + Stabilize 032.dml_adaptive_loadbalance (Tatsuo Ishii) + + + + + + + + Release 4.3.13 + + Release Date + 2024-11-28 + + + + Bug fixes + + + + + + Abort SSL negotiation if backend sends an error message. (Tatsuo Ishii) + + + In the client side implementation of SSL negotiation + (pool_ssl_negotiate_clientserver()), it was possible for a + man-in-the-middle attacker to send a long error message to confuse + Pgpool-II or client while in the SSL negotiation phase. This commit + rejects the negotiation immediately (issue a FATAL error) and exits + the session to prevent such an attack. + + + This resembles PostgreSQL's CVE-2024-10977. + + + + + + + Fix the watchdog process not reloading configurations. (Bo Peng) + + + The reload_config() function + in Pgpool-II should send + a SIGHUP signal to the watchdog process. + + + + + + + Fix bug in do_query. (Tatsuo Ishii) + + + Fix do_query to use ntohs/ntohl instead of htons/htonl. + + + + + + + Fix authentication failure after updating pool_passwd and reload. (Tatsuo Ishii) + + + If pool_hba.conf is disabled, + updating pool_passwd was not recognized + by Pgpool-II child process even + if Pgpool-II reload was performed. + The reload processing function check_config_reload() mistakenly assumed + that reopening pool_passwd was only necessary when + is on. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html" + + + + + + + Fix COPY hangs. (#79) (Tatsuo Ishii) + + + During COPY IN state (i.e. COPY FROM STDIN), frontend can send Flush + or Sync messages. According to the F/B protocol specification, they + should be ignored but Pgpool-II treated as an invalid message and this + causes COPY hung. + + + Also a regression test is added for this issue. + + + + + + + Fix Pgpool-II child process crash during shutdown. (Tatsuo Ishii) + + + The actual crash was in close_all_backend_connections(). + close_all_backend_connections() was + called because on_system_exit registers + child_will_go_down(). + At the moment it seems pgpool child had just started up and doing + pool_init_cp(). The connection pool + object had not been completely initialized, that's cause of the crash. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + Fix sporadic health check failures due to authentication failure. (Tatsuo Ishii) + + + When is empty string, + health check process looks for the password from pool_passwd file. + Problem is, the file descriptor for the file is inherited from + parent pgpool process. + This means that pgpool main and health check process (possibly multiple + process) share the same descriptor, which causes various problem + including the issue reported here. To fix the problem, re-open the + file when health check process starts so that each health check + process owns its own file descriptor. + + + Note that pgpool child process (responsible for frontend sessions) + already re-opens the file descriptor and they are not related to the + issue. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + Optimize query cache invalidation for ALTER ROLE. (Tatsuo Ishii) + + + Commit 6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89 invalidates query + cache if any ALTER ROLE/USER statement is used. + Actually this is an overkill. + Because following queries do not affect the privilege of the role. + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + So do not invalidate query cache if those commands are used. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Fix Pgpool-II crash when pgpool child process exits. (Tatsuo Ishii) + + + When a pgpool child process exits, + close_all_backend_connections() is + called, which is responsible for closing all connections to backend in + the connection pool. It used mistakenly MAIN_CONNECTION macro, which + is fine for current active connections but is not good for pooled + connections because a main node could be different at the time when + the connection pool was created. + Fix is using in_use_backend() instead. + + + Reported-by: Emond Papegaaij + + + + + + + Fix bug in replication/snapshot isolation mode. (#69) (Tatsuo Ishii) + + + When INSERT command is received, + pgpool automatically issues table LOCK command to the + target table but it forgot to send the command to + other than main nodes. This only happened in extended query mode. + + + + + + + Fix another bug in native replication/snapshot isolation mode. (Tatsuo Ishii) + + + insert_lock() forgot to send row lock command (lock_kind == 3 case) to + other than main node. + + + + + + + Fix resource leaks in pool_memqcache.c. (Tatsuo Ishii) + + + These leaks were brought in by commit 6fdba5c33. + + + + + + + + Documents + + + + + Fix typos in the documentation and sample configuration files. (Bo Peng) + + + + + + + Regression Tests + + + + + Adapt 024.cert_auth test to OpenSSL 3.2. (Tatsuo Ishii) + + + + + + + + Release 4.3.12 + + Release Date + 2024-09-09 + + + + Overview + + This release contains a security fix. + + + When the query cache () feature is enabled, + it was possible that a database user can read rows from tables that should + not be visible for the user through query cache (CVE-2024-45624). + + + All versions of Pgpool-II older than + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22, and all older + versions that has the query cache feature (the query cache feature was + implemented in 3.2) are affected by the vulnerability. + + + + + + If query cache is created for a table for a user, and then the + access right of the table is revoked from the user by + REVOKE command, still it was possible for the + user to access the table which the user does not have the access + right through the query + cache. + + + + + + If query cache is created for a table for user A, and then other + user B accesses the table via SET ROLE or + SET SESSION_AUTHORIZATION in the same session, + still it was possible for the user B to access the table which B + does not have the access right through the query + cache. + + + + + + If query cache is created for a row security enabled table for user + A, and then other user B accesses the table via SET ROLE + or SET SESSION_AUTHORIZATION in the same session, + it was possible for the user B to retrieve rows which should not be + visible from the user B through the query cache. + + + + + + It is strongly recommend to upgrade to Pgpool-II + 4.5.4, 4.4.9, 4.3.12, 4.2.19 and 4.1.22 or later. Or you should better turn + off the query cache feature. + + + + Note that to fix the vulnerability, some commands (ALTER DATABASE, + ALTER ROLE, ALTER TABLE, REVOKE) now invalidate whole query cache + data. This may affect the performance when using the query cache + feature. + + + + + Changes + + + + + Back port . (Tatsuo Ishii) + + + This is mainly for testing. Backpatch-through: v4.1 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + Bug fixes + + + + + + Fix bugs in replication mode and snapshot isolation mode. (Tatsuo Ishii) + + + The following bugs was fixed: + + + + + In replication mode and snapshot isolation mode when a command finishes, + Pgpool-II waits for a ready for query message + but forgot that some commands (for example SET ROLE) + produces a parameter status message. As a result + Pgpool-II errors + out that other message arrives before the ready for query message. + + + + + + If previous query produces parameter status message, subsequent + parse() needs to read and process it because + it wants to read Ready for query message which is supposed to follow + the parameter status message. + However when ParameterStatus() gets called, + the query in progress flag was set and it was possible that only + one of parameter status message from backend was processed if the + query processed in this parse() call is load + balanced. It is likely that the parameter status message comes from + all live backend because they are generated by SET + command, and SET command are sent to all live backend + in replication mode and snapshot isolation mode. So unset the query in + progress flag before calling ParameterStatus(). + + + + + + + + + + + Release 4.3.11 + + Release Date + 2024-08-15 + + + + Changes + + + + + + Use psql -V instead of initdb -V + in sample scripts. (Bo Peng) + + + Use psql -V instead of initdb -V + in the sample scripts because in some cases postgresqlxx-server may not + be installed. + + + + + + + + Bug fixes + + + + + + Fix hang after a flush message received. (#59) (Tatsuo Ishii) + + + + + + + Fix segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool child segfaulted in pool_do_auth. The cause + was MAIN_CONNECTION() returns NULL. It seems my_main_node_id was set + to incorrect node id 0, which was actually in down status. thus there + was no connection in cp->slots[0]. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9175] + + + + + + + Fixed segmentation fault at parsing config file. (Tatsuo Ishii) + + + This commit fixed a segmentation fault that occurs when parsing pgpool.conf + if the setting value was not enclosed in single quotes. + + + The patch is created by Carlos Chapi, reviewed and modified by Tatsuo Ishii. + + + + + + + Fix segfault to not use MAIN_NODE macro. (Tatsuo Ishii) + + + Some functions (close_idle_connection(), new_connection() and + pool_create_cp()) used MAIN* and VALID_BACKEND where they are not + appropriate. MAIN* and VALID_BACKEND are only useful against current + connections to backend, not for pooled connections since in pooled + connections which backend is the main node or up and running is + necessarily same as the current connections to backend. + The misuses of those macros sometimes leads to segfault. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9114] + + + + + + + Fix MAIN_NODE macro (actually pool_virtual_main_db_node_id()). (Tatsuo Ishii) + + + The macro used to return REAL_MAIN_NODE_ID if there's no session context. + This is wrong since REAL_MAIN_NODE_ID can be changed any time when + failover/failback happens. + + + Suppose REAL_MAIN_NODE_ID == my_main_node_id == 1. + Then due to failback, REAL_MAIN_NODE_ID is changed to 0. + Then MAIN_CONNECTION(cp) will return NULL and any + reference to it will cause segmentation fault. To prevent the issue we + should return my_main_node_id instead. + + + + + + + Fix show pool_processes to not show row description twice. (Tatsuo Ishii) + + + processes_reporting() accidentaly called both send_row_description() + and send_row_description_and_data_rows(). + + + Discussion: [pgpool-hackers: 4471] + + + + + + + Fix segfault in a child process. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + Watchdog dies and kills pgpool2 when network gets shortly interrupted. (#823) (Muhammad Usama) + + + With network monitoring enabled, a Pgpool-II + node would shut down immediately if it lost all network interfaces or + assigned IP addresses, providing extra protection by quickly removing + a non-communicative node from the cluster. + + + The issue was that Pgpool-II responded to network blackout events even when network + monitoring was disabled. This fix ensures that the network monitoring socket is + not opened when network monitoring is not enabled, preventing unnecessary shutdowns. + + + + + + + Fix pgpool reset command not working if watchdog is enabled. (Tatsuo Ishii) + + + Bug reported and problem analysis by keiseo. + Discussion: [pgpool-hackers: 4465] + + + + + + + Fix psql_scan crash. (#54) (Tatsuo Ishii) + + + It was reported that psql_scan crashes while determining whether a + string in a long query is psql variable (i.e. starting with ":") or not. + + + + + + + + Documents + + + + + + Mega typo fix for docs and program source codes. (Tatsuo Ishii) + + + Patch is created by Umar Hayat. + + + + + + + Enhance failover document. (Tatsuo Ishii) + + + Clarify the condition on failover when is enabled. + + + + + + + Add the missing default values for virtual IP related parameters. (Bo Peng) + + + + + + + + + Release 4.3.10 + + Release Date + 2024-05-16 + + + + Bug fixes + + + + + Fix compiler error with -Werror=implicit-function-declaration. (Bo Peng) + + + Add LDAP_DEPRECATED to include prototypes for deprecated ldap functions. + Also Add missing header files in autoconf check. + + + Patch is created by Vladimir Petko. + + + + + + + Fix assorted causes of segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool and its child process segfault in certain + cases when failover involved. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + Fix uninitialized memory error. (Tatsuo Ishii) + + + It was reported that valgrind found several errors including an + uninitialized memory error in read_startup_packet. It allocates memory + for user name in a startup packet in case cancel or SSL request using + palloc, and later on the memory is used by pstrdup. Since memory + allocated by palloc is undefined, this should have been palloc0. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + Fix errors/hung up when load_balance_mode is off. (Tatsuo Ishii) + + + Commit 3f3c1656 + brought errors/hung up when load_balance_mode is off, primary node id + is not 0 and queries are BEGIN etc. + + + Bug found and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + Fix compile errors with certain CFLAGS. (Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42 + reported that with CFLAGS + -flto=4 -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing + gcc emits errors. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + Fix comments in sample pgpool.conf. (Bo Peng) + + + The default value for sr_check_period should be 10 seconds. + Also fixed some typos in comments. + + + Patch is created by hiroin and modified by Bo Peng. + + + + + + + Allow reset queries to run even if extended queries do not end. (Tatsuo Ishii) + + + Commit 240c668d + caused reset queries fail if extended query messages do not end. This commit + fix that by checking whether we are running reset queries in + SimpleQuery(). Also add the test case for this. + + + + + + + Fix memory leak pointed out by Coverity. (Takuma Hoshiai) + + + + + + + Guard against inappropriate protocol data. (Tatsuo Ishii) + + + If a simple query message arrives before a sequence of extended query + messages ends pgpool could hang. This is because the query context in + the session context for the simple query is overwritten by the query + contexts of the extended query messages. + + + This commit implements a guard in SimpleQuery() by checking whether + extended query protocol messages ended. If they do not end, raise a + FATAL error. A known example detected by this checking is JDBC + driver's "autosave=always" option. This means pgpool will not accept + the option after this commit until the issue (sending a simple + protocol message before ending extended query message protocol) is + fixed by the JDBC driver side. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + Documents + + + + + + Enhance "Upstream server connection" documentation. (Bo Peng) + + + + + + + Language cleanup in Japanese document. (Masaya Kawamoto) + + + + + + + Add the note about using pcp_promote_node when two postgres nodes. (Masaya Kawamoto) + + + Even if there are two postgres nodes, there are cases that + follow_primary_command is required to be set. + + + + + + + + Regression Tests + + + + + + Fixed regression test 005.jdbc to avoid Java 21 deprecation warnings. (Bo Peng) + + + Replace Runtime.exec(String) with Runtime.exec(String[]) to avoid Java 21 deprecation warnings. + Patch is created by Vladimir Petko and modified by Bo Peng. + + + + + + + + + Release 4.3.9 + + Release Date + 2024-02-29 + + + + Changes + + + + + Remove restore_command from sample scripts. (Bo Peng) + + + Restore_command is not required because replication slot is enabled. + It causes occasional failover failure. + + + + + + + Bug fixes + + + + + Fixed the default values of , + and + . (Bo Peng) + + + Because the default value of recovery_user + should be same as and + , I changed the default value + from '' to 'nobody'. + + + The correct default value of failover_on_backend_shutdown + should be "false" and the correct default value of insert_lock + should be "on". + + + + + + + Fixed with BEGIN etc. (Tatsuo Ishii) + + + When statement_level_load_balance is enabled, + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE + ALL/DISCARD were sent to primary node and all standby nodes even if + is off. + This is not only plain wrong but caused slow + down if one of the standby nodes are in remote network. + + + Fix this in that pgpool sends such queries to primary node only when + load_balance_mode is off. + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + + Documents + + + + + Fix Japanese watchdog document. (Tatsuo Ishii) + + + It mistakenly used "master" watchdog node instead of "leader". + + + + + + + Fix English watchdog document. (Tatsuo Ishii) + + + It mistakenly used "main" PostgreSQL node instead of "primary". + + + + + + + + + Release 4.3.8 + + Release Date + 2023-11-30 + + + + Changes + + + + + Modify the replication slot name conversion in sample scripts + to support for the hostname in uppercase. (Bo Peng) + + + Replication slots are automatically created or deleted in the scripts + which are executed during failover or online recovery. + Since uppercase can't be used for a replication slot name, modify these scripts + to convert the hostname to lowercase. + + + Patch is created by Sheikh Wasiu Al Hasib and modified by Bo Peng. + + + + + + + Add SSH timeout in sample script escalation.sh.sample + which is set in parameter. (Bo Peng) + + + + + + + Bug fixes + + + + + Remove unnecessary logging line. (Tatsuo Ishii) + + + Debug message "unset_tx_started_by_multi_statement_query is called in CommandComplete" was accidentally left. + + + + + + + Fix Describe() so that it does not abort with portal created by DECLARE. (Tatsuo Ishii) + + + When DECLARE foo CURSOR FOR is executed, + a portal named "foo" is automatically created by PostgreSQL. + As the portal is not managed by Pgpool-II, + "Describe foo" message failed with "unable to execute Describe. + unable to get the bind message" error. + + + To fix this, make Describe() create a dummy write query + context so that the describe message is sent to primary (streaming replication + mode) or all nodes (replication/snapshot isolation mode). + + + Also add test case 080 for this commit. + + + This problem was reported and analyzed by Heather Lapointe. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + Remove duplication definitions of NAMEDATALEN. (Tatsuo Ishii) + + + The definition for NAMEDATALEN is now in + src/include/pg_config_manual.h only. + Also replace POOL_NAMEDATALEN with + NAMEDATALEN in + src/utils/pool_select_walker.c. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + Documents + + + + + Modify "Pgpool-II + Watchdog Setup Example" to mention that + pcp_listen_addresses = '*' is required to + allow PCP to listen on all addresses. + + + + + + + Fix docs. (Tatsuo Ishii) + + + The actual backend status is obtained using PQpingParams, not pg_isready. + + + + + + + Enhance manual. (Tatsuo Ishii) + + + Mention that it is necessary to run if + is not used. + + + + + + + Regression Tests + + + + + Enhance pgpool_setup. (Tatsuo Ishii) + + + Enhance failover script generation and follow primary script + generation so that they create better logging. + + + + + + + + Release 4.3.7 + + Release Date + 2023-08-17 + + + + Changes + + + + + Install system exit callback only after initialization of shared memory. (Muhammad Usama) + + + When the on-exit callback gets called because of a failure to acquire + shared memory. The cleanup function can produce a segfault while accessing + process_info, that lives in shared memory. + Although we can also fix this by bailing out from the exit callback when + process_info is NULL but installing the function after successful initialization + of shared memory is a better approach as the rest of the system always assumes + the process_info can never be NULL, and also, there is nothing to + clean up before child processes are spawned. + + + + + + + Add schema qualification to some system catalog inquiry functions. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + Fix coverity warning. (Tatsuo Ishii) + + + Fix query cache module assigned time_t value to int32 variable. Change + the variable type to int64. Per Coverity. Also use difftime() to + calculate time_t difference. This is a recommended practice. + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + Fix find_primary_node_repeatedly doesn't terminate within . (Bo Peng) + + + + + + + Fix crash when v2 protocol is used.(bug 807)(Tatsuo Ishii) + + + When read_kind_from_backend() accumulates statistics data, it was not prepared for v2 protocol case. + + + Bug report and patch from MCanivez. Slightly modified by me. + + + + + + + Fix PREPARE in multi-statement case. (Tatsuo Ishii) + + + If multi-statement query includes PREPARE in the second or latter + position, and subsequent bind message uses the prepared statement, it + fails with "unable to bind" error because the prepared statement is not + saved in sent messages. + + + To fix this if such a case found after parsing the statement, create a + query context for the named statement and add it to the sent message list. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + For this new regression test 079..multi_prepare is added. + + + + + + + Fix pgproto to work with bind message using params. (Tatsuo Ishii) + + + Previously pgproto can only process bind messages without params. + + + + + + + Fix the wrong variable names in replication_mode_recovery_2nd_stage.sample sample script. (Bo Peng) + + + + + + + Documents + + + + + Fix the missing "logger" application name. (Bo Peng) + + + + + + + Clarify the meaning of stop mode. (Tatsuo Ishii) + + + + + + + Remove the incorrect information from release note 4.2.10. (Bo Peng) + + + Remove "Fix pgpool_recovery extension script. (Tatsuo Ishii)" from release note 4.2.10. + + + + + + + Enhance SSH public key authentication setting section in "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix load balance mode chapter. (Tatsuo Ishii) + + + In some places "streaming replication mode" was written as "native + replication mode". Also enhance description regarding additional + requirements for load balancing in the streaming replication mode. + Add some indexes. + + + + + + + Enhance online recovery documentation. (Bo Peng) + + + Mention that 2nd stage of online recovery does not work properly only for multiple pgpool nodes without watchdog enabled. + + + + + + + Regression Tests + + + + + Fix occasional 069.memory_leak_extended test failure. (Tatsuo Ishii) + + + It turned out that reason of the occasional test failure is, pgpool + child process is gone before running ps command after pgbench + finishes. The cause is a kind mismatch FATAL error, "DISCARD ALL + cannot be executed within a pipeline". To fix this, run pgbench in + background and get the process size before pgbench finishes. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + Release 4.3.6 + + Release Date + 2023-05-18 + + + + Changes + + + + + Import psqlscan source code into Pgpool-II to judge multi statement query. (Tatsuo Ishii) + + + Psqlscan is a module in the PostgreSQL source tree. + It is essentially subset of PostgreSQL SQL scanner + but it is specialized for detecting + the end of each SQL statement. Therefore we can count the number of + SQL statements in a query string by using it. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + Allow to use multiple statements extensively. (Tatsuo Ishii) + + + This commit tries to eliminate pgpool's long standing limitations + regarding multiple statements (multi-statements). + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + Use schema qualification for internal queries. (Tatsuo Ishii) + + + Some of objects such as function and cast did not use "pg_catalog." + schema qualification. This does not lead to immediate security + concern but using the schema qualification is always good practice. + + + + + + + Bug fixes + + + + + Fix possible dead lock with shared relation cache. (Tatsuo Ishii) + + + When a user defined function obtains table locking, call to the + function using extended query protocol could lead to dead lock. Here's + a scenario: + + + + (1) In session A client sends parse, bind, execute request for the function to pgpool. + + + + + + + (2) Pgpool-II in session A forwards + the request to PostgreSQL. + + + + + + + (3) PostgreSQL in session A performs execute, resulting in a table lock. + + + + + + + (4) In session B client sends parse, bind, execute request for the + function to pgpool. + + + + + + + (5) Pgpool in session B forwards the request to PostgreSQL. + + + + + + + (6) PostgreSQL in session B performs bind but the table was already + locked by PostgreSQL in session A, and it waits for release of the + lock. + + + + + + + (7) After pgpool in session B forwards the execute to PostgreSQL, it + acquires semaphore to search shared relation cache to check the + volatility of the function. Then it calls do_query and sends flush + message to PostgreSQL to obtain the response from PostgreSQL up to + this point. But since PostgreSQL is waiting for table lock in #6, + pgpool has to wait for messages beyond bind complete. + + + + + + + (8) After pgpool in session A forwards the execute to PostgreSQL, it + tries to acquire semaphore to search shared relation cache to check + the volatility of the function but the semaphore was already + acquired by pgpool in session B, it waits for the release of the + semaphore. + + + + + + + (9) Session A and session B wait for each other, resulting in a dead lock. + + + + + + To fix this, modify pool_search_relcache() so that it releases + semaphore before calling do_query() (but acquires semaphore after + do_query()). By this, session A in #8 above can get semaphore, and go + forward. It receives sync message from client and forwards it to + PostgreSQL. Upon receiving sync, the user defined function will finish + the execution and releases the table lock. This makes PostgreSQL in + session B move forward because now it can obtain the table lock. + + + + + + + Fix bug. + (bug 798) (Tatsuo Ishii) + + + When client connects to pgpool, one of standbys are chosen as the load + balancing node. If standby delay exceeds delay_threshold while the + session continues, prefer_lower_delay_standby will choose + the least delay standby node as the new load balancing node and set the target + backend to the node. Unfortunately the decision was made before the + checking that SELECT query includes writing function etc., + Pgpool-II + happily sends SELECT which cannot be executed on standby. To fix + this, prefer_lower_delay_standby treatment is moved + after the writing function etc. check. + + + Also 033.prefer_lower_standby_delay regression test is modified to include the case above. + + + + + + + Fix compile error on systems using musl libc. + (bug 790) (Tatsuo Ishii) + + + Patch provided by leimaohui. + + + + + + + Fix multiple query cache bug. (Tatsuo Ishii) + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + Fix sr worker to not send wrong query to standby server in corner case. (Tatsuo Ishii) + + + When ALWAYS_PRIMARY flag is set, PRIMARY_NODE_ID macro returns node + id, rather than -1 even if the primary is down. + In this case streaming replication delay check worker + sends SELECT pg_current_wal_lsn() or + SELECT pg_current_xlog_location() + depending on PostgreSQL's version to + standby which of course raises an error. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + Fix kind mismatch error with DEALLOCATE. + (bug 780) (Tatsuo Ishii) + + + Kind mismatch error occurs when conditions below are all met: + + + + streaming replication mode + + + + + + + load balance node is other than primary + + + + + + + PREPARE is used in a multi-statement query + + + + + + + + + + Fix compile error of regression test (Takuma Hoshiai) + + + The error occurred by timestamp test using gcc10. + + + + + + + Fix that show pool_version shows row description twice. (Tatsuo Ishii) + + + + + + + Documents + + + + + Add explanation for . (Chen Ningwei) + + + + + + + Add restriction regarding PREPARE/EXECUTE/DEALLOCATE. (Tatsuo Ishii) + + + + + + + Add caution to use -D option with pgpool. (Tatsuo Ishii) + + + + + + + Enhancing "Installation from RPM" section. (Bo Peng) + + + + + + + Add "Backing up PostgreSQL database" section to "Server Setup and Operation" chapter. (Tatsuo Ishii) + + + + + + + Remove the configuration of "-D" start OPTS from "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix restrictions section. (Tatsuo Ishii) + + + + + + Add mention about SCRAM-SHA-256 authentication + + + + + + + Add mention about snapshot isolation mode + + + + + + + + + + Add explanation when pg node status is shown as "unknown". (Tatsuo Ishii) + + + + + + + Mention that the target node to promote must be up and running when executing + . (Tatsuo Ishii) + + + + + + + Mention that AES256 support requires option. (Tatsuo Ishii) + + + + + + + Explicitly stat that it is -w option of pcp command is needed to use .pcppass. (Tatsuo Ishii) + + + + + + + Fix "2.8 Creating insert lock table" section. (Tatsuo Ishii) + + + It only referred to the native replication where it should have referred + to the snapshot isolation mode. + + + + + + + Enhance . (Tatsuo Ishii) + + + + + + + Test Tools + + + + + Change pgpool_setup to append some parameters to the end of the configuration file. (Bo Peng) + + + + + + + Regression Tests + + + + + Refactor 071.execute_and_deallocate/test.sh. (Tatsuo Ishii) + + + + + + + Enhance regression tests. (Tatsuo Ishii) + + + + + + + Fix occasional 005.jdbc test failure. (Tatsuo Ishii) + + + + + + + + Release 4.3.5 + + Release Date + 2023-01-23 + + + + Overview + + This release contains a security fix. + + + If following conditions are all met, the password of is + exposed by command. + The command can be executed by any user who can + connect to Pgpool-II. (CVE-2023-22332) + + + + + + Version 3.3 or later. + + + + + + is on. + + + + + + is query. + + + + + + A plain text password is set + to . + + + + + + In this case it is strongly recommended to upgrade to this version + (we do not expose in + show pool_status command any more), or use one of following + workarounds. + + + + Workarounds for 4.0.x to 4.4.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + Set an empty string + to . This will use + password in the pool_passwd file. + + + + + + Set an AES encrypted password + to . + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Workarounds for 3.0.x to 3.7.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Please note that Pgpool-II 3.7.x or + before are end of life and no minor updates are provided for those + versions. + + + + + Changes + + + + + + Do not expose in + , + and + commands. (CVE-2023-22332) (Bo Peng) + + + + + + + Change the default value + for to empty string as + documented. (Bo Peng) + + + + + + + + Bug fixes + + + + + + Fix compiler warning + in pgpool-regclass.c. (Florian Weimer, + Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: Enhance and fix some mistakes + in Configurations + to use shared memory chapter. (Tatsuo Ishii) + + + + + + + + + Release 4.3.4 + + Release Date + 2022-12-22 + + + + Changes + + + + + Downgrade LOG messages "new IPC connection received" to DEBUG1. + (bug 775) (Bo Peng) + + + It is a normal messages and should not be logged as LOG. + Patch is created by pstef and reviewed by Bo Peng. + + + + + + + + Bug fixes + + + + + + Fix issue with . (Muhammad Usama) + + + The fix is to dynamically set the failover command timeout based on the maximum + value of health check parameters across the watchdog cluster. + + + Reviewed and tested by Tatsuo Ishii. + Discussion: [pgpool-hackers: 4227] + + + + + + + Fix ROLLBACK TO command to work in aborted transaction. (Tatsuo Ishii) + + + Commit: eea522ebfcf791a623e865deaa1aa6fb59e3c50b + fixed some cases in aborted transaction so that SQL commands except + COMMIT/ROLLBACK are not forwarded to backend. But it missed ROLLBACK + TO command. As a result even if ROLLBACK TO command is issued, the + command was not forwarded to backend and the transaction keeps on in + aborted state. + Back patched through 4.3 which the commit was brought in. + Also add a test case for ROLLBACK TO to test 078. + + + Discussion: [pgpool-general-jp: 1716] + + + + + + + Fix not to print warnings of use of backslashes in parser. (Tatsuo Ishii) + + + When standard_conforming_strings = off and escape_string_warning = on, + PostgreSQL prints warnings if backslashes are used in string + literal. This is fine. But previously Pgpool-II's parser printed the + same message too. This is redundant. + + + + + + + + Deal with idle_session_timeout. (Tatsuo Ishii) + + + If idle_session_timeout (added in PostgreSQL 14) is enabled and the + timeout fires, followings happen: + + + + If failover_on_backend_error is on (the default), Pgpool-II will trigger failover. + + + + + + + If only one of PostgreSQL servers enables idle_session_timeout, Pgpool-II could hang. + + + + + + To deal with idle_session_timeout detect_idle_session_timeout_error() + is added to detect the error code for idle_session_timeout. If the + error is detected, Pgpool-II returns the error code to frontend as a + fatal error and disconnects the session. This is a similar fix + implemented for idle_in_transaction_session_timeout. + 3f5986eee360f12e6a0bb77aa46f95abf5f6bc10 + + + Discussion: [pgpool-hackers: 4208] + + + + + + + Deal with SSL error SSL_ERROR_ZERO_RETURN. (Tatsuo Ishii) + + + Previously this caused failover, which was actually unnecessary because + it means the server is just going to close the connection. + + + Discussion: [pgpool-general: 8366] + Discussion: [pgpool-hackers: 4193] + + + + + + + Fix: Setting memory cache size greater than 2GB causes a segfault. (Muhammad Usama) + + + The problem was in the block_address() function that returns the memory address + for a given cache block, It was using 32bit integers to calculate the offset of + the block within the shared memory space that is only good until the 2GB limit. + + + + + + + Fix rare segfaults in pcp_proc_info, SHOW pool_pools + and SHOW pool_processes. (Tatsuo Ishii) + + + The segfaults were in get_pools() and get_processes(). They first + extracted pid of particular process info slot on shared memory then + searched the slot again by using pid as the key. Because these steps + were not protected by any locking, it was possible that the search + using the pid failed and returned NULL if the process id is + overwritten by pgpool parent which is responsible for forking new + child process after the process exiting. As a result any subsequent + reference to the NULL pointer generated segfaults. + + + Solution is, first get the pointer to the process info slot then + extract the process id member from the pointer. This way, still + concurrent updating to the shared memory info by the parent process is + possible (which may lead to strange results in the output) but at + least we can avoid segfaults. + + + + + + + Fix to not allow Unix-domain socket path with invalid length. (Masaya Kawamoto) + + + + + + + + Documents + + + + + + Doc: fix typo in Aurora example. (Tatsuo Ishii) + + + + + + + Doc: enhance restrictions section. (Tatsuo Ishii) + + + Mention that failover_on_backend_shutdown can be used to avoid + unwanted failover caused by pg_terminate_backend. + + + + + + + Doc: enhance description about memqcache_method. (Tatsuo Ishii) + + + Add explanation which method should be used. + + + + + + + Doc: mention that health check process may use SSL. (Tatsuo Ishii) + + + Also mention that streaming replication check may use SSL too. + This should have been added since 2010. + + + Discussion: [pgpool-hackers: 4187] + + + + + + + + Regression Tests + + + + + + Allow to define PGPOOLDIR using environment variable. + (bug 766) (Bo Peng) + + + + + + + + + Release 4.3.3 + + Release Date + 2022-08-18 + + + + Changes + + + + + + Add ssh options to restore_command in sample scripts. (Bo Peng) + + + Patch is created by Jon SCHEWE and updated by Bo Peng. + + + + + + + Update sample scripts. (Bo Peng) + + + + Update PSQL connection information to use postgres database when creating or dropping replication slots. + + + + + + + Allow to set ssh login user and ssh key file using variables. + + + + + + + + + + When CloseComplete is received, forward to frontend without buffering. (Tatsuo Ishii) + + + It seems this caused occasional timeout error in 074.bug700_memqcache_segfault. + + + + + + + Bug fixes + + + + + + Fix pgpool_recovery extension script. (Tatsuo Ishii) + + + + + + + Fix bug in query cache. (Tatsuo Ishii) + + + Pgpool-II did not cache the query like "Select '2022-02-18 07:00:00.006547'::timestamp". + SELECTs include TIMESTAMP, TIME and DATE are cached, and SELECTs include TIMESTAMPZ + and TIMEZ are not cached because the result can be changed by SET TIME ZONE command etc. + Furthermore, SELECTs having functions with return types are timestamptz or timetz are + not cached too as same reason. + Discussion: [pgpool-general: 8285] + + + + + + + Fix internal transaction handling bug in snapshot isolation mode. (Tatsuo Ishii) + + + + + + + + Documents + + + + + + Doc: mention that certain SELECTs are not cached. (Tatsuo Ishii) + + + certain SELECTs are follows. + + + + SELECTs including TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including CAST to TIMESTAMP WITH TIMEZONE or TIME WITH TIMEZONE + + + + + SELECTs including SQLValueFunction (CURRENT_TIME, CURRENT_USER etc.) + + + + + + + + + + Doc: fix description about using PCP password file when connect to Unix domain socket (Masaya Kawamoto) + + + The localhost entry in pcppass matches only for the default PCP socket + directory path, not all Unix socket connections. This behavior is the + same as pgpass. + + + + + + + Doc: enhance and fix memory requirement section. (Tatsuo Ishii) + + + + + + Add explanation about memory usage while pgpool child process is running. + + + + + Enhance the formula to calculate shared memory requirement so that it computes more accurate result. + + + + + Fix shared memory requirement for shared rel cache. The old value 64MB was simply wrong. + + + + + Fix process memory requirement. Previously the formula was based on + RSS. However PSS should be used because RSS includes shared memory + such as the memory used for libraries. This results in lot smaller + memory requirement than before. + + + + + + + + + + Doc: fix wrong explanation on , . (Tatsuo Ishii) + + + Those parameters cannot be changed by reloading config file. Restarting + pgpool is required. + + Discussion: [pgpool-general: 8195] + + + + + + + + Test Tools + + + + + + Allow to run pgpool_setup on PostgreSQL 15. (Tatsuo Ishii) + + + Per ticket 757 + + + + + + + Allow pgpool_setup to test sample scripts and sample config files contained in RPMs. (Bo Peng) + + + + + + + + Regression Tests + + + + + + Test: print Pgpool-II version in the regression test. (Tatsuo Ishii) + + + + + + + Test: Fix regression test script to look for pgpool.conf in the proper install directory. (Tatsuo Ishii) + + + + + + + + + Release 4.3.2 + + Release Date + 2022-05-19 + + + + Changes + + + + + Enhance in stopping pgpool main process. (Tatsuo Ishii) + + + If "pgpool stop" couldn't terminate the main process within certain period (currently 5 seconds), send the signal again. + + + + + + + Fix not to abort session while in failed transaction. (Tatsuo Ishii) + + + When an explicit transaction fails, subsequent commands should be + ignored until commit or rollback command comes in. However pgpool + sometimes aborted the session if relcache lookup happened. + + + Discussion: [pgpool-general: 8096] + + + + + + + Change the PID length of pcp_proc_count command to 7 characters long. (Bo Peng) + + + + + + + Enhance error message to include the message kind returned and the backend node id while processing parse message. (Tatsuo Ishii) + + + + + + + Downgrade log level of ParameterStatus message from LOG to DEBUG5. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 8042] + + + + + + + Change the default value of from '*' to 'localhost'. (Tatsuo Ishii) + + + + + + + Adjust the field name in . (Muhammad Usama) + + + + + + + Enable parameters related to by default in RPM packages. (Bo Peng) + + + + + + + + Bug fixes + + + + + Fix issue that watchdog cluster keeps rejecting the restarted remote node which is lost previously. (Muhammad Usama) + + + Issue report: [pgpool-general: 7896] + + + + + + + Fix exit_handler in pgpool main process to avoid possible infinite wait. (Tatsuo Ishii) + + + + + + + Fix pgpool child process to obtain process information. (Tatsuo Ishii) + + + + + + + Fix a potential issue in shared memory allocation function. (Tatsuo Ishii) + + + + + + + Fix bug with pg_enc and pg_md5 when using "-i" option. (bug 747)(Tatsuo Ishii) + + + + + + + Fix not to include garbage in %m . (Tatsuo Ishii) + + + + + + + Fix main process exiting if a backend is failing or shutting down while performing finding primary. (Tatsuo Ishii) + + + + + + + Fix segfaults in watchdog. (Muhammad Usama) + + + Discussion: [pgpool-general: 8030] + + + + + + + Fix issue that failover request is refused if backend node status managed + in private_backend_status and the one in the share memory area do not agree. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4127] + + + + + + + Fixed follow_primary.sh.sample script to check the status of PostgreSQL using pg_isready. (Bo Peng) + + + + + + + + Documents + + + + + Doc: move the example of "Pgpool-II on Kubernetes" to github repository. (Bo Peng) + + + + + + + Doc: update configuration example. (Masaya Kawamoto) + + + + + + + Doc: update the example output of . (Bo Peng) + + + + + + + Doc: mention that escaping is required if you are providing the password as an argument to pg_enc and the password contains a "$" character. (Bo Peng) + + + + + + + + + Regression Tests + + + + + Enhance regression test 018.detach_primary to avoid the timeout error. (Tatsuo Ishii) + + + + + + + Enhance regression test 074.bug700_memqcache_segfault to avoid the timeout error. (Tatsuo Ishii) + + + + + + + Improve regression test to detect segmentation fault. (Bo Peng) + + + + + + + Increase timeout for regression test 077.invalid_failover_node. (Tatsuo Ishii) + + + + + + + + + Release 4.3.1 + + Release Date + 2022-02-17 + + + + Changes + + + + + + Suppress message length log for in_hot_standby. (Tatsuo Ishii) + + + PostgreSQL 14 introduced new config parameter in_hot_standby. + + + The value is either "on" for standby servers or "off" for primary + servers. As a result pgpool log is flooded by the messages: + + + + LOG: reading message length + DETAIL: message length (22) in slot 1 does not match with slot 0(23) + + + + To avoid this, only complain if the parameter name is not in_hot_standby. + + + Also the message is enhanced to show the parameter name. + + + + LOG: ParameterStatus "TimeZone": node 1 message length 30 is different from main node message length 24 + + + + Discussion: [pgpool-hackers: 4076] + + + + + + + Change the default value for . (Tatsuo Ishii) + + + The default value for log_line_prefix is changed from + "%t pid: %p" to "%m %a pid: %p". + Discussion: [pgpool-hackers: 4097] + + + + + + + Add validations of and format (Masaya Kawamoto) + + + wd_lifecheck_password and recovery_password + are not allowed to be md5 hashed password format but pgpool just reported + authentication failure and did not check them. + + + + + + + Enhance parameter status handling. (Tatsuo Ishii) + + + When a parameter status message arrives from backend Pgpool-II + forwards it to frontend not just memorize. + + + + + + + + Bug fixes + + + + + + Fix pgpool_remote_start.sample script. (Bo Peng) + + + + + + + Rename the parameter "wd_initial_node_showup_time" to . (Bo Peng) + + + Differently from documentation wd_no_show_node_removal_timeout + was written as wd_initial_node_showup_time in source code. + + + + + + + Fix for a small mistake in pgpool-recovery SQL script (Muhammad Usama) + + + + + + + Fix pcp_node_info hang when pgpool cannot connect to backend. (Tatsuo Ishii) + + + Problem reported and patch reviewed by Emond Papegaaij. + Discussion: [pgpool-general: 7983] + + + + + + + Fix long standing bug with pcp_node_info. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4109] + + + + + + + Fix health check process issues pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix memory leak pointed out by Coverity. (Tatsuo Ishii) + + + + + + + Fix failover() to deal with the case when no former primary node exists. (Tatsuo Ishii) + + + In case Req_info->primary_node_id is -1 like no primary + node exists when Pgpool-II starts up, + failover() skipped to call + find_primary_node_repeatedly(). Also + follow_master_command was not executed. + + + Discussion: [pgpool-hackers: 4113] + + + + + + + Fixed sample failover script. (Bo Peng) + + + This script did not consider the case when the old primary node id is "-1". + + + + + + + Fixed the streaming replication check process not to retry if it cannot connect to the backend.(bug 742) (Bo Peng) + + + This retry caused a long time failover. + + + + + + + + Documents + + + + + + Sync with English manual. (Tatsuo Ishii) + + + + + + + Fix typo in pcp_watchdog_info manual. (Tatsuo Ishii) + + + + + + + Fix documentation typos. (pengbo) + + + Patch is created by Umar Hayat. + + + + + + + Add "exclude" settings to /etc/yum.repos.d/pgdg-redhat-all.repo so + that Pgpool-II is not installed from + PostgreSQL YUM repository. (Bo Peng) + + + + + + + Add restriction regarding ParameterStatus and in_hot_standby parameter. (Tatsuo Ishii) + + + + + + + Add restriction about set_config. (Tatsuo Ishii) + + + + + + + + Test tools + + + + + + Fix pgpool_setup in failover scrip creation. (Tatsuo Ishii) + + + When pgpool_setup creates failover.sh, + it did not consider the case when no primary server existed. + + + + + + + + Regression Tests + + + + + + Allow to run regression test against existing installation without recompiling. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4077] + + + + + + + Fix regression test 075. (Tatsuo Ishii) + + + The test reported success even if pgpool does not start up. + Problem reported and patch provided by Qiang Lingjie. + Discussion: [pgpool-hackers: 4085] + + + + + + + Fix pgpool_setup and watchdog_setup binary PATH in noinstall mode. (Bo Peng) + + + + + + + + + Release 4.3.0 + + Release Date + 2021-12-07 + + + + Overview + + Many enhancements are added to this version for easier + configuration and administration. A new cluster membership + mechanism is introduced to dynamically adjust the Watchdog + cluster size. + This allows the leader Watchdog node to retain the quorum/VIP + even when some of watchdog nodes get Shutdown or disconnected. + New PostgreSQL 14 SQL + parser is imported. + The Snapshot Isolation + Mode is now ready for production. + New sample configuration for the mode is provided in + the configuration example + section. + + + + Please be warned that in this version default values for some + configuration parameters are changed to be more consistent and + useful. See Migration + section for more details. + + + + Below are major enhancements. + + + + + + + A new membership mechanism is introduced to Watchdog to allow to + keep quorum/VIP when some of watchdog nodes are removed. + + + + + + Allow to choose the least replication delay standby node when + selecting the load balance node. For this purpose a new + parameter is + added. + + + + + + Allow to specify the node id to be promoted in + . For this purpose new + switch --switchover is added. If the switch + is specified, detaches the + current primary node and actually promote the specified node. + + + + + + Allow to configure to not trigger failover + when PostgreSQL is shutdown by admin + or killed by pg_terminate_backend. For this + purpose a new + parameter is + added. + + + + + + Add new fields + to , + and command to display more + useful information to admin. + + + + + + Allow to list all backend nodes + information. + + + + + + Add new fields showing + actual PostgreSQL status + to command and friends. + + + + + + Add a new parameter which represents the recovery source hostname + to + and . This is + useful for some systems on which hostname command returns + unexpected host name. + + + + + + Add support for log time stamp with milliseconds. + + + + + + Import PostgreSQL 14's SQL parser. + + + Major changes of PostgreSQL 14 parser include: + + + + + Allow an alias to be used to a JOIN ... USING + + + + + Allow DISTINCT to be added to GROUP BY + + + + + New SEARCH and CYCLE clauses for common table expressions + + + + + + + + Support include directive in pgpool.conf + file. You can have separate sub-config file to be included in + pgpool.conf. + + + + + + pgpool.conf sample files are unified into + single sample file for easier configuration. + + + + + + All configuration parameters in pgpool.conf + sample file are commented out to clarify which parameter is + needed to be changed. Please note that some configuration + parameter's default values are + changed. See Migration + section for more details. + + + + + + + Migration to Version 4.3 + + + + + + + Until Pgpool-II 4.2, + if PostgreSQL was shutdown by an + administrator using pg_ctl command, it + triggered an immediate failover if clients are connected + to Pgpool-II. In 4.3 this is not a + case anymore. If a configuration + parameter is + set to false (the default), the shutdown does not trigger a + failover. Setting the parameter to true will preserve the same + behavior as pre-4.3. + + + + + + + Commenting out all parameters + in pgpool.conf. (Tatsuo Ishii) + + + This will make pgpool.conf less confusing + and make PostgreSQL users easier to + understand pgpool.conf because this follows + the PostgreSQL way. + + + + + + + Unify all pgpool.conf.sample files into + single pgpool.conf.sample. (Tatsuo Ishii) + + + Now that all configuration parameters + in pgpool.conf are commented out, there's no + point to have separate configuration sample files. Just specify + the parameter is + enough. + + + + + + + Change compile time default value of to on. (Tatsuo Ishii) + + + insert_lock is already on + in pgpool.conf.sample. So sync with it. + + + + + + + Change compile time default value + of to + on. (Tatsuo Ishii) + + + is already on in + the docs and in pgpool.conf. So sync with them. + + + + + + + Change compile time default value + of to + on. (Tatsuo Ishii) + + + is already on in + the docs and in pgpool.conf. So sync with them. + + + + + + + Change compile time default value + of to on. (Tatsuo Ishii) + + + is already on + in pgpool.conf.sample. So sync with it. + + + + + + + Enable streaming replication check by default. (Tatsuo Ishii) + + + Change the compile time default value + of from 0 to 10. This means + if operating in streaming replication mode, now streaming + replication check is enabled by default. The parameter is already + set to 10 in pgpool.conf.sample. So the only + difference is, when is + commented out. + + + + + + + Change compile time default + of from 'none' to + 'if_over_threshold'. (Tatsuo Ishii) + + + Before the compile time default was 'none' but the default value + of sample pgpool.conf was + 'if_over_threshold'. Since 'if_over_threshold' is more useful for + most users, change the compile time default to + 'if_over_threshold' as well. + + + + + + + Fix some compile time default values. (Tatsuo Ishii) + + + Some default values defined in src/config/pool_config_variable.c + were different from what the documentation expects. Namely: + + (changed from "false" to "true") + (changed from "postgres" to "template1") + (changed from "32" to "2") + (changed from "0" to "60") + + + + + + + + + Bug fixes + + + + In this release same bug fixes as Pgpool-II 4.2.5 are + already applied. See for more details of those fixes. + + + + + + + Changes + + + + + + Enable dynamic watchdog cluster definition by introducing the + concept of Member and Nonmember watchdog nodes. (Muhammad Usama) + + + If the node's membership gets revoked from the watchdog cluster, + then the cluster re-calibrate itself dynamically to adjust all + subsequent majority rule computations. + + + Three new settings , + + and are added to + configure the membership criteria of the watchdog nodes. + + + + + + + Add (Masaya Kawamoto) + + + + + + + Allow to specify node id to be promoted in . (Tatsuo Ishii) + + + + + + + Add new config parameter . (Tatsuo Ishii) + + + + + + + Add new fields + to , + and command. (Masaya + Kawamoto) + + + + + + + Allow to list all backend nodes. (Bo Peng) + + + + + + + Add new fields to show + actual PostgreSQL status + to , + and . (Tatsuo Ishii) + + + + + + + Add a new parameter which represents the recovery source hostname + to + and . (Tatsuo + Ishii) + + + + + + + Add support for log time stamp with millisecond + in . (Tatsuo Ishii) + + + + + + + Import PostgreSQL 14's new SQL + parser. (Bo Peng) + + + + + + + Unify all pgpool.conf.sample files into + single pgpool.conf.sample. (Tatsuo Ishii) + + + + + + + Fix missing comment out in + sample pgpool.conf. (Tatsuo Ishii) + + + + and were not + commented out. + + + + + + + + Documentation changes + + + + + Add new configuration example for native replication mode and + snapshot isolation mode. (Bo Peng) + + + + + + + Update Pgpool-II + Watchdog Setup + Example and sample scripts + for PostgreSQL 14. (Masaya Kawamoto) + + + + + + + diff --git a/doc/src/sgml/release-4.4.sgml b/doc/src/sgml/release-4.4.sgml new file mode 100644 index 000000000..cf2fca701 --- /dev/null +++ b/doc/src/sgml/release-4.4.sgml @@ -0,0 +1,4226 @@ + + + + + Release 4.4.17 + + Release Date + 2026-06-04 + + + + Bug fixes + + + + + Allow pgproto to accept new line data. (Tatsuo Ishii) + + + Now "\n" is recognized as a new line. This is necessary for COPY command. + + + + + + + Keep local primary_node_id when leader watchdog reports the initial -2 sentinel. (Tatsuo Ishii) + + + Fix a watchdog synchronization issue after simultaneous restart of all pgpool nodes, + where standby nodes could overwrite a valid primary_node_id with the initial -2 sentinel + value and remain stuck in an uninitialized state indefinitely. Fix is, keep the local + primary_node_id when the leader reports the initial -2 sentinel. + + + Problem reported by Emond Papegaaij and Claude Code. + + + Discussion: Primary node detection race at clean startup + + + + + + + Fix empty query case in aborted transaction. (Tatsuo Ishii) + + + Fix empty queries in aborted transactions incorrectly raising errors. + Empty queries should be allowed in aborted transactions, + but a previous commit caused check_transaction_state_and_abort() to reject them. + Fix is, detect empty queries in SimpleQuery() and bypass the check. + + + Problem reported by Ronaldo Raivil. + + + Discussion: pgpool >= 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + Fix description about ssl_dh_params_file. (Tatsuo Ishii) + + + It actually falls back to compiled-in default not only when the + parameter is empty (the default), but when specified parameter is + incorrect one. + + + + + + + Fix PCP main process to remember child pids upon restarting. (Tatsuo Ishii) + + + Upon failover/failback, pgpool main process sends a signal to PCP main + process to request restarting, and PCP main restarts. Problem is, when + PCP main restarts, it forgets the list of pids of its child PCP worker + process. + + As a result, commands such as pcp_promote_node could hang indefinitely. + Fix is, store PCP worker PIDs in shared memory so they survive PCP main restart. + + + Problem reported by Taiki Koshino. + + + Discussion: Problem with pcp process + + + + + + + Fix version mismatch: regenerate configure for 4.4.16. (Bo Peng) + + + + + + + Fix query cache to invalidate cache when MERGE statement is used. (Tatsuo Ishii) + + + MERGE was introduced in PostgreSQL 15 + and Pgpool-II 4.4 imported PostgreSQL 15's parser. + However, there was an oversight in query cache sub module: + MERGE statement did not trigger invalidation of query cache. + + + Problem reported by Nadav Shatz. + + + Discussion: Re: Proposal: Recent mutated table tracking in memory + + + + + + + Fix memory leak in a SSL module. (Tatsuo Ishii) + + + Fix a memory leak in load_dh_file() when invalid DH parameters are supplied. + The function failed to free memory returned by PEM_read_DHparams(). + Also update the copyright notice in the same file to retain the original PostgreSQL copyright. + + + Discussion: Memory leak in SSL module + + + + + + + Fix incorrect routing of SET transaction_read_only = 0. (Bo Peng) + + + Fix incorrect routing of SET transaction_read_only = 0 to standby node, which caused query errors. + Also replace incorrect bool ret = POOL_BOTH with the proper enum type. + + + Problem reported by liujinyang-highgo. + + + Discussion: set command 'set transaction_read_only = 0;' routed to standby node and execute failed. + + + + + + + Fix session local relation cache case bug. (Tatsuo Ishii) + + + Fix incorrect handling of session local relation cache in pool_search_relcache(). + Temporary table information could be incorrectly registered in shared relation cache, causing subsequent queries + to use stale cache entries and potentially route queries incorrectly. + Fix is, avoid registering temp table information in shared relation cache for session local cache entries. + + + Discussion: query temp table is routed to standby node. + + + + + + + Fix lock release leak in pool_search_relcache(). (Tatsuo Ishii) + + + Fix a lock release leak in pool_search_relcache(). + During shared relation cache updates, the lock state was not reset correctly after reacquiring an exclusive lock, + which could leave the shared memory lock held. Also rename confusing variable locked to locked_by_others + and fix unnecessary per_node_statement_log output. + + + Discussion: Lock release leak in pool_search_relcache + + + + + + + Close listening sockets before forking. (Tatsuo Ishii) + + + Fix inherited unnecessary listening sockets in forked child processes. + Previously, subprocesses such as pcp_main, health check, + and lifecheck processes inherited pgpool and/or PCP listening sockets they did not use, + which could prevent subsequent pgpool startup from binding ports correctly. + Fix is, close unnecessary listening sockets after forking using close_listening_sockets(). + + + Discussion: Close listening socokets before forking + + + + + + + Documents + + + + + Doc: fix ignore_leading_white_space and allow_sql_comments docs. (Tatsuo Ishii) + + + They lacked a description on the default values. + + + + + + + + Release 4.4.16 + + Release Date + 2026-02-26 + + + + Changes + + + + + Allow parallel make. (Tatsuo Ishii) + + + Previously a parallel make failed with: + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + Patch is created by anthonyroussel and reviewed by Tatsuo Ishii. + + + Discussion: Fix parallel build + + + + + + + Add detail log about mismatch between and primary_conninfo host. (Taiki Koshino) + + + If the set in pgpool.conf does not match + the host setting in PostgreSQL's primary_conninfo, + the following log message will be output. + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + Explicitly stat supported minimum OpenSSL version. (Tatsuo Ishii) + + + That can be done in configure.ac by using + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + The supported minimum version is 1.0.2, which is identical to + PostgreSQL at this point. (Actually the AC_DEFINE is brought in from + PostgreSQL). Also this could avoid OpenSSL deprecation warnings if + your installed OpenSSL is new, like 3.0. + Moreover, add mention to installation document that required minimum + version of OpenSSL is 1.0.2. + + + + + + + Bug fixes + + + + + Fix oversight in check_transaction_state_and_abort(). (Tatsuo Ishii) + + + The function does not take the case when frontend is NULL into account. + + + Problem pointed out by Coverity. + + + + + + + Fix walker() functions to return earlier. (Tatsuo Ishii) + + + Previously walker() functions returned false once it found target + objects. But it is possible to short-circuit the traverse and it + should have been. + + Also import comments from PostgreSQL to clarify walker function + design. + + + Problem reported by liujinyang-highgo and reviewed by Tatsuo Ishii. + + + Discussion: Improper handling in the function view_walker(). + + + + + + + Fix memory leak in scram-sha-256 authentication. (Tatsuo Ishii) + + + Problem pointed out by Coverity. + + + + + + + Fix to check the return value of malloc(). (Tatsuo Ishii) + + + create_inet_domain_sockets() forgot to check the return value of + malloc() while allocating memory for socket fds. + + + + + + + Fix health check process to not start. (Tatsuo Ishii) + + + Previously pgpool_main() did not start a health check process if the + backend node is down. This prevented auto_failback from working. + Pgpool reads status from pool_status file when option is not + present. If the status recorded in the file is "down", pgpool will + not start health check process for the node. Since auto_failback is + invoked from health check process, this means that auto_failback does + not work for the backend node. + + Fix is, unconditionally start health check process. + + + Problem reported by Meng Feilong and reviewed by Tatsuo Ishii. + + + Discussion: Nodes in the down state cannot failback + + + + + + + Fix possible integer overflow. (Tatsuo Ishii) + + + In pool_write_flush() and pool_flus_it() write(2) is used. write(2) + returns ssize_t and in the code there are some places where the return + value was assigned to an int variable. As a result it was possible + that the return value was evaluated to negative value, which led to an + error. + + + + + + + + Release 4.4.15 + + Release Date + 2025-12-15 + + + + Changes + + + + + Use "grep -E" instead of deprecated "egrep" in pgpool_setup. (Bo Peng) + + + Replace "egrep" with "grep -E" to avoid obsolescence warnings on newer GNU grep versions. + + + + + + + Bug fixes + + + + + Fix buffer overflow error in show pool_status. (Tatsuo Ishii) + + + "show pool_status", "pgpool show" and pcp_pool_status could cause a + buffer overflow error. If backend_flag is set to "ALWAYS_PRIMARY", + pool_flag_to_str(), which is responsible to produce printable format + of backend_flag, wrote data past to the end of static buffer. + + + Problem reported by zam bak and reviewed by Bo Peng. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + Fix memqcache_stats_start_time shown in "show pool_status". (Tatsuo Ishii) + + + get_config() uses ctime() to generate printable form of + memqcache_stats_start_time. But it did not take into account that + ctime() adds newline at the end of result. As a result, not only the + output of memqcache_stats_start_time was with unnecessary newline but + next row printed empty items. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + + Release 4.4.14 + + Release Date + 2025-11-25 + + + + Changes + + + + + Remove unnecessary application_name treatment. (Tatsuo Ishii) + + + A previous commit added a step to set application_name when reusing existing connections. + However, this is unnecessary because DISCARD ALL automatically resets application_name, + and send_params() already sends all necessary parameter status messages, including application_name, to the frontend. + Removing this redundant step also improves performance, particularly for backend nodes that are geographically distant. + + + Discussion: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + Bug fixes + + + + + Fix segfault with CopyOut. (Tatsuo Ishii) + + + When COPY relname TO STDOUT is executed in the extended query + protocol mode, pgpool segfaulted. + + + This problem is reported by https://github.com/tetesh. + + + Discussion: datanymizer and pg-pool segmentation fault + + + + + + Prevent watchdog split-brain scenario in some corner cases. (Tatsuo Ishii) + + + Watchdog uses both beacon messages and heartbeat for communication. + If the heartbeat is not yet active, missing beacon messages + for over 30 seconds can cause a split-brain scenario, + where the old leader remains active while a new leader is elected. + This change prevents two leaders from existing simultaneously by revoking the old leader. + When a node detects that it has missed beacon messages from the leader more than twice, + the leader is set to LOST and a new leader election is triggered via set_state(WD_JOINING). + + + + + + + Prevent FATAL error when non-existing prepared statement is given. (Tatsuo Ishii) + + + Previously, Bind() raised a FATAL error when a non-existing prepared statement was used, unlike PostgreSQL. + This change changes Bind() to check for the statement's existence and send an ERROR message to the frontend if it does not exist. + Note that no log is written, as logging this is not currently possible. + + + + + + + Fix not working if both -p and -P are provided. (Tatsuo Ishii) + + + The original report showed that running pg_enc -p -P prompted for a password and encryption key, + but failed if the key was not provided. + + + Discussion: pg_enc + + + + + + + Fix compiling issue on 32-bit environments. (Tatsuo Ishii) + + + On 32-bit systems, compiling src/parser/snprintf.c fails due to undefined functions isnan() and isinf(), which come from math.h. + This change includes math.h and also reorders the include files for clarity. + The file was originally imported from PostgreSQL, where math.h was already included. + This fix was provided via pull request: https://github.com/pgpool/pgpool2/pull/128 + + + Discussion: Compiling issues for 32-bit targets + + + + + + + Fix safer directory deletion in Bash in recovery_1st_stage.sample. (Taiki Koshino) + + + Quote variables in rm commands to avoid accidental deletion: + rm -rf "${DEST_NODE_PGDATA}" + + If the variable is empty, rm could delete unexpected files or directories. + + + + + + + Fix the compilation error when building without the option. (Tatsuo Ishii) + + + A compiler error occurred when configuring without . + The issue arose because the compiler could not determine that ptr would only be freed when memcached is enabled. + To fix this, the relevant code block was wrapped with #ifdef USE_MEMCACHED. + + + Problem reported by Bo Peng. + + + + + + Fix query cache lock file handling. (Tatsuo Ishii) + + + The query cache module creates a lock file in logdir for concurrency control, + but two bugs existed: the main pgpool process could create a stray "QUERY_CACHE_LOCK_FILE", + and the lock file was not removed on shutdown. This change fixes both issues. + + + Problem reported and analyzed by Bo Peng. + + + + + + + Documents + + + + + Update doc about "Setting up PostgreSQL standby" in 8.2. Pgpool-II + Watchdog Setup Example. (Taiki Koshino) + + + Add a note that when setting up a standby without online recovery, do not write primary_conninfo to postgresql.auto.conf. + + + Discussion: Follow primary command not fixing postgresql.auto.conf + + + + + + + Fix watchdog_setup manual. (Tatsuo Ishii) + + + It mistakenly stated that heartbeart is not setup in watchdog_setup. + + + + + + + Regression Tests + + + + + Adapt 023.ssl_connection to PostgreSQL 18. (Tatsuo Ishii) + + + PostgreSQL 18 heavily changed psql's \conninfo output format, which + made the test fail because the test relies on \conninfo. This change + makes the test script aware the PostgreSQL version to fix the issue. + + + + + + + Fix ruby script in 010.rewrite_timestamp. (Tatsuo Ishii) + + + The ruby script used "File.exists", which is said to be obsoleted in + newer version of Ruby. Replace it with "File.exist". + + + + + + + Tweak timeout in 034 and 075 tests. (Tatsuo Ishii) + + + 034.promote_node and 075.detach_primary_left_down_node set the timeout + 60 seconds for finishing follow primary script. It turns out that + these timeout values are not long enough, and sometimes caused false + errors. So make them from 60 seconds to 120 seconds. + + + + + + + Add ssl_ecdh_curve test to 023.ssl_connection. (Tatsuo Ishii) + + + 023.ssl_connection did not cover the test for ssl_ecdh_curve. This + commit tests it using bad ssl_ecdh_curve parameter to see if connection + between frontend and pgpool fails. + + + + + + + + Release 4.4.13 + + Release Date + 2025-08-21 + + + + Bug fixes + + + + + Fix watchdog to print inappropriate NOTICE message. (Tatsuo Ishii) + + + read_ipc_socket_and_process() printed a notice message every time when + it wrote commands to IPC socket even if it was successful. Fix this to + print the notice message only when the write failed. + + The reason why this bug was not recognized is, the message appears + only when log_min_messages is set to notice or higher. + + + Discussion: pgpool IPC socket connection issue + + + + + + + + Fix resource leak while reading startup packet. (Tatsuo Ishii) + + + Fix resource leak in pool_push_pending_data. + + + + + + + Fix broken scram-sha-256 authentication on big-endian machines. (Tatsuo Ishii) + + + When scram-sha-256 authentication is performed, a hash function + pg_sha_256_final is used. It was imported from PostgreSQL and it uses + preprocessor define WORDS_BIGENDIAN to judge host machine's + endianness. Although WORDS_BIGENDIAN should be defined while + configure, this part was missed when pg_sha_256_final (and others) was + imported from PostgreSQL. As a result, scram-sha-256 worked only in + little endian machines. Fixed the issue by adding + AC_C_BIGENDIAN macro to configure.ac. + + + Problem reported by Christoph Berg and analyzed by pranavkaruvally. + + + Discussion: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + Fix source code typos. (Bo Peng) + + + + + + + Fix heartbeat device treatment. (Tatsuo Ishii) + + + While processing pgpool.conf, heartbeat_device was mistakenly treated + and the first device was ignored. + + + Problem analyzed by Bo Peng. + + + + + + + Fix typo in the comments of pgpool.conf. (Tatsuo Ishii) + + + + + + + Documents + + + + + Enhance "8.3. Replication Mode and Snapshot Isolation Mode Configuration Example" Document. (Taiki Koshino) + + + Updated the link to the example script and the explanation in the "8.3.3. Before you begin" section. + + + + + + + Fix documentation for parameters that are not reflected by reload. (Taiki Koshino) + + + "authentication_timeout" and "memqcache_oiddir" is not reflected by reload. + The documentation is changed to "This parameter can only be set at server start.". + + + + + + + + Unify watchdog leader terms (followup). (Tatsuo Ishii) + + + + + + + + Fix example script link. (Taiki Koshino) + + + Modified the sample script in the section "8.2. Pgpool-II + Watchdog Setup Example" + + + + + + + Fix load balance explanation missed logical replication mode and Slony mode. (Tatsuo Ishii) + + + + + + + Enhance document. (Bo Peng) + + + Clarify that each backend_application_nameX must match the value specified + in the application_name of primary_conninfo to correctly display + "replication_state" and "replication_sync_state". + + + + + + + Add section of kernel resources. (Tatsuo Ishii) + + + Pgpool-II uses System V shared memory and semaphores. It's better to + describe the requirements in the docs. + + + + + + + Add description for option of configure. (Tatsuo Ishii) + + + It was missed when LDAP support was introduced in v4.2 + + + + + + + Clarify supported platforms for Pgpool-II. (Tatsuo Ishii) + + + + + + + Enhance document. (Tatsuo Ishii) + + + + + + + Regression Tests + + + + + Stabilize 029.cert_passphrase regression test. (Tatsuo Ishii) + + + When ssl_passphrase_command is not valid, the error message is + typically "bad decrypt" but it seems sometimes "wrong tag". + + + + + + + + Release 4.4.12 + + Release Date + 2025-05-15 + + + + Overview + + This release contains a security fix. + + + An authentication bypass vulnerability exists in the client authentication + mechanism of Pgpool-II. + In Pgpool-II, authentication may be bypassed even + when it is supposed to be enforced. As a result, an attacker could log in as + any user, potentially leading to information disclosure, data tampering, or + even a complete shutdown of the database. (CVE-2025-46801) + + + This vulnerability affects systems where the authentication configuration + matches one of the following patterns: + + + + + Pattern 1: This vulnerability occurs when all of the following conditions are met: + + + + + The password authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is not set in pool_passwd + + + + + The scram-sha-256 or md5 authentication + method is used in pg_hba.conf + + + + + + + + Pattern 2: This vulnerability occurs when all of the following conditions are met: + + + + + enable_pool_hba = off + + + + + One of the following authentication methods is used in pg_hba.conf: + password, pam, or ldap + + + + + + + + Pattern 3: This vulnerability occurs when all of the following conditions are met: + + + + + Raw mode is used (backend_clustering_mode = 'raw') + + + + + The md5 authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is registered in pool_passwd in plain + text or AES format + + + + + One of the following authentication methods is used in + pg_hba.conf: + password, pam, or ldap + + + + + + + All versions of Pgpool-II 4.0 and 4.1 series, 4.2.0 to 4.2.21, 4.3.0 to 4.3.14, + 4.4.0 to 4.4.11, 4.5.0 to 4.5.6 and 4.6.0 are affected by this vulnerability. + It is strongly recommended to upgrade to Pgpool-II + 4.6.1, 4.5.7, 4.4.12, 4.3.15 and 4.2.22 or later. + Alternatively, you can modify your settings so that they do not match any of + the vulnerable configuration patterns. + + + + + Changes + + + + + Add major version information to the configuration file. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect client authentication in some cases. (Tatsuo Ishii) + + + If enable_pool_hba = on, it's auth method is "password", no + password is registered in pool_passwd, and auth method in + pg_hba.conf is "scram-sha-256" or "md5", for the first time when + a client connects to pgpool, authentication is performed as + expected. But if a client connects to the cached connection, any + password from the client is accepted. + + + Also if enable_pool_hba = off, in some cases a client is not + asked password for the first time, or when a client connects to + cached connection, even if it should be. + + + In addition to fixing above, following changes are made: + + + + + Remove single PostgreSQL code path to simplify the authentication code. + + + + + Remove crypt authentication support for frontend and + backend. The feature had not been documented and never + tested. Moreover crypt authentication was removed long time + ago in PostgreSQL (8.4, 2009). + + + + + Add new regression test "040.client_auth". The test performs + exhaustive client authentication tests using a test + specification file formatted in CSV. + + + + + + + + Fix long standing bind bug with query cache. (Tatsuo Ishii) + + + When a named statement is prepared, it is possible to bind then execute without a parse message. + Problem is, table oids which are necessary to invalidate query cache at execute or COMMIT was + collected only in parse messages process (Parse()). Thus if bind is executed + without parse after previous execute, no table oids were collected, and pgpool failed to invalidate query cache. + Fix is collecting table oids at bind time too. + Add regression test to 006.memqcache. + + + Problem reported by and test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + When an execute message is received, pgpool checks its max number of rows paramter. If it's not zero, + pgpool sets "partial_fetch" flag to instruct pool_handle_query_cache() to not create query cache. + Problem is, commit 2a99aa5d1 missed that even INSERT/UPDATE/DELETE sets the execute message parameter to non 0 (mostly 1) + and pgpool set the flag for even none SELECTs. This resulted in failing to invalidate query cache because if the flag is true, + subsequent code in pool_handle_query_cache() skips cache invalidation. + To fix this change Execute() to check if the query is read only SELECT before setting the flag. + Also add test to 006.memqcache. + + + Problem reported by and a test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix portability to OpenBSD. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + The patch was created by Martijn van Duren. + + + + + + Fix json_writer did not properly encode special characters. (Bo Peng) + + + Pgpool-II would crash when the watchdog was enabled if contained special characters (e.g., a backslash). + + + The patch was created by Martijn van Duren and slightly modified by Bo Peng. + + + + + + Fix sr check and health check to reopen upon reload. (Tatsuo Ishii) + + + The streaming replication check and health check process forgot to + reopen upon reload. If or + is empty string, the password is obtained from + . Thus those process read outdated content of + upon reload. + + + + + + + Documents + + + + + Enhance the description on (Tatsuo Ishii) + + + is a config value to determine the life time of + cached connections to PostgreSQL backend. Current document lacks a + description that the expiration calculation is actually done at the + time when the client disconnects to the process which holds the cached + connections. + + + Discussion: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + Enhance the explanation on . (Tatsuo Ishii) + + + It must be a superuser or in the pg_monitor group. + + + + + + + + Release 4.4.11 + + Release Date + 2025-02-28 + + + + Changes + + + + + Remove pg_basebackup from the sample follow primary script. (Bo Peng) + + + If pg_rewind fails, the safest way for users is to recover manually. + + + + + + + Bug fixes + + + + + Fix per_node_error_log() error message that is printed with two colons. (Bo Peng) + + + Patch is created by Umar Hayat. + + + + + + + Fix pool_signal. (Tatsuo Ishii) + + + Previously pool_signal did not set SA_RESTART flag. Thus any system + calls interrupted by a signal does not restart. Some of our code are + prepared so that they restart if a system call is interrupted by a + signal. But not sure all places are prepared too. So add the + flag. Note, PostgreSQL always uses the flag. + + + + + + + Fixed an issue where pg_md5 and + pg_enc would not update the password + file if a file other than the default value was specified + in the parameter. (Bo Peng) + + + This issue is reported by Sadhuprasad Patro. + + + + + + + Fix several query cache bugs in streaming replication mode. (Tatsuo Ishii) + + + + + When query cache is enabled and an execute message is sent from + frontend, Pgpool-II injects query cache + data into backend message buffer if query cache data is available. + But it was possible that the cached message is inserted at + inappropriate position and Pgpool-II + mistakenly raised "kind mismatch" error. + + + + + If query cache is enabled and query is operated in extended query mode + and pgpool is running in streaming replication mode, an execute + message could return incorrect results. + + + + + Another trouble is when multiple execute messages are sent + consecutively. In this case Pgpool-II returned exactly the same + results from query cache for each execute message. This is wrong since + the second or subsequent executes should return 0 rows. + + + Discussion: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + Documents + + + + + Enhance client authentication chapter. (Tatsuo Ishii) + + + Add intro about pool_passwd. Previously there was only description on + pool_hba.conf in the overview page. A general guide to + + will help users to understand this chapter. + + + + + + + Regression Tests + + + + + Stabilize 032.dml_adaptive_loadbalance (Tatsuo Ishii) + + + + + + + + Release 4.4.10 + + Release Date + 2024-11-28 + + + + Bug fixes + + + + + + Abort SSL negotiation if backend sends an error message. (Tatsuo Ishii) + + + In the client side implementation of SSL negotiation + (pool_ssl_negotiate_clientserver()), it was possible for a + man-in-the-middle attacker to send a long error message to confuse + Pgpool-II or client while in the SSL negotiation phase. This commit + rejects the negotiation immediately (issue a FATAL error) and exits + the session to prevent such an attack. + + + This resembles PostgreSQL's CVE-2024-10977. + + + + + + + Fix the watchdog process not reloading configurations. (Bo Peng) + + + The reload_config() function + in Pgpool-II should send + a SIGHUP signal to the watchdog process. + + + + + + + Fix bug in do_query. (Tatsuo Ishii) + + + Fix do_query to use ntohs/ntohl instead of htons/htonl. + + + + + + + Fix authentication failure after updating pool_passwd and reload. (Tatsuo Ishii) + + + If pool_hba.conf is disabled, + updating pool_passwd was not recognized + by Pgpool-II child process even + if Pgpool-II reload was performed. + The reload processing function check_config_reload() mistakenly assumed + that reopening pool_passwd was only necessary when + is on. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html" + + + + + + + Fix COPY hangs. (#79) (Tatsuo Ishii) + + + During COPY IN state (i.e. COPY FROM STDIN), frontend can send Flush + or Sync messages. According to the F/B protocol specification, they + should be ignored but Pgpool-II treated as an invalid message and this + causes COPY hung. + + + Also a regression test is added for this issue. + + + + + + + Fix Pgpool-II child process crash during shutdown. (Tatsuo Ishii) + + + The actual crash was in close_all_backend_connections(). + close_all_backend_connections() was + called because on_system_exit registers + child_will_go_down(). + At the moment it seems pgpool child had just started up and doing + pool_init_cp(). The connection pool + object had not been completely initialized, that's cause of the crash. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + Fix sporadic health check failures due to authentication failure. (Tatsuo Ishii) + + + When is empty string, + health check process looks for the password from pool_passwd file. + Problem is, the file descriptor for the file is inherited from + parent pgpool process. + This means that pgpool main and health check process (possibly multiple + process) share the same descriptor, which causes various problem + including the issue reported here. To fix the problem, re-open the + file when health check process starts so that each health check + process owns its own file descriptor. + + + Note that pgpool child process (responsible for frontend sessions) + already re-opens the file descriptor and they are not related to the + issue. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + Optimize query cache invalidation for ALTER ROLE. (Tatsuo Ishii) + + + Commit 6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89 invalidates query + cache if any ALTER ROLE/USER statement is used. + Actually this is an overkill. + Because following queries do not affect the privilege of the role. + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + So do not invalidate query cache if those commands are used. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Fix Pgpool-II crash when pgpool child process exits. (Tatsuo Ishii) + + + When a pgpool child process exits, + close_all_backend_connections() is + called, which is responsible for closing all connections to backend in + the connection pool. It used mistakenly MAIN_CONNECTION macro, which + is fine for current active connections but is not good for pooled + connections because a main node could be different at the time when + the connection pool was created. + Fix is using in_use_backend() instead. + + + Reported-by: Emond Papegaaij + + + + + + + Fix bug in replication/snapshot isolation mode. (#69) (Tatsuo Ishii) + + + When INSERT command is received, + pgpool automatically issues table LOCK command to the + target table but it forgot to send the command to + other than main nodes. This only happened in extended query mode. + + + + + + + Fix another bug in native replication/snapshot isolation mode. (Tatsuo Ishii) + + + insert_lock() forgot to send row lock command (lock_kind == 3 case) to + other than main node. + + + + + + + Fix resource leaks in pool_memqcache.c. (Tatsuo Ishii) + + + These leaks were brought in by commit 6fdba5c33. + + + + + + + + Documents + + + + + Fix typos in the documentation and sample configuration files. (Bo Peng) + + + + + + + Regression Tests + + + + + Adapt 024.cert_auth test to OpenSSL 3.2. (Tatsuo Ishii) + + + + + + + + Release 4.4.9 + + Release Date + 2024-09-09 + + + + Overview + + This release contains a security fix. + + + When the query cache () feature is enabled, + it was possible that a database user can read rows from tables that should + not be visible for the user through query cache (CVE-2024-45624). + + + All versions of Pgpool-II older than + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22, and all older + versions that has the query cache feature (the query cache feature was + implemented in 3.2) are affected by the vulnerability. + + + + + + If query cache is created for a table for a user, and then the + access right of the table is revoked from the user by + REVOKE command, still it was possible for the + user to access the table which the user does not have the access + right through the query + cache. + + + + + + If query cache is created for a table for user A, and then other + user B accesses the table via SET ROLE or + SET SESSION_AUTHORIZATION in the same session, + still it was possible for the user B to access the table which B + does not have the access right through the query + cache. + + + + + + If query cache is created for a row security enabled table for user + A, and then other user B accesses the table via SET ROLE + or SET SESSION_AUTHORIZATION in the same session, + it was possible for the user B to retrieve rows which should not be + visible from the user B through the query cache. + + + + + + It is strongly recommend to upgrade to Pgpool-II + 4.5.4, 4.4.9, 4.3.12, 4.2.19 and 4.1.22 or later. Or you should better turn + off the query cache feature. + + + + Note that to fix the vulnerability, some commands (ALTER DATABASE, + ALTER ROLE, ALTER TABLE, REVOKE) now invalidate whole query cache + data. This may affect the performance when using the query cache + feature. + + + + + Changes + + + + + Back port . (Tatsuo Ishii) + + + This is mainly for testing. Backpatch-through: v4.1 + + + Discussion: [pgpool-hackers: 4504] + + + + + + + Bug fixes + + + + + + Fix bugs in replication mode and snapshot isolation mode. (Tatsuo Ishii) + + + The following bugs was fixed: + + + + + In replication mode and snapshot isolation mode when a command finishes, + Pgpool-II waits for a ready for query message + but forgot that some commands (for example SET ROLE) + produces a parameter status message. As a result + Pgpool-II errors + out that other message arrives before the ready for query message. + + + + + + If previous query produces parameter status message, subsequent + parse() needs to read and process it because + it wants to read Ready for query message which is supposed to follow + the parameter status message. + However when ParameterStatus() gets called, + the query in progress flag was set and it was possible that only + one of parameter status message from backend was processed if the + query processed in this parse() call is load + balanced. It is likely that the parameter status message comes from + all live backend because they are generated by SET + command, and SET command are sent to all live backend + in replication mode and snapshot isolation mode. So unset the query in + progress flag before calling ParameterStatus(). + + + + + + + + + + + Release 4.4.8 + + Release Date + 2024-08-15 + + + + Changes + + + + + + Use psql -V instead of initdb -V + in sample scripts. (Bo Peng) + + + Use psql -V instead of initdb -V + in the sample scripts because in some cases postgresqlxx-server may not + be installed. + + + + + + + + Bug fixes + + + + + + Fix hang after a flush message received. (#59) (Tatsuo Ishii) + + + + + + + Fix segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool child segfaulted in pool_do_auth. The cause + was MAIN_CONNECTION() returns NULL. It seems my_main_node_id was set + to incorrect node id 0, which was actually in down status. thus there + was no connection in cp->slots[0]. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9175] + + + + + + + Fix dynamic process management. (Tatsuo Ishii) + + + Calculation of pooled_connection, which is used by the process + eviction algorithm, was not correct. The number always resulted in + max_pool. Also more comments are added. + + + Discussion: [pgpool-hackers: 4490] + + + + + + + Fixed segmentation fault at parsing config file. (Tatsuo Ishii) + + + This commit fixed a segmentation fault that occurs when parsing pgpool.conf + if the setting value was not enclosed in single quotes. + + + The patch is created by Carlos Chapi, reviewed and modified by Tatsuo Ishii. + + + + + + + Fix segfault to not use MAIN_NODE macro. (Tatsuo Ishii) + + + Some functions (close_idle_connection(), new_connection() and + pool_create_cp()) used MAIN* and VALID_BACKEND where they are not + appropriate. MAIN* and VALID_BACKEND are only useful against current + connections to backend, not for pooled connections since in pooled + connections which backend is the main node or up and running is + necessarily same as the current connections to backend. + The misuses of those macros sometimes leads to segfault. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9114] + + + + + + + Fix MAIN_NODE macro (actually pool_virtual_main_db_node_id()). (Tatsuo Ishii) + + + The macro used to return REAL_MAIN_NODE_ID if there's no session context. + This is wrong since REAL_MAIN_NODE_ID can be changed any time when + failover/failback happens. + + + Suppose REAL_MAIN_NODE_ID == my_main_node_id == 1. + Then due to failback, REAL_MAIN_NODE_ID is changed to 0. + Then MAIN_CONNECTION(cp) will return NULL and any + reference to it will cause segmentation fault. To prevent the issue we + should return my_main_node_id instead. + + + + + + + Fix show pool_processes to not show row description twice. (Tatsuo Ishii) + + + processes_reporting() accidentaly called both send_row_description() + and send_row_description_and_data_rows(). + + + Discussion: [pgpool-hackers: 4471] + + + + + + + Fix segfault in a child process. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + Watchdog dies and kills pgpool2 when network gets shortly interrupted. (#823) (Muhammad Usama) + + + With network monitoring enabled, a Pgpool-II + node would shut down immediately if it lost all network interfaces or + assigned IP addresses, providing extra protection by quickly removing + a non-communicative node from the cluster. + + + The issue was that Pgpool-II responded to network blackout events even when network + monitoring was disabled. This fix ensures that the network monitoring socket is + not opened when network monitoring is not enabled, preventing unnecessary shutdowns. + + + + + + + Fix pgpool reset command not working if watchdog is enabled. (Tatsuo Ishii) + + + Bug reported and problem analysis by keiseo. + Discussion: [pgpool-hackers: 4465] + + + + + + + Fix psql_scan crash. (#54) (Tatsuo Ishii) + + + It was reported that psql_scan crashes while determining whether a + string in a long query is psql variable (i.e. starting with ":") or not. + + + + + + + + Documents + + + + + + Mega typo fix for docs and program source codes. (Tatsuo Ishii) + + + Patch is created by Umar Hayat. + + + + + + + Add the criteria for selecting processes to be killed to . (Bo Peng) + + + + + + + Enhance failover document. (Tatsuo Ishii) + + + Clarify the condition on failover when is enabled. + + + + + + + Add the missing default values for virtual IP related parameters. (Bo Peng) + + + + + + + + + Release 4.4.7 + + Release Date + 2024-05-16 + + + + Bug fixes + + + + + Fix compiler error with -Werror=implicit-function-declaration. (Bo Peng) + + + Add LDAP_DEPRECATED to include prototypes for deprecated ldap functions. + Also Add missing header files in autoconf check. + + + Patch is created by Vladimir Petko. + + + + + + + Fix assorted causes of segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool and its child process segfault in certain + cases when failover involved. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + Fix uninitialized memory error. (Tatsuo Ishii) + + + It was reported that valgrind found several errors including an + uninitialized memory error in read_startup_packet. It allocates memory + for user name in a startup packet in case cancel or SSL request using + palloc, and later on the memory is used by pstrdup. Since memory + allocated by palloc is undefined, this should have been palloc0. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + Fix errors/hung up when load_balance_mode is off. (Tatsuo Ishii) + + + Commit 3f3c1656 + brought errors/hung up when load_balance_mode is off, primary node id + is not 0 and queries are BEGIN etc. + + + Bug found and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + Fix compile errors with certain CFLAGS. (Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42 + reported that with CFLAGS + -flto=4 -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing + gcc emits errors. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + Fix comments in sample pgpool.conf. (Bo Peng) + + + The default value for sr_check_period should be 10 seconds. + Also fixed some typos in comments. + + + Patch is created by hiroin and modified by Bo Peng. + + + + + + + Allow reset queries to run even if extended queries do not end. (Tatsuo Ishii) + + + Commit 240c668d + caused reset queries fail if extended query messages do not end. This commit + fix that by checking whether we are running reset queries in + SimpleQuery(). Also add the test case for this. + + + + + + + Fix memory leak pointed out by Coverity. (Takuma Hoshiai) + + + + + + + Guard against inappropriate protocol data. (Tatsuo Ishii) + + + If a simple query message arrives before a sequence of extended query + messages ends pgpool could hang. This is because the query context in + the session context for the simple query is overwritten by the query + contexts of the extended query messages. + + + This commit implements a guard in SimpleQuery() by checking whether + extended query protocol messages ended. If they do not end, raise a + FATAL error. A known example detected by this checking is JDBC + driver's "autosave=always" option. This means pgpool will not accept + the option after this commit until the issue (sending a simple + protocol message before ending extended query message protocol) is + fixed by the JDBC driver side. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + Documents + + + + + + Enhance "Upstream server connection" documentation. (Bo Peng) + + + + + + + Language cleanup in Japanese document. (Masaya Kawamoto) + + + + + + + Add the note about using pcp_promote_node when two postgres nodes. (Masaya Kawamoto) + + + Even if there are two postgres nodes, there are cases that + follow_primary_command is required to be set. + + + + + + + + Regression Tests + + + + + + Fixed regression test 005.jdbc to avoid Java 21 deprecation warnings. (Bo Peng) + + + Replace Runtime.exec(String) with Runtime.exec(String[]) to avoid Java 21 deprecation warnings. + Patch is created by Vladimir Petko and modified by Bo Peng. + + + + + + + + + Release 4.4.6 + + Release Date + 2024-02-29 + + + + Changes + + + + + Remove restore_command from sample scripts. (Bo Peng) + + + Restore_command is not required because replication slot is enabled. + It causes occasional failover failure. + + + + + + + Bug fixes + + + + + Fixed the default values of , + and + . (Bo Peng) + + + Because the default value of recovery_user + should be same as and + , I changed the default value + from '' to 'nobody'. + + + The correct default value of failover_on_backend_shutdown + should be "false" and the correct default value of insert_lock + should be "on". + + + + + + + Fixed with BEGIN etc. (Tatsuo Ishii) + + + When statement_level_load_balance is enabled, + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE + ALL/DISCARD were sent to primary node and all standby nodes even if + is off. + This is not only plain wrong but caused slow + down if one of the standby nodes are in remote network. + + + Fix this in that pgpool sends such queries to primary node only when + load_balance_mode is off. + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + + Documents + + + + + Fix Japanese watchdog document. (Tatsuo Ishii) + + + It mistakenly used "master" watchdog node instead of "leader". + + + + + + + Fix English watchdog document. (Tatsuo Ishii) + + + It mistakenly used "main" PostgreSQL node instead of "primary". + + + + + + + + + Release 4.4.5 + + Release Date + 2023-11-30 + + + + Changes + + + + + Modify the replication slot name conversion in sample scripts + to support for the hostname in uppercase. (Bo Peng) + + + Replication slots are automatically created or deleted in the scripts + which are executed during failover or online recovery. + Since uppercase can't be used for a replication slot name, modify these scripts + to convert the hostname to lowercase. + + + Patch is created by Sheikh Wasiu Al Hasib and modified by Bo Peng. + + + + + + + Add SSH timeout in sample script escalation.sh.sample + which is set in parameter. (Bo Peng) + + + + + + + Bug fixes + + + + + Remove unnecessary logging line. (Tatsuo Ishii) + + + Debug message "unset_tx_started_by_multi_statement_query is called in CommandComplete" was accidentally left. + + + + + + + Fix Describe() so that it does not abort with portal created by DECLARE. (Tatsuo Ishii) + + + When DECLARE foo CURSOR FOR is executed, + a portal named "foo" is automatically created by PostgreSQL. + As the portal is not managed by Pgpool-II, + "Describe foo" message failed with "unable to execute Describe. + unable to get the bind message" error. + + + To fix this, make Describe() create a dummy write query + context so that the describe message is sent to primary (streaming replication + mode) or all nodes (replication/snapshot isolation mode). + + + Also add test case 080 for this commit. + + + This problem was reported and analyzed by Heather Lapointe. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-September/008995.html + + + + + + + Remove duplication definitions of NAMEDATALEN. (Tatsuo Ishii) + + + The definition for NAMEDATALEN is now in + src/include/pg_config_manual.h only. + Also replace POOL_NAMEDATALEN with + NAMEDATALEN in + src/utils/pool_select_walker.c. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004366.html + + + + + + + Documents + + + + + Modify "Pgpool-II + Watchdog Setup Example" to mention that + pcp_listen_addresses = '*' is required to + allow PCP to listen on all addresses. + + + + + + + Fix docs. (Tatsuo Ishii) + + + The actual backend status is obtained using PQpingParams, not pg_isready. + + + + + + + Enhance manual. (Tatsuo Ishii) + + + Mention that it is necessary to run if + is not used. + + + + + + + Regression Tests + + + + + Enhance pgpool_setup. (Tatsuo Ishii) + + + Enhance failover script generation and follow primary script + generation so that they create better logging. + + + + + + + + Release 4.4.4 + + Release Date + 2023-08-17 + + + + Changes + + + + + Install system exit callback only after initialization of shared memory. (Muhammad Usama) + + + When the on-exit callback gets called because of a failure to acquire + shared memory. The cleanup function can produce a segfault while accessing + process_info, that lives in shared memory. + Although we can also fix this by bailing out from the exit callback when + process_info is NULL but installing the function after successful initialization + of shared memory is a better approach as the rest of the system always assumes + the process_info can never be NULL, and also, there is nothing to + clean up before child processes are spawned. + + + + + + + Disallowing setting the greater than when is set to "dynamic". (Muhammad Usama) + + + Config post-processing stage now throws an error if num_init_children is + smaller than max_spare_children. + Commit also adjusts the number of child processes spawned at startup based on + the configured process management strategy. + For the Aggressive strategy, max_spare_children number of processes is spawned; + for the other two strategies, min_spare_children number of children gets + created at startup. + + + + + + + Downgrade log message. (Tatsuo Ishii) + + + It is pointed out in https://www.pgpool.net/mantisbt/view.php?id=806 + that there are log entries in the log file: + + + LOG: pool_pending_message_set_flush_request: msg: Parse + + + The messages were for debugging and the log level should have been a + DEBUG*. So I changed the log level from LOG to DEBUG5. + + + + + + + Add schema qualification to some system catalog inquiry functions. (Tatsuo Ishii) + + + + + + + Bug fixes + + + + + Fix coverity warning. (Tatsuo Ishii) + + + Fix query cache module assigned time_t value to int32 variable. Change + the variable type to int64. Per Coverity. Also use difftime() to + calculate time_t difference. This is a recommended practice. + https://www.jpcert.or.jp/sc-rules/c-msc05-c.html + + + + + + + Fix find_primary_node_repeatedly doesn't terminate within . (Bo Peng) + + + + + + + Fix crash when v2 protocol is used.(bug 807) (Tatsuo Ishii) + + + When read_kind_from_backend() accumulates statistics data, it was not prepared for v2 protocol case. + + + Bug report and patch from MCanivez. Slightly modified by me. + + + + + + + Fix PREPARE in multi-statement case. (Tatsuo Ishii) + + + If multi-statement query includes PREPARE in the second or latter + position, and subsequent bind message uses the prepared statement, it + fails with "unable to bind" error because the prepared statement is not + saved in sent messages. + + + To fix this if such a case found after parsing the statement, create a + query context for the named statement and add it to the sent message list. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-July/008931.html + + + For this new regression test 079..multi_prepare is added. + + + + + + + Fix pgproto to work with bind message using params. (Tatsuo Ishii) + + + Previously pgproto can only process bind messages without params. + + + + + + + Fix typo in log message. (Bo Peng) + + + + + + + Fix missing CTE SEARCH and CYCLE rewrites. (Bo Peng) + + + In native replication mode, Pgpool-II need to rewrite Date/Time functions to timestamp in WRITE queries. + CTE SEARCH and CYCLE rewrites were missing. + + + + + + + Removed duplicate pcp_listen_address setting in src/sample/pgpool.conf.sample-stream. (Bo Peng) + + + + + + + Prevent query cache update under shared lock. (Tatsuo Ishii) + + + In bug 795 it was pointed out + that expired query cache entry can be modified under shared lock. This + could cause shared memory corruption used by query cache. In order to + fix this, we temporarily release the shared lock and then acquire an + exclusive lock before modifying the cache entry. This could create a + window and we need to get the cache entry meta data again to make sure + that the meta data has not been modified by someone else. + + + Back-patch to V4.4 stable where shared locking for query cache was introduced. + + + + + + + Fix and . (Tatsuo Ishii) + + + They were broken since delay_threshold_by_time was introduced in 4.4. + + + + + delay_threshold_by_time was not checked in where_to_send. This broke + load balancing when replication is delayed. + + + + + + + select_load_balancing_node was broken if both delay_threshold_by_time + and prefer_lower_standby_delay were enabled. + + + + + In order to fix the issue, where_to_send and + select_load_balancing_node are fixed. Also add test case for + delay_threshold_by_time are added to 033.prefer_lower_standby_delay. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2023-June/008864.html + + + + + + + Fix the wrong variable names in replication_mode_recovery_2nd_stage.sample sample script. (Bo Peng) + + + + + + + Documents + + + + + Fix the missing "logger" application name. (Bo Peng) + + + + + + + Clarify the meaning of stop mode. (Tatsuo Ishii) + + + + + + + Remove the incorrect information from release note 4.2.10. (Bo Peng) + + + Remove "Fix pgpool_recovery extension script. (Tatsuo Ishii)" from release note 4.2.10. + + + + + + + Enhance SSH public key authentication setting section in "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix load balance mode chapter. (Tatsuo Ishii) + + + In some places "streaming replication mode" was written as "native + replication mode". Also enhance description regarding additional + requirements for load balancing in the streaming replication mode. + Add some indexes. + + + + + + + Enhance online recovery documentation. (Bo Peng) + + + Mention that 2nd stage of online recovery does not work properly only for multiple pgpool nodes without watchdog enabled. + + + + + + + Regression Tests + + + + + Fix occasional 069.memory_leak_extended test failure. (Tatsuo Ishii) + + + It turned out that reason of the occasional test failure is, pgpool + child process is gone before running ps command after pgbench + finishes. The cause is a kind mismatch FATAL error, "DISCARD ALL + cannot be executed within a pipeline". To fix this, run pgbench in + background and get the process size before pgbench finishes. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004338.html + + + + + + + + Release 4.4.3 + + Release Date + 2023-05-18 + + + + Changes + + + + + Import psqlscan source code into Pgpool-II to judge multi statement query. (Tatsuo Ishii) + + + Psqlscan is a module in the PostgreSQL source tree. + It is essentially subset of PostgreSQL SQL scanner + but it is specialized for detecting + the end of each SQL statement. Therefore we can count the number of + SQL statements in a query string by using it. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/04291.html + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-April/004320.html + + + + + + + Allow to use multiple statements extensively. (Tatsuo Ishii) + + + This commit tries to eliminate pgpool's long standing limitations + regarding multiple statements (multi-statements). + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + Use schema qualification for internal queries. (Tatsuo Ishii) + + + Some of objects such as function and cast did not use "pg_catalog." + schema qualification. This does not lead to immediate security + concern but using the schema qualification is always good practice. + + + + + + + Bug fixes + + + + + Fix bug. + (bug 798) (Tatsuo Ishii) + + + When client connects to pgpool, one of standbys are chosen as the load + balancing node. If standby delay exceeds delay_threshold while the + session continues, prefer_lower_delay_standby will choose + the least delay standby node as the new load balancing node and set the target + backend to the node. Unfortunately the decision was made before the + checking that SELECT query includes writing function etc., + Pgpool-II + happily sends SELECT which cannot be executed on standby. To fix + this, prefer_lower_delay_standby treatment is moved + after the writing function etc. check. + + + Also modify 033.prefer_lower_standby_delay regression test to include the case above. + + + + + + + Fix compile error on systems using musl libc. + (bug 790) (Tatsuo Ishii) + + + Patch provided by leimaohui. + + + + + + + Fix multiple query cache bug. (Tatsuo Ishii) + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-January/004259.html + + + + + + + Fix sr worker to not send wrong query to standby server in corner case. (Tatsuo Ishii) + + + When ALWAYS_PRIMARY flag is set, PRIMARY_NODE_ID macro returns node + id, rather than -1 even if the primary is down. + In this case streaming replication delay check worker + sends SELECT pg_current_wal_lsn() or + SELECT pg_current_xlog_location() + depending on PostgreSQL's version to + standby which of course raises an error. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html + + + + + + + Fix kind mismatch error with DEALLOCATE. + (bug 780) (Tatsuo Ishii) + + + Kind mismatch error occurs when conditions below are all met: + + + + streaming replication mode + + + + + + + load balance node is other than primary + + + + + + + PREPARE is used in a multi-statement query + + + + + + + + + + Fix compile error of regression test (Takuma Hoshiai) + + + The error occurred by timestamp test using gcc10. + + + + + + + Obtain stronger lock while committing shared relcache. (Tatsuo Ishii) + + + + + + + Fix that show pool_version shows row description twice. (Tatsuo Ishii) + + + + + + + Documents + + + + + Add explanation for . (Chen Ningwei) + + + + + + + Add restriction regarding PREPARE/EXECUTE/DEALLOCATE. (Tatsuo Ishii) + + + + + + + Add caution to use -D option with pgpool. (Tatsuo Ishii) + + + + + + + Enhancing "Installation from RPM" section. (Bo Peng) + + + + + + + Add "Backing up PostgreSQL database" section to "Server Setup and Operation" chapter. (Tatsuo Ishii) + + + + + + + Remove the configuration of "-D" start OPTS from "8.2. Pgpool-II + Watchdog Setup Example". (Bo Peng) + + + + + + + Fix restrictions section. (Tatsuo Ishii) + + + + + + Add mention about SCRAM-SHA-256 authentication + + + + + + + Add mention about snapshot isolation mode + + + + + + + + + + Add explanation when pg node status is shown as "unknown". (Tatsuo Ishii) + + + + + + + Mention that the target node to promote must be up and running when executing + . (Tatsuo Ishii) + + + + + + + Mention that AES256 support requires option. (Tatsuo Ishii) + + + + + + + Explicitly stat that it is -w option of pcp command is needed to use .pcppass. (Tatsuo Ishii) + + + + + + + Fix "2.8 Creating insert lock table" section. (Tatsuo Ishii) + + + It only referred to the native replication where it should have referred + to the snapshot isolation mode. + + + + + + + Enhance . (Tatsuo Ishii) + + + + + + + Test Tools + + + + + Change pgpool_setup to append some parameters to the end of the configuration file. (Bo Peng) + + + + + + + Regression Tests + + + + + Refactor 071.execute_and_deallocate/test.sh. (Tatsuo Ishii) + + + + + + + Enhance regression tests. (Tatsuo Ishii) + + + + + + + Fix occasional 005.jdbc test failure. (Tatsuo Ishii) + + + + + + + + Release 4.4.2 + + Release Date + 2023-01-23 + + + + Overview + + This release contains a security fix. + + + If following conditions are all met, the password of is + exposed by command. + The command can be executed by any user who can + connect to Pgpool-II. (CVE-2023-22332) + + + + + + Version 3.3 or later. + + + + + + is on. + + + + + + is query. + + + + + + A plain text password is set + to . + + + + + + In this case it is strongly recommended to upgrade to this version + (we do not expose in + show pool_status command any more), or use one of following + workarounds. + + + + Workarounds for 4.0.x to 4.4.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + Set an empty string + to . This will use + password in the pool_passwd file. + + + + + + Set an AES encrypted password + to . + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Workarounds for 3.0.x to 3.7.x users: + + + + + + Disable watchdog. Set + to off. + + + + + + Change + to heartbeat. + + + + + + In any case we recommend to + change + in PostgreSQL. + + + + Please note that Pgpool-II 3.7.x or + before are end of life and no minor updates are provided for those + versions. + + + + + Changes + + + + + + Do not expose in + , + and + commands. (CVE-2023-22332) (Bo Peng) + + + + + + + Change the default value + for to empty string as + documented. (Bo Peng) + + + + + + + + Bug fixes + + + + + + Fixed pgpool_adm: pcp_pool_status error when this function is used with PostgreSQL 15. (Tatsuo Ishii) + + + pcp_pool_status actually returns SETOF record, but it was declared as + "returns record". This sloppiness had been tolerated until + PostgreSQL 14 but PostgreSQL 15 + becomes more strict. To fix this we need to change the return type of + pcp_pool_status from "RETURNS record" to "RETURNS SETOF record". + + + And the pgpool_adm extension version is bumped to 1.5. + + + + + + + Fix integer overflow in streaming replication check. (Tatsuo Ishii) + + + When is enabled and + the replication delay is about more than 36 minutes, an integer + overflow error was logged and replication check failed. + + + + + + + Fix compiler warning + in pgpool-regclass.c. (Florian Weimer, + Tatsuo Ishii) + + + + + + + Fix Uninitialized variables pointed out by Coverity. (Takuma Hoshiai) + + + + + + + + Documents + + + + + + Doc: Enhance and fix some mistakes + in Configurations + to use shared memory chapter. (Tatsuo Ishii) + + + + + + + Doc: Enhance explanation + of . (zam bak, Tatsuo + Ishii) + + + + + + + + + Release 4.4.1 + + Release Date + 2022-12-22 + + + + Changes + + + + + Downgrade streaming replication LOG message "standby_delay: 54" to DEBUG1. (Tatsuo Ishii) + + + + + + + Downgrade LOG messages "we have hit the ceiling" to DEBUG5. (Tatsuo Ishii) + + + + + + + + Bug fixes + + + + + + Fix time stamp rewrite bug. (Tatsuo Ishii) + + + In Pgpool-II 4.4 outfuncs module, boolean constant was ignored and turned into + an empty string in the rewritten query string, which caused syntax errors. + + + This issue is reported by Michiel van Leening. + Discussion: [pgpool-general: 8521] + + + + + + + Fix issue with . (Muhammad Usama) + + + The fix is to dynamically set the failover command timeout based on the maximum + value of health check parameters across the watchdog cluster. + + + Reviewed and tested by Tatsuo Ishii. + Discussion: [pgpool-hackers: 4227] + + + + + + + + Documents + + + + + + Doc: enhance the performance section. (Tatsuo Ishii) + + + Mention about dynamic process management. + + + + + + + Doc: fix typo in Aurora example. (Tatsuo Ishii) + + + + + + + Doc: enhance dynamic process management document. (Tatsuo Ishii) + + + + + + + + Regression Tests + + + + + + Allow to define PGPOOLDIR using environment variable. + (bug 766) (Bo Peng) + + + + + + + + + Release 4.4.0 + + Release Date + 2022-12-06 + + + + Overview + + Many enhancements are added to this version for easier + configuration and administration. New dynamic spare process management mode is added. + Streaming replication delay can be controlled by time, rather than WAL + bytes. Pgpool-II and PCP's listen + addresses accept multiple addresses. Full configuration of Unix + socket directory is now possible. + Allow to customize the command used by trusted_servers for checking upstream connection. + New PostgreSQL 15 SQL + parser is imported. Performance is also improved in query cache. + + + + Major enhancements are as follows: + + + + + + Add new dynamic spare process management feature. + This feature allows selecting between static and dynamic process management modes. + + + + + + Allow to specify replication delay by time in streaming + replication mode. For this purpose new + parameter is + introduced. + + + + + + As PostgreSQL already + does, Pgpool-II now supports + , + and for more + flexible and precise control of UNIX domain sockets. + + + + + + Allow to use comma separated multiple listen addresses in + + and . They control + which interfaces accept connection attempts, which can help + prevent repeated malicious connection requests on insecure + network interfaces. + + + + + + Allow to customize the command used by for checking upstream connection. + For this purpose new parameter is introduced. + + + + + + Import PostgreSQL 15's SQL parser. + + + + + + Speed up query + cache by reducing lock contention. This allows concurrent + running clients to fetch cache contents much more quicker. + + + + + + + + Migration to Version 4.4 + + + + + Rename configuration parameter socket_dir to . + + + + + + Configuration parameter delegate_IP is renamed + to . For compatibility with the + old versions, the old parameter delegate_IP can still work. If + the old parameter delegate_IP is + used, Pgpool-II will set the value to + delegate_ip and throw a warning message. + + + + + + Parameter status messages from backend are now forwarded to + frontend. When a parameter status message arrives from + backend, Pgpool-II memorized it but + did not forward to frontend. Now they are forwarded to frontend. + Applications using Pgpool-II should be + prepared to accept the message. But + since PostgreSQL already sends + parameter status messages to frontend whenever they are + generated, those application that are working + with PostgreSQL should have no problem + with this change. + + + + + + + + Changes + + + + + + Add new dynamic spare process management feature. (Jianshen Zhou, Muhammad Usama) + + + This feature allows selecting between static and dynamic process management modes. + Static process management is the same as the existing behavior of Pgpool-II, + where it spawns all child processes at startup. The new Dynamic mode keeps track of idle + processes and forks or kills processes to keep this number within + the specified boundaries. + + + Four new settings, , + , + , and + are added to configure the process management behavior, while process_management_strategy + allows selecting between three possible scaling-down strategies. + + + + + + + Allow to specify replication delay by time. (Tatsuo Ishii) + + + specifies replication delay + upper limit in bytes. Add similar parameter called + so that the limit + can be specified by time (seconds). The new parameter is + effective if it is greater than 0. + In this case and + display the replication delay in seconds. + If the parameter is set to 0, + is ignored and falls back to delay_threshold mode. + + + For this purpose new member standby_delay_by_time is added to shared + memory data Backendinfo to distinguish whether replication delay is + measured in bytes (standby_delay_by_time = false) or seconds + (standby_delay_by_time = true). If standby_delay_by_time is true, + standby_delay is measured in second * 1000000, so that the precision + is 6 digits after decimal point. + + + + + + + Support for unix_socket_directories and related parameters. (Masaya Kawamoto) + + + Rename configuration parameter socket_dir to , + and add new configuration parameters and . + + + + + + + Add configuration parameter. (Takuma Hoshiai) + + + This feature is able to specify a command that is used by + for checking up stream connection. + Previously, ping command was only used, and it was hard coded. + + + Default is 'ping -q -c3 %h' which means same as before. + + + + + + + Implement comma separated multiple listen addresses. (Tatsuo Ishii) + + + Previously Pgpool-II only allowed to + set single hostname, IP or '*' to + the parameter. Now we can + set multiple listen addresses to the parameter + as PostgreSQL already does. + + + Also now accepts comma + separated multiple listen addresses. + + + + + + + Import PostgreSQL 15's SQL parser.(Bo Peng, Tatsuo Ishii) + + + Major changes of PostgreSQL 15 parser include: + + + + + + Add new SQL MERGE command + + +MERGE INTO ... USING ... + + + + + + Add new option HEADER MATCH to COPY FROM + + +COPY ... FROM stdin WITH (HEADER MATCH); + + + + + + Allow foreign key ON DELETE SET actions + + +CREATE TABLE t1 ( +... +FOREIGN KEY (c1, c2) REFERENCES t2 ON DELETE SET NULL (c2) +); + + + + + + Allow SET ACCESS METHOD in ALTER TABLE + + +ALTER TABLE ... SET ACCESS METHOD ...; + + + + + + + + + + Replace exclusive locking with shared locking in query cache. (Tatsuo Ishii) + + + Previously the query cache module used semaphore to protect critical + region in the query cache module. However this had serious down side + because the locking using semaphore is exclusive lock. This + introduces unnecessary wait for cache reading clients and performance + degradation when there are many concurrent clients. + + + To overcome the issue replace locking implementation + with flock(2) which allows shared + locking. Now the cache reading clients do not need to fight each + other to obtain a lock thus this increases concurrency. + + + For this purpose pgpool main process creates a dummy file as + logdir/memq_lock_file and opens it. The file + descriptor is inherited by all child process so that they can + issue flock(2) on the file. + + + + + + + Add validations of + and format. (Masaya Kawamoto) + + + + + + + Enhance parameter status handling. (Tatsuo Ishii) + + + When a parameter status message arrives from backend, Pgpool-II + memorized it but did not forward to frontend. This commit allows + forwarding a parameter status message to frontend. + + + + + + + Change the way to obtain replication delay when + is + specified. (Tatsuo Ishii) + + + Use pg_stat_replication.replay_lag. This way makes the code much + simpler and more precise replication delay can be obtained. The only + downside is pg_stat_replication.replay_lag is only available in + PostgreSQL 10 or later (previous method can be used in 9.5 or later). + + + + + + + Implement flush tracking feature. (Tatsuo Ishii) + + + When a flush message arrives from frontend, any pending message from + backend should be flushed and sent to frontend. In order to do that, + this commit implements "flush tracking" feature. i.e. when a flush + message arrives, pgpool sets "flush pending" flag in each pending + messages. If the response message from backend corresponds to the + pending message with the flush pending flag being set, the message is + immediately flushed to frontend, rather than buffered. + + + + + + + Enhance pgproto. (Tatsuo Ishii) + + + Allow to show ParameterStatus's parameter name and value. + + + Add new command 'z'. This is similar to 'y' except 'z' reads only 1 + message and do not wait for "ready for query" arrives (or timeout if + no message arrives within 1 second). + + + + + + + Downgrade LOG message "new IPC connection received" to DEBUG1. + (bug 775) (Bo Peng) + + + This message is output periodically and should not be logged as LOG. + Patch is created by pstef and reviewed by Bo Peng. + + + + + + + Bug fixes + + + + In this release same bug fixes as Pgpool-II 4.3.4 are + already applied. See for more details of those fixes. + + + + + + + Documentation changes + + + + + Doc: Update documentation of AWS configuration example and add sample scripts for AWS. (Bo Peng) + + + + + + diff --git a/doc/src/sgml/release-4.5.sgml b/doc/src/sgml/release-4.5.sgml new file mode 100644 index 000000000..c9ceaead8 --- /dev/null +++ b/doc/src/sgml/release-4.5.sgml @@ -0,0 +1,3128 @@ + + Release 4.5.12 + + Release Date + 2026-06-04 + + + + Bug fixes + + + + + Allow pgproto to accept new line data. (Tatsuo Ishii) + + + Now "\n" is recognized as a new line. This is necessary for COPY command. + + + + + + + Keep local primary_node_id when leader watchdog reports the initial -2 sentinel. (Tatsuo Ishii) + + + Fix a watchdog synchronization issue after simultaneous restart of all pgpool nodes, + where standby nodes could overwrite a valid primary_node_id with the initial -2 sentinel + value and remain stuck in an uninitialized state indefinitely. Fix is, keep the local + primary_node_id when the leader reports the initial -2 sentinel. + + + Problem reported by Emond Papegaaij and Claude Code. + + + Discussion: Primary node detection race at clean startup + + + + + + + Fix to not call pool_get_transaction_isolation() in elog(DEBUG). (Tatsuo Ishii) + + + Fix a FATAL error in aborted transactions caused by DEBUG logging in + where_to_send_main_replica() and where_to_send_native_replication(). + The DEBUG logging called pool_get_transaction_isolation(), which internally executed queries + via do_query() and could raise a FATAL error in aborted transactions. Fix is, remove the calls from DEBUG logging. + + + + + + + Fix empty query case in aborted transaction. (Tatsuo Ishii) + + + Fix empty queries in aborted transactions incorrectly raising errors. + Empty queries should be allowed in aborted transactions, + but a previous commit caused check_transaction_state_and_abort() to reject them. + Fix is, detect empty queries in SimpleQuery() and bypass the check. + + + Problem reported by Ronaldo Raivil. + + + Discussion: pgpool >= 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + Fix description about ssl_dh_params_file. (Tatsuo Ishii) + + + It actually falls back to compiled-in default not only when the + parameter is empty (the default), but when specified parameter is + incorrect one. + + + + + + + Fix PCP main process to remember child pids upon restarting. (Tatsuo Ishii) + + + Upon failover/failback, pgpool main process sends a signal to PCP main + process to request restarting, and PCP main restarts. Problem is, when + PCP main restarts, it forgets the list of pids of its child PCP worker + process. + + As a result, commands such as pcp_promote_node could hang indefinitely. + Fix is, store PCP worker PIDs in shared memory so they survive PCP main restart. + + + Problem reported by Taiki Koshino. + + + Discussion: Problem with pcp process + + + + + + + Fix query cache to invalidate cache when MERGE statement is used. (Tatsuo Ishii) + + + MERGE was introduced in PostgreSQL 15 + and Pgpool-II 4.4 imported PostgreSQL 15's parser. + However, there was an oversight in query cache sub module: + MERGE statement did not trigger invalidation of query cache. + + + Problem reported by Nadav Shatz. + + + Discussion: Re: Proposal: Recent mutated table tracking in memory + + + + + + + Fix memory leak in a SSL module. (Tatsuo Ishii) + + + Fix a memory leak in load_dh_file() when invalid DH parameters are supplied. + The function failed to free memory returned by PEM_read_DHparams(). + Also update the copyright notice in the same file to retain the original PostgreSQL copyright. + + + Discussion: Memory leak in SSL module + + + + + + + Fix incorrect routing of SET transaction_read_only = 0. (Bo Peng) + + + Fix incorrect routing of SET transaction_read_only = 0 to standby node, which caused query errors. + Also replace incorrect bool ret = POOL_BOTH with the proper enum type. + + + Problem reported by liujinyang-highgo. + + + Discussion: set command 'set transaction_read_only = 0;' routed to standby node and execute failed. + + + + + + + Remove unnecessary check STREAM in where_to_send_main_replica(). (Tatsuo Ishii) + + + The check is already done in check_replication_delay(). + + + + + + + Fix session local relation cache case bug. (Tatsuo Ishii) + + + Fix incorrect handling of session local relation cache in pool_search_relcache(). + Temporary table information could be incorrectly registered in shared relation cache, causing subsequent queries + to use stale cache entries and potentially route queries incorrectly. + Fix is, avoid registering temp table information in shared relation cache for session local cache entries. + + + Discussion: query temp table is routed to standby node. + + + + + + + Fix lock release leak in pool_search_relcache(). (Tatsuo Ishii) + + + Fix a lock release leak in pool_search_relcache(). + During shared relation cache updates, the lock state was not reset correctly after reacquiring an exclusive lock, + which could leave the shared memory lock held. Also rename confusing variable locked to locked_by_others + and fix unnecessary per_node_statement_log output. + + + Discussion: Lock release leak in pool_search_relcache + + + + + + + Close listening sockets before forking. (Tatsuo Ishii) + + + Fix inherited unnecessary listening sockets in forked child processes. + Previously, subprocesses such as pcp_main, health check, + and lifecheck processes inherited pgpool and/or PCP listening sockets they did not use, + which could prevent subsequent pgpool startup from binding ports correctly. + Fix is, close unnecessary listening sockets after forking using close_listening_sockets(). + + + Discussion: Close listening socokets before forking + + + + + + + Documents + + + + + Doc: fix ignore_leading_white_space and allow_sql_comments docs. (Tatsuo Ishii) + + + They lacked a description on the default values. + + + + + + + Regression Tests + + + + + Test: addition to 001.load_balance test for previous commit. (Tatsuo Ishii) + + + + + + + + Release 4.5.11 + + Release Date + 2026-02-26 + + + + Changes + + + + + Allow parallel make. (Tatsuo Ishii) + + + Previously a parallel make failed with: + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + Patch is created by anthonyroussel and reviewed by Tatsuo Ishii. + + + Discussion: Fix parallel build + + + + + + + Add detail log about mismatch between and primary_conninfo host. (Taiki Koshino) + + + If the set in pgpool.conf does not match + the host setting in PostgreSQL's primary_conninfo, + the following log message will be output. + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + Explicitly stat supported minimum OpenSSL version. (Tatsuo Ishii) + + + That can be done in configure.ac by using + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + The supported minimum version is 1.0.2, which is identical to + PostgreSQL at this point. (Actually the AC_DEFINE is brought in from + PostgreSQL). Also this could avoid OpenSSL deprecation warnings if + your installed OpenSSL is new, like 3.0. + Moreover, add mention to installation document that required minimum + version of OpenSSL is 1.0.2. + + + + + + + Bug fixes + + + + + Fix oversight in check_transaction_state_and_abort(). (Tatsuo Ishii) + + + The function does not take the case when frontend is NULL into account. + + + Problem pointed out by Coverity. + + + + + + + Fix walker() functions to return earlier. (Tatsuo Ishii) + + + Previously walker() functions returned false once it found target + objects. But it is possible to short-circuit the traverse and it + should have been. + + Also import comments from PostgreSQL to clarify walker function + design. + + + Problem reported by liujinyang-highgo and reviewed by Tatsuo Ishii. + + + Discussion: Improper handling in the function view_walker(). + + + + + + + Fix memory leak in scram-sha-256 authentication. (Tatsuo Ishii) + + + Problem pointed out by Coverity. + + + + + + + Fix to check the return value of malloc(). (Tatsuo Ishii) + + + create_inet_domain_sockets() forgot to check the return value of + malloc() while allocating memory for socket fds. + + + + + + + Fix health check process to not start. (Tatsuo Ishii) + + + Previously pgpool_main() did not start a health check process if the + backend node is down. This prevented auto_failback from working. + Pgpool reads status from pool_status file when option is not + present. If the status recorded in the file is "down", pgpool will + not start health check process for the node. Since auto_failback is + invoked from health check process, this means that auto_failback does + not work for the backend node. + + Fix is, unconditionally start health check process. + + + Problem reported by Meng Feilong and reviewed by Tatsuo Ishii. + + + Discussion: Nodes in the down state cannot failback + + + + + + + Fix duplicate NodeTag enum in nodes.h. (Tatsuo Ishii) + + + Fixed the duplication between NodeTag definitions in nodes.h imported from PostgreSQL and Pgpool-II's own definitions. + + + Problem reported and diagnosed by liujinyang-highgo and reviewed by Tastuo Ishii. + + + Discussion: an issue about NodeTag definition. + + + + + + + Fix possible integer overflow. (Tatsuo Ishii) + + + In pool_write_flush() and pool_flus_it() write(2) is used. write(2) + returns ssize_t and in the code there are some places where the return + value was assigned to an int variable. As a result it was possible + that the return value was evaluated to negative value, which led to an + error. + + + + + + + + Release 4.5.10 + + Release Date + 2025-12-15 + + + + Changes + + + + + Use "grep -E" instead of deprecated "egrep" in pgpool_setup. (Bo Peng) + + + Replace "egrep" with "grep -E" to avoid obsolescence warnings on newer GNU grep versions. + + + + + + + Bug fixes + + + + + Fix buffer overflow error in show pool_status. (Tatsuo Ishii) + + + "show pool_status", "pgpool show" and pcp_pool_status could cause a + buffer overflow error. If backend_flag is set to "ALWAYS_PRIMARY", + pool_flag_to_str(), which is responsible to produce printable format + of backend_flag, wrote data past to the end of static buffer. + + + Problem reported by zam bak and reviewed by Bo Peng. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + Fix memqcache_stats_start_time shown in "show pool_status". (Tatsuo Ishii) + + + get_config() uses ctime() to generate printable form of + memqcache_stats_start_time. But it did not take into account that + ctime() adds newline at the end of result. As a result, not only the + output of memqcache_stats_start_time was with unnecessary newline but + next row printed empty items. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + Regression Tests + + + + + Test: stabilize 037.failover_session. (Tatsuo Ishii) + + + On some platform (in my case Rocky Linux 10 running on VitualBox) + fails to finish shutdownall after test1. This could be caused by the + failover in the test to fail to restore the signal handler which + should accept shutdown signal from shutdownall. Adding "sleep 5" + before shutdownall seems to mitigate the problem. + + + + + + + + Release 4.5.9 + + Release Date + 2025-11-25 + + + + Changes + + + + + Remove unnecessary application_name treatment. (Tatsuo Ishii) + + + A previous commit added a step to set application_name when reusing existing connections. + However, this is unnecessary because DISCARD ALL automatically resets application_name, + and send_params() already sends all necessary parameter status messages, including application_name, to the frontend. + Removing this redundant step also improves performance, particularly for backend nodes that are geographically distant. + + + Discussion: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + Bug fixes + + + + + Fix segfault with CopyOut. (Tatsuo Ishii) + + + When COPY relname TO STDOUT is executed in the extended query + protocol mode, pgpool segfaulted. + + + This problem is reported by https://github.com/tetesh. + + + Discussion: datanymizer and pg-pool segmentation fault + + + + + + Prevent watchdog split-brain scenario in some corner cases. (Tatsuo Ishii) + + + Watchdog uses both beacon messages and heartbeat for communication. + If the heartbeat is not yet active, missing beacon messages + for over 30 seconds can cause a split-brain scenario, + where the old leader remains active while a new leader is elected. + This change prevents two leaders from existing simultaneously by revoking the old leader. + When a node detects that it has missed beacon messages from the leader more than twice, + the leader is set to LOST and a new leader election is triggered via set_state(WD_JOINING). + + + + + + + Prevent FATAL error when non-existing prepared statement is given. (Tatsuo Ishii) + + + Previously, Bind() raised a FATAL error when a non-existing prepared statement was used, unlike PostgreSQL. + This change changes Bind() to check for the statement's existence and send an ERROR message to the frontend if it does not exist. + Note that no log is written, as logging this is not currently possible. + + + + + + + Fix not working if both -p and -P are provided. (Tatsuo Ishii) + + + The original report showed that running pg_enc -p -P prompted for a password and encryption key, + but failed if the key was not provided. + + + Discussion: pg_enc + + + + + + + Fix compiling issue on 32-bit environments. (Tatsuo Ishii) + + + On 32-bit systems, compiling src/parser/snprintf.c fails due to undefined functions isnan() and isinf(), which come from math.h. + This change includes math.h and also reorders the include files for clarity. + The file was originally imported from PostgreSQL, where math.h was already included. + This fix was provided via pull request: https://github.com/pgpool/pgpool2/pull/128 + + + Discussion: Compiling issues for 32-bit targets + + + + + + + Fix safer directory deletion in Bash in recovery_1st_stage.sample. (Taiki Koshino) + + + Quote variables in rm commands to avoid accidental deletion: + rm -rf "${DEST_NODE_PGDATA}" + + If the variable is empty, rm could delete unexpected files or directories. + + + + + + + Fix the compilation error when building without the option. (Tatsuo Ishii) + + + A compiler error occurred when configuring without . + The issue arose because the compiler could not determine that ptr would only be freed when memcached is enabled. + To fix this, the relevant code block was wrapped with #ifdef USE_MEMCACHED. + + + Problem reported by Bo Peng. + + + + + + Fix query cache lock file handling. (Tatsuo Ishii) + + + The query cache module creates a lock file in logdir for concurrency control, + but two bugs existed: the main pgpool process could create a stray "QUERY_CACHE_LOCK_FILE", + and the lock file was not removed on shutdown. This change fixes both issues. + + + Problem reported and analyzed by Bo Peng. + + + + + + + Documents + + + + + Update doc about "Setting up PostgreSQL standby" in 8.2. Pgpool-II + Watchdog Setup Example. (Taiki Koshino) + + + Add a note that when setting up a standby without online recovery, do not write primary_conninfo to postgresql.auto.conf. + + + Discussion: Follow primary command not fixing postgresql.auto.conf + + + + + + + Fix watchdog_setup manual. (Tatsuo Ishii) + + + It mistakenly stated that heartbeart is not setup in watchdog_setup. + + + + + + + Regression Tests + + + + + Adapt 023.ssl_connection to PostgreSQL 18. (Tatsuo Ishii) + + + PostgreSQL 18 heavily changed psql's \conninfo output format, which + made the test fail because the test relies on \conninfo. This change + makes the test script aware the PostgreSQL version to fix the issue. + + + + + + + Fix ruby script in 010.rewrite_timestamp. (Tatsuo Ishii) + + + The ruby script used "File.exists", which is said to be obsoleted in + newer version of Ruby. Replace it with "File.exist". + + + + + + + Tweak timeout in 034 and 075 tests. (Tatsuo Ishii) + + + 034.promote_node and 075.detach_primary_left_down_node set the timeout + 60 seconds for finishing follow primary script. It turns out that + these timeout values are not long enough, and sometimes caused false + errors. So make them from 60 seconds to 120 seconds. + + + + + + + Add ssl_ecdh_curve test to 023.ssl_connection. (Tatsuo Ishii) + + + 023.ssl_connection did not cover the test for ssl_ecdh_curve. This + commit tests it using bad ssl_ecdh_curve parameter to see if connection + between frontend and pgpool fails. + + + + + + + + Release 4.5.8 + + Release Date + 2025-08-21 + + + + Bug fixes + + + + + Fix watchdog to print inappropriate NOTICE message. (Tatsuo Ishii) + + + read_ipc_socket_and_process() printed a notice message every time when + it wrote commands to IPC socket even if it was successful. Fix this to + print the notice message only when the write failed. + + The reason why this bug was not recognized is, the message appears + only when log_min_messages is set to notice or higher. + + + Discussion: pgpool IPC socket connection issue + + + + + + + + Fix resource leak while reading startup packet. (Tatsuo Ishii) + + + Fix resource leak in pool_push_pending_data. + + + + + + + Fix broken scram-sha-256 authentication on big-endian machines. (Tatsuo Ishii) + + + When scram-sha-256 authentication is performed, a hash function + pg_sha_256_final is used. It was imported from PostgreSQL and it uses + preprocessor define WORDS_BIGENDIAN to judge host machine's + endianness. Although WORDS_BIGENDIAN should be defined while + configure, this part was missed when pg_sha_256_final (and others) was + imported from PostgreSQL. As a result, scram-sha-256 worked only in + little endian machines. Fixed the issue by adding + AC_C_BIGENDIAN macro to configure.ac. + + + Problem reported by Christoph Berg and analyzed by pranavkaruvally. + + + Discussion: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + Fix source code typos. (Bo Peng) + + + + + + + Fix heartbeat device treatment. (Tatsuo Ishii) + + + While processing pgpool.conf, heartbeat_device was mistakenly treated + and the first device was ignored. + + + Problem analyzed by Bo Peng. + + + + + + + Fix typo in the comments of pgpool.conf. (Tatsuo Ishii) + + + + + + + Documents + + + + + Enhance "8.3. Replication Mode and Snapshot Isolation Mode Configuration Example" Document. (Taiki Koshino) + + + Updated the link to the example script and the explanation in the "8.3.3. Before you begin" section. + + + + + + + Fix documentation for parameters that are not reflected by reload. (Taiki Koshino) + + + "authentication_timeout" and "memqcache_oiddir" is not reflected by reload. + The documentation is changed to "This parameter can only be set at server start.". + + + + + + + + Unify watchdog leader terms (followup). (Tatsuo Ishii) + + + + + + + + Fix example script link. (Taiki Koshino) + + + Modified the sample script in the section "8.2. Pgpool-II + Watchdog Setup Example" + + + + + + + Fix load balance explanation missed logical replication mode and Slony mode. (Tatsuo Ishii) + + + + + + + Enhance document. (Bo Peng) + + + Clarify that each backend_application_nameX must match the value specified + in the application_name of primary_conninfo to correctly display + "replication_state" and "replication_sync_state". + + + + + + + Add section of kernel resources. (Tatsuo Ishii) + + + Pgpool-II uses System V shared memory and semaphores. It's better to + describe the requirements in the docs. + + + + + + + Add description for option of configure. (Tatsuo Ishii) + + + It was missed when LDAP support was introduced in v4.2 + + + + + + + Clarify supported platforms for Pgpool-II. (Tatsuo Ishii) + + + + + + + Enhance document. (Tatsuo Ishii) + + + + + + + Regression Tests + + + + + Stabilize 029.cert_passphrase regression test. (Tatsuo Ishii) + + + When ssl_passphrase_command is not valid, the error message is + typically "bad decrypt" but it seems sometimes "wrong tag". + + + + + + + + Release 4.5.7 + + Release Date + 2025-05-15 + + + + Overview + + This release contains a security fix. + + + An authentication bypass vulnerability exists in the client authentication + mechanism of Pgpool-II. + In Pgpool-II, authentication may be bypassed even + when it is supposed to be enforced. As a result, an attacker could log in as + any user, potentially leading to information disclosure, data tampering, or + even a complete shutdown of the database. (CVE-2025-46801) + + + This vulnerability affects systems where the authentication configuration + matches one of the following patterns: + + + + + Pattern 1: This vulnerability occurs when all of the following conditions are met: + + + + + The password authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is not set in pool_passwd + + + + + The scram-sha-256 or md5 authentication + method is used in pg_hba.conf + + + + + + + + Pattern 2: This vulnerability occurs when all of the following conditions are met: + + + + + enable_pool_hba = off + + + + + One of the following authentication methods is used in pg_hba.conf: + password, pam, or ldap + + + + + + + + Pattern 3: This vulnerability occurs when all of the following conditions are met: + + + + + Raw mode is used (backend_clustering_mode = 'raw') + + + + + The md5 authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is registered in pool_passwd in plain + text or AES format + + + + + One of the following authentication methods is used in + pg_hba.conf: + password, pam, or ldap + + + + + + + All versions of Pgpool-II 4.0 and 4.1 series, 4.2.0 to 4.2.21, 4.3.0 to 4.3.14, + 4.4.0 to 4.4.11, 4.5.0 to 4.5.6 and 4.6.0 are affected by this vulnerability. + It is strongly recommended to upgrade to Pgpool-II + 4.6.1, 4.5.7, 4.4.12, 4.3.15 and 4.2.22 or later. + Alternatively, you can modify your settings so that they do not match any of + the vulnerable configuration patterns. + + + + + Changes + + + + + Add major version information to the configuration file. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect client authentication in some cases. (Tatsuo Ishii) + + + If enable_pool_hba = on, it's auth method is "password", no + password is registered in pool_passwd, and auth method in + pg_hba.conf is "scram-sha-256" or "md5", for the first time when + a client connects to pgpool, authentication is performed as + expected. But if a client connects to the cached connection, any + password from the client is accepted. + + + Also if enable_pool_hba = off, in some cases a client is not + asked password for the first time, or when a client connects to + cached connection, even if it should be. + + + In addition to fixing above, following changes are made: + + + + + Remove single PostgreSQL code path to simplify the authentication code. + + + + + Remove crypt authentication support for frontend and + backend. The feature had not been documented and never + tested. Moreover crypt authentication was removed long time + ago in PostgreSQL (8.4, 2009). + + + + + Add new regression test "040.client_auth". The test performs + exhaustive client authentication tests using a test + specification file formatted in CSV. + + + + + + + + Fix long standing bind bug with query cache. (Tatsuo Ishii) + + + When a named statement is prepared, it is possible to bind then execute without a parse message. + Problem is, table oids which are necessary to invalidate query cache at execute or COMMIT was + collected only in parse messages process (Parse()). Thus if bind is executed + without parse after previous execute, no table oids were collected, and pgpool failed to invalidate query cache. + Fix is collecting table oids at bind time too. + Add regression test to 006.memqcache. + + + Problem reported by and test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + When an execute message is received, pgpool checks its max number of rows paramter. If it's not zero, + pgpool sets "partial_fetch" flag to instruct pool_handle_query_cache() to not create query cache. + Problem is, commit 2a99aa5d1 missed that even INSERT/UPDATE/DELETE sets the execute message parameter to non 0 (mostly 1) + and pgpool set the flag for even none SELECTs. This resulted in failing to invalidate query cache because if the flag is true, + subsequent code in pool_handle_query_cache() skips cache invalidation. + To fix this change Execute() to check if the query is read only SELECT before setting the flag. + Also add test to 006.memqcache. + + + Problem reported by and a test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix portability to OpenBSD. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + The patch was created by Martijn van Duren. + + + + + + Fix json_writer did not properly encode special characters. (Bo Peng) + + + Pgpool-II would crash when the watchdog was enabled if contained special characters (e.g., a backslash). + + + The patch was created by Martijn van Duren and slightly modified by Bo Peng. + + + + + + Fix sr check and health check to reopen upon reload. (Tatsuo Ishii) + + + The streaming replication check and health check process forgot to + reopen upon reload. If or + is empty string, the password is obtained from + . Thus those process read outdated content of + upon reload. + + + + + + + Documents + + + + + Enhance the description on (Tatsuo Ishii) + + + is a config value to determine the life time of + cached connections to PostgreSQL backend. Current document lacks a + description that the expiration calculation is actually done at the + time when the client disconnects to the process which holds the cached + connections. + + + Discussion: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + Enhance the explanation on . (Tatsuo Ishii) + + + It must be a superuser or in the pg_monitor group. + + + + + + + Regression Tests + + + + + Allow regression tests to use multiple socket directories. (Taiki Koshino, Tatsuo Ishii, Bo Peng) + + + + + + + + Release 4.5.6 + + Release Date + 2025-02-28 + + + + Changes + + + + + Remove pg_basebackup from the sample follow primary script. (Bo Peng) + + + If pg_rewind fails, the safest way for users is to recover manually. + + + + + + + Bug fixes + + + + + Fix per_node_error_log() error message that is printed with two colons. (Bo Peng) + + + Patch is created by Umar Hayat. + + + + + + + Fix pool_signal. (Tatsuo Ishii) + + + Previously pool_signal did not set SA_RESTART flag. Thus any system + calls interrupted by a signal does not restart. Some of our code are + prepared so that they restart if a system call is interrupted by a + signal. But not sure all places are prepared too. So add the + flag. Note, PostgreSQL always uses the flag. + + + + + + + Fixed an issue where pg_md5 and + pg_enc would not update the password + file if a file other than the default value was specified + in the parameter. (Bo Peng) + + + This issue is reported by Sadhuprasad Patro. + + + + + + + Fix several query cache bugs in streaming replication mode. (Tatsuo Ishii) + + + + + When query cache is enabled and an execute message is sent from + frontend, Pgpool-II injects query cache + data into backend message buffer if query cache data is available. + But it was possible that the cached message is inserted at + inappropriate position and Pgpool-II + mistakenly raised "kind mismatch" error. + + + + + If query cache is enabled and query is operated in extended query mode + and pgpool is running in streaming replication mode, an execute + message could return incorrect results. + + + + + Another trouble is when multiple execute messages are sent + consecutively. In this case Pgpool-II returned exactly the same + results from query cache for each execute message. This is wrong since + the second or subsequent executes should return 0 rows. + + + Discussion: [pgpool-hackers: 4547] Bug in query cache + + + + + + + + + Documents + + + + + Enhance client authentication chapter. (Tatsuo Ishii) + + + Add intro about pool_passwd. Previously there was only description on + pool_hba.conf in the overview page. A general guide to + + will help users to understand this chapter. + + + + + + + Regression Tests + + + + + Stabilize 032.dml_adaptive_loadbalance (Tatsuo Ishii) + + + + + + + + Release 4.5.5 + + Release Date + 2024-11-28 + + + + Bug fixes + + + + + + Abort SSL negotiation if backend sends an error message. (Tatsuo Ishii) + + + In the client side implementation of SSL negotiation + (pool_ssl_negotiate_clientserver()), it was possible for a + man-in-the-middle attacker to send a long error message to confuse + Pgpool-II or client while in the SSL negotiation phase. This commit + rejects the negotiation immediately (issue a FATAL error) and exits + the session to prevent such an attack. + + + This resembles PostgreSQL's CVE-2024-10977. + + + + + + + Fix the watchdog process not reloading configurations. (Bo Peng) + + + The reload_config() function + in Pgpool-II should send + a SIGHUP signal to the watchdog process. + + + + + + + Fix bug in do_query. (Tatsuo Ishii) + + + Fix do_query to use ntohs/ntohl instead of htons/htonl. + + + + + + + Fix authentication failure after updating pool_passwd and reload. (Tatsuo Ishii) + + + If pool_hba.conf is disabled, + updating pool_passwd was not recognized + by Pgpool-II child process even + if Pgpool-II reload was performed. + The reload processing function check_config_reload() mistakenly assumed + that reopening pool_passwd was only necessary when + is on. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001944.html" + + + + + + + Fix COPY hangs. (#79) (Tatsuo Ishii) + + + During COPY IN state (i.e. COPY FROM STDIN), frontend can send Flush + or Sync messages. According to the F/B protocol specification, they + should be ignored but Pgpool-II treated as an invalid message and this + causes COPY hung. + + + Also a regression test is added for this issue. + + + + + + + Fix Pgpool-II child process crash during shutdown. (Tatsuo Ishii) + + + The actual crash was in close_all_backend_connections(). + close_all_backend_connections() was + called because on_system_exit registers + child_will_go_down(). + At the moment it seems pgpool child had just started up and doing + pool_init_cp(). The connection pool + object had not been completely initialized, that's cause of the crash. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-November/001938.html + + + + + + + Fix sporadic health check failures due to authentication failure. (Tatsuo Ishii) + + + When is empty string, + health check process looks for the password from pool_passwd file. + Problem is, the file descriptor for the file is inherited from + parent pgpool process. + This means that pgpool main and health check process (possibly multiple + process) share the same descriptor, which causes various problem + including the issue reported here. To fix the problem, re-open the + file when health check process starts so that each health check + process owns its own file descriptor. + + + Note that pgpool child process (responsible for frontend sessions) + already re-opens the file descriptor and they are not related to the + issue. + + + Problem reported and analyzed by Emond Papegaaij. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-October/001913.html + + + + + + + Optimize query cache invalidation for ALTER ROLE. (Tatsuo Ishii) + + + Commit 6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89 invalidates query + cache if any ALTER ROLE/USER statement is used. + Actually this is an overkill. + Because following queries do not affect the privilege of the role. + + +ALTER ROLE user WITH [ENCRYPTED] PASSWORD +ALTER ROLE user WITH CONNECTION LIMIT + + + So do not invalidate query cache if those commands are used. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html + + + + + + + Fix Pgpool-II crash when pgpool child process exits. (Tatsuo Ishii) + + + When a pgpool child process exits, + close_all_backend_connections() is + called, which is responsible for closing all connections to backend in + the connection pool. It used mistakenly MAIN_CONNECTION macro, which + is fine for current active connections but is not good for pooled + connections because a main node could be different at the time when + the connection pool was created. + Fix is using in_use_backend() instead. + + + Reported-by: Emond Papegaaij + + + + + + + Fix bug in replication/snapshot isolation mode. (#69) (Tatsuo Ishii) + + + When INSERT command is received, + pgpool automatically issues table LOCK command to the + target table but it forgot to send the command to + other than main nodes. This only happened in extended query mode. + + + + + + + Fix another bug in native replication/snapshot isolation mode. (Tatsuo Ishii) + + + insert_lock() forgot to send row lock command (lock_kind == 3 case) to + other than main node. + + + + + + + Fix resource leaks in pool_memqcache.c. (Tatsuo Ishii) + + + These leaks were brought in by commit 6fdba5c33. + + + + + + + + Documents + + + + + Fix typos in the documentation and sample configuration files. (Bo Peng) + + + + + + + Regression Tests + + + + + Adapt 024.cert_auth test to OpenSSL 3.2. (Tatsuo Ishii) + + + + + + + + Release 4.5.4 + + Release Date + 2024-09-09 + + + + Overview + + This release contains a security fix. + + + When the query cache () feature is enabled, + it was possible that a database user can read rows from tables that should + not be visible for the user through query cache (CVE-2024-45624). + + + All versions of Pgpool-II older than + 4.5.4, 4.4.9, 4.3.12, 4.2.19, 4.1.22, and all older + versions that has the query cache feature (the query cache feature was + implemented in 3.2) are affected by the vulnerability. + + + + + + If query cache is created for a table for a user, and then the + access right of the table is revoked from the user by + REVOKE command, still it was possible for the + user to access the table which the user does not have the access + right through the query + cache. + + + + + + If query cache is created for a table for user A, and then other + user B accesses the table via SET ROLE or + SET SESSION_AUTHORIZATION in the same session, + still it was possible for the user B to access the table which B + does not have the access right through the query + cache. + + + + + + If query cache is created for a row security enabled table for user + A, and then other user B accesses the table via SET ROLE + or SET SESSION_AUTHORIZATION in the same session, + it was possible for the user B to retrieve rows which should not be + visible from the user B through the query cache. + + + + + + It is strongly recommend to upgrade to Pgpool-II + 4.5.4, 4.4.9, 4.3.12, 4.2.19 and 4.1.22 or later. Or you should better turn + off the query cache feature. + + + + Note that to fix the vulnerability, some commands (ALTER DATABASE, + ALTER ROLE, ALTER TABLE, REVOKE) now invalidate whole query cache + data. This may affect the performance when using the query cache + feature. + + + + + Bug fixes + + + + + + Fix bugs in replication mode and snapshot isolation mode. (Tatsuo Ishii) + + + The following bugs was fixed: + + + + + In replication mode and snapshot isolation mode when a command finishes, + Pgpool-II waits for a ready for query message + but forgot that some commands (for example SET ROLE) + produces a parameter status message. As a result + Pgpool-II errors + out that other message arrives before the ready for query message. + + + + + + If previous query produces parameter status message, subsequent + parse() needs to read and process it because + it wants to read Ready for query message which is supposed to follow + the parameter status message. + However when ParameterStatus() gets called, + the query in progress flag was set and it was possible that only + one of parameter status message from backend was processed if the + query processed in this parse() call is load + balanced. It is likely that the parameter status message comes from + all live backend because they are generated by SET + command, and SET command are sent to all live backend + in replication mode and snapshot isolation mode. So unset the query in + progress flag before calling ParameterStatus(). + + + + + + + + + + + Release 4.5.3 + + Release Date + 2024-08-15 + + + + Changes + + + + + + Use psql -V instead of initdb -V + in sample scripts. (Bo Peng) + + + Use psql -V instead of initdb -V + in the sample scripts because in some cases postgresqlxx-server may not + be installed. + + + + + + + + Bug fixes + + + + + + Fix hang after a flush message received. (#59) (Tatsuo Ishii) + + + + + + + Fix segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool child segfaulted in pool_do_auth. The cause + was MAIN_CONNECTION() returns NULL. It seems my_main_node_id was set + to incorrect node id 0, which was actually in down status. thus there + was no connection in cp->slots[0]. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9175] + + + + + + + Fix dynamic process management. (Tatsuo Ishii) + + + Calculation of pooled_connection, which is used by the process + eviction algorithm, was not correct. The number always resulted in + max_pool. Also more comments are added. + + + Discussion: [pgpool-hackers: 4490] + + + + + + + Fixed segmentation fault at parsing config file. (Tatsuo Ishii) + + + This commit fixed a segmentation fault that occurs when parsing pgpool.conf + if the setting value was not enclosed in single quotes. + + + The patch is created by Carlos Chapi, reviewed and modified by Tatsuo Ishii. + + + + + + + Fix segfault to not use MAIN_NODE macro. (Tatsuo Ishii) + + + Some functions (close_idle_connection(), new_connection() and + pool_create_cp()) used MAIN* and VALID_BACKEND where they are not + appropriate. MAIN* and VALID_BACKEND are only useful against current + connections to backend, not for pooled connections since in pooled + connections which backend is the main node or up and running is + necessarily same as the current connections to backend. + The misuses of those macros sometimes leads to segfault. + + + Problem is reported by Emond Papegaaij. + Discussion: [pgpool-general: 9114] + + + + + + + Fix MAIN_NODE macro (actually pool_virtual_main_db_node_id()). (Tatsuo Ishii) + + + The macro used to return REAL_MAIN_NODE_ID if there's no session context. + This is wrong since REAL_MAIN_NODE_ID can be changed any time when + failover/failback happens. + + + Suppose REAL_MAIN_NODE_ID == my_main_node_id == 1. + Then due to failback, REAL_MAIN_NODE_ID is changed to 0. + Then MAIN_CONNECTION(cp) will return NULL and any + reference to it will cause segmentation fault. To prevent the issue we + should return my_main_node_id instead. + + + + + + + Fix show pool_processes to not show row description twice. (Tatsuo Ishii) + + + processes_reporting() accidentaly called both send_row_description() + and send_row_description_and_data_rows(). + + + Discussion: [pgpool-hackers: 4471] + + + + + + + Fix segfault in a child process. (Tatsuo Ishii) + + + Discussion: [pgpool-general: 9104] + + + + + + + Watchdog dies and kills pgpool2 when network gets shortly interrupted. (#823) (Muhammad Usama) + + + With network monitoring enabled, a Pgpool-II + node would shut down immediately if it lost all network interfaces or + assigned IP addresses, providing extra protection by quickly removing + a non-communicative node from the cluster. + + + The issue was that Pgpool-II responded to network blackout events even when network + monitoring was disabled. This fix ensures that the network monitoring socket is + not opened when network monitoring is not enabled, preventing unnecessary shutdowns. + + + + + + + Fix pgpool reset command not working if watchdog is enabled. (Tatsuo Ishii) + + + Bug reported and problem analysis by keiseo. + Discussion: [pgpool-hackers: 4465] + + + + + + + Fix psql_scan crash. (#54) (Tatsuo Ishii) + + + It was reported that psql_scan crashes while determining whether a + string in a long query is psql variable (i.e. starting with ":") or not. + + + + + + + + Documents + + + + + + Mega typo fix for docs and program source codes. (Tatsuo Ishii) + + + Patch is created by Umar Hayat. + + + + + + + Add the criteria for selecting processes to be killed to . (Bo Peng) + + + + + + + Enhance failover document. (Tatsuo Ishii) + + + Clarify the condition on failover when is enabled. + + + + + + + Add the missing default values for virtual IP related parameters. (Bo Peng) + + + + + + + + + Release 4.5.2 + + Release Date + 2024-05-16 + + + + Bug fixes + + + + + Fix compiler error with -Werror=implicit-function-declaration. (Bo Peng) + + + Add LDAP_DEPRECATED to include prototypes for deprecated ldap functions. + Also Add missing header files in autoconf check. + + + Patch is created by Vladimir Petko. + + + + + + + Fix assorted causes of segmentation fault. (Tatsuo Ishii) + + + It is reported that pgpool and its child process segfault in certain + cases when failover involved. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009131.html + + + + + + + Fix uninitialized memory error. (Tatsuo Ishii) + + + It was reported that valgrind found several errors including an + uninitialized memory error in read_startup_packet. It allocates memory + for user name in a startup packet in case cancel or SSL request using + palloc, and later on the memory is used by pstrdup. Since memory + allocated by palloc is undefined, this should have been palloc0. + + + Problem is reported and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-April/009126.html + + + + + + + Fix errors/hung up when load_balance_mode is off. (Tatsuo Ishii) + + + Commit 3f3c1656 + brought errors/hung up when load_balance_mode is off, primary node id + is not 0 and queries are BEGIN etc. + + + Bug found and analyzed by Emond Papegaaij. + Discussion: https://www.pgpool.net/pipermail/pgpool-general/2024-March/009113.html + + + + + + + Fix compile errors with certain CFLAGS. (Tatsuo Ishii) + + + https://github.com/pgpool/pgpool2/issues/42 + reported that with CFLAGS + -flto=4 -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing + gcc emits errors. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-March/004443.html + + + + + + + Fix comments in sample pgpool.conf. (Bo Peng) + + + The default value for sr_check_period should be 10 seconds. + Also fixed some typos in comments. + + + Patch is created by hiroin and modified by Bo Peng. + + + + + + + Remove a file under config directory. (Takuma Hoshiai) + + + Remove Makefile.in etc. generated by autoconf. + Create .gitignore under src/config and add generated files by + bison and flex. + + + + + + + Allow reset queries to run even if extended queries do not end. (Tatsuo Ishii) + + + Commit 240c668d + caused reset queries fail if extended query messages do not end. This commit + fix that by checking whether we are running reset queries in + SimpleQuery(). Also add the test case for this. + + + + + + + Fix memory leak pointed out by Coverity. (Takuma Hoshiai) + + + + + + + Guard against inappropriate protocol data. (Tatsuo Ishii) + + + If a simple query message arrives before a sequence of extended query + messages ends pgpool could hang. This is because the query context in + the session context for the simple query is overwritten by the query + contexts of the extended query messages. + + + This commit implements a guard in SimpleQuery() by checking whether + extended query protocol messages ended. If they do not end, raise a + FATAL error. A known example detected by this checking is JDBC + driver's "autosave=always" option. This means pgpool will not accept + the option after this commit until the issue (sending a simple + protocol message before ending extended query message protocol) is + fixed by the JDBC driver side. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004428.html + + + + + + + + Documents + + + + + + Enhance "Upstream server connection" documentation. (Bo Peng) + + + + + + + Language cleanup in Japanese document. (Masaya Kawamoto) + + + + + + + Add the note about using pcp_promote_node when two postgres nodes. (Masaya Kawamoto) + + + Even if there are two postgres nodes, there are cases that + follow_primary_command is required to be set. + + + + + + + + Regression Tests + + + + + Fix 037.failover_session. (Tatsuo Ishii) + + + The test script forgot to execute shutdownall before exiting. + + + + + + + Fixed regression test 005.jdbc to avoid Java 21 deprecation warnings. (Bo Peng) + + + Replace Runtime.exec(String) with Runtime.exec(String[]) to avoid Java 21 deprecation warnings. + Patch is created by Vladimir Petko and modified by Bo Peng. + + + + + + + + + Release 4.5.1 + + Release Date + 2024-02-29 + + + + Changes + + + + + Remove restore_command from sample scripts. (Bo Peng) + + + Restore_command is not required because replication slot is enabled. + It causes occasional failover failure. + + + + + + + Bug fixes + + + + + Fixed the default values of , + and + . (Bo Peng) + + + Because the default value of recovery_user + should be same as and + , I changed the default value + from '' to 'nobody'. + + + The correct default value of failover_on_backend_shutdown + should be "false" and the correct default value of insert_lock + should be "on". + + + + + + + Fixed with BEGIN etc. (Tatsuo Ishii) + + + When statement_level_load_balance is enabled, + BEGIN/END/COMMIT/ABORT/SET/SAVEPOINT/RELEASE SAVEPOINT/DEALLOCATE + ALL/DISCARD were sent to primary node and all standby nodes even if + is off. + This is not only plain wrong but caused slow + down if one of the standby nodes are in remote network. + + + Fix this in that pgpool sends such queries to primary node only when + load_balance_mode is off. + + + Reported: https://www.pgpool.net/pipermail/pgpool-general/2024-January/009059.html + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-February/004423.html + + + + + + + + Documents + + + + + Fix Japanese watchdog document. (Tatsuo Ishii) + + + It mistakenly used "master" watchdog node instead of "leader". + + + + + + + Fix English watchdog document. (Tatsuo Ishii) + + + It mistakenly used "main" PostgreSQL node instead of "primary". + + + + + + + + Fix Japanese document mistake. (Bo Peng) + + + If this value is specified without units, it should be taken as milliseconds. + + + + + + + Regression Tests + + + + + Enhance 037.failover_session/test.sh. (Tatsuo Ishii) + + + Previously it mistakenly executed pg_ctl stop + after starting pgbench in background. + The smart shutdown always allows pgbench to run + successfully with pgbench -C option not being set because backend + does not shutdown while client session continues. + + + In order to shutdown backend in the middle of pgbench run, + tweak health check parameters so + that it detects the backend down as soon as possible. This will + trigger failover in the middle of pgbench run. + + + + + + + + Release 4.5.0 + + Release Date + 2023-12-12 + + + + Overview + + This release resolves several long-standing issues, including + lacking support for some types of queries in multiple statements + and session disconnections issue in some cases. Many enhancements + are also added for easier configuration and administration. + + + + Major enhancements are as follows: + + + + + + Allow to use more kind of multiple statements in a query string. + + + + + Allow to load balance PREPARE/EXECUTE/DEALLOCATE. + + + + + Allow to set in milliseconds. + + + + + Avoid session disconnection issue in failover/failback/backend error in some cases. + + + + + Allow to route queries to a specific backend node for a specific user connection. + + + + + Support multiple directories specification for . + + + + + Import PostgreSQL 16's SQL parser. + + + + + + + Migration to Version 4.5 + + + + + + The following normal ERROR messages are downgraded to DEBUG messages. (Bo Peng) + + + + + + These two messages are caused when the client did not send a + terminate message before disconnecting to pgpool. + For example, when the client process was forcefully terminated, this error occurs. + Although they are harmless, it may sometimes confuse users. + + +ERROR:unable to flush data to frontend + + +ERROR: unable to read data from frontend +DETAIL: EOF encountered with frontend + + + + + If is set to a non-zero value, + the connection will be disconnected if it remains idle since the last query. + Because the disconnection is caused by Pgpool-II settings, + Pgpool-II should handle it as "DEBUG" instead of "ERROR". + + +ERROR: unable to read data +DETAIL: child connection forced to terminate due to client_idle_limit:30 is reached + + + + + + + + + option is not required to read the pcp command password from the password file (~/.pcppass). (Chen Ningwei) + + + Previously pcp command didn't read the pcp command password from the password file (~/.pcppass) + if option is not given, + which is inconsistent with psql. + + + + + + + + Changes + + + + + + Add SSH timeout in sample script escalation.sh.sample + which is set in parameter. (Bo Peng) + + + + + + + Allow to set in milliseconds. (Tatsuo Ishii) + + + Previously it was allowed only in seconds. Also put some + refactoring. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-August/004372.html + + + + + + + Import PostgreSQL 16 new parser. (Chen Ningwei) + + + Major changes of PostgreSQL 16 parser include: + + + + + + Add new option DEFAULT to COPY FROM + + +COPY ... FROM stdin WITH (default 'xx'); + + + + + + Allow the STORAGE type to be specified by CREATE TABLE + + +CREATE TABLE t1 ( + c1 VARCHAR(10) STORAGE PLAIN, + c2 TEXT STORAGE EXTENDED +); + + + + + + Add EXPLAIN option GENERIC_PLAN to display the generic plan for a parameterized query + + +EXPLAIN (GENERIC_PLAN) SELECT ...; + + + + + + Allow subqueries in the FROM clause to omit aliases + + +SELECT COUNT(*) FROM (SELECT ... FROM ...); + + + + + + Add SQL/JSON constructors + + + + + + Add VACUUM options: + SKIP_DATABASE_STATS, ONLY_DATABASE_STATS to skip or update all frozen statistics + and PROCESS_MAIN to only process TOAST tables. + + +VACUUM (SKIP_DATABASE_STATS); +VACUUM (PROCESS_MAIN FALSE) t1 ; + + + + + + + + + Add new field load_balance_node to and . (Tatsuo Ishii) + + + The new field load_balance_node is "1" + if pgpool process is connected by a client and + the session uses the backend id as a load balance node. Users can + execute the commands to find out if there's any session that uses the + backend as the load balance node. If so, shutting down the backend may + cause session disconnection. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-July/004353.html + + + + + + + Mitigate session disconnection issue in failover/failback/backend error. (Tatsuo Ishii) + + + Previously Pgpool-II disconnected client + sessions in various cases. This release tries to avoid some of cases, + especially when a backend goes down and the backend is not either + primary (or main node) nor load balance node. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-July/004352.html + + + + + + + Add new parameter to allow to send SELECT queries to a specific backend node for a specific user connection. (Bo Peng) + + + + + + + Support multiple directories specification for . (Chen Ningwei) + + + + + + + Allow to load balance PREPARE/EXECUTE/DEALLOCATE. (Tatsuo Ishii) + + + Previously PREPARE/EXECUTE/DEALLOCATE are + not load balanced. In streaming replication/logical replication + mode, they were sent to always primary node. + In native replication/snapshot isolation mode, + they were always sent to all nodes. + + + Now they can be load balanced if the SQL statement prepared by PREPARE + command is a read only SELECT. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-May/004334.html + + + + + + + Add new config parameter to allow disable logging normal PCP Process fork and exit status. (Tatsuo Ishii) + + + When pcp command is executed, pgpool logs its fork/exit event + even if there's no error. + + + Abnormal fork/exit event will be logged even if the parameter is + disabled. + + + Patch is created by Maximilien Cuony and reviewed by Tatsuo Ishii. + + + + + + + Allow to use multiple statements extensively. (Tatsuo Ishii) + + + This release tries to eliminate pgpool's long standing limitations + regarding multiple statements (multi-statements). + For example, previously following queries raised errors. + +BEGIN;SELECT; +SAVEPOINT foo; + + Please note that each query in multi-statement is not still load balanced. + + + Although this is a new feature, it is also meant to be a bug fix, + so it has been backported to versions 4.1 to 4.4. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004287.html + + + + + + + + Import psqlscan source code into Pgpool-II to judge multi statement query. (Tatsuo Ishii) + + + Psqlscan is a module in the PostgreSQL source tree. + It is essentially subset of PostgreSQL + SQL scanner but it is specialized for detecting + the end of each SQL statement. Therefore we can count the number of + SQL statements in a query string by using it. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004291.html + + + + + + + Add new configuration parameter . (Tatsuo Ishii) + + + The new GUC variable allows to emit NOTICE message of queries per + backend basis. It's similar to + but as the log level is NOTICE, the log is printed on client's terminal, + thus users can know where their queries go to without looking into pgpool + log files. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004276.html + + + + + + + Enhance status file reading log. (Tatsuo Ishii) + + + Previously only if pgpool_status exists and + the status is down, a log message was printed. However it is more + useful no matter what the status (up or unused) is because it also + represents that pgpool_status exists and it is read while pgpool + starting up, which is useful information. + + + + + + + Remove pool_config.c and scan.c + from git repository. (Tatsuo Ishii) + + + They are generated files and we should not keep in the git repository. + + + + + + + Remove Makefile.in etc. generated by autoconf. (Tatsuo Ishii) + + + Also update some .gitignore files and add some new .gitignore files. Now + developers need to run autoconf/autoreconf before compiling since the + generated files are not provided by git anymore. + + + + + + + Bug fixes + + + + + Fix race condition with Pgpool-II main and pcp child process. (Tatsuo Ishii) + + + When pcp child process is forked off, pgpool main process unblock all + signals. This could lead to a race condition if a signal is sent to + the pcp process before it sets up signal handlers. Fix is, do not + unblock signals until the signal handlers are set up. + + + Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-September/004398.html + + + + + + This release fixes the same bugs as other minor releases. + See for more details of those fixes. + + + + + + + Documents + + + + + Update Configuration Example "8.2. Pgpool-II + Watchdog Setup Example" to Pgpool-II 4.5 and PostgreSQL 16. (Bo Peng) + + + + + + + Regression Tests + + + + + Attempt to fix 001.load_balance test timeout. (Tatsuo Ishii) + + + + + + + Enhance regression 001.load_balance. (Tatsuo Ishii) + + + + + + diff --git a/doc/src/sgml/release-4.6.sgml b/doc/src/sgml/release-4.6.sgml new file mode 100644 index 000000000..dd2e7fb43 --- /dev/null +++ b/doc/src/sgml/release-4.6.sgml @@ -0,0 +1,2036 @@ + + Release 4.6.7 + + Release Date + 2026-06-04 + + + + Bug fixes + + + + + Allow pgproto to accept new line data. (Tatsuo Ishii) + + + Now "\n" is recognized as a new line. This is necessary for COPY command. + + + + + + + Keep local primary_node_id when leader watchdog reports the initial -2 sentinel. (Tatsuo Ishii) + + + Fix a watchdog synchronization issue after simultaneous restart of all pgpool nodes, + where standby nodes could overwrite a valid primary_node_id with the initial -2 sentinel + value and remain stuck in an uninitialized state indefinitely. Fix is, keep the local + primary_node_id when the leader reports the initial -2 sentinel. + + + Problem reported by Emond Papegaaij and Claude Code. + + + Discussion: Primary node detection race at clean startup + + + + + + + Fix to not call pool_get_transaction_isolation() in elog(DEBUG). (Tatsuo Ishii) + + + Fix a FATAL error in aborted transactions caused by DEBUG logging in + where_to_send_main_replica() and where_to_send_native_replication(). + The DEBUG logging called pool_get_transaction_isolation(), which internally executed queries + via do_query() and could raise a FATAL error in aborted transactions. Fix is, remove the calls from DEBUG logging. + + + + + + + Fix empty query case in aborted transaction. (Tatsuo Ishii) + + + Fix empty queries in aborted transactions incorrectly raising errors. + Empty queries should be allowed in aborted transactions, + but a previous commit caused check_transaction_state_and_abort() to reject them. + Fix is, detect empty queries in SimpleQuery() and bypass the check. + + + Problem reported by Ronaldo Raivil. + + + Discussion: pgpool >= 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + Fix description about ssl_dh_params_file. (Tatsuo Ishii) + + + It actually falls back to compiled-in default not only when the + parameter is empty (the default), but when specified parameter is + incorrect one. + + + + + + + Fix PCP main process to remember child pids upon restarting. (Tatsuo Ishii) + + + Upon failover/failback, pgpool main process sends a signal to PCP main + process to request restarting, and PCP main restarts. Problem is, when + PCP main restarts, it forgets the list of pids of its child PCP worker + process. + + As a result, commands such as pcp_promote_node could hang indefinitely. + Fix is, store PCP worker PIDs in shared memory so they survive PCP main restart. + + + Problem reported by Taiki Koshino. + + + Discussion: Problem with pcp process + + + + + + + Fix query cache to invalidate cache when MERGE statement is used. (Tatsuo Ishii) + + + MERGE was introduced in PostgreSQL 15 + and Pgpool-II 4.4 imported PostgreSQL 15's parser. + However, there was an oversight in query cache sub module: + MERGE statement did not trigger invalidation of query cache. + + + Problem reported by Nadav Shatz. + + + Discussion: Re: Proposal: Recent mutated table tracking in memory + + + + + + + Fix memory leak in a SSL module. (Tatsuo Ishii) + + + Fix a memory leak in load_dh_file() when invalid DH parameters are supplied. + The function failed to free memory returned by PEM_read_DHparams(). + Also update the copyright notice in the same file to retain the original PostgreSQL copyright. + + + Discussion: Memory leak in SSL module + + + + + + + Fix incorrect routing of SET transaction_read_only = 0. (Bo Peng) + + + Fix incorrect routing of SET transaction_read_only = 0 to standby node, which caused query errors. + Also replace incorrect bool ret = POOL_BOTH with the proper enum type. + + + Problem reported by liujinyang-highgo. + + + Discussion: set command 'set transaction_read_only = 0;' routed to standby node and execute failed. + + + + + + + Remove unnecessary check STREAM in where_to_send_main_replica(). (Tatsuo Ishii) + + + The check is already done in check_replication_delay(). + + + + + + + Fix session local relation cache case bug. (Tatsuo Ishii) + + + Fix incorrect handling of session local relation cache in pool_search_relcache(). + Temporary table information could be incorrectly registered in shared relation cache, causing subsequent queries + to use stale cache entries and potentially route queries incorrectly. + Fix is, avoid registering temp table information in shared relation cache for session local cache entries. + + + Discussion: query temp table is routed to standby node. + + + + + + + Fix lock release leak in pool_search_relcache(). (Tatsuo Ishii) + + + Fix a lock release leak in pool_search_relcache(). + During shared relation cache updates, the lock state was not reset correctly after reacquiring an exclusive lock, + which could leave the shared memory lock held. Also rename confusing variable locked to locked_by_others + and fix unnecessary per_node_statement_log output. + + + Discussion: Lock release leak in pool_search_relcache + + + + + + + Close listening sockets before forking. (Tatsuo Ishii) + + + Fix inherited unnecessary listening sockets in forked child processes. + Previously, subprocesses such as pcp_main, health check, + and lifecheck processes inherited pgpool and/or PCP listening sockets they did not use, + which could prevent subsequent pgpool startup from binding ports correctly. + Fix is, close unnecessary listening sockets after forking using close_listening_sockets(). + + + Discussion: Close listening socokets before forking + + + + + + + Documents + + + + + Doc: fix ignore_leading_white_space and allow_sql_comments docs. (Tatsuo Ishii) + + + They lacked a description on the default values. + + + + + + + Regression Tests + + + + + Test: addition to 001.load_balance test for previous commit. (Tatsuo Ishii) + + + + + + + + Release 4.6.6 + + Release Date + 2026-02-26 + + + + Changes + + + + + Allow parallel make. (Tatsuo Ishii) + + + Previously a parallel make failed with: + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + Patch is created by anthonyroussel and reviewed by Tatsuo Ishii. + + + Discussion: Fix parallel build + + + + + + + Add detail log about mismatch between and primary_conninfo host. (Taiki Koshino) + + + If the set in pgpool.conf does not match + the host setting in PostgreSQL's primary_conninfo, + the following log message will be output. + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + Explicitly stat supported minimum OpenSSL version. (Tatsuo Ishii) + + + That can be done in configure.ac by using + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + The supported minimum version is 1.0.2, which is identical to + PostgreSQL at this point. (Actually the AC_DEFINE is brought in from + PostgreSQL). Also this could avoid OpenSSL deprecation warnings if + your installed OpenSSL is new, like 3.0. + Moreover, add mention to installation document that required minimum + version of OpenSSL is 1.0.2. + + + + + + + Bug fixes + + + + + Fix oversight in check_transaction_state_and_abort(). (Tatsuo Ishii) + + + The function does not take the case when frontend is NULL into account. + + + Problem pointed out by Coverity. + + + + + + + Fix walker() functions to return earlier. (Tatsuo Ishii) + + + Previously walker() functions returned false once it found target + objects. But it is possible to short-circuit the traverse and it + should have been. + + Also import comments from PostgreSQL to clarify walker function + design. + + + Problem reported by liujinyang-highgo and reviewed by Tatsuo Ishii. + + + Discussion: Improper handling in the function view_walker(). + + + + + + + Fix memory leak in scram-sha-256 authentication. (Tatsuo Ishii) + + + Problem pointed out by Coverity. + + + + + + + Fix to check the return value of malloc(). (Tatsuo Ishii) + + + create_inet_domain_sockets() forgot to check the return value of + malloc() while allocating memory for socket fds. + + + + + + + Fix health check process to not start. (Tatsuo Ishii) + + + Previously pgpool_main() did not start a health check process if the + backend node is down. This prevented auto_failback from working. + Pgpool reads status from pool_status file when option is not + present. If the status recorded in the file is "down", pgpool will + not start health check process for the node. Since auto_failback is + invoked from health check process, this means that auto_failback does + not work for the backend node. + + Fix is, unconditionally start health check process. + + + Problem reported by Meng Feilong and reviewed by Tatsuo Ishii. + + + Discussion: Nodes in the down state cannot failback + + + + + + + Fix duplicate NodeTag enum in nodes.h. (Tatsuo Ishii) + + + Fixed the duplication between NodeTag definitions in nodes.h imported from PostgreSQL and Pgpool-II's own definitions. + + + Problem reported and diagnosed by liujinyang-highgo and reviewed by Tastuo Ishii. + + + Discussion: an issue about NodeTag definition. + + + + + + + Fix resource leak in pcp_connect(). (Tatsuo Ishii) + + + The function did not call freeaddrinfo() in some places. + + + + + + + Fix possible integer overflow. (Tatsuo Ishii) + + + In pool_write_flush() and pool_flus_it() write(2) is used. write(2) + returns ssize_t and in the code there are some places where the return + value was assigned to an int variable. As a result it was possible + that the return value was evaluated to negative value, which led to an + error. + + + + + + + + Release 4.6.5 + + Release Date + 2025-12-15 + + + + Changes + + + + + Use "grep -E" instead of deprecated "egrep" in pgpool_setup. (Bo Peng) + + + Replace "egrep" with "grep -E" to avoid obsolescence warnings on newer GNU grep versions. + + + + + + + Bug fixes + + + + + Fix buffer overflow error in show pool_status. (Tatsuo Ishii) + + + "show pool_status", "pgpool show" and pcp_pool_status could cause a + buffer overflow error. If backend_flag is set to "ALWAYS_PRIMARY", + pool_flag_to_str(), which is responsible to produce printable format + of backend_flag, wrote data past to the end of static buffer. + + + Problem reported by zam bak and reviewed by Bo Peng. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + Fix memqcache_stats_start_time shown in "show pool_status". (Tatsuo Ishii) + + + get_config() uses ctime() to generate printable form of + memqcache_stats_start_time. But it did not take into account that + ctime() adds newline at the end of result. As a result, not only the + output of memqcache_stats_start_time was with unnecessary newline but + next row printed empty items. + + + Discussion: Re: "buffer overflow detected" when running SHOW POOL_STATUS + + + + + + + Regression Tests + + + + + Test: stabilize 037.failover_session. (Tatsuo Ishii) + + + On some platform (in my case Rocky Linux 10 running on VitualBox) + fails to finish shutdownall after test1. This could be caused by the + failover in the test to fail to restore the signal handler which + should accept shutdown signal from shutdownall. Adding "sleep 5" + before shutdownall seems to mitigate the problem. + + + + + + + + Release 4.6.4 + + Release Date + 2025-11-25 + + + + Changes + + + + + Remove unnecessary application_name treatment. (Tatsuo Ishii) + + + A previous commit added a step to set application_name when reusing existing connections. + However, this is unnecessary because DISCARD ALL automatically resets application_name, + and send_params() already sends all necessary parameter status messages, including application_name, to the frontend. + Removing this redundant step also improves performance, particularly for backend nodes that are geographically distant. + + + Discussion: Severely degraded performance of pgPool in geo-distributed configurations + + + + + + + Make time calculations always long long. (Tatsuo Ishii) + + + Previously, Pgpool-II treated time_t as a simple long, which caused compile-time warnings on some systems, + such as OpenBSD, where time_t is __int64. This change upcasts the calculations to long long, + preventing truncation and ensuring pgpool continues to work correctly after Y2038 on 64-bit clean time_t systems. + Additionally, json_get_long_value_for_key has been changed to json_get_llong_value_for_key + with a long long parameter, aligning it with _json_value's int64 type. This improves + integer handling on 32-bit platforms and helps avoid potential integer overflow issues. + + + Problem analyzed by Tatsuo Ishii and Gyorgy Sarvari. + + + Discussion: Fix time_t warnings on OpenBSD + + + Discussion: Fix time_t warnings on OpenBSD + + + Discussion: fix compiling issues for 32-bit targets + + + + + + + Allow to compile against gcc 15 (C23). (Tatsuo Ishii) + + + This change includes several fixes to compile Pgpool-II on Fedora 42 with gcc 15 (C23). + It updates pool_type.h to use stdbool.h and defines TRUE/FALSE as (bool) 1/0, aligning with C99 standards. + Function pointer arguments were corrected to match their prototypes, + and pool_create_relcache()'s prototype was updated. + Calls to walker() in raw_expression_tree_walker() were adjusted to cast the first argument to (Node *) via the WALK macro. + Note that OpenSSL warnings on Fedora 42 remain and will be addressed in the future. + + + Discussion: 4.6.X build issue against GCC 15 + + + + + + + Bug fixes + + + + + Fix segfault with CopyOut. (Tatsuo Ishii) + + + When COPY relname TO STDOUT is executed in the extended query + protocol mode, pgpool segfaulted. + + + This problem is reported by https://github.com/tetesh. + + + Discussion: datanymizer and pg-pool segmentation fault + + + + + + Prevent watchdog split-brain scenario in some corner cases. (Tatsuo Ishii) + + + Watchdog uses both beacon messages and heartbeat for communication. + If the heartbeat is not yet active, missing beacon messages + for over 30 seconds can cause a split-brain scenario, + where the old leader remains active while a new leader is elected. + This change prevents two leaders from existing simultaneously by revoking the old leader. + When a node detects that it has missed beacon messages from the leader more than twice, + the leader is set to LOST and a new leader election is triggered via set_state(WD_JOINING). + + + + + + + Prevent FATAL error when non-existing prepared statement is given. (Tatsuo Ishii) + + + Previously, Bind() raised a FATAL error when a non-existing prepared statement was used, unlike PostgreSQL. + This change changes Bind() to check for the statement's existence and send an ERROR message to the frontend if it does not exist. + Note that no log is written, as logging this is not currently possible. + + + + + + + Fix not working if both -p and -P are provided. (Tatsuo Ishii) + + + The original report showed that running pg_enc -p -P prompted for a password and encryption key, + but failed if the key was not provided. + + + Discussion: pg_enc + + + + + + + Fix compiling issue on 32-bit environments. (Tatsuo Ishii) + + + On 32-bit systems, compiling src/parser/snprintf.c fails due to undefined functions isnan() and isinf(), which come from math.h. + This change includes math.h and also reorders the include files for clarity. + The file was originally imported from PostgreSQL, where math.h was already included. + This fix was provided via pull request: https://github.com/pgpool/pgpool2/pull/128 + + + Discussion: Compiling issues for 32-bit targets + + + + + + + Fix safer directory deletion in Bash in recovery_1st_stage.sample. (Taiki Koshino) + + + Quote variables in rm commands to avoid accidental deletion: + rm -rf "${DEST_NODE_PGDATA}" + + If the variable is empty, rm could delete unexpected files or directories. + + + + + + + Fix point less warning in query cache invalidation. (Tatsuo Ishii) + + + When memcached support is disabled, query cache invalidation by query + emitted point less warning. This makes 006.memcached regression test + failed. + + + + + + + Fix the compilation error when building without the option. (Tatsuo Ishii) + + + A compiler error occurred when configuring without . + The issue arose because the compiler could not determine that ptr would only be freed when memcached is enabled. + To fix this, the relevant code block was wrapped with #ifdef USE_MEMCACHED. + + + Problem reported by Bo Peng. + + + + + + Fix query cache lock file handling. (Tatsuo Ishii) + + + The query cache module creates a lock file in logdir for concurrency control, + but two bugs existed: the main pgpool process could create a stray "QUERY_CACHE_LOCK_FILE", + and the lock file was not removed on shutdown. This change fixes both issues. + + + Problem reported and analyzed by Bo Peng. + + + + + + + Documents + + + + + Update doc about "Setting up PostgreSQL standby" in 8.2. Pgpool-II + Watchdog Setup Example. (Taiki Koshino) + + + Add a note that when setting up a standby without online recovery, do not write primary_conninfo to postgresql.auto.conf. + + + Discussion: Follow primary command not fixing postgresql.auto.conf + + + + + + + Fix watchdog_setup manual. (Tatsuo Ishii) + + + It mistakenly stated that heartbeart is not setup in watchdog_setup. + + + + + + + Regression Tests + + + + + Adapt 023.ssl_connection to PostgreSQL 18. (Tatsuo Ishii) + + + PostgreSQL 18 heavily changed psql's \conninfo output format, which + made the test fail because the test relies on \conninfo. This change + makes the test script aware the PostgreSQL version to fix the issue. + + + + + + + Unbreak 039.log_backend_messages. (Tatsuo Ishii) + + + Commit 8ff2b9f6e mistakenly put synchronous commit parameters in + pgpool.conf. Unbreak the test by putting the parameters in + postgresql.conf. Also check if clustering mode is streaming + replication. Because that parameters causes suspends PostgreSQL if + clustering mode is other than streaming replication. + + + + + + + Stabilize 039.log_backend_messages test. (Tatsuo Ishii) + + + In the test a query is sent to standby server right after rows are + inserted into primary server. Due to a replication lag, the inserted + rows could not be found on the standby in slower machines. This + change tries to fix the issue by using synchronous replication with + remote_apply option. + + + + + + + Fix ruby script in 010.rewrite_timestamp. (Tatsuo Ishii) + + + The ruby script used "File.exists", which is said to be obsoleted in + newer version of Ruby. Replace it with "File.exist". + + + + + + + Tweak timeout in 034 and 075 tests. (Tatsuo Ishii) + + + 034.promote_node and 075.detach_primary_left_down_node set the timeout + 60 seconds for finishing follow primary script. It turns out that + these timeout values are not long enough, and sometimes caused false + errors. So make them from 60 seconds to 120 seconds. + + + + + + + Add ssl_ecdh_curve test to 023.ssl_connection. (Tatsuo Ishii) + + + 023.ssl_connection did not cover the test for ssl_ecdh_curve. This + commit tests it using bad ssl_ecdh_curve parameter to see if connection + between frontend and pgpool fails. + + + + + + + + Release 4.6.3 + + Release Date + 2025-08-21 + + + + Changes + + + + + Enhance connecting process to backend. (Tatsuo Ishii) + + + In certain environment (especially k8s), DNS look up is unstable and + connecting to backend process fails. This occurs in call to + getaddrinfo() in connect_inet_domain_socket_by_port(). To enhance the + situation, retry up to 5 times (at each retry, sleep 1 second) if + getaddrinfo() fails with EAI_AGAIN. Note that if + connect_inet_domain_socket_by_port() is called with "retry" argument + is false, the retry will not happen. Health check calls + connect_inet_domain_socket_by_port() with the retry flag to false so + that retrying is controlled health check's own parameters. + + + Discussion: A single DNS lookup failure will trigger backend failover + + + + + + + Bug fixes + + + + + Fix watchdog to print inappropriate NOTICE message. (Tatsuo Ishii) + + + read_ipc_socket_and_process() printed a notice message every time when + it wrote commands to IPC socket even if it was successful. Fix this to + print the notice message only when the write failed. + + The reason why this bug was not recognized is, the message appears + only when log_min_messages is set to notice or higher. + + + Discussion: pgpool IPC socket connection issue + + + + + + + + Fix resource leak while reading startup packet. (Tatsuo Ishii) + + + Fix resource leak in pool_push_pending_data. + + + + + + + Fix broken scram-sha-256 authentication on big-endian machines. (Tatsuo Ishii) + + + When scram-sha-256 authentication is performed, a hash function + pg_sha_256_final is used. It was imported from PostgreSQL and it uses + preprocessor define WORDS_BIGENDIAN to judge host machine's + endianness. Although WORDS_BIGENDIAN should be defined while + configure, this part was missed when pg_sha_256_final (and others) was + imported from PostgreSQL. As a result, scram-sha-256 worked only in + little endian machines. Fixed the issue by adding + AC_C_BIGENDIAN macro to configure.ac. + + + Problem reported by Christoph Berg and analyzed by pranavkaruvally. + + + Discussion: 4.6.1 fails on big-endian s390x: backend response with kind 'E' when expecting 'R' + + + + + + + Fix source code typos. (Bo Peng) + + + + + + + Fix heartbeat device treatment. (Tatsuo Ishii) + + + Fix wd_create_hb_recv_socket() and wd_create_hb_send_socket() + to pass a null-terminated device name string to setsockopt(SO_BINDTODEVICE) + instead of incorrectly passing a struct ifreq. + + + Discussion: [pgpool-hackers: 4602] heartbeat and SO_BINDTODEVICE + + + + + + + Fix resource leak in hearbeat receiver process. (Tatsuo Ishii) + + + + + + + Fix heartbeat device treatment. (Tatsuo Ishii) + + + While processing pgpool.conf, heartbeat_device was mistakenly treated + and the first device was ignored. + + + Problem analyzed by Bo Peng. + + + + + + + Fix heartbeat receiver not working. (Tatsuo Ishii) + + + IPv6 support for heartbeat was added in version 4.6, + but the receive process mistakenly bound only to loopback addresses, + preventing reception from other nodes. + Adding the AI_PASSIVE flag to getaddrinfo() fixes this by binding to all network interfaces. + + + Problem analyzed by Bo Peng. + + + + + + + Fix typo in the comments of pgpool.conf. (Tatsuo Ishii) + + + + + + + Documents + + + + + Enhance "8.3. Replication Mode and Snapshot Isolation Mode Configuration Example" Document. (Taiki Koshino) + + + Updated the link to the example script and the explanation in the "8.3.3. Before you begin" section. + + + + + + + Fix documentation for parameters that are not reflected by reload. (Taiki Koshino) + + + "authentication_timeout" and "memqcache_oiddir" is not reflected by reload. + The documentation is changed to "This parameter can only be set at server start.". + + + + + + + + Unify watchdog leader terms (followup). (Tatsuo Ishii) + + + + + + + + Fix example script link. (Taiki Koshino) + + + Modified the sample script in the section "8.2. Pgpool-II + Watchdog Setup Example" + + + + + + + Fix load balance explanation missed logical replication mode and Slony mode. (Tatsuo Ishii) + + + + + + + Enhance document. (Bo Peng) + + + Clarify that each backend_application_nameX must match the value specified + in the application_name of primary_conninfo to correctly display + "replication_state" and "replication_sync_state". + + + + + + + Add section of kernel resources. (Tatsuo Ishii) + + + Pgpool-II uses System V shared memory and semaphores. It's better to + describe the requirements in the docs. + + + + + + + Add description for option of configure. (Tatsuo Ishii) + + + It was missed when LDAP support was introduced in v4.2 + + + + + + + Fix command in "8.2. Pgpool-II + Watchdog Setup Example" to escape $PGDATA. (Bo Peng) + + + + + + + Clarify supported platforms for Pgpool-II. (Tatsuo Ishii) + + + + + + + Enhance document. (Tatsuo Ishii) + + + + + + + Regression Tests + + + + + Stabilize 029.cert_passphrase regression test. (Tatsuo Ishii) + + + When ssl_passphrase_command is not valid, the error message is + typically "bad decrypt" but it seems sometimes "wrong tag". + + + + + + + + Release 4.6.2 + Release Date + 2025-05-30 + + + + Changes + + + + + Suppress unnecessary information upon authentication failure. (Tatsuo Ishii) + + + Previously a message "password size does not match" was displayed when + client authentication failed. This could help an attacker to guess + password. Replace it just "password does not match". + + + + + + + Allow pcp clients to connect to IPv6 addresses. (Tatsuo Ishii) + + + We have already allowed pcp server to connect to IPv6 addresses, but + pcp clients were not allowed to connect to them until today. This + commit allows pcp clients to connect to IPv6 addresses. + + Discussion: [pgpool-general: 9481] Does pgpool 4.6.0 support pure ipv6 configuration? + + + + + + + Bug fixes + + + + + Fix watchdog receive socket creation without IPv6. (#99) (Tatsuo Ishii) + + + When IPv6 network is not available, it was possible that watchdog + process won't start. Previously wd_create_recv_socket() + issued elog(ERROR) if creation or handling IPv6 socket failed. + Unfortunately at the time when wd_create_recv_socket() + is called, the exception stack is not established, and elog happily + converts ERROR to FATAL, + which causes exiting watchdog process, thus exiting pgpool process. + To fix this, the elog(ERROR) calls are changed to elog(LOG). + + + + + + + + Release 4.6.1 + + Release Date + 2025-05-15 + + + + Overview + + This release contains a security fix. + + + An authentication bypass vulnerability exists in the client authentication + mechanism of Pgpool-II. + In Pgpool-II, authentication may be bypassed even + when it is supposed to be enforced. As a result, an attacker could log in as + any user, potentially leading to information disclosure, data tampering, or + even a complete shutdown of the database. (CVE-2025-46801) + + + This vulnerability affects systems where the authentication configuration + matches one of the following patterns: + + + + + Pattern 1: This vulnerability occurs when all of the following conditions are met: + + + + + The password authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is not set in pool_passwd + + + + + The scram-sha-256 or md5 authentication + method is used in pg_hba.conf + + + + + + + + Pattern 2: This vulnerability occurs when all of the following conditions are met: + + + + + enable_pool_hba = off + + + + + One of the following authentication methods is used in pg_hba.conf: + password, pam, or ldap + + + + + + + + Pattern 3: This vulnerability occurs when all of the following conditions are met: + + + + + Raw mode is used (backend_clustering_mode = 'raw') + + + + + The md5 authentication method is used in + pool_hba.conf + + + + + allow_clear_text_frontend_auth = off + + + + + The user's password is registered in pool_passwd in plain + text or AES format + + + + + One of the following authentication methods is used in + pg_hba.conf: + password, pam, or ldap + + + + + + + All versions of Pgpool-II 4.0 and 4.1 series, 4.2.0 to 4.2.21, 4.3.0 to 4.3.14, + 4.4.0 to 4.4.11, 4.5.0 to 4.5.6 and 4.6.0 are affected by this vulnerability. + It is strongly recommended to upgrade to Pgpool-II + 4.6.1, 4.5.7, 4.4.12, 4.3.15 and 4.2.22 or later. + Alternatively, you can modify your settings so that they do not match any of + the vulnerable configuration patterns. + + + + + Changes + + + + + Add major version information to the configuration file. (Bo Peng) + + + + + + + Bug fixes + + + + + Fix incorrect client authentication in some cases. (Tatsuo Ishii) + + + If enable_pool_hba = on, it's auth method is "password", no + password is registered in pool_passwd, and auth method in + pg_hba.conf is "scram-sha-256" or "md5", for the first time when + a client connects to pgpool, authentication is performed as + expected. But if a client connects to the cached connection, any + password from the client is accepted. + + + Also if enable_pool_hba = off, in some cases a client is not + asked password for the first time, or when a client connects to + cached connection, even if it should be. + + + In addition to fixing above, following changes are made: + + + + + Remove single PostgreSQL code path to simplify the authentication code. + + + + + Remove crypt authentication support for frontend and + backend. The feature had not been documented and never + tested. Moreover crypt authentication was removed long time + ago in PostgreSQL (8.4, 2009). + + + + + Add new regression test "040.client_auth". The test performs + exhaustive client authentication tests using a test + specification file formatted in CSV. + + + + + + + + Fix long standing bind bug with query cache. (Tatsuo Ishii) + + + When a named statement is prepared, it is possible to bind then execute without a parse message. + Problem is, table oids which are necessary to invalidate query cache at execute or COMMIT was + collected only in parse messages process (Parse()). Thus if bind is executed + without parse after previous execute, no table oids were collected, and pgpool failed to invalidate query cache. + Fix is collecting table oids at bind time too. + Add regression test to 006.memqcache. + + + Problem reported by and test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix query cache invalidation bug. (Tatsuo Ishii) + + + When an execute message is received, pgpool checks its max number of rows paramter. If it's not zero, + pgpool sets "partial_fetch" flag to instruct pool_handle_query_cache() to not create query cache. + Problem is, commit 2a99aa5d1 missed that even INSERT/UPDATE/DELETE sets the execute message parameter to non 0 (mostly 1) + and pgpool set the flag for even none SELECTs. This resulted in failing to invalidate query cache because if the flag is true, + subsequent code in pool_handle_query_cache() skips cache invalidation. + To fix this change Execute() to check if the query is read only SELECT before setting the flag. + Also add test to 006.memqcache. + + + Problem reported by and a test program provided by Achilleas Mantzios. + + + Discussion: [pgpool-general: 9427] Clarification on query results cache visibility + + + + + + + Fix portability to OpenBSD. (Tatsuo Ishii) + + + Discussion: [pgpool-hackers: 4582] Make pgpool build on OpenBSD + + + The patch was created by Martijn van Duren. + + + + + + Fix json_writer did not properly encode special characters. (Bo Peng) + + + Pgpool-II would crash when the watchdog was enabled if contained special characters (e.g., a backslash). + + + The patch was created by Martijn van Duren and slightly modified by Bo Peng. + + + + + + + Fix sr check and health check to reopen upon reload. (Tatsuo Ishii) + + + The streaming replication check and health check process forgot to + reopen upon reload. If or + is empty string, the password is obtained from + . Thus those process read outdated content of + upon reload. + + + + + + + Fix heartbeat processes issue in the system where IPv6 is disabled. (#99) (Tatsuo Ishii) + + + From Pgpool-II4.6.0, heartbeat process can handle IPv6 receiver + sockets. However, the process does not work normally if IPv6 is + disabled in the system. Like Pgpool-II main process and PostgreSQL, I + think it should work normally if IPv4 is available. + + + Discussion: [pgpool-hackers: 4578] Fix IPv6 in heatbeat + + + + + + + Documents + + + + + Enhance query cache doc. (Tatsuo Ishii) + + + Pgpool refuses to cache a query calling functions returning TIMESTAMP + WITH TIMEZONE, TIME WITH TIMEZONE. If there are multiple functions + having same name and one of them returns TIMESTAMP WITH TIMEZONE, TIME + WITH TIMEZONE, pgpool refuses to cache even if one of them does not + return the data types. So add a note on this along with workaround. + + + + + + Enhance the description on (Tatsuo Ishii) + + + is a config value to determine the life time of + cached connections to PostgreSQL backend. Current document lacks a + description that the expiration calculation is actually done at the + time when the client disconnects to the process which holds the cached + connections. + + + Discussion: [pgpool-hackers: 4577] Doc: enhance the description on connection_life_time + + + + + + + Enhance the explanation on . (Tatsuo Ishii) + + + It must be a superuser or in the pg_monitor group. + + + + + + + Regression Tests + + + + + Allow regression tests to use multiple socket directories. (Taiki Koshino, Tatsuo Ishii, Bo Peng) + + + + + + + + Release 4.6.0 + + Release Date + 2025-02-28 + + + + Overview + + This release adds convenient features for logging and + administration of Pgpool-II. Now you can + rotate log without restarting or sending a signal + to Pgpool-II by using new PCP + command. related parameters + can be changed by reloading of the configuration file. Also new PC + commands are added to invalidate query cache without + restarting Pgpool-II. Another features + for query cache are forcing to create a query cache entry and + removing particular query cache entry. New configuration parameter + allows to log messages + from backend for easier analysis of communication + between Pgpool-II + and PostgreSQL. The SQL parser is + updated to sync with the latest PostgreSQL + 17 version as usual. Finally now you can use IPv6 for + watchdog's hostname and heartbeat_hostname parameter. + + + + Major enhancements are as follows: + + + + + + + New PCP command to trigger log rotation. + + + + + + Allow related parameters to be changed by reloading. + + + + + + New PCP command to invalidate query cache. + + + + + + Allow to force to + create query + cache + + + + + + New PGPOOL SET CACHE DELETE command. + + + + + + New configuration parameter . + + + + + + Import PostgreSQL 17's SQL parser. + + + + + + Add IPv6 support for watchdog + and parameter. + + + + + + + + Migration to Version 4.6 + + + + + The default values of , , + + and are changed from + 'noboy' to '' (empty string). You need to set them in + 4.6. Otherwise you will get an error. + + + + + + Ignore leading/trailing spaces in string list type configuration + parameters, for + example, + and . + + + + + + The following log messages appear when a child process exits due + to + or . Downgrade them to + DEBUG1 because they are normal messages. + + reaper handler + reaper handler: exiting normally + + + + + + + + + Changes + + + + + + Add to trigger log rotation. (Bo Peng) + + + + + + + Allow related parameters + to be changed by reloading + the Pgpool-II configurations. (Bo + Peng) + + + The following related + parameters can now be changed by reloading: + + + + log_truncate_on_rotation + + + + + log_directory + + + + + log_filename + + + + + log_rotation_age + + + + + log_rotation_size + + + + + log_file_mode + + + + + + + + + + Add to invalidate + query cache. (Tatsuo Ishii) + + + + + + + Add PGPOOL SET CACHE + DELETE command to invalidate specified query cache entry. + (Tatsuo Ishii) + + + + + + + Add new configuration + parameter to log + protocol messages from each backend. (Tatsuo Ishii) + + + + + + + Import PostgreSQL 17 RC1 new parser. (Bo Peng) + + + Major changes of PostgreSQL 17 parser include: + + +- Allow MERGE to use NOT MATCHED BY SOURCE and RETURNING clause: + + MERGE INTO ... WHEN NOT MATCHED BY SOURCE ... + MERGE INTO ... RETURNING ... + +- Add new COPY option ON_ERROR ignore and LOG_VERBOSITY: + + COPY ... WITH (ON_ERROR ignore); + COPY ... WITH (LOG_VERBOSITY verbose); + +- Allow to use '*' to specify the COPY FROM options FORCE_NOT_NULL and FORCE_NULL for all columns. + + COPY ... WITH (FORCE_NOT_NULL *); + COPY ... WITH (FORCE_NULL *); + +- Add EXPLAIN option SERIALIZE and MEMORY + + EXPLAIN (MEMORY) ... + EXPLAIN (ANALYZE, SERIALIZE ...) ... + +- Allow ALTER TABLE to use SET STATISTICS DEFAULT to set a column to the default statistics target + + ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DEFAULT; + +- Allow ALTER TABLE to change a column's generation expression + + ALTER TABLE ... ALTER COLUMN ... SET EXPRESSION; + +- Add DEFAULT setting for ALTER TABLE .. SET ACCESS METHOD + + ALTER TABLE ... SET ACCESS METHOD new_access_method DEFAULT; + +- Allow event triggers to use login event: + + CREATE EVENT TRIGGER ... ON login ... + +- Add event trigger support for REINDEX. + + + + + + + + Add IPv6 support for and parameter. (Kwangwon Seo) + + + + + + + Ignore leading/trailing spaces in string list type configuration parameters. (Bo Peng) + + + If the string list type configuration parameters + (e.g. , , + etc.) contain white spaces, it may cause startup failure. + + + + + + + Downgrade reaper handler logs. (Bo Peng) + + + The following log messages appear when a child process exits due + to settings (e.g., child_life_time or child_max_connections) . + Downgrade them to DEBUG1 because they are normal messages. + + reaper handler + reaper handler: exiting normally + + + + + + + + Eliminate unnecessary memory allocation in extended query protocol. (Tatsuo Ishii) + Note this is only releated to streaming replication mode. + + + + + + + + Bug fixes + + + + This release fixes the same bugs as other minor releases. + See for more details of those fixes. + + + + + + diff --git a/doc/src/sgml/release-4.7.sgml b/doc/src/sgml/release-4.7.sgml new file mode 100644 index 000000000..16037c47d --- /dev/null +++ b/doc/src/sgml/release-4.7.sgml @@ -0,0 +1,1134 @@ + + Release 4.7.2 + + Release Date + 2026-06-04 + + + + Bug fixes + + + + + Allow pgproto to accept new line data. (Tatsuo Ishii) + + + Now "\n" is recognized as a new line. This is necessary for COPY command. + + + + + + + Keep local primary_node_id when leader watchdog reports the initial -2 sentinel. (Tatsuo Ishii) + + + Fix a watchdog synchronization issue after simultaneous restart of all pgpool nodes, + where standby nodes could overwrite a valid primary_node_id with the initial -2 sentinel + value and remain stuck in an uninitialized state indefinitely. Fix is, keep the local + primary_node_id when the leader reports the initial -2 sentinel. + + + Problem reported by Emond Papegaaij and Claude Code. + + + Discussion: Primary node detection race at clean startup + + + + + + + Fix to not call pool_get_transaction_isolation() in elog(DEBUG). (Tatsuo Ishii) + + + Fix a FATAL error in aborted transactions caused by DEBUG logging in + where_to_send_main_replica() and where_to_send_native_replication(). + The DEBUG logging called pool_get_transaction_isolation(), which internally executed queries + via do_query() and could raise a FATAL error in aborted transactions. Fix is, remove the calls from DEBUG logging. + + + + + + + Fix empty query case in aborted transaction. (Tatsuo Ishii) + + + Fix empty queries in aborted transactions incorrectly raising errors. + Empty queries should be allowed in aborted transactions, + but a previous commit caused check_transaction_state_and_abort() to reject them. + Fix is, detect empty queries in SimpleQuery() and bypass the check. + + + Problem reported by Ronaldo Raivil. + + + Discussion: pgpool >= 4.3.2 synthesizes 25P02 on driver health-check probes inside aborted savepoints, breaking ORMs that need to call ROLLBACK TO SAVEPOINT + + + + + + + Fix description about ssl_dh_params_file. (Tatsuo Ishii) + + + It actually falls back to compiled-in default not only when the + parameter is empty (the default), but when specified parameter is + incorrect one. + + + + + + + Fix PCP main process to remember child pids upon restarting. (Tatsuo Ishii) + + + Upon failover/failback, pgpool main process sends a signal to PCP main + process to request restarting, and PCP main restarts. Problem is, when + PCP main restarts, it forgets the list of pids of its child PCP worker + process. + + As a result, commands such as pcp_promote_node could hang indefinitely. + Fix is, store PCP worker PIDs in shared memory so they survive PCP main restart. + + + Problem reported by Taiki Koshino. + + + Discussion: Problem with pcp process + + + + + + + Fix query cache to invalidate cache when MERGE statement is used. (Tatsuo Ishii) + + + MERGE was introduced in PostgreSQL 15 + and Pgpool-II 4.4 imported PostgreSQL 15's parser. + However, there was an oversight in query cache sub module: + MERGE statement did not trigger invalidation of query cache. + + + Problem reported by Nadav Shatz. + + + Discussion: Re: Proposal: Recent mutated table tracking in memory + + + + + + + Fix memory leak in a SSL module. (Tatsuo Ishii) + + + Fix a memory leak in load_dh_file() when invalid DH parameters are supplied. + The function failed to free memory returned by PEM_read_DHparams(). + Also update the copyright notice in the same file to retain the original PostgreSQL copyright. + + + Discussion: Memory leak in SSL module + + + + + + + Fix incorrect routing of SET transaction_read_only = 0. (Bo Peng) + + + Fix incorrect routing of SET transaction_read_only = 0 to standby node, which caused query errors. + Also replace incorrect bool ret = POOL_BOTH with the proper enum type. + + + Problem reported by liujinyang-highgo. + + + Discussion: set command 'set transaction_read_only = 0;' routed to standby node and execute failed. + + + + + + + Remove unnecessary check STREAM in where_to_send_main_replica(). (Tatsuo Ishii) + + + The check is already done in check_replication_delay(). + + + + + + + Fix session local relation cache case bug. (Tatsuo Ishii) + + + Fix incorrect handling of session local relation cache in pool_search_relcache(). + Temporary table information could be incorrectly registered in shared relation cache, causing subsequent queries + to use stale cache entries and potentially route queries incorrectly. + Fix is, avoid registering temp table information in shared relation cache for session local cache entries. + + + Discussion: query temp table is routed to standby node. + + + + + + + Fix lock release leak in pool_search_relcache(). (Tatsuo Ishii) + + + Fix a lock release leak in pool_search_relcache(). + During shared relation cache updates, the lock state was not reset correctly after reacquiring an exclusive lock, + which could leave the shared memory lock held. Also rename confusing variable locked to locked_by_others + and fix unnecessary per_node_statement_log output. + + + Discussion: Lock release leak in pool_search_relcache + + + + + + + Close listening sockets before forking. (Tatsuo Ishii) + + + Fix inherited unnecessary listening sockets in forked child processes. + Previously, subprocesses such as pcp_main, health check, + and lifecheck processes inherited pgpool and/or PCP listening sockets they did not use, + which could prevent subsequent pgpool startup from binding ports correctly. + Fix is, close unnecessary listening sockets after forking using close_listening_sockets(). + + + Discussion: Close listening socokets before forking + + + + + + + Downgrade debug log used in pcp_proc_info and show pool_pools etc. (Tatsuo Ishii) + + + Debug logs accidentally added by previous commit are downgraded from + LOG to DEBUG5. + + + + + + + Documents + + + + + Doc: fix ignore_leading_white_space and allow_sql_comments docs. (Tatsuo Ishii) + + + They lacked a description on the default values. + + + + + + + Regression Tests + + + + + Test: addition to 001.load_balance test for previous commit. (Tatsuo Ishii) + + + + + + + + Release 4.7.1 + + Release Date + 2026-02-26 + + + + Changes + + + + + Add parameters to specify the watchdog/heartbeat listen address and port. (Taiki Koshino) + + + By specifying and , + watchdog will listen only on the specified address and port. + You can also now specify the listening port for the heartbeat process using + and . + + + Discussion: Re: Pgpool-II 4.7.0 released. + + + + + + + Allow parallel make. (Tatsuo Ishii) + + + Previously a parallel make failed with: + +In file included from parser.c:27: +../../src/include/parser/gramparse.h:33:10: fatal error: gram.h: No such file or directory +33 | #include "gram.h" + + + + Patch is created by anthonyroussel and reviewed by Tatsuo Ishii. + + + Discussion: Fix parallel build + + + + + + + Add detail log about mismatch between and primary_conninfo host. (Taiki Koshino) + + + If the set in pgpool.conf does not match + the host setting in PostgreSQL's primary_conninfo, + the following log message will be output. + +sr_check_worker pid 25099: DETAIL: pgpool.conf backend_hostname: "pgpool0" does not match PostgreSQL primary_conninfo host: "pgpool_logtest" + + + + + + + Explicitly stat supported minimum OpenSSL version. (Tatsuo Ishii) + + + That can be done in configure.ac by using + +AC_DEFINE(OPENSSL_API_COMPAT, [0x10002000L], + [Define to the OpenSSL API version in use. This avoids deprecation warnings from newer OpenSSL versions.]) + + + The supported minimum version is 1.0.2, which is identical to + PostgreSQL at this point. (Actually the AC_DEFINE is brought in from + PostgreSQL). Also this could avoid OpenSSL deprecation warnings if + your installed OpenSSL is new, like 3.0. + Moreover, add mention to installation document that required minimum + version of OpenSSL is 1.0.2. + + + + + + Rename libpcp to libpgpoolpcp to avoid conflict with RHEL PCP library. (Bo Peng) + + + The libpcp.so library provided by Pgpool-II conflicts with + libpcp.so shipped by RHEL. + To avoid this conflict, the Pgpool-II libpcp library has been renamed + to libpgpoolpcp. + + + Discussion: Installing pgpool-II fails due to naming conflict with RHEL provided library + + + + + + + Bug fixes + + + + + Fix startup failure when neither logdir nor is configured. (Taiki Koshino) + + + Problem reported by Luca Ferrari and reviewed by Taiki Koshino. + + + Discussion: work_dir and/or logdir not set to default on 4.7 ? + + + + + + + Fix oversight in check_transaction_state_and_abort(). (Tatsuo Ishii) + + + The function does not take the case when frontend is NULL into account. + + + Problem pointed out by Coverity. + + + + + + + Fix walker() functions to return earlier. (Tatsuo Ishii) + + + Previously walker() functions returned false once it found target + objects. But it is possible to short-circuit the traverse and it + should have been. + + Also import comments from PostgreSQL to clarify walker function + design. + + + Problem reported by liujinyang-highgo and reviewed by Tatsuo Ishii. + + + Discussion: Improper handling in the function view_walker(). + + + + + + + Fix memory leak in scram-sha-256 authentication. (Tatsuo Ishii) + + + Problem pointed out by Coverity. + + + + + + + Fix to check the return value of malloc(). (Tatsuo Ishii) + + + create_inet_domain_sockets() forgot to check the return value of + malloc() while allocating memory for socket fds. + + + + + + + Fix health check process to not start. (Tatsuo Ishii) + + + Previously pgpool_main() did not start a health check process if the + backend node is down. This prevented auto_failback from working. + Pgpool reads status from pool_status file when option is not + present. If the status recorded in the file is "down", pgpool will + not start health check process for the node. Since auto_failback is + invoked from health check process, this means that auto_failback does + not work for the backend node. + + Fix is, unconditionally start health check process. + + + Problem reported by Meng Feilong and reviewed by Tatsuo Ishii. + + + Discussion: Nodes in the down state cannot failback + + + + + + + Fix duplicate NodeTag enum in nodes.h. (Tatsuo Ishii) + + + Fixed the duplication between NodeTag definitions in nodes.h imported from PostgreSQL and Pgpool-II's own definitions. + + + Problem reported and diagnosed by liujinyang-highgo and reviewed by Tastuo Ishii. + + + Discussion: an issue about NodeTag definition. + + + + + + + Fix resource leak in pcp_connect(). (Tatsuo Ishii) + + + The function did not call freeaddrinfo() in some places. + + + + + + + Fix possible integer overflow. (Tatsuo Ishii) + + + In pool_write_flush() and pool_flus_it() write(2) is used. write(2) + returns ssize_t and in the code there are some places where the return + value was assigned to an int variable. As a result it was possible + that the return value was evaluated to negative value, which led to an + error. + + + + + + + + Release 4.7.0 + + Release Date + 2025-12-23 + + + + Overview + + This release of Pgpool-II includes several enhancements, + such as the removal of the legacy Slony mode, strengthened security, + enhanced frontend/backend protocol compatibility, and improved operational + transparency. + + + + Major enhancements are as follows: + + + + + + + Retire Slony mode. + + + + + + Rename logdir parameter to work_dir. + + + + + + Add support for frontend/backend protocol version 3.2. + + + + + + Enhance security for watchdog and heartbeat receiver. + + + + + + Add new fields to pcp_proc_info and + show pool_pools to display client information, + and add pgpool_adm_pcp_proc_info extension function. + + + + + + Make online recovery database configurable. + + + + + + Import PostgreSQL 18's SQL parser. + + + + + + + + Migration to Version 4.7 + + + + + + Retire Slony mode. (Tatsuo Ishii) + + + Previously Pgpool-II accepted slony + mode as one of the to support + Slony-I + (https://www.slony.info/). However the latest Slony-I was + released in 2022, nearly 3 years ago at this point. And we heard nothing from + users about retiring Slony mode. This suggests that there + would be no active Slony-I mode users. + So let's drop Slony-I support. + + + Discussion: [pgpool-general: 9486] Retiring slony mode + + + Discussion: https://www.postgresql.org/message-id/20250722.153130.1007226654125839063.ishii%40postgresql.org + + + + + + + Change default to off. (Tatsuo Ishii) + + + Previously log_pcp_processes default was on, + and it could produce excessive log lines if admins use pcp commands frequently to + monitor pgpool status. Also the log is kind of debugging message, thus it is + best to change its default value to off. + + + Discussion: https://www.postgresql.org/message-id/20250815.111100.2261166502134199972.ishii%40postgresql.org + + + + + + Make online recovery database configurable. (Bo Peng) + + + A new configuration parameter + has been added to allow users to specify the database used for online recovery. + Previously, this value was hardcoded as template1. + The default is now set to postgres. + + + For users migrating from versions earlier than 4.6, compatibility can be + maintained by setting recovery_database = 'template1', + or by creating the necessary extension for online recovery in the + postgres database. + + + + + + Rename logdir parameter to . (Taiki Koshino) + + + Previously, the directory for storing pgpool_status and + lock files was specified by the logdir parameter. + However, since the name logdir was misleading, the parameter + has been renamed to work_dir for clarity. + The default value is /tmp, which is the same as the + previous parameter logdir. + + + For backward compatibility, the old logdir parameter + is still supported. If the old parameter logdir is used, + Pgpool-II will set its value to + work_dir and throw a warning message. + + + + + + + Changes + + + + + + Import PostgreSQL 18 new parser. (Bo Peng) + + + Major changes of PostgreSQL 18 parser include: + + + + + Allow generated columns to be virtual + + + + + Add OLD/NEW support to RETURNING in DML queries + + + + + Addition of various constraints (e.g. WITHOUT OVERLAPS, ENFORCED / NOT ENFORCED) + + + + + etc. + + + + + + + + + Restrict watchdog and heartbeat receiver to listen only on configured addresses. (Bo Peng) + + + Previously, both the watchdog and heartbeat receiver processes + listen on all interfaces. + For security reasons, they now listen only on the addresses + specified by hostname and heartbeat_hostname. + + + + + + + Cleanup watchdog source code. (Tatsuo Ishii) + + + + + + Remove wd_is_upper_ok() from wd_utils.h because there's no actual + definition for it. + + + + + Make wd_get_ping_result() and wd_issue_ping_command() static. It's + only used in wd_ping.c. + + + + + + + + + + Emit warning if life check has not started yet. (Tatsuo Ishii) + + + Currently lifecheck emits a log only when life check becomes + ready. This is inconvenient for admins since they need to keep on + watching log file until life check is ready. This commit makes the + life check process to emit additional warnings periodically until life + check has started. The interval of the warnings is wd_interval * 10 + seconds. However for the first time at lifecheck starting, no warning + is emitted since it is likely that lifecheck is not ready at that + point. + + + + + + + Add support for frontend/backend protocol 3.2. (Tatsuo Ishii) + + + + + Implement NegotiateProtocolVersion message. + + + Implementing the message is necessary when frontend requests the + protocol version 3.2 (i.e. PostgreSQL 18+ or compatible clients), + while backend still only supports 3.0 (i.e. backend is PostgreSQL 17 + or before). + + + This commit handles the message so that the message is forwarded from + backend to frontend when there's no connection cache exists. + + + If connection cache exists, pgpool sends the message, which has been + saved at the time when the connection cache was created, to frontend. + + + Discussion: https://www.postgresql.org/message-id/20250708.112133.1324153277751075866.ishii%40postgresql.org + + + + + + Implement protocol version 3.2 BackendKeyData and query cancel message. + + + Starting from PostgreSQL 18, frontend/backend protocol has been + changed to 3.2. In the changes the BackendKeyData and query cancel + message are modified to allow variable length cancel key. + + + This commit implements the changes and now we can connect to + PostgreSQL frontend and backend using 3.2 protocol. + + +Example session is: +PGMAXPROTOCOLVERSION="3.2" psql -p 11000 test + + + Discussion: https://www.postgresql.org/message-id/20250714.155710.1706961744888449986.ishii%40postgresql.org + + + + + + + + + Add . (Tatsuo Ishii) + + + This commit adds new pgpool_adm extension function: + pcp_proc_info. Also add new fields: client_host, client_port and SQL + statement to pcp_proc_info and "show pool_pools". With these additions + now it is possible to track the relationship among clients of pgpool, + pgpool itself and PostgreSQL. + + + Moreover the commit allows to know what commands (statements) are last + executed by using pcp_proc_info. Previously it was not possible unless + looking into the pgpool log. + + + lipcp.so version is bumped from 2.0.0 to 3.0.0. + + + + + + + Enhance lifecheck log. (Tatsuo Ishii) + + + Previously when wd_lifecheck_method = 'query', life checking prints + SQL without application name if "%a" is specified in + log_line_prefix. This commit add application_name "lifecheck_ping" to + make the log looks better. Since this changes user visible behavior, + I do not apply this to stable branches. + + + Discussion: [pgpool-hackers: 4603] life check log is not nicea + + + + + + + Replace random() with pg_prng random function. (Martijn van Duren, Tatsuo Ishii) + + + Previously we used random() for choosing load balancing node. However + PostgreSQL has better random number generator: pg_prng.c. This commit + imports the file and use pg_prng_double() to generate random number in + range [0.0, 1.0). The seed is generated using pg_strong_random(). + + + Discussion: [pgpool-hackers: 4588] Shuffle random functions and use better random numbers + + + + + + + Retry bind on watchdog receive socket. (Tatsuo Ishii) + + + Occasionally 028.watchdog_enable_consensus_with_half_votes times out + due to failure on binding watchdog receive socket. This commit tries + to mitigate the issue by retrying bind. Currently the retry is + performed up to 5 times and each retry is with 1 second sleep. + + + + + + + Import likely/unlikely from PostgreSQL. (Tatsuo Ishii) + + + These macros are not only useful to enhance performance (if correctly + used) but make porting codes from PostgreSQL to pgpool easier since + the macros occasionally used in the code. + + + Discussion: [pgpool-hackers: 4599] Porting likely/unlikely + + + + + + + Replace PostmasterRandom() with pg_strong_random(). (Tatsuo Ishii) + + + Our PostmasterRandmon() was imported from PostgreSQL long time ago (in + 2016). In the same year PostgreSQL replaced PostmasterRandmon() with + pg_strong_random()(src/port/pg_strong_random.c). This commit follows + it. + + + Discussion: [pgpool-hackers: 4588] Shuffle random functions and use better random numbers + + + + + + + Fall back to prompting for password if reading from .pcppass file fails. (Bo Peng) + + + If reading password from .pcppass file fails, + it should fall back to prompting the user for input, + similar to how PostgreSQL handles .pgpass. + + + This commit also changes the following messages to be displayed + without requiring the option: + +WARNING: password file \"%s\" is not a plain file +WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less + + + + Discussion: [pgpool-hackers: 4589] If reading password from .pcppass file fails, try to read it from prompt. + + + + + + + Remove or downgrade inappropriate log messages at pgpool startup. (Tatsuo Ishii) + + + + + + + Add major version information to the configuration file. (Bo Peng) + + + + + + + + Documents + + + + + Fix documentation for enum parameters reported as strings. (Taiki Koshino) + + + Fix documentations for 6 parameters: + +log_standby_delay +log_backend_messages +wd_lifecheck_method +memqcache_method +disable_load_balance_on_write +backend_clustering_mode + + + + + + + Enhance query cache doc. (Tatsuo Ishii) + + + Pgpool refuses to cache a query calling functions returning + TIMESTAMP WITH TIMEZONE, TIME WITH TIMEZONE. + If there are multiple functions having same name and one of them returns + TIMESTAMP WITH TIMEZONE, TIME WITH TIMEZONE, + pgpool refuses to cache even if one of them does not + return the data types. So add a note on this along with workaround. + + + + + + + Test Tools + + + + + Allow to specify VIP in . (Tatsuo Ishii) + + + This commit allows to specify VIP parameter (delegate_ip) + in watchdog_setup using new option . + If ip is omitted, 127.0.0.1 is assumed. Even if vip option + is specified, pgpool will not actually set the VIP to the system: + , are + just set to echo command and do nothing except emit a log. This option + is intended to trace the action of Pgpool-II + regarding VIP handling. + + + Discussion: https://www.postgresql.org/message-id/20250820.151646.1640218512808280876.ishii%40postgresql.org + + + + + + + Regression Tests + + + + + Fix 038.pcp_commands regression test. (Tatsuo Ishii) + + + The result of the test showed local host IP. Although the IP can be + either IPv4 or IPv6, the test script hadn't considered it. To fix + this, now test.sh converts IPv4 and IPv6 IP to "localhost". + + + + + + + Stabilize 029.cert_passphrase regression test. (Tatsuo Ishii) + + + When ssl_passphrase_command is not valid, the error message is + typically "bad decrypt" but it seems sometimes "wrong tag". + + + + + diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index 11b2031d2..f2c6d2f6c 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -41,44 +41,51 @@ For new features, add links to the documentation sections. Release Notes - - The release notes contain the significant changes in each - Pgpool-II release, with major features and migration - issues listed at the top. The release notes do not contain changes - that affect only a few users or changes that are internal and therefore not - user-visible. - - - - A complete list of changes for each release can be obtained by - viewing the Git logs for each release. - The + The release notes contain the significant changes in each + Pgpool-II release, with major features and migration + issues listed at the top. The release notes do not contain changes + that affect only a few users or changes that are internal and therefore not + user-visible. + + + + A complete list of changes for each release can be obtained by + viewing the Git logs for each release. + The pgpool-committers email list records all source code changes as well. There is also - a web + a web interface that shows changes to specific files. - - - - The name appearing next to each item represents the major developer for - that item. Of course all changes involve community discussion and patch - review, so each item is truly a community effort. - - - - -&release-4.0; -&release-3.7; -&release-3.6; -&release-3.5; -&release-3.4; -&release-3.3; -&release-3.2; -&release-3.1; + + + + The name appearing next to each item represents the major developer for + that item. Of course all changes involve community discussion and patch + review, so each item is truly a community effort. + + + + + &release-4.7; + &release-4.6; + &release-4.5; + &release-4.4; + &release-4.3; + &release-4.2; + &release-4.1; + &release-4.0; + &release-3.7; + &release-3.6; + &release-3.5; + &release-3.4; + &release-3.3; + &release-3.2; + &release-3.1; diff --git a/doc/src/sgml/restrictions.sgml b/doc/src/sgml/restrictions.sgml index 7bcb29641..c8444b5c4 100644 --- a/doc/src/sgml/restrictions.sgml +++ b/doc/src/sgml/restrictions.sgml @@ -4,23 +4,42 @@ Restrictions - This section descibes current restrictions of Pgpool-II. + This section describes current restrictions of Pgpool-II. - Functionality of PostgreSQL + Using pg_terminate_backend - If you use pg_terminate_backend() to stop - a backend, this will trigger a failover. The reason why this - happens is that PostgreSQL sends - exactly the same message for a terminated backend as for a full - postmaster shutdown. There is no workaround prior of version - 3.6. From version 3.6, this limitation has been mitigated. If - the argument to the function (that is a process id) is a - constant, you can safely use the function. In extended protocol - mode, you cannot use the function though. + If you use pg_terminate_backend() to stop a + backend, this will trigger a failover. The reason why this + happens is that PostgreSQL sends + exactly the same message for a terminated backend as for a full + postmaster shutdown. There is no workaround prior of version + 3.6. From version 3.6, this limitation has been mitigated. If + the argument to the function (that is a process id) is a + constant, you can safely use the function. In extended protocol + mode, you cannot use the function though. In 4.3 or later you + can completely prevent the failover caused + by pg_terminate_backend() by + setting off + to , this will + prevent failover caused by termination of postmaster though. + + + + + + Load Balancing + + + Multi-statement queries (multiple SQL commands on single line) + are always sent to primary node (in streaming replication mode) + or main node (in other + modes). Usually Pgpool-II dispatch + query to appropriate node, but it's not applied to + multi-statement queries. @@ -28,55 +47,61 @@ Authentication/Access Controls - - In the replication mode or master/slave mode, trust, clear - text password, and pam methods are supported. md5 in also - supported since Pgpool-II 3.0. md5 - is supported by using a authencitaion file pool_passwd. - pool_passwd is default name of the - authentication file. Here are the - steps to enable md5 authentication: - - - - - - - Login as the database's operating system user and type: - - pg_md5 --md5auth --username=your_username your_passwd - - user name and md5 encrypted password are registered into - pool_passwd. If pool_passwd does not exist yet, pg_md5 - command will automatically create it for you. The format - of pool_passwd - is username:encrypted_passwd. - - - - - - You also need to add an appropriate md5 entry to - pool_hba.conf. See for more details. - - - - - - Please note that the user name and password must be - identical to those registered - in PostgreSQL. - - - - - - After changing md5 password (in both pool_passwd and - PostgreSQL of course), you need to - execute pgpool reload. - - - + + Trust and pam methods are supported. md5 is also + supported since Pgpool-II 3.0. md5 + is supported by using an authentication file pool_passwd. + scram-sha-256, cert, and clear text password is also supported since + Pgpool-II 4.0. + pool_passwd is default name of the + authentication file. Here are the + steps to enable md5 authentication: + + + + + + + Login as the database's operating system user and type: + + pg_md5 --md5auth --username=your_username your_passwd + + user name and md5 encrypted password are registered into + pool_passwd. If pool_passwd does not exist yet, pg_md5 + command will automatically create it for you. The format + of pool_passwd + is username:encrypted_passwd. + + + + + + You also need to add an appropriate md5 entry to + pool_hba.conf. See for more details. + + + + + + Please note that the user name and password must be + identical to those registered + in PostgreSQL. + + + + + + After changing md5 password (in both pool_passwd and + PostgreSQL of course), you need to + execute pgpool reload. + + + + + + See for + details about setting scram-sha-256 authentication. + @@ -84,156 +109,259 @@ Large objects - - In streaming replication - mode, Pgpool-II supports large - objects. - - - In native replication - mode, Pgpool-II supports large - objects if the backend - is PostgreSQL 8.1 or later. For - this, you need to enable lobj_lock_table directive - in pgpool.conf. Large object replication - using backend function lo_import is not - supported, however. - - - In other mode, including Slony mode, large - objects are not supported. - + + In , Pgpool-II + supports large objects. + + + In + and , Pgpool-II + supports large objects if the backend + is PostgreSQL 8.1 or later. For + this, you need to enable lobj_lock_table directive + in pgpool.conf. Large object replication + using backend function lo_import is not + supported, however. + + + In other mode, large + objects are not supported. + Temporary tables - - Creating/inserting/updating/deleting temporary tables are - always executed on the master (primary) in master slave mode. - SELECT on these tables is executed on master as well. However - if the temporary table name is used as a literal in SELECT, - there's no way to detect it, and the SELECT will be load - balanced. That will trigger a "not found the table" error or - will find another table having same name. To avoid the - problem, use /*NO LOAD BALANCE*/ SQL comment. - - - Note that such literal table names used in queries to access - system catalogs do cause problems described above. psql's \d - command produces such that query: - -SELECT 't1'::regclass::oid; - - In such that case Pgpool-II always - sends the query to master and will not cause the problem. - - - - Tables created by CREATE TEMP TABLE will be - deleted at the end of the session by specifying DISCARD ALL in - reset_query_list if you are using PostgreSQL 8.3 or later. - - - For 8.2.x or earlier, tables created by CREATE TEMP - TABLE will not be deleted after exiting a - session. It is because of the connection pooling which, from - PostgreSQL's backend point of view, keeps the session - alive. To avoid this, you must explicitly drop the temporary - tables by issuing DROP TABLE, or - use CREATE TEMP TABLE ... ON COMMIT DROP - inside the transaction block. - + + Creating/inserting/updating/deleting temporary tables are + always executed on the primary in native replication mode. + SELECT on these tables is executed on primary as well. However + if the temporary table name is used as a literal in SELECT, + there's no way to detect it, and the SELECT will be load + balanced. That will trigger a "not found the table" error or + will find another table having same name. To avoid the + problem, use SQL comment. + + + Note that such literal table names used in queries to access + system catalogs do cause problems described above. psql's \d + command produces such that query: + + SELECT 't1'::regclass::oid; + + In such that case Pgpool-II always + sends the query to primary and will not cause the problem. + + + + Tables created by CREATE TEMP TABLE will be + deleted at the end of the session by specifying DISCARD ALL in + reset_query_list if you are using PostgreSQL 8.3 or later. + + + For 8.2.x or earlier, tables created by CREATE TEMP + TABLE will not be deleted after exiting a + session. It is because of the connection pooling which, from + PostgreSQL's backend point of view, keeps the session + alive. To avoid this, you must explicitly drop the temporary + tables by issuing DROP TABLE, or + use CREATE TEMP TABLE ... ON COMMIT DROP + inside the transaction block. + - Functions, etc. In Native Replication mode + Functions, + etc. in + and - - There is no guarantee that any data provided using a - context-dependent mechanism (e.g. random number, transaction - ID, OID, SERIAL, sequence), will be replicated correctly on - multiple backends. For SERIAL, enabling insert_lock will help - replicating data. insert_lock also helps SELECT setval() and - SELECT nextval(). - - - INSERT/UPDATE - using CURRENT_TIMESTAMP, CURRENT_DATE, - now() will be replicated - correctly. INSERT/UPDATE for tables - using CURRENT_TIMESTAMP, CURRENT_DATE, - now() as their DEFAULT values will also - be replicated correctly. This is done by replacing those - functions by constants fetched from master at query execution - time. There are a few limitations however: - - - In Pgpool-II 3.0 or before, the - calculation of temporal data in table default value is not - accurate in some cases. For example, the following table - definition: - -CREATE TABLE rel1( - d1 date DEFAULT CURRENT_DATE + 1 -) - - is treated the same as: - -CREATE TABLE rel1( - d1 date DEFAULT CURRENT_DATE -) - - Pgpool-II 3.1 or later handles - these cases correctly. Thus the column "d1" will have - tomorrow as the default value. However this enhancement does - not apply if extended protocols (used in JDBC, PHP PDO for - example) or PREPARE are used. - - - Please note that if the column type is not a temporal one, - rewriting is not performed. Such example: - -foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision) - - Suppose we have the following table: - -CREATE TABLE rel1( - c1 int, - c2 timestamp default now() -) - - We can replicate - -INSERT INTO rel1(c1) VALUES(1) - + + There is no guarantee that any data provided using a + context-dependent mechanism (e.g. random number, transaction + ID, OID, SERIAL, sequence etc,), will be replicated correctly on + multiple backends. For SERIAL, enabling insert_lock will help + replicating data. insert_lock also helps SELECT setval() and + SELECT nextval(). + + + INSERT/UPDATE + using CURRENT_TIMESTAMP, CURRENT_DATE, + now() will be replicated + correctly. INSERT/UPDATE for tables + using CURRENT_TIMESTAMP, CURRENT_DATE, + now() as their DEFAULT values will also + be replicated correctly. This is done by replacing those + functions by constants fetched from PostgreSQL at query execution + time. There are a few limitations however: + + + In Pgpool-II 3.0 or before, the + calculation of temporal data in table default value is not + accurate in some cases. For example, the following table + definition: + + CREATE TABLE rel1( + d1 date DEFAULT CURRENT_DATE + 1 + ) + + is treated the same as: + + CREATE TABLE rel1( + d1 date DEFAULT CURRENT_DATE + ) + + Pgpool-II 3.1 or later handles + these cases correctly. Thus the column "d1" will have + tomorrow as the default value. However this enhancement does + not apply if extended protocols (used in JDBC, PHP PDO for + example) or PREPARE are used. + + + Please note that if the column type is not a temporal one, + rewriting is not performed. Such example: + + foo bigint default (date_part('epoch'::text,('now'::text)::timestamp(3) with time zone) * (1000)::double precision) + + Suppose we have the following table: + + CREATE TABLE rel1( + c1 int, + c2 timestamp default now() + ) + + We can replicate + + INSERT INTO rel1(c1) VALUES(1) + - since this turn into + since this turn into - -INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09') - + + INSERT INTO rel1(c1, c2) VALUES(1, '2009-01-01 23:59:59.123456+09') + - However, - -INSERT INTO rel1(c1) SELECT 1 - - cannot to be transformed, thus cannot be properly replicated in the current implementation. - Values will still be inserted, with no transformation at all. - + However, + + INSERT INTO rel1(c1) SELECT 1 + + cannot to be transformed, thus cannot be properly replicated in the current implementation. + Values will still be inserted, with no transformation at all. + SQL type commands - - SQL type commands cannot - be used in extended query mode. - + + SQL type commands cannot + be used in extended query mode. + + + + + + Multi-byte Characters + + + Pgpool-II does not perform encoding conversion between client and + PostgreSQL for multi-byte characters. + The encoding for the client and backends must be the same. + + + + + + libpq + + + libpq is linked while building Pgpool-II. + libpq version must be 3.0 or later. Building Pgpool-II with libpq version 2.0 will fail. + + + + + + ParameterStatus + + + When a client connects + to PostgreSQL, PostgreSQL + sends back some parameter/value pairs to clients. This protocol + is + called ParameterStatus. + The parameter/value pairs can be extracted by using some APIs + such as PQParameterStatus of libpq. The + actual parameter names can be + found here. + Pgpool-II collects ParameterStatus + values from multiple PostgreSQL + servers and it is possible that the values vary among the + servers. A typical example is in_hot_standby, + which is introduced in PostgreSQL + 14. The value for the variable is off on + primary server and on on standby + servers. Problem is, Pgpool-II has + to return client only one of them. In this case it chooses the + value reported by the primary + server. So PQParameterStatus will + return off. On the other hand, when the + client issues show in_hot_standby, the + returned value can either on + or off depending on which is the load + balance node for the session. + + + Note that if the values differ among + servers, Pgpool-II will emit a log + message except in_hot_standby. This is to + prevent the log file from being flooded + since in_hot_standby always differs. + + + + + + set_config + + + PostgreSQL + has set_config function which allows to + change parameter values within current session + like SET command + (actually set_config has more feature than + SET. See PostgreSQL manual for more + details). When Pgpool-II is + operated + with clustering + mode being set to + streaming_replication, it sends the function + only to the primary server. As the function is not sent to the + standby servers, the parameter values are different among each + servers. To avoid the problem, you can + use SET command instead + of set_config. + Since SET command is sent to all servers + used for this session, the issue will not happen. However, if + you use more than 2 PostgreSQL + servers, you need to + disable and + use SET command. This is because, + if enabled, + queries might be sent to the third server in addition to the + primary server and the server which is assigned to the load + balance node. + + + If you need to use set_config, turn off + load balancing for the session (not only + for set_config, load balancing should be + disabled in the whole session). You can avoid the issue by + sacrificing performance. + diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 4eca8e86d..077b0e014 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -8,6 +8,35 @@ and its interactions with the operating system. + + Managing kernel resouces + + + kernel resouces + + + + To run Pgpool-II System V shared memory + and System V semaphore are necessary. Although on linux enough + amount of both resources are provided, other platforms may need to + configure the kernel parameters. + + + The minimum requirement of System V shared memory is around 140 MB. + If you plan to use more than default 64MB + of query + cache, you may need more shared memory. Number of necessary + shared memory segments is 3. Usually the kernel provides enough + shared memory segments. + + + + The minimum requirement of System V semaphore is around 10. Number + of necessary semaphore sets is 3. Usually the kernel provides + enough semaphore sets. + + + The <productname>Pgpool-II</productname> User Account @@ -42,47 +71,47 @@ - Pgpool-II provides a interface - for administrators to perform management operation, such as - getting Pgpool-II status or terminating - Pgpool-II processes - remotely. pcp.conf is the user/password file - used for authentication by this interface. All operation modes - require the pcp.conf file to be set. A - $prefix/etc/pcp.conf.sample file is created - during the installation - of Pgpool-II. Copy the file as - $prefix/etc/pcp.conf and add your user name and password - to it. - - -$ cp $prefix/etc/pcp.conf.sample $prefix/etc/pcp.conf - - - An empty line or a line starting with # is treated as a - comment and will be ignored. A user name and its associated - password must be written as one line using the following format: - - -username:[md5 encrypted password] - - -[md5 encrypted password] can be produced with the $prefix/bin/pg_md5 command. - - -$ pg_md5 your_password -1060b7b46a3bd36b3a0d66e0127d0517 - - -If you don't want pass the password as the argument, execute pg_md5 -p. - - -$ pg_md5 -p -password: your_password - - - The pcp.conf file must be readable by the - user who executes Pgpool-II. + Pgpool-II provides a interface + for administrators to perform management operation, such as + getting Pgpool-II status or terminating + Pgpool-II processes + remotely. pcp.conf is the user/password file + used for authentication by this interface. All operation modes + require the pcp.conf file to be set. A + $prefix/etc/pcp.conf.sample file is created + during the installation + of Pgpool-II. Copy the file as + $prefix/etc/pcp.conf and add your user name and password + to it. + + + $ cp $prefix/etc/pcp.conf.sample $prefix/etc/pcp.conf + + + An empty line or a line starting with # is treated as a + comment and will be ignored. A user name and its associated + password must be written as one line using the following format: + + + username:[md5 encrypted password] + + + [md5 encrypted password] can be produced with the $prefix/bin/pg_md5 command. + + + $ pg_md5 your_password + 1060b7b46a3bd36b3a0d66e0127d0517 + + + If you don't want pass the password as the argument, execute pg_md5 -p. + + + $ pg_md5 -p + password: your_password + + + The pcp.conf file must be readable by the + user who executes Pgpool-II. @@ -95,325 +124,630 @@ password: your_password - Configuring pgpool.conf - - - pgpool.conf is the main configuration file - of Pgpool-II. You need to specify the - path to the file when - starting Pgpool-II - using option. - pgpool.conf is located - at $prefix/etc/pgpool.conf by default. - + Configuring pgpool.conf + + + pgpool.conf is the main configuration file + of Pgpool-II. You need to specify the + path to the file when + starting Pgpool-II + using option. + pgpool.conf is located + at $prefix/etc/pgpool.conf by default, + if it installed from source code. + + + + To specify the Pgpool-II clustering + mode, set parameter + to the value explained below. + + + + <xref linkend="guc-backend-clustering-mode"> value in pgpool.conf + + + + + Clustering mode + value + + + + + + Streaming replication mode + streaming_replication + + + Replication mode + native_replication + + + Logical replication mode + logical_replication + + + Snapshot isolation mode + snapshot_isolation + + + Raw mode + raw + + + +
+ + + These configuration files are located at /usr/local/etc with + default installation from source code. + You can copy one of them as pgpool.conf. + (probably you need root privilege for this) + +# cd /usr/local/etc +# cp pgpool.conf.sample pgpool.conf + +
- Running mode of Pgpool-II - - - streaming replication mode - - - - master slave mode - - - - native replication mode - - - - logical replication mode - - - - There are four different running modes - in Pgpool-II: streaming replication mode, - logical replication mode, master slave mode (slony mode), native - replication mode and raw mode. In any - mode, Pgpool-II provides connection pooling, - automatic fail over and online recovery. The sample - configuration files for each mode are provied. They are located - under $prefix/etc. You can copy one of them - to $prefix/etc/pgpool.conf. - - - - Those modes are exclusive each other and cannot be changed after - starting the server. You should make a decision which to use in - the early stage of designing the system. If you are not sure, it - is recommended to use the streaming replication mode. - - - - The streaming replication mode can be - used with PostgreSQL servers operating streaming - replication. In this mode, PostgreSQL is - responsible for synchronizing databases. This mode is widely - used and most recommended way to - use Pgpool-II. Load balancing is possible in the - mode. The sample configuration file - is $prefix/etc/pgpool.conf.sample-stream. - - - - The logical replication mode can be used - with PostgreSQL servers operating logical - replication. In this mode, PostgreSQL is - responsible for synchronizing tables. Load balancing is possible - in the mode. Since logical replication does not replicate all - tables, it's user's responsibility to replicate the table which - could be load balanced. Pgpool-II load balaces - all tables. This means that if a table is not - replicated, Pgpool-II may lookup outdated tables - in the subscriber side. The sample configuration file - is $prefix/etc/pgpool.conf.sample-logical. - - - - The master slave mode mode (slony mode) - can be used with PostgreSQL servers - operating Slony. In this - mode, Slony/PostgreSQL is - responsible for synchronizing - databases. Since Slony-I is being obsoleted by - streaming replication, we do not recommend to use this mode - unless you have specific reason to - use Slony. Load balancing is possible in the - mode. The sample configuration file - is $prefix/etc/pgpool.conf.sample-master-slave. - - - - In the native replication - mode, Pgpool-II is responsible for - synchronizing databases. The advantage for the mode is the - synchronization is done in synchronous way: writing to the - database does not return until all of PostgreSQL - servers finish the write operation. However, you could get a - similar effect using PostgreSQL 9.6 or later - with synchronous_commit = remote_apply being - set in streaming replication. If you could use the setting, we - strongly recommend to use it instead of native replication mode - because you can avoid some in the - native replication mode. Since PostgreSQL does - not provide cross node snapshot control, it is possible that - session X can see data on node A committed by session Y before - session Y commits data on node B. If session X tries to update - data on node B based on the data seen on node A, then data - consistency between node A and B might be lost. To avoid the - problem, user need to issue an explict lock on the data. This is - another reason why we recommend to use streaming replication - mode with synchronous_commit = remote_apply. - - - Load balancing is possible in the mode. The sample configuration - file $prefix/etc/pgpool.conf.sample-replication. - - - - In the raw - mode, Pgpool-II does not care about - the database synchronization. It's user's responsibility to make - the whole system does a meaningfull thing. Load balancing - is not possible in the mode. The sample - configuration - file $prefix/etc/pgpool.conf.sample. - + Clustering mode of Pgpool-II + + + streaming replication mode + + + + native replication mode + + + + main replica mode + + + + logical replication mode + + + + snapshot isolation mode + + + + There are six different clustering modes in + Pgpool-II: streaming replication mode, logical + replication mode, native + replication mode, raw mode and snapshot isolation mode. In any + mode, Pgpool-II provides connection pooling, and + automatic fail over. Online recovery can be used only with + streaming replication mode, snapshot isolation mode and native + replication mode. See + for more details of online recovery. + + + + Those modes are exclusive each other and cannot be changed after + starting the server. You should make a decision which to use in + the early stage of designing the system. If you are not sure, it + is recommended to use the streaming replication mode or the + snapshot isolation mode. + + + + The streaming replication mode can be used + with PostgreSQL servers operating streaming + replication. In this mode, PostgreSQL is + responsible for synchronizing databases. This mode is widely used + and most recommended way to use Pgpool-II. Load + balancing is possible in the mode. visibility consistency among + nodes is not guaranteed. + + + + In the snapshot isolation mode + Pgpool-II is responsible for synchronizing + databases. The advantage for the mode is the synchronization is + done in synchronous way: writing to the database does not return + until all of PostgreSQL servers finish the write + operation. Also it guarantees the visibility consistency among + nodes. To put it simply, it means that the visibility rule of + transactions on single server is applied to a cluster consisting + of multiple servers as well. This is a remarkable feature of the + snapshot isolation mode in + Pgpool-II. In fact, the snapshot + isolation mode in Pgpool-II is the only + system which guarantees the visibility consistency among nodes + without modifications to PostgreSQL at the moment. + Because of this, applications do not need to recognize that they + are using a cluster consisting of + PostgreSQL servers, rather than a + single PostgreSQL system. However in + this mode the transaction isolation level must be + REPEATABLE READ. You need to set + postgresql.conf like this: + +default_transaction_isolation = 'repeatable read' + + + + Also you need to aware that performance in the mode may be worse + than the streaming replication mode and native replication mode + due to the overhead to keep the consistency in transactions. + + + + In the native replication mode, + Pgpool-II is responsible for synchronizing + databases. The advantage for the mode is the synchronization is + done in synchronous way: writing to the database does not return + until all of PostgreSQL servers finish the write + operation. As visibility consistency among nodes is not + guaranteed, it is recommended to use the snapshot isolation mode + except you want to use other than REPEATABLE READ isolation mode. + Load balancing is possible in the mode. + + + + The logical replication mode can be used + with PostgreSQL servers operating logical + replication. In this mode, PostgreSQL is + responsible for synchronizing tables. Load balancing is possible + in the mode. Since logical replication does not replicate all + tables, it's user's responsibility to replicate the table which + could be load balanced. Pgpool-II load balances + all tables. This means that if a table is not + replicated, Pgpool-II may lookup outdated tables + in the subscriber side. + + + + In the raw + mode, Pgpool-II does not care about + the database synchronization. It's user's responsibility to make + the whole system does a meaningful thing. Load balancing + is not possible in the mode. + + + + Process management modes + + + dynamic process management + + + + static process management + + + Pgpool-II implements a multi-process architecture where + each child process can handle exactly one client connection at any time. + The total number of concurrent client connections Pgpool-II + can handle is configured by the + num_init_children config parameter. + Pgpool-II supports two child process management modes. + Dynamic and Static. + In static process management mode, Pgpool-II pre-forks the + num_init_children number of child + process at startup, and each child process keeps listening for incoming + client connection. While with dynamic process management mode, + Pgpool-II keeps track of idle processes and forks or kills + processes to keep this number within the specified boundaries. + + + is not available prior to + Pgpool-II V4.4. + + + +
Configuring backend information - For Pgpool-II to recognize PostgreSQL - backend servers, you need to configure backend* - in pgpool.conf. For starters, at - least - and paramters are required to - be set up to start Pgpool-II server. + For Pgpool-II to recognize PostgreSQL + backend servers, you need to configure backend* + in pgpool.conf. For starters, at + least + and parameters are required to + be set up to start Pgpool-II server. - Backend Settings - - - Backend PostgreSQL used by Pgpool-II must be specified in pgpool.conf. - See - - - + Backend Settings + + + Backend PostgreSQL used by Pgpool-II must be specified in pgpool.conf. + See + + + + + + + + + Starting Pgpool-II and PostgreSQL + + + To start Pgpool-II, execute: + +$ pgpool -f /usr/local/etc/pgpool.conf -F /usr/local/etc/pcp.conf + + which will start the server running in the background. "-f" + specifies the path to the main pgpool configuration file and "-F" + specifies the path to the configuration file of pcp server, which + is the control server for Pgpool-II. For + other options of the command please take a look at manual. + + + + Before starting Pgpool-II, you must + start PostgreSQL because if + PostgreSQL has not started yet, + Pgpool-II triggers failover process and + makes PostgreSQL is in down status. + + + + If you have difficulty in controlling the startup sequence of + PostgreSQL, for example + Pgpool-II and + PostgreSQL are installed on different + servers, you can make longer (the default is 5 + minutes) so that Pgpool-II waits for + PostgreSQL starts up until expires. If + PostgreSQL starts up before expires, + Pgpool-II should start up without + problem. If + expires before PostgreSQL starts up, no + primary node will be detected, which means you cannot execute + DML/DDL. You need to restart Pgpool-II + in this case. To confirm that the primary node exists you can use + command. + + + + Please note can + only be used in the streaming replication mode because the + parameter is only valid in the mode. See for more details about streaming + replication mode. For other mode, tweak the health check (see ) parameters so that there's + enough time before PostgreSQL becomes + available. + + + + If health check detects that PostgreSQL + is not available before Pgpool-II starts + up, some or all PostgreSQL are + recognized in "down" status. In this case you need to manually put + the PostgreSQL server in "up" state by + using command. If a client tries + to connect to Pgpool-II before + PostgreSQL is available, failover could + be triggered. In this case you also need to execute command to put the + PostgreSQL server in "up" state. + + + + + Stopping Pgpool-II and PostgreSQL + + + shutdown + + + + To stop Pgpool-II, execute: + +$ pgpool -f /usr/local/etc/pgpool.conf -F /usr/local/etc/pcp.conf -m fast stop + + "-m" option specifies how gently stops + Pgpool-II. "fast" means shutdown + Pgpool-II immediately even if there are + existing connections from clients. You can specify "smart" to the + option, which force Pgpool-II to wait + until all clients are disconnected from + Pgpool-II. But this could make + Pgpool-II wait forever and this may + result in sending SIGKILL signal from the operating system and + leaving garbage, which will bring troubles next time when you start + Pgpool-II. + + + + After shutting down Pgpool-II, you can + shutdown PostgreSQL. + + + + + Temporarily Shutting Down PostgreSQL + + + shutdown + + + + Sometimes you want to temporarily stop or restart + PostgreSQL to maintain or version up + it. In this section how to perform the task with minimum downtime. + + + + Using pcp_detach_node command + + If you stop PostgreSQL by using + pg_ctl, failover will not happen until + Pgpool-II detects it by the health + check depending on the health check settings and it will take + sometime to detach PostgreSQL. + Especially if Watchdog is + enabled and is on, + Pgpool-II will not start failover until + more than half of watchdog nodes agree that + PostgreSQL is stopped. If you detach + the node by using , failover will + immediately start regardless the settings of health check. Please + note that the detached PostgreSQL node + is not actually stopped and if necessary, you need to manually + stop it. + + + + + Using backend_flag + + Stopping or restarting PostgreSQL + causes failover. If the running mode is not streaming replication + mode, or the server is a standby server in streaming replication + mode, probably that's not a big deal because clients can always + use other servers in the cluster. However if the server is primary + server, it will cause change of primary server by promoting one of + the standby servers. Moreover if there's only one server remains + in the cluster, there are no alternative server or standby server + which can be promoted. + + + + In this case you can use to avoid + failover. By setting below in pgpool.conf will avoid failover of + backend0. + +backend_flag0 = DISALLOW_TO_FAILOVER + + This will take effect by reloading or restarting + Pgpool-II. If this flag is set, failover + will not happen if the backend is not available. While the backend + is not available, clients will get error message: + +psql: error: could not connect to server: FATAL: failed to create a backend connection +DETAIL: executing failover on backend + + After restarting the backend, clients can connect as usual. + To allow failover on the backend again, you can set: + +backend_flag0 = ALLOW_TO_FAILOVER + + and reload or restart Pgpool-II. + + + Backing up PostgreSQL database + + + backup + + + + If you plan to backup PostgreSQL + database + using pg_dump, pg_basebackup + or any other tools, we strongly recommend to run the commands + against PostgreSQL + directly. As Pgpool-II is a proxy + software, it gives an overhead for relaying message packets. Since + obtaining a backup tends to produce lots of packets, performing + backup through Pgpool-II will be slow + compared with directly + connecting PostgreSQL unless the + database is very small. + + + Moreover, parallel pg_dump raises error if it is + executed through Pgpool-II because the + command handles snapshot id, which is a database depending object. + + + In most cases you want to choose primary server as the backup + target. If you want backup standby server, you have to be very + careful in choosing the right PostgreSQL + server to obtain a backup because if the data is outdated, you are + likely to have outdated database backup. You can + use + or to know how the standby server + catches up the primary server. + + + diff --git a/doc/src/sgml/ssl.sgml b/doc/src/sgml/ssl.sgml index f91da84fd..e2687d1be 100644 --- a/doc/src/sgml/ssl.sgml +++ b/doc/src/sgml/ssl.sgml @@ -1,7 +1,7 @@ - Secure Sockect Layer (SSL) + Secure Socket Layer (SSL) @@ -9,122 +9,310 @@ - - ssl (boolean) - - ssl configuration parameter - + + ssl (boolean) + + ssl configuration parameter + + + When set to on, Pgpool-II enables the SSL + for both the frontend and backend communications. + Default is off. + + - When set to on, Pgpool-II enables the SSL - for both the frontend and backend communications. - Default is off. + and must also be + configured in order for SSL to work with frontend connections. - - - and must also be - configured in order for SSL to work with frontend connections. - - - - - For SSL to work Pgpool-II must be build with OpenSSL support. - See for details on building the - Pgpool-II. - - + + - This parameter can only be set at server start. + For SSL to work Pgpool-II must be build with OpenSSL support. + See for details on building the + Pgpool-II. - - - - - ssl_key (string) - - ssl_key configuration parameter - + + + This parameter can only be set at server start. + + + + + + ssl_key (string) + + ssl_key configuration parameter + - - Specifies the path to the private key file to be used for - incoming frontend connections. - There is no default value for this option, and if left unset - SSL will be disabled for incoming frontend connections. - - - This parameter can only be set at server start. - - - - - - ssl_cert (string) - - ssl_cert configuration parameter - + + Specifies the private key file to be used for + incoming frontend connections. Relative paths are relative to + Pgpool-II configuration directory. + There is no default value for this option, and if left unset + SSL will be disabled for incoming frontend connections. + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_cert (string) + + ssl_cert configuration parameter + - - Specifies the path to the public x509 certificate file to be used - for the incoming frontend connections. - There is no default value for this option, and if left unset - SSL will be disabled for incoming frontend connections. - + + Specifies the public x509 certificate file to be used + for the incoming frontend connections. Relative paths are relative to + Pgpool-II configuration directory. + There is no default value for this option, and if left unset + SSL will be disabled for incoming frontend connections. + - - This parameter can only be set at server start. - - - - - - ssl_ca_cert (string) - - ssl_ca_cert configuration parameter - + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_ca_cert (string) + + ssl_ca_cert configuration parameter + - - Specifies the path to a PEM - format CA certificate files, which can be used - to verify the backend server certificates. This is analogous to - the -CApath option of the - OpenSSL verify(1) command. - + + Specifies a PEM format CA + certificate file, which can be used to verify the backend server + certificates. Relative paths are relative to + Pgpool-II configuration directory. This is + analogous to the -CApath option of the + OpenSSL verify(1) command. + - - This parameter can only be set at server start. - - - - - - ssl_ca_cert_dir (string) - - ssl_ca_cert_dir configuration parameter - + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_ca_cert_dir (string) + + ssl_ca_cert_dir configuration parameter + - - Specifies the path to a directory containing PEM - format CA certificate files, which can be used - to verify the backend server certificates. This is analogous to - the -CApath option of the - OpenSSL verify(1) command. - - - The default value for this option is unset, which means no - verification takes place. Verification will still happen if - this option is not set but a value is provided for - . - - - This parameter can only be set at server start. - - - + + Specifies the path to a directory containing PEM + format CA certificate files, which can be used + to verify the backend server certificates. This is analogous to + the -CApath option of the + OpenSSL verify(1) command. + + + The default value for this option is unset, which means no + verification takes place. Verification will still happen if + this option is not set but a value is provided for + . + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_crl_file (string) + + ssl_crl_file configuration parameter + + + + + Specifies the file containing the SSL server certificate + revocation list (CRL). Relative paths are relative to + Pgpool-II configuration directory. + The default is empty, meaning no CRL file is loaded. + + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_ciphers (string) + + ssl_ciphers configuration parameter + + + + + Specifies a list of SSL cipher suites that + are allowed to be used by SSL connections. See + the ciphers + manual page in the OpenSSL package + for the syntax of this setting and a list of supported values. + Only connections using TLS version 1.2 and lower are affected. + There is currently no setting that controls the cipher choices + used by TLS version 1.3 connections. + The default value + is HIGH:MEDIUM:+3DES:!aNULL, which is same + as PostgreSQL. + See PostgreSQL manual to know why + the value is chosen. + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_prefer_server_ciphers (boolean) + + ssl_prefer_server_ciphers configuration parameter + + + + + Specifies whether to use the server's SSL + cipher preferences, rather than the client's. + The default value is false. + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_ecdh_curve (string) + + ssl_ecdh_curve configuration parameter + + + + + Specifies the name of the curve to use in ECDH key + exchange. It needs to be supported by all clients that connect. + It does not need to be the same curve used by the server's Elliptic + Curve key. The default value is prime256v1. + + + OpenSSL names for the most common curves are: + prime256v1 (NIST P-256), + secp384r1 (NIST P-384), + secp521r1 (NIST P-521). + The full list of available curves can be shown with the command + openssl ecparam -list_curves. Not all of them + are usable in TLS though. + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_dh_params_file (string) + + ssl_dh_params_file configuration parameter + + + + + Specifies the name of the file containing Diffie-Hellman parameters + used for so-called ephemeral DH family of SSL ciphers. The default is + empty. If empty or specified file is not correct one, compiled-in default DH parameters used. Using + Custom DH parameters reduces the exposure if an attacker manages to + crack the well-known compiled-in DH parameters. You can create your own + DH parameters file with the command openssl -out dhparams.pem 2048. + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + + + + ssl_passphrase_command (string) + + ssl_passphrase_command configuration parameter + + + + + Sets an external command to be invoked when a passphrase for decrypting + an SSL file such as a private key needs to be obtained. By default, + this parameter is empty, which means SSL file will not be loaded if passphrase is required. + + + The command must print the passphrase to the standard output and + exit with code 0. In the parameter value, %p is replaced by a prompt + string. (Write %% for a literal %.) Note that the prompt string will probably + contain whitespace, so be sure to quote adequately. A single newline is stripped + from the end of the output if present. + + + The command does not actually have to prompt the user for a passphrase. + It can read it from a file, obtain it from a keychain facility, or similar. + It is up to the user to make sure the chosen mechanism is adequately secure. + + + This parameter can be changed by reloading + the Pgpool-II configurations. However, if the + new parameter is not valid, the old value will be retained until + Pgpool-II is restarted, even if the new + parameter is displayed in "pgpool show". + + + @@ -134,11 +322,11 @@ Generating SSL certificates - Certificate handling is outside the scope of this document. The - - Secure TCP/IP Connections with SSL page at postgresql.org has - pointers with sample commands for how to generate self-signed - certificates. + Certificate handling is outside the scope of this document. The + + Secure TCP/IP Connections with SSL page at postgresql.org has + pointers with sample commands for how to generate self-signed + certificates. diff --git a/doc/src/sgml/start.sgml b/doc/src/sgml/start.sgml index 69a10bcf2..b5615e853 100644 --- a/doc/src/sgml/start.sgml +++ b/doc/src/sgml/start.sgml @@ -1,436 +1,449 @@ - Getting Started - - - Installation - - - In this section we assume that you have already - installed Pgpool-II following an - instruction described in . - Alternatively you can use to - create a temporary installation - of Pgpool-II - and PostgreSQL. - - - - - Your First Replication - - - In this section we are going to explain how to manage a - PostgreSQL cluster with streaming - replication using Pgpool-II, which is - one of most common setup. - - - - Before going further, you should properly set - up pgpool.conf with streaming replication - mode. For this at least - following two directives must be set: - -master_slave_mode = on -master_slave_sub_mode = 'stream' - - - - If you plan to use pgpool_setup, type: - -pgpool_setup - - This will create - a Pgpool-II with streaming - replication mode installation, - primary PostgreSQL installation, and - a async standby PostgreSQL - installation. - - - From now on, we assume that you - use pgpool_setup to create the installation - under current directory. Please note that the current directory - must be empty before executing pgpool_setup. - - - To start the whole system, type: - -./startall - - - - Once the system starts, you can check the cluster status by - issuing a pseudo SQL command called "show pool_node" to any of - databases. pgpool_setup automatically creates - "test" database. We use the database. Note that the port number - is 11000, which is the default port number assigned - to Pgpool-II - by pgpool_setup. - -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 -(2 rows) - - The result shows that the "status" column is "up", which means - the - PostgreSQL is up and running, which - is good. - - - - - Testing Load Balance - - Pgpool-II allows read query load - balancing. It is enabled by default. To see the effect, let's - use pgbench -S command. - -$ pgbench -p 11000 -c 10 -S -T 10 test -starting vacuum...end. -transaction type: <builtin: select only> -scaling factor: 1 -query mode: simple -number of clients: 10 -number of threads: 1 -duration: 10 s -number of transactions actually processed: 148044 -latency average = 0.676 ms -tps = 14802.897506 (including connections establishing) -tps = 14810.213749 (excluding connections establishing) - -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 75152 | true | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 72893 | false | 0 -(2 rows) - - "select_cnt" column shows how many SELECT are dispatched to each - node. Since with the default - configuration, Pgpool-II tries to - dispatch equal number of SELECT, the column shows almost same - numbers. - - - Pgpool-II offers more sophisticated - strategy for load - balancing. See - for more details. - - - - - Testing Replication - - - Let's test the replication functionality using a benchmark - tool pgbench, which comes with the - standard PostgreSQL installation. - Type following to create the benchmark tables. - -$ pgbench -i -p 11000 test - - To see if the replication works correctly, directly connect to - the primary and the standby server to see if they return - identical results. - -$ psql -p 11002 test -\dt - List of relations - Schema | Name | Type | Owner ---------+------------------+-------+--------- - public | pgbench_accounts | table | t-ishii - public | pgbench_branches | table | t-ishii - public | pgbench_history | table | t-ishii - public | pgbench_tellers | table | t-ishii -(4 rows) -\q -$ psql -p 11003 test -\dt - List of relations - Schema | Name | Type | Owner ---------+------------------+-------+--------- - public | pgbench_accounts | table | t-ishii - public | pgbench_branches | table | t-ishii - public | pgbench_history | table | t-ishii - public | pgbench_tellers | table | t-ishii -(4 rows) - - The primary server (port 11002) and the standby server (port - 11003) return identical results. Next, let's run pgbench for a - while and check to results. - -$ pgbench -p 11000 -T 10 test -starting vacuum...end. -transaction type: <builtin: TPC-B (sort of)> -scaling factor: 1 -query mode: simple -number of clients: 1 -number of threads: 1 -duration: 10 s -number of transactions actually processed: 2171 -latency average = 4.692 ms -tps = 213.147520 (including connections establishing) -tps = 213.258008 (excluding connections establishing) - -$ psql -p 11002 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) - -$ psql -p 11003 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) - - Again, the results are identical. - - - - - Testing Fail Over - - - Pgpool-II allows an automatic fail - over when PostgreSQL server goes - down. In this case Pgpool-II sets the - status of the server to "down" and continue the database - operation using remaining servers. - -$ pg_ctl -D data1 stop -waiting for server to shut down.... done -server stopped -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 2172 | true | 0 - 1 | /tmp | 11003 | down | 0.500000 | standby | 0 | false | 0 -(2 rows) - -$ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) - - The standby node was shut down by pg_ctl - command. Pgpool-II detects it and - detaches the standby node. "show pool_nodes" command shows that - the standby node is in down status. You can continue to use the - cluster without the standby node: - -$ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test - sum --------- - 192112 -(1 row) - - What happens if the primary server goes down? In this case, one - of remaining standby server is promoted to new primary - server. For this testing, we start from the state in which both - nodes are up. - -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | primary | 2173 | true | 0 - 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | false | 0 -(2 rows) - -$ pg_ctl -D data0 stop -waiting for server to shut down.... done -server stopped -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | down | 0.500000 | standby | 2173 | false | 0 - 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 -(2 rows) - - Now the primary node is changed from 0 to 1. What happens - inside? When the node 0 goes - down, Pgpool-II detects it and - executes "fail_over_script" defined - in pgpool.conf. Here is the content of the - file. - -#! /bin/sh -# Execute command by failover. -# special values: %d = node id -# %h = host name -# %p = port number -# %D = database cluster path -# %m = new master node id -# %M = old master node id -# %H = new master node host name -# %P = old primary node id -# %R = new master database cluster path -# %r = new master port number -# %% = '%' character -failed_node_id=$1 -failed_host_name=$2 -failed_port=$3 -failed_db_cluster=$4 -new_master_id=$5 -old_master_id=$6 -new_master_host_name=$7 -old_primary_node_id=$8 -new_master_port_number=$9 -new_master_db_cluster=${10} -mydir=/home/t-ishii/tmp/Tutorial -log=$mydir/log/failover.log -pg_ctl=/usr/local/pgsql/bin/pg_ctl -cluster0=$mydir/data0 -cluster1=$mydir/data1 - -date >> $log -echo "failed_node_id $failed_node_id failed_host_name $failed_host_name failed_port $failed_port failed_db_cluster $failed_db_cluster new_master_id $new_master_id old_master_id $old_master_id new_master_host_name $new_master_host_name old_primary_node_id $old_primary_node_id new_master_port_number $new_master_port_number new_master_db_cluster $new_master_db_cluster" >> $log - -if [ a"$failed_node_id" = a"$old_primary_node_id" ];then # master failed -! new_primary_db_cluster=${mydir}/data"$new_master_id" - echo $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over - $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over -fi - - The script receives necessary information as parameters - from Pgpool-II. If the primary server - goes down, it executes "pg_ctl -D data1 promote", which should - promote the standby server to a new primary server. - - - - - Testing Online Recovery - - Pgpool-II allows to recover a downed - node by technique called "Online Recovery". This copies data - from the primary node to a standby node so that it sync with the - primary. This may take long time and database may be updated - during the process. That's no problem because in the streaming - configuration, the standby will receive WAL log and applies it - to catch up the primary. To test online recovery, let's start - with previous cluster, where node 0 is in down state. - -$ pcp_recovery_node -p 11001 0 -Password: -pcp_recovery_node -- Command Successful - -$ psql -p 11000 -c "show pool_nodes" test - node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ----------+----------+-------+--------+-----------+---------+------------+-------------------+------------------- - 0 | /tmp | 11002 | up | 0.500000 | standby | 2173 | true | 0 - 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | false | 0 -(2 rows) - - is one of control commands - coming with Pgpool-II - installation. The argument -p is to specify the port number - assigned to the command, which is 11001 set - by pgpool_setup. The second argument is the - target node id. After executing the command, node 0 returned to - "up" status. - - - The script executed by pcp_recovery_node is - specified as "recovery_1st_stage_command" - in pgpool.conf. Here is the file installed - by pgpool_setup. - -#! /bin/sh -psql=/usr/local/pgsql/bin/psql -DATADIR_BASE=/home/t-ishii/tmp/Tutorial -PGSUPERUSER=t-ishii - -master_db_cluster=$1 -recovery_node_host_name=$2 -DEST_CLUSTER=$3 -PORT=$4 - -log=$DATADIR_BASE/log/recovery.log - -$psql -p $PORT -c "SELECT pg_start_backup('Streaming Replication', true)" postgres - -echo "source: $master_db_cluster dest: $DEST_CLUSTER" > $log - -rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \ ---exclude postmaster.opts --exclude pg_log \ ---exclude recovery.conf --exclude recovery.done \ ---exclude pg_xlog \ -$master_db_cluster/ $DEST_CLUSTER/ - -rm -fr $DEST_CLUSTER/pg_xlog -mkdir $DEST_CLUSTER/pg_xlog -chmod 700 $DEST_CLUSTER/pg_xlog -rm $DEST_CLUSTER/recovery.done -cat > $DEST_CLUSTER/recovery.conf $lt;$lt;REOF -standby_mode = 'on' -primary_conninfo = 'port=$PORT user=$PGSUPERUSER' -recovery_target_timeline='latest' -REOF - -$psql -p $PORT -c "SELECT pg_stop_backup()" postgres - - - - - - Architectural Fundamentals - - - Pgpool-II is a proxy server sitting - between clients and PostgreSQL. - Pgpool-II understands the wire level - protocol used by PostgreSQL called - "frontend and backend protocol". For more details of the - protocol, see the PostgreSQL manual. - No modified PostgreSQL is required to - use Pgpool-II (more precisely, you - will need a few extensions to use full functions - of Pgpool-II). So Pgpool-II - can cope with variety of PostgreSQL - versions. In theory, even the earliest version - of PostgreSQL can be used - with Pgpool-II. Same thing can be - said to client side. As long as it follows the - protocol, Pgpool-II happily accept - connections from it, no matter what kind of languages or drivers - it uses. - - - - Pgpool-II consists of multiple - process. There is a main process, which is the parent process of - all other process. It is responsible for forking child process - each of which accepts connections from clients. There are some - worker process those are forked from the main process as well, - which is responsible for detecting streaming replication - delay. There is also a special process called "pcp process", - which is solely used for management - of Pgpool-II - itself. Pgpool-II has a built-in high - availability function called "watchdog". Watchdog consists of - some process. For more details of watchdog, - see . - - -
- Process architecure of <productname>Pgpool-II</productname> - - - - - -
-
- -
+ Getting Started + + + Installation + + + In this section we assume that you have already + installed Pgpool-II following an + instruction described in . + Alternatively you can use to + create a temporary installation + of Pgpool-II + and PostgreSQL. + + + + + Your First Replication + + + In this section we are going to explain how to manage a + PostgreSQL cluster with streaming + replication using Pgpool-II, which is + one of most common setup. + + + + Before going further, you should properly set + up pgpool.conf with streaming replication + mode. Sample configurations are provided with + Pgpool-II, there configuration file + are located at /usr/local/etc with default installation from + source code. you can copy + pgpool.conf.sample as pgpool.conf. + + cp /usr/local/etc/pgpool.conf.sample pgpool.conf + + + + If you plan to use pgpool_setup, type: + + pgpool_setup + + This will create + a Pgpool-II with streaming + replication mode installation, + primary PostgreSQL installation, and + a async standby PostgreSQL + installation. + + + From now on, we assume that you + use pgpool_setup to create the installation + under current directory. Please note that the current directory + must be empty before executing pgpool_setup. + + + To start the whole system, type: + + ./startall + + + + Once the system starts, you can check the cluster status by + issuing a pseudo SQL command called "show pool_nodes" to any of + databases. pgpool_setup automatically creates + "test" database. We use the database. Note that the port number + is 11000, which is the default port number assigned + to Pgpool-II + by pgpool_setup. + + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 | 2019-01-31 10:23:09 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 | 2019-01-31 10:23:09 + (2 rows) + + The result shows that the "status" column is "up", which means + the + PostgreSQL is up and running, which + is good. + + + + + Testing Replication + + + Let's test the replication functionality using a benchmark + tool pgbench, which comes with the + standard PostgreSQL installation. + Type following to create the benchmark tables. + + $ pgbench -i -p 11000 test + + To see if the replication works correctly, directly connect to + the primary and the standby server to see if they return + identical results. + + $ psql -p 11002 test + \dt + List of relations + Schema | Name | Type | Owner + --------+------------------+-------+--------- + public | pgbench_accounts | table | t-ishii + public | pgbench_branches | table | t-ishii + public | pgbench_history | table | t-ishii + public | pgbench_tellers | table | t-ishii + (4 rows) + \q + $ psql -p 11003 test + \dt + List of relations + Schema | Name | Type | Owner + --------+------------------+-------+--------- + public | pgbench_accounts | table | t-ishii + public | pgbench_branches | table | t-ishii + public | pgbench_history | table | t-ishii + public | pgbench_tellers | table | t-ishii + (4 rows) + + The primary server (port 11002) and the standby server (port + 11003) return identical results. Next, let's run pgbench for a + while and check to results. + + $ pgbench -p 11000 -T 10 test + starting vacuum...end. + transaction type: <builtin: TPC-B (sort of)> + scaling factor: 1 + query mode: simple + number of clients: 1 + number of threads: 1 + duration: 10 s + number of transactions actually processed: 4276 + latency average = 2.339 ms + tps = 427.492167 (including connections establishing) + tps = 427.739078 (excluding connections establishing) + + $ psql -p 11002 -c "SELECT sum(abalance) FROM pgbench_accounts" test + sum + -------- + 216117 + (1 row) + + $ psql -p 11003 -c "SELECT sum(abalance) FROM pgbench_accounts" test + sum + -------- + 216117 + (1 row) + + Again, the results are identical. + + + + + Testing Load Balance + + Pgpool-II allows read query load + balancing. It is enabled by default. To see the effect, let's + use pgbench -S command. + + $ ./shutdownall + $ ./startall + $ pgbench -p 11000 -c 10 -j 10 -S -T 60 test + starting vacuum...end. + transaction type: <builtin: select only> + scaling factor: 1 + query mode: simple + number of clients: 10 + number of threads: 10 + duration: 60 s + number of transactions actually processed: 1086766 + latency average = 0.552 ms + tps = 18112.487043 (including connections establishing) + tps = 18125.572952 (excluding connections establishing) + + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 537644 | false | 0 | 2019-01-31 11:51:58 + 1 | /tmp | 11003 | up | 0.500000 | standby | 548582 | true | 0 | 2019-01-31 11:51:58 + (2 rows) + + "select_cnt" column shows how many SELECT are dispatched to each + node. Since with the default + configuration, Pgpool-II tries to + dispatch equal number of SELECT, the column shows almost same + numbers. + + + Pgpool-II offers more sophisticated + strategy for load + balancing. See + for more details. + + + + + Testing Fail Over + + + Pgpool-II allows an automatic fail + over when PostgreSQL server goes + down. In this case Pgpool-II sets the + status of the server to "down" and continue the database + operation using remaining servers. + + $ pg_ctl -D data1 stop + waiting for server to shut down.... done + server stopped + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 4276 | true | 0 | 2019-01-31 12:00:09 + 1 | /tmp | 11003 | down | 0.500000 | standby | 1 | false | 0 | 2019-01-31 12:03:07 + (2 rows) + + The standby node was shut down by pg_ctl + command. Pgpool-II detects it and + detaches the standby node. "show pool_nodes" command shows that + the standby node is in down status. You can continue to use the + cluster without the standby node: + + $ psql -p 11000 -c "SELECT sum(abalance) FROM pgbench_accounts" test + sum + -------- + 216117 + (1 row) + + What happens if the primary server goes down? In this case, one + of remaining standby server is promoted to new primary + server. For this testing, we start from the state in which both + nodes are up. + + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | primary | 0 | false | 0 | 2019-01-31 12:04:58 + 1 | /tmp | 11003 | up | 0.500000 | standby | 0 | true | 0 | 2019-01-31 12:04:58 + (2 rows) + + $ pg_ctl -D data0 stop + waiting for server to shut down.... done + server stopped + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | down | 0.500000 | standby | 0 | false | 0 | 2019-01-31 12:05:20 + 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 | 2019-01-31 12:05:20 + (2 rows) + + Now the primary node is changed from 0 to 1. What happens + inside? When the node 0 goes + down, Pgpool-II detects it and + executes failover_command defined + in pgpool.conf. Here is the content of the + file. + + #! /bin/sh + # Execute command by failover. + # special values: %d = node id + # %h = host name + # %p = port number + # %D = database cluster path + # %m = new main node id + # %M = old main node id + # %H = new main node host name + # %P = old primary node id + # %R = new main database cluster path + # %r = new main port number + # %% = '%' character + failed_node_id=$1 + failed_host_name=$2 + failed_port=$3 + failed_db_cluster=$4 + new_main_id=$5 + old_main_id=$6 + new_main_host_name=$7 + old_primary_node_id=$8 + new_main_port_number=$9 + new_main_db_cluster=${10} + mydir=/home/t-ishii/tmp/Tutorial + log=$mydir/log/failover.log + pg_ctl=/usr/local/pgsql/bin/pg_ctl + cluster0=$mydir/data0 + cluster1=$mydir/data1 + + date >> $log + echo "failed_node_id $failed_node_id failed_host_name $failed_host_name failed_port $failed_port failed_db_cluster $failed_db_cluster new_main_id $new_main_id old_main_id $old_main_id new_main_host_name $new_main_host_name old_primary_node_id $old_primary_node_id new_main_port_number $new_main_port_number new_main_db_cluster $new_main_db_cluster" >> $log + + if [ a"$failed_node_id" = a"$old_primary_node_id" ];then # main failed + ! new_primary_db_cluster=${mydir}/data"$new_main_id" + echo $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over + $pg_ctl -D $new_primary_db_cluster promote >>$log # let standby take over + sleep 2 + fi + + The script receives necessary information as parameters + from Pgpool-II. If the primary server + goes down, it executes "pg_ctl -D data1 promote", which should + promote the standby server to a new primary server. + + + + + + Testing Online Recovery + + Pgpool-II allows to recover a downed + node by technique called "Online Recovery". This copies data + from the primary node to a standby node so that it sync with the + primary. This may take long time and database may be updated + during the process. That's no problem because in the streaming + configuration, the standby will receive WAL log and applies it + to catch up the primary. To test online recovery, let's start + with previous cluster, where node 0 is in down state. + + $ pcp_recovery_node -p 11001 -n 0 + Password: + pcp_recovery_node -- Command Successful + + $ psql -p 11000 -c "show pool_nodes" test + node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay | last_status_change + ---------+----------+-------+--------+-----------+---------+------------+-------------------+-------------------+--------------------- + 0 | /tmp | 11002 | up | 0.500000 | standby | 0 | false | 0 | 2019-01-31 12:06:48 + 1 | /tmp | 11003 | up | 0.500000 | primary | 0 | true | 0 | 2019-01-31 12:05:20 + (2 rows) + + is one of control commands + coming with Pgpool-II + installation. The argument -p is to specify the port number + assigned to the command, which is 11001 set + by pgpool_setup. The argument -n is to + specify the node id to be recovered. After executing the command, + node 0 returned to "up" status. + + + The script executed by pcp_recovery_node is + specified as "recovery_1st_stage_command" + in pgpool.conf. Here is the file installed + by pgpool_setup. + + #! /bin/sh + psql=/usr/local/pgsql/bin/psql + DATADIR_BASE=/home/t-ishii/tmp/Tutorial + PGSUPERUSER=t-ishii + + main_db_cluster=$1 + recovery_node_host_name=$2 + DEST_CLUSTER=$3 + PORT=$4 + recovery_node=$5 + + pg_rewind_failed="true" + + log=$DATADIR_BASE/log/recovery.log + echo >> $log + date >> $log + if [ $pg_rewind_failed = "true" ];then + + $psql -p $PORT -c "SELECT pg_start_backup('Streaming Replication', true)" postgres + + echo "source: $main_db_cluster dest: $DEST_CLUSTER" >> $log + + rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \ + --exclude postmaster.opts --exclude pg_log \ + --exclude recovery.conf --exclude recovery.done \ + --exclude pg_xlog \ + $main_db_cluster/ $DEST_CLUSTER/ + + rm -fr $DEST_CLUSTER/pg_xlog + mkdir $DEST_CLUSTER/pg_xlog + chmod 700 $DEST_CLUSTER/pg_xlog + rm $DEST_CLUSTER/recovery.done + fi + cat > $DEST_CLUSTER/recovery.conf $lt;$lt;REOF + standby_mode = 'on' + primary_conninfo = 'port=$PORT user=$PGSUPERUSER' + recovery_target_timeline='latest' + restore_command = 'cp $DATADIR_BASE/archivedir/%f "%p" 2> /dev/null' + REOF + + if [ $pg_rewind_failed = "true" ];then + $psql -p $PORT -c "SELECT pg_stop_backup()" postgres + fi + + if [ $pg_rewind_failed = "false" ];then + cp /tmp/postgresql.conf $DEST_CLUSTER/ + fi + + + + + + Architectural Fundamentals + + + Pgpool-II is a proxy server sitting + between clients and PostgreSQL. + Pgpool-II understands the wire level + protocol used by PostgreSQL called + "frontend and backend protocol". For more details of the + protocol, see the PostgreSQL manual. + No modified PostgreSQL is required to + use Pgpool-II (more precisely, you + will need a few extensions to use full functions + of Pgpool-II). So Pgpool-II + can cope with variety of PostgreSQL + versions. In theory, even the earliest version + of PostgreSQL can be used + with Pgpool-II. Same thing can be + said to client side. As long as it follows the + protocol, Pgpool-II happily accept + connections from it, no matter what kind of languages or drivers + it uses. + + + Pgpool-II consists of multiple + process. There is a main process, which is the parent process of + all other process. It is responsible for forking child process + each of which accepts connections from clients. There are some + worker process those are forked from the main process as well, + which is responsible for detecting streaming replication + delay. There is also a special process called "pcp process", + which is solely used for management + of Pgpool-II + itself. Pgpool-II has a built-in high + availability function called "watchdog". Watchdog consists of + some process. For more details of watchdog, + see . + + +
+ Process architecture of <productname>Pgpool-II</productname> + + + + + +
+
+ +
diff --git a/doc/src/sgml/stream-check.sgml b/doc/src/sgml/stream-check.sgml index 79205e57e..b1f8f4691 100644 --- a/doc/src/sgml/stream-check.sgml +++ b/doc/src/sgml/stream-check.sgml @@ -1,218 +1,441 @@ - Streaming Replication Check - - - Pgpool-II can work with PostgreSQL native - Streaming Replication, that is available since PostgreSQL 9.0. - To configure Pgpool-II with streaming - replication, enable and set - to 'stream'. - - - Pgpool-II assumes that Streaming Replication - is configured with Hot Standby on PostgreSQL, which means that the - standby database can handle read-only queries. - - - - - - sr_check_period (integer) - - sr_check_period configuration parameter - - - - - - Specifies the time interval in seconds to check the streaming - replication delay. - Default is 0, which means the check is disabled. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - - sr_check_user (string) - - sr_check_user configuration parameter - - - - - - Specifies the PostgreSQL user name to perform streaming replication check. - The user must exist on all the PostgreSQL backends. - - - - sr_check_user> and - are used even when is set to 0 (disabled) - for the identification of the primary server. - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - - sr_check_password (string) - - sr_check_password configuration parameter - - - - - - Specifies the password of the PostgreSQL user - to perform the streaming replication checks. - Use '' (empty string) if the user does not requires a password. - - - If sr_check_password is left blank Pgpool-II - will first try to get the password for from - file before using the empty password. - - - You can also specify AES256-CBC encrypted password in sr_check_password field. - To specify the AES encrypted password, password string must be prefixed with - AES after encrypting (using aes-256-cbc algorithm) and - encoding to base64. - - - To specify the unencrypted clear text password, prefix the password string with - TEXT. For example if you want to set mypass as - a password, you should specify TEXTmypass in the password field. - In the absence of a valid prefix, Pgpool-II will considered - the string as a plain text password. - - - You can also use utility to create the correctly formatted - AES encrypted password strings. - - - Pgpool-II will require a valid decryption key at the - startup to use the encrypted passwords. - see for more details on providing the - decryption key to Pgpool-II - - - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - - sr_check_database (string) - - sr_check_database configuration parameter - - - - - - Specifies the database to perform streaming replication delay checks. - The default is "postgres". - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - - delay_threshold (integer) - - delay_threshold configuration parameter - - - - - - Specifies the maximum tolerance level of replication delay in - WAL bytes on the standby server against the - primary server. If the delay exceeds this configured level, - Pgpool-II stops sending the - SELECT queries to the standby server and starts routing - everything to the primary server even if - is enabled, until the standby catches-up with the primary. - Setting this parameter to 0 disables the delay checking. - This delay threshold check is performed every . - Default is 0. - - - - This parameter can be changed by reloading the Pgpool-II configurations. - - - - - - - log_standby_delay (string) - - log_standby_delay configuration parameter - - - - - - Specifies when to log the replication delay. Below table contains the list - of all valid values for the parameter. - - - - Log standby delay options - - - - Value - Description - - - - - - 'none' - Never log the standby delay - - - - 'always' - Log the standby delay, every time the replication delay is checked - - - - 'if_over_threshold' - Only log the standby delay, when it exceeds value - - - -
- - - This parameter can be changed by reloading the Pgpool-II configurations. - - -
-
- -
+ Streaming Replication Check + + + Pgpool-II can work with PostgreSQL native + Streaming Replication, that is available since PostgreSQL 9.0. + To configure Pgpool-II with streaming + replication, set + to 'streaming-replication'. + + + Pgpool-II assumes that Streaming Replication + is configured with Hot Standby on PostgreSQL, which means that the + standby database can handle read-only queries. + + + + + + sr_check_period (integer) + + sr_check_period configuration parameter + + + + + + Specifies the time interval in seconds to check the streaming + replication delay. + The default is 10. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + sr_check_user (string) + + sr_check_user configuration parameter + + + + + + Specifies the PostgreSQL user name to perform streaming replication check. + Default is ''(empty). + The user must have LOGIN privilege and exist on all the + PostgreSQL backends. + Moreover the user must be a PostgreSQL + super user or in "pg_monitor" group. + + + To make in pg_monitor + group, execute following SQL command + by PostgreSQL super user (replace + "sr_check_user" with the setting of ): + +GRANT pg_monitor TO sr_check_user; + + For PostgreSQL 9.6, there's no + pg_monitor group and must + be PostgreSQL super user. + + + + + + If SSL is enabled, the + streaming replication check process may use SSL connection. + + + + and are used even when is set to 0 (disabled) for the + identification of the primary server. + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + sr_check_password (string) + + sr_check_password configuration parameter + + + + + + Specifies the password of the PostgreSQL user + to perform the streaming replication checks. + Use '' (empty string) if the user does not requires a password. + + + If sr_check_password is left blank Pgpool-II + will first try to get the password for from + file before using the empty password. + + + + Pgpool-II accepts following forms + of password in either sr_check_password + or file: + + + + AES256-CBC encrypted password + + + Most secure and recommended way to store password. The + password string must be prefixed + with AES. + You can use utility to create the correctly formatted + AES encrypted password strings. + Pgpool-II will require a valid decryption key at the + startup to use the encrypted passwords. + see for more details on providing the + decryption key to Pgpool-II + + + + + + MD5 hashed password + + + Not so secure as AES256, but still better than clear + text password. The password string must be prefixed + with MD5. Note that the backend + must set up MD5 authentication as well. You can + use utility to create the + correctly formatted + MD5 hashed password strings. + + + + + + Plain text password + + + Not encrypted, clear text password. You should avoid + to use this if possible. The password string must be + prefixed with TEXT. For example if + you want to set mypass as a + password, you should + specify TEXTmypass in the password + field. In the absence of a valid + prefix, Pgpool-II will + considered the string as a plain text password. + + + + + + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + sr_check_database (string) + + sr_check_database configuration parameter + + + + + + Specifies the database to perform streaming replication delay checks. + The default is "postgres". + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + delay_threshold (integer) + + delay_threshold configuration parameter + + + + + + Specifies the maximum tolerance level of replication delay in + WAL bytes on the standby server against the + primary server. If the delay exceeds this configured level, + Pgpool-II stops sending the + SELECT queries to the standby server and starts routing + everything to the primary server even if + is enabled, until the standby catches-up with the primary. + Setting this parameter to 0 disables the delay checking. + This delay threshold check is performed every . + Default is 0. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + delay_threshold_by_time (integer) + + delay_threshold_by_time configuration parameter + + + + + + Specifies the maximum tolerance level of replication delay + on the standby server against the primary server. + If this value is specified without units, it is taken as milliseconds. + If the specified value is greater than + 0, is ignored. If the delay + exceeds this configured level, + Pgpool-II stops sending the + SELECT queries to the standby server and starts routing + everything to the primary server even if + is enabled, until the standby catches-up with the primary. + Setting this parameter to 0 disables the delay checking. + This delay threshold check is performed every . + Default is 0. + + + + Replication delay is taken + from PostgreSQL's system + view pg_stat_replication.replay_lag. The + view is available PostgreSQL 10 or + later. If earlier version + of PostgreSQL is + used, Pgpool-II automatically falls + back to + and is ignored. + + + + This parameter relies + on being correctly + set and matching application_name in + your PostgreSQL standby's + primary_conninfo. + + + + If this parameter is + enabled, + and show replication delay in + seconds, rather than bytes. + + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + + prefer_lower_delay_standby (boolean) + + prefer_lower_delay_standby configuration parameter + + + + + This parameter is valid only + when + or is set to + greater than 0. When set to on, if the delay of the load + balancing node is greater + than + or , + Pgpool-II does not send read queries + to the primary node but the least delay standby with + backend_weight to greater than 0. If delay of all standby nodes + are greater than + or the primary + selected as the load balancing node + first, Pgpool-II sends to the + primary. Default is off. + + + This parameter can be changed by reloading the Pgpool-II configurations. + + + + + + log_standby_delay (enum) + + log_standby_delay configuration parameter + + + + + + Specifies when to log the replication delay. Below table contains the list + of all valid values for the parameter. + + + + Log standby delay options + + + + Value + Description + + + + + + none + Never log the standby delay + + + + always + Log the standby delay if it's greater than 0, every time the replication delay is checked + + + + if_over_threshold + Only log the standby delay, when it exceeds or value (the default) + + + +
+ + + This parameter can be changed by reloading the Pgpool-II configurations. + +
+
+ + + replication_delay_source_cmd (string) + + replication_delay_source_cmd configuration parameter + + + + + Specifies an external command to retrieve replication delay information + for replica nodes. When this parameter is set and not + empty, Pgpool-II uses the external command + instead of built-in database queries to obtain replication delays. The + command is executed as the Pgpool-II process + user. + + + The command receives replica node identifiers as positional arguments, + with the primary node omitted. Each identifier is in the + format <hostname>:<port>, for + example server1:5432 server2:5432. The order matches + Pgpool-II's backend order (excluding the + primary), allowing the script to correlate external metrics (such as from + AWS CloudWatch for Aurora) to the correct nodes. + + + The command must write a single line to stdout containing one + whitespace-separated delay value per replica, in milliseconds, in the + same order as the arguments. The line can be terminated with or without a + new line character. The primary node's delay is implicitly zero and + should not be included in the output. Delay values can be integers or + floating-point numbers. + + + Special value: -1 indicates a replica that is down but + not yet detected by Pgpool-II's health + checks. Pgpool-II will log this condition but + rely on its own health-check logic to decide whether to trigger failover; + no failover is triggered solely by receiving -1. + + + Example for a 3-node cluster (1 primary + 2 replicas): if the command + receives arguments + server1:5432 server2:5432, it should + output "25.5 100" to indicate the first replica has + 25.5ms delay and the second has 100ms delay. + + + Default is empty (use built-in replication delay queries). + + + This parameter can be changed by reloading the Pgpool-II + configurations. + + + + + + replication_delay_source_timeout (integer) + + replication_delay_source_timeout configuration parameter + + + + + Specifies the timeout in seconds for the external command specified by + . If the command does + not finish within the timeout, Pgpool-II logs + an error. + + + Default is 10 seconds. Valid range is 1-3600 seconds. + + + This parameter can be changed by reloading the Pgpool-II + configurations. + + + + +
diff --git a/doc/src/sgml/stylesheet.css b/doc/src/sgml/stylesheet.css index c4e185f0e..1cb5f406f 100644 --- a/doc/src/sgml/stylesheet.css +++ b/doc/src/sgml/stylesheet.css @@ -122,7 +122,7 @@ BLOCKQUOTE.NOTE, BLOCKQUOTE.TIP, table.CAUTION, table.WARNING, div.note, div.tip max-width: 720px; border-width: 1px; border-style: solid; - overfileow: auto; + overflow: auto; -moz-border-radius: 8px; -webkit-border-radius: 8px; -khtml-border-radius: 8px; diff --git a/doc/src/sgml/version.sgml b/doc/src/sgml/version.sgml index 997e1f0d5..001c98a34 100644 --- a/doc/src/sgml/version.sgml +++ b/doc/src/sgml/version.sgml @@ -1 +1 @@ - + diff --git a/doc/src/sgml/watchdog.sgml b/doc/src/sgml/watchdog.sgml index ce838d405..581cc3e89 100644 --- a/doc/src/sgml/watchdog.sgml +++ b/doc/src/sgml/watchdog.sgml @@ -1,575 +1,1054 @@ - Watchdog + Watchdog - + configuring watchdog - - Watchdog configuration parameters are described in pgpool.conf. - There is sample configuration in the WATCHDOG section of - pgpool.conf.sample file. - All following options are required to be specified in watchdog process. - - - - Enable watchdog - - - - use_watchdog (boolean) - - use_watchdog configuration parameter - - - - - If on, activates the watchdog. Default is off - - - This parameter can only be set at server start. - - - - - - - - Watchdog communication - - - - - wd_hostname (string) - - wd_hostname configuration parameter - - - - - Specifies the hostname or IP address of - Pgpool-II server. - This is used for sending/receiving queries and packets, - and also as an identifier of the watchdog node. - - - This parameter can only be set at server start. - - - - - - wd_port (integer) - - wd_port configuration parameter - - - - - Specifies the port number to be used by watchdog - process to listen for connections. Default is 9000. - - - This parameter can only be set at server start. - - - - - - wd_authkey (string) - - wd_authkey configuration parameter - - - - - Specifies the authentication key used for all watchdog communications. - All Pgpool-II must have the same key. - Packets from watchdog having different key will get rejected. - This authentication is also applied to the heatrbeat singals - when the heartbeat mode is used as a lifecheck method. - - - Since in Pgpool-IIV3.5 or beyond - wd_authkey is also used to authenticate - the watchdog IPC clients, - all clients communicating with Pgpool-II - watchdog process needs to provide this wd_authkey value - for "IPCAuthKey" key in the JSON data - of the command. - - - Default is '' (empty) which means disables - the watchdog authentication. - - - This parameter can only be set at server start. - - - - - - - - Upstream server connection - - - - - trusted_servers (string) - - trusted_servers configuration parameter - - - - - Specifies the list of trusted servers to check the up stream connections. - Each server in the list is required to respond to ping. - Specify a comma separated list of servers such as - "hostA,hostB,hostC". - If none of the server are reachable, watchdog will regard it as - failure of the Pgpool-II. - Therefore, it is recommended to specify multiple servers. - - - This parameter can only be set at server start. - - - - - - ping_path (string) - - ping_path configuration parameter - - - - - Specifies the path of a ping command for monitoring - connection to the upper servers. Set the only path of the directory containing the - ping utility, such as "/bin" or such directory. - - - This parameter can only be set at server start. - - - - - - - - Virtual IP control - - - - - delegate_IP (string) - - delegate_IP configuration parameter - - - - - Specifies the virtual IP address (VIP) of pgpool-II that is - connected from client servers (application servers etc.). - When a Pgpool-II is switched from standby to active, - the Pgpool-II takes over - this VIP. - Default is ''(empty): which means virtual - IP will never be brought up. - - - This parameter can only be set at server start. - - - - - - if_cmd_path (string) - - if_cmd_path configuration parameter - - - - - Specifies the path to the command that Pgpool-II - will use to switch the virtual IP on the system. - Set only the path of the directory containing the binary, - such as "/sbin" or such directory. - - - This parameter can only be set at server start. - - - - - - if_up_cmd (string) - - if_up_cmd configuration parameter - - - - - Specifies the command to bring up the virtual IP. - Set the command and parameters such as - "ip addr add $_IP_$/24 dev eth0 label eth0:0" - $_IP_$ will get replaced by the IP address - specified in the . - - - This parameter can only be set at server start. - - - - - - if_down_cmd (string) - - if_down_cmd configuration parameter - - - - - Specifies the command to bring down the virtual IP. - Set the command and parameters such as - "ip addr del $_IP_$/24 dev eth0". - - - This parameter can only be set at server start. - - - - - - arping_path (string) - - arping_path configuration parameter - - - - - Specifies the path to the command that Pgpool-II - will use to send the ARP requests after the virtual IP switch. - Set only the path of the directory containing the binary, - such as "/usr/sbin" or such directory. - + + Watchdog configuration parameters are described in pgpool.conf. + There is sample configuration in the WATCHDOG section of + pgpool.conf.sample file. + All following options are required to be specified in watchdog process. + + + + Enable watchdog + + + + use_watchdog (boolean) + + use_watchdog configuration parameter + + + + + If on, activates the watchdog. Default is off + + + This parameter can only be set at server start. + + + Pgpool-II 4.1 or earlier, because it is required to specify + its own pgpool node information and the destination pgpool nodes information, the + settings are different per pgpool node. + Since Pgpool-II 4.2, all configuration parameters are + identical on all hosts. If watchdog feature is enabled, to distinguish which host + is which, a pgpool_node_id file is required. + You need to create a pgpool_node_id file and specify the + pgpool (watchdog) node number (e.g. 0, 1, 2 ...) to identify pgpool (watchdog) host. + + + pgpool_node_id configuration + + If you have 3 pgpool nodes with hostname server1, server2 and server3, create the + pgpool_node_id file on each host as follows. + When installing Pgpool-II using RPM, + pgpool.conf is installed under /etc/pgpool-II/. + + + - This parameter can only be set at server start. + server1 - - - - - arping_cmd (string) - - arping_cmd configuration parameter - - - + +[server1]# cat /etc/pgpool-II/pgpool_node_id +0 + + + - Specifies the command to use for sending the ARP requests - after the virtual IP switch. - Set the command and parameters such as - "arping -U $_IP_$ -w 1". - $_IP_$ will get replaced by - the IP address specified in the delegate_IP. + server2 + +[server2]# cat /etc/pgpool-II/pgpool_node_id +1 + + + - This parameter can only be set at server start. + server3 - - + +[server3]# cat /etc/pgpool-II/pgpool_node_id +2 + + + + + + + + + + + Watchdog communication + + + + + hostnameX (string) + + hostnameX configuration parameter + + + + + Specifies the hostname or IP (IPv4 or IPv6) address of + Pgpool-II server. + This is used for sending/receiving queries and packets, + and also as an identifier of the watchdog node. + The number at the end of the parameter name is referred + as "pgpool node id", and it starts from 0 (e.g. hostname0). + + + This parameter can only be set at server start. + + + + + + wd_listen_address (string) + + wd_listen_address configuration parameter + + + + + Specifies the hostname or IP (IPv4 or IPv6) address which watchdog will listen on. + Default is '' (empty). Specify only one address here. + If a value other than the default value is set, + the value of hostnameX of the local node will be ignored and a socket + that listens on the address specified in wd_listen_address will be created. + For wd_listen_address, specifying * will listen on all addresses. + + + This parameter can only be set at server start. + + + + + wd_portX (integer) + + wd_portX configuration parameter + + + + + Specifies the port number to be used by watchdog + process to listen for connections. Default is 9000. + The number at the end of the parameter name is referred + as "pgpool node id", and it starts from 0 (e.g. wd_port0). + + + This parameter can only be set at server start. + + + + + + wd_listen_port (integer) + + wd_listen_port configuration parameter + + + + + Specifies the port number which watchdog will listen on. + Default is 0. Specify only one address here. + If a value other than the default value is set, + the value of wd_portX of the local node will be ignored and a socket + that listens on the port specified in wd_listen_port will be created. + + + This parameter can only be set at server start. + + + + + + pgpool_portX (integer) + + pgpool_portX configuration parameter + + + + + Specifies the Pgpool-II port number. + Default is 9999. + The number at the end of the parameter name is referred + as "pgpool node id", and it starts from 0 (e.g. pgpool_port0). + + + This parameter can only be set at server start. + + + + Watchdog configuration + + If you have 3 pgpool nodes with hostname server1, server2 and server3, + you can configure , + and like below: + +hostname0 = 'server1' +wd_port0 = 9000 +pgpool_port0 = 9999 + +hostname1 = 'server2' +wd_port1 = 9000 +pgpool_port1 = 9999 + +hostname2 = 'server3' +wd_port2 = 9000 +pgpool_port2 = 9999 + + + + + + + + wd_authkey (string) + + wd_authkey configuration parameter + + + + + Specifies the authentication key used for all watchdog communications. + All Pgpool-II must have the same key. + Packets from watchdog having different key will get rejected. + This authentication is also applied to the heartbeat signals + when the heartbeat mode is used as a lifecheck method. + + + Since in Pgpool-IIV3.5 or beyond + wd_authkey is also used to authenticate + the watchdog IPC clients, + all clients communicating with Pgpool-II + watchdog process needs to provide this wd_authkey value + for "IPCAuthKey" key in the JSON data + of the command. + + + Default is '' (empty) which means disables + the watchdog authentication. + + + This parameter can only be set at server start. + + + - + - - Behaivor on escalation and de-escalation + + Upstream server connection - - Configuration about behavior when Pgpool-II - escalates to active (virtual IP holder) - + + Upstream servers are the clients (DB clients) served by + Pgpool-II. + Even if Pgpool-II is alive and + connected to PostgreSQL, + if the link with the upstream server is broken, + Pgpool-II cannot provide services. + Therefore, the watchdog also monitors connections to upstream servers + from the Pgpool-II. + - + - - clear_memqcache_on_escalation (boolean) - - clear_memqcache_on_escalation configuration parameter - - - - - When set to on, watchdog clears all the query cache in the shared memory - when pgpool-II escaltes to active. This prevents the new active Pgpool-II - from using old query caches inconsistence to the old active. - - - Default is on. - - - This works only if - is 'shmem'. - - - This parameter can only be set at server start. - - - - - - wd_escalation_command (string) - - wd_escalation_command configuration parameter - - - - - Watchdog executes this command on the node that is escalated - to the master watchdog. - - - This command is executed just before bringing up the - virtual IP if that is configured on the node. - - - This parameter can only be set at server start. - - - - - - wd_de_escalation_command (string) - - wd_de_escalation_command configuration parameter - - - - - Watchdog executes this command on the master Pgpool-II - watchdog node when that node resigns from the master node responsibilities. - A master watchdog node can resign from being a master node, - when the master node Pgpool-II shuts down, detects a network - blackout or detects the lost of quorum. - - - This command is executed before bringing down the virtual/floating IP address - if it is configured on the watchdog node. - - - wd_de_escalation_command is not available prior to - Pgpool-II V3.5. - - - This parameter can only be set at server start. - - - + + trusted_servers (string) + + trusted_servers configuration parameter + + + + + Specifies the list of trusted servers to check the upstream connections. + For example, the list of upstream servers or routers between + Pgpool-II and upstream servers. + Each server in the list is required to respond to ping. + Specify a comma separated list of servers such as + "hostA,hostB,hostC". + If none of the server are reachable, watchdog will regard it as + failure of the Pgpool-II. + Therefore, it is recommended to specify multiple servers. + Please note that you should not assign PostgreSQL servers to this parameter. + + + This parameter can only be set at server start. + + + + + + trusted_server_command (string) + + trusted_server_command configuration parameter + + + + + Specifies a user command to run when Pgpool-II check + that trusted servers respond to ping. Any %h in the string is replaced by each host + name specified trusted_servers. Default is + ping -q -c3 %h. + + + This parameter can only be set at server start. + + + - - - - Controlling the Failover behavior - - - These settings are used to control the behavior of backend node failover when the watchdog is enabled. - The effect of these configurations is limited to the failover/degenerate requests initiated by - Pgpool-II internally, while the user initiated detach backend requests - (using PCP command) by-pass these configuration settings. - - - - - - failover_when_quorum_exists (boolean) - - failover_when_quorum_exists configuration parameter - - - - - When enabled, Pgpool-II will perform the degenerate/failover on - backend node if the quorum exists. In the absence of the quorum, Pgpool-II - node that detects the backend failure will quarantine the failed backend node until the quorum exists again. - - - The quarantine nodes behaves similar to the detached backend nodes but unlike failed/degenerated backends - the quarantine status is not propagated to the other Pgpool-II nodes in the - watchdog cluster, So even if the backend node is in the quarantine state on one - Pgpool-II node, other Pgpool-II nodes may - still continue to use that backend. - - - Although there are many similarities in quarantine and failover operations, but they both differ in a very - fundamental way. The quarantine operations does not executes the - and silently detaches the problematic node, So in the case when the master backend node is quarantined, the - Pgpool-II will not promote the standby to take over the master responsibilities - and until the master node is quarantined the Pgpool-II will not have - any useable master backend node. - - - Default is on. - - - failover_when_quorum_exists is not available prior to - Pgpool-II V3.7. - - - This parameter can only be set at server start. - - - - - - failover_require_consensus (boolean) - - failover_require_consensus configuration parameter - - - - - When enabled, Pgpool-II will perform the degenerate/failover on a - backend node if the watchdog quorum exists and at-least minimum number of nodes necessary - for the quorum vote for the failover. - - - For example, in a three node watchdog cluster, the failover will only be performed until at - least two nodes ask for performing the failover on the particular backend node. - - - Default is on. - + - - - When failover_require_consensus is - enabled, Pgpool-II does not - execute the failover until it get enough votes from - other Pgpool-II nodes. So it is - strongly recommended to enable the backend health check on - all - Pgpool-II nodes to ensure - proper detection of backend node failures. For more - details of health check, - see . - - + + Virtual IP control - - failover_require_consensus is not available prior to - Pgpool-II V3.7. and it is only - effective when is enabled - - - This parameter can only be set at server start. - - - - - - allow_multiple_failover_requests_from_node (boolean) - - allow_multiple_failover_requests_from_node configuration parameter - - - - - This parameter works in connection with the - . When enabled, a single Pgpool-II - node can cast multiple votes for the failover. - - - For example, in a three node watchdog cluster, if one Pgpool-II node sends two - failover requests for a particular backend node failover, Both requests will be counted as a separate - vote in the favor of the failover and Pgpool-II will execute the failover, - even if it does not get the vote from any other Pgpool-II node. - - - Default is off. - - - allow_multiple_failover_requests_from_node is not available prior to - Pgpool-II V3.7. and it is only - effective when both and - are enabled - - - This parameter can only be set at server start. - - - + + + + delegate_ip (string) + + delegate_ip configuration parameter + + + + + Specifies the virtual IP address (VIP) of + Pgpool-II that is connected from + client servers (application servers etc.). When a + Pgpool-II is switched from standby to + leader, the Pgpool-II takes over this + VIP. VIP will not be brought up in case the quorum + does not exist. Default is ''(empty): which + means virtual IP will never be brought up. + + + This parameter can only be set at server start. + + + + + if_cmd_path (string) + + if_cmd_path configuration parameter + + + + + Specifies the path to the command that Pgpool-II + will use to switch the virtual IP on the system. + Set only the path of the directory containing the binary, + such as "/sbin" or such directory. + If or starts with "/", + this parameter will be ignored. + Default is /sbin. + + + This parameter can only be set at server start. + + + + + + if_up_cmd (string) + + if_up_cmd configuration parameter + + + + + Specifies the command to bring up the virtual IP. + Set the command and parameters such as + "ip addr add $_IP_$/24 dev eth0 label eth0:0". + Since root privilege is required to execute this command, + use setuid on ip command or + allow Pgpool-II startup user (postgres user by default) + to run sudo command without a password, and specify it such as + "/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev eth0 label eth0:0". + $_IP_$ will get replaced by the IP address + specified in the . + + + Default is /usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev eth0 label eth0:0. + + + This parameter can only be set at server start. + + + + + + if_down_cmd (string) + + if_down_cmd configuration parameter + + + + + Specifies the command to bring down the virtual IP. + Set the command and parameters such as + "ip addr del $_IP_$/24 dev eth0". + Since root privilege is required to execute this command, + use setuid on ip command or + allow Pgpool-II startup user (postgres user by default) + to run sudo command without a password, and specify it such as + "/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev eth0". + $_IP_$ will get replaced by the IP address + specified in the . + + + Default is /usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev eth0. + + + This parameter can only be set at server start. + + + + + + arping_path (string) + + arping_path configuration parameter + + + + + Specifies the path to the command that Pgpool-II + will use to send the ARP requests after the virtual IP switch. + Set only the path of the directory containing the binary, + such as "/usr/sbin" or such directory. + If starts with "/", + this parameter will be ignored. + Default is /usr/sbin. + + + This parameter can only be set at server start. + + + + + + arping_cmd (string) + + arping_cmd configuration parameter + + + + + Specifies the command to use for sending the ARP requests + after the virtual IP switch. + Set the command and parameters such as + "arping -U $_IP_$ -w 1 -I eth0". + Since root privilege is required to execute this command, + use setuid on ip command or + allow Pgpool-II startup user (postgres user by default) + to run sudo command without a password, and specify it such as + "/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I eth0". + $_IP_$ will get replaced by + the IP address specified in the delegate_ip. + + + Default is /usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I eth0. + + + This parameter can only be set at server start. + + + + + + ping_path (string) + + ping_path configuration parameter + + + + + Specifies the path of a ping command to check startup of the virtual IP. + Set the only path of the directory containing the ping utility, + such as "/bin" or such directory. + Default is /bin. + + + This parameter can only be set at server start. + + + - + + + + Behaviour on escalation and de-escalation + + + Configuration about behavior when Pgpool-II + escalates to leader (virtual IP holder) + - - Life checking <productname>Pgpool-II</productname> + + + + clear_memqcache_on_escalation (boolean) + + clear_memqcache_on_escalation configuration parameter + + + + + When set to on, watchdog clears all the query cache in the shared memory + when pgpool-II escalates to leader. This prevents the new leader Pgpool-II + from using old query caches inconsistent to the old leader. + + + Default is on. + + + This works only if + is 'shmem'. + + + This parameter can only be set at server start. + + + + + wd_escalation_command (string) + + wd_escalation_command configuration parameter + + + + + Watchdog executes this command on the node that is escalated + to the leader watchdog. + + + This command is executed just before bringing up the + virtual IP if that is configured on the node. + + + This parameter can only be set at server start. + + + + + + wd_de_escalation_command (string) + + wd_de_escalation_command configuration parameter + + + + + Watchdog executes this command on the leader Pgpool-II + watchdog node when that node resigns from the leader node responsibilities. + A leader watchdog node can resign from being a leader node, + when the leader node Pgpool-II shuts down, detects a network + blackout or detects the lost of quorumquorum. + + + This command is executed before bringing down the virtual/floating IP address + if it is configured on the watchdog node. + + + wd_de_escalation_command is not available prior to + Pgpool-II V3.5. + + + This parameter can only be set at server start. + + + + + + + + Controlling the Failover behavior + + + These settings are used to control the behavior of backend node failover when the watchdog is enabled. + The effect of these configurations is limited to the failover/degenerate requests initiated by + Pgpool-II internally, while the user initiated detach backend requests + (using PCP command) by-pass these configuration settings. + + + + + + failover_when_quorum_exists (boolean) + + failover_when_quorum_exists configuration parameter + + + + + When enabled, Pgpool-II will consider quorumquorum when it performs the degenerate/failover on backend node. + + + We can say that "quorum exists" if the number of live + watchdog nodes (that is number + of Pgpool-II nodes) can be a + majority against the total number of watchdog nodes. For + example, suppose number of watchdog nodes is 5. If number of + live nodes is greater than or equal to 3, then quorum + exists. On the other hand if number of live nodes is 2 or + lower, quorum does not exist since it never be + majority. + + + If the quorum exists, Pgpool-II + could work better on failure detection because even if a + watchdog node mistakenly detects a failure of backend node, + it would be denied by other major watchdog nodes. + Pgpool-II works that way + when is on + (the default), but you can change it so that immediate + failover happens when a failure is detected. + A Pgpool-II node which mistakenly + detects failure of backend node will quarantine the backend + node. + + + The existence of quorum can be shown by invoking command with --verbose option. + If Quorum state is QUORUM EXIST or QUORUM IS ON THE EDGE, then the quorum exists. + If Quorum state is QUORUM ABSENT, then the quorum does not exist. + + + In the absence of the + quorum, Pgpool-II node that + detects the backend failure will quarantine the failed + backend node until the quorum exists again. + + + Although it is possible to force detaching the quarantine + node by using pcp_detach_node command, it + is not possible to attach the node again by + using pcp_attach_node command. + + + The quarantine + quarantine nodes behaves similar to the detached backend nodes + but unlike failed/degenerated backends the quarantine status is + not propagated to the other Pgpool-II + nodes in the watchdog cluster, So even if the backend node is in + the quarantine state on one Pgpool-II + node, other Pgpool-II nodes may still + continue to use that backend. + + + Although there are many similarities in quarantine and failover operations, but they both differ in a very + fundamental way. The quarantine operations does not executes the + and silently detaches the problematic node, so in the case when the primary backend node is quarantined, the + Pgpool-II will not promote the standby to take over the primary node responsibilities + and until the primary node is quarantined the Pgpool-II will not have + any usable primary backend node. + + + Moreover, unlike for the failed nodes, + Pgpool-II keeps the health-check + running on the quarantined nodes and as soon as the quarantined + node becomes reachable again it gets automatically + re-attached. Note that this is only applied to + Pgpool-II V4.1 + or greater. If you are using previous versions you need to + re-attach the quarantined node by using when the connectivity issue is + solved. + + + From Pgpool-II V4.1 onward, if the watchdog-leader node + fails to build the consensus for primary backend node failover and the primary backend node gets into a + quarantine state, then it resigns from its leader responsibilities and lowers its wd_priority + for next leader election and let the cluster elect some different new leader. + + + When the leader node fails to build the consensus for standby backend node failure, it takes no action + and similarly quarantined standby backend nodes on watchdog-leader do not trigger a new leader election. + + + + + If this parameter is off, failover will be triggered even if + quorum does not exist. + + + Default is on. + + + failover_when_quorum_exists is not available prior to + Pgpool-II V3.7. + + + This parameter can only be set at server start. + + - Watchdog checks pgpool-II status periodically. This is called "life check". + enabling failover_when_quorum_exists is not allowed in native replication mode. + + + - + + failover_require_consensus (boolean) + + failover_require_consensus configuration parameter + + + + + When enabled, Pgpool-II will perform the degenerate/failover on a + backend node if the watchdog quorum exists and at-least minimum number of nodes necessary + for the quorum vote for the failover. + + + For example, in a three node watchdog cluster, the failover will only be performed until at + least two nodes ask for performing the failover on the particular backend node. + + + If this parameter is off, failover will be triggered even if + there's no consensus. + + + Default is on. + + + + + When failover_require_consensus is + enabled, Pgpool-II does not + execute the failover until it get enough votes from + other Pgpool-II nodes. So it is + strongly recommended to enable the backend health check on + all + Pgpool-II nodes to ensure + proper detection of backend node failures. For more + details of health check, + see . + + - - wd_lifecheck_method (string) - - wd_lifecheck_method configuration parameter - - - + - Specifies the method of life check. This can be either of 'heartbeat' (default), - 'query' or 'external'. + enabling failover_require_consensus is not allowed in native replication mode. + + + + failover_require_consensus is not available prior to + Pgpool-II V3.7. and it is only + effective when is enabled + + + This parameter can only be set at server start. + + + + + + allow_multiple_failover_requests_from_node (boolean) + + allow_multiple_failover_requests_from_node configuration parameter + + + + + This parameter works in connection with the + . When enabled, a single Pgpool-II + node can cast multiple votes for the failover. + + + For example, in a three node watchdog cluster, if one Pgpool-II node sends two + failover requests for a particular backend node failover, Both requests will be counted as a separate + vote in the favor of the failover and Pgpool-II will execute the failover, + even if it does not get the vote from any other Pgpool-II node. + + + For example, if an error found in a health check round does + not get enough vote and the error still persists, next round + of health check will give one more vote. This parameter is + useful if you want to detect a persistent error which might + not be found by other watchdog nodes. + + + Default is off. + + + allow_multiple_failover_requests_from_node is not available prior to + Pgpool-II V3.7. and it is only + effective when both and + are enabled + + + This parameter can only be set at server start. + + + + + + enable_consensus_with_half_votes (boolean) + + enable_consensus_with_half_votes configuration parameter + + + + + This parameter configures how the majority rule computation + is made by Pgpool-II for calculating + the quorum and resolving the consensus for failover. + + - heartbeat: In this mode, watchdog sends the heartbeat singals (UDP packets) - periodically to other Pgpool-II. Similarly watchdog also receives the signals - from other Pgpool-II . - If there are no signal for a certain period, watchdog regards is as failure - of the Pgpool-II . - - - query: In this mode, watchdog sends the monitoring queries - to other Pgpool-II and checks the response - + This parameter affects not only the failover behavior of the + backend but the quorum and the failover behavior of + Pgpool-II itself. + + + + When enabled the existence of quorum and consensus on failover requires only half of + the total number of votes configured in the cluster. Otherwise, both of these + decisions require at least one more vote than half of the total number of votes. + For failover, this parameter works in conjunction with the + . In both cases, whether making a + decision of quorum existence or building the consensus on failover this + parameter only comes into play when the watchdog cluster is configured for even + number of Pgpool-II nodes. + The majority rule decision in the watchdog cluster having an odd number of participants. + It is not affected by the value of this configuration parameter. + + + For example, when this parameter is enabled in a two node watchdog + cluster, one Pgpool-II node needs to + be alive to make the quorum exist. If the parameter is off, two + nodes need to be alive to make quorum exist. + + + When this parameter is enabled in a four node watchdog cluster, + two Pgpool-II node needs to be alive + to make the quorum exist. If the parameter is off, three nodes + need to be alive to make quorum exist. + + + By enabling this parameter, you should aware that you take a + risk to make split-brain happen. For example, in four node + cluster consisted of node A, B, C and D, it is possible that the + cluster goes into two separated networks (A, B) and (C, D). For + (A, B) and (C, D) the quorum still exist since for both groups + there are two live nodes out of 4. The two groups choose their + own leader watchdog, which is a split-brain. + + + Default is off. + + + enable_consensus_with_half_votes is not available + prior to Pgpool-II + V4.1. The prior versions work + as if the parameter is on. + + + This parameter can only be set at server start. + + + + + + + + + Controlling the watchdog cluster membership + + + By default the watchdog cluster consists of all watchdog nodes + that are defined in the pgpool.conf file + irrespective of the current state of the node. Whether the node + is LOST, SHUTDOWN + or never started, the node is considered as the member of the + watchdog cluster definition as long as it is configured in the + configuration file. + All the majority rule computations for identifying the existence + of a quorum and resolving the consensus are made based on the + number of watchdog nodes that makes up the watchdog cluster. + + + + Pgpool-II V4.3 enables + dynamic cluster definition by introducing the concept of + Member and Nonmember. + If the node's membership gets revoked from the watchdog cluster, + then the cluster re-calibrate itself dynamically to adjust all + subsequent majority rule computations. + + + All majority rule computations are done based on the number of + member watchdog nodes instead of total number of configured nodes. + + + + For example: In a five node cluster (pgpool.conf has five + watchdog nodes defined) at-least three nodes need to be alive to make the quorum. + With the dynamic cluster membership mechanism the cluster can re-adjust + itself to only count the MEMBER nodes + (Member node doesn't necessarily need to be alive). + That means effectively a single alive node + can also fulfill the quorum requirements (depending on the membership criteria settings) + if at some point in time the cluster only has one or two member nodes. + + + + + Using the dynamic cluster membership has an associated risk of causing a split-brain. + So it is strongly recommended to carefully review if the setup requires the dynamic cluster + membership and consider using conservative values for related settings. + + + + + These settings configures when the node is marked as Nonmember. + Leaving all these settings to default values retains the + pre V4.3 behaviour. + + + + + + wd_remove_shutdown_nodes (boolean) + + wd_remove_shutdown_nodes configuration parameter + + + + + When enabled, the SHUTDOWN nodes are immediately marked as Nonmember + and removed from the cluster. If the previously shutdown node starts again, + it gets added to cluster automatically. + + Default is off. + + + + + + wd_lost_node_removal_timeout (integer) + + wd_lost_node_removal_timeout configuration parameter + + + + + Timeout in seconds to mark the LOST watchdog node as + Nonmember and remove from the cluster. + When LOST node re-connects to the cluster, its cluster membership is restored. + + + Setting the timeout to 0 disables the removal + of LOST nodes from cluster. + + Default is 0. + + + + + + wd_no_show_node_removal_timeout (integer) + + wd_no_show_node_removal_timeout configuration parameter + + + + + Timeout in seconds to mark the node as Nonmember if it doesn't show up + at cluster initialisation. Nonmember node becomes the cluster Member as + soon as it starts up and connects to the cluster. + + + Setting the timeout to 0 disables the removal + of NO-SHOW nodes from cluster. + + Default is 0. + + + + + + + + + Life checking <productname>Pgpool-II</productname> + + + Watchdog checks pgpool-II status periodically. This is called "life check". + + + + + + wd_lifecheck_method (enum) + + wd_lifecheck_method configuration parameter + + + + + Specifies the method of life check. This can be either of heartbeat (default), + query or external. + + + heartbeat: In this mode, watchdog sends the heartbeat signals (UDP packets) + periodically to other Pgpool-II. Similarly watchdog also receives the signals + from other Pgpool-II . + If there are no signal for a certain period, watchdog regards is as failure + of the Pgpool-II . + + + query: In this mode, watchdog sends the monitoring queries + to other Pgpool-II and checks the response. + When installation location between Pgpool-II + servers is far, query may be useful. + In query mode, you need to set - large enough if you plan to use watchdog. - This is because the watchdog process connects to - Pgpool-II as a client. - + large enough if you plan to use watchdog. + This is because the watchdog process connects to + Pgpool-II as a client. + - - + + external: This mode disables the built in lifecheck of Pgpool-II watchdog and relies on external system to provide node health checking of local and remote watchdog nodes. - + - + external mode is not available in versions prior to Pgpool-II V3.5. - + - + This parameter can only be set at server start. - - - + + + - + wd_monitoring_interfaces_list (string) - + wd_monitoring_interfaces_list configuration parameter - + - + Specify a comma separated list of network device names, to be monitored by the watchdog process for the network link state. If all network interfaces in the list becomes inactive (disabled or cable unplugged), the watchdog will consider it as a complete network failure @@ -577,434 +1056,427 @@ Specifying an ''(empty) list disables the network interface monitoring. Setting it to 'any' enables the monitoring on all available network interfaces except the loopback. Default is '' empty list (monitoring disabled). - + - + wd_monitoring_interfaces_list is not available in versions prior to Pgpool-II V3.5. - + - + This parameter can only be set at server start. - - - + + + - - wd_interval (integer) - + + wd_interval (integer) + wd_interval configuration parameter - - - - + + + + Specifies the interval between life checks of Pgpool-II in seconds. (A number greater than or equal to 1) Default is 10. - + - + This parameter can only be set at server start. - - + + - - wd_priority (integer) - + + wd_priority (integer) + wd_priority configuration parameter - - - - + + + + This parameter can be used to elevate the local watchdog node priority in the elections - to select master watchdog node. + to select leader watchdog node. The node with the higher wd_priority value will get selected - as master watchdog node when cluster will be electing its new master node - at the time of cluster startup or in the event of old master watchdog node failure - - - wd_priority is not available in versions prior to - Pgpool-II V3.5. - + as leader watchdog node when cluster will be electing its new leader node + in the event of old leader watchdog node failure. + wd_priority is also valid at the time of cluster startup. + When some watchdog nodes start up at same time,a node with the higher wd_priority + value is selected as a leader node. + So we should start watchdog nodes in order of wd_priority priority to prevent + unintended nodes from being selected as leader. + If wd_priority of each nodes has the same value, + leader node will be decided on base of starting time of watchdog. + + + wd_priority is not available in versions prior to + Pgpool-II V3.5. + - + This parameter can only be set at server start. - - - + + + - - wd_ipc_socket_dir (string) - + + wd_ipc_socket_dir (string) + wd_ipc_socket_dir configuration parameter - - - - + + + + The directory where the UNIX domain socket - accepting Pgpool-II + accepting Pgpool-II watchdog IPC connections will be created. Default is '/tmp'. Be aware that this socket might be deleted by a cron job. We recommend to set this value to '/var/run' or such directory. - - + + wd_ipc_socket_dir is not available in versions prior to Pgpool-II V3.5. - - - This parameter can only be set at server start. - - - - - - - - - Lifecheck Heartbeat mode configuration - - - - wd_heartbeat_port (integer) - - wd_heartbeat_port configuration parameter - - - - - Specifies the UDP port number to receive heartbeat signals. - Default is 9694. - wd_heartbeat_port is only applicable if the + + + This parameter can only be set at server start. + + + + + + + + + Lifecheck Heartbeat mode configuration + + + heartbeat_hostnameX (string) + + heartbeat_hostnameX configuration parameter + + + + + Specifies the IP (IPv4 or IPv6) address or hostname + for sending and receiving the heartbeat signals. + The number at the end of the parameter name is referred + as "pgpool node id", and it starts from 0 (e.g. heartbeat_hostname0). + You can specify multiple IP address or hostname + by separating them using semicolon (;). + + + heartbeat_hostnameX is only applicable if the + is set to 'heartbeat' + + + This parameter can only be set at server start. + + + + + + wd_heartbeat_listen_addresses (string) + + wd_heartbeat_listen_addresses configuration parameter + + + + + Specifies the IP (IPv4 or IPv6) address or hostname + which heartbeat process will listen on. + Default is '' (empty). + You can specify multiple IP address or hostname + by separating them using semicolon (;). + If a value other than the default value is set, + the value of heartbeat_hostnameX of the local node will be ignored and a socket + that listens on the address specified in wd_heartbeat_listen_addresses will be created. + For wd_heartbeat_listen_addresses, specifying * will listen on all addresses. + + + This parameter can only be set at server start. + + + + + + heartbeat_portX (integer) + + heartbeat_portX configuration parameter + + + + + Specifies the port number for sending and receiving the heartbeat signals. + Specify only one port number here. Default is 9694. + The number at the end of the parameter name is referred + as "pgpool node id", and it starts from 0 (e.g. heartbeat_port0). + + + heartbeat_portX is only applicable if the + is set to 'heartbeat' + + + This parameter can only be set at server start. + + + + + + wd_heartbeat_listen_port (integer) + + wd_heartbeat_listen_port configuration parameter + + + + + Specifies the port number which heartbeat process will listen on. + Specify only one port number here. Default is 0. + If a value other than the default value is set, + the value of heartbeat_portX of the local node will be ignored and a socket + that listens on the port specified in wd_heartbeat_listen_port will be created. + + + This parameter can only be set at server start. + + + + + + heartbeat_deviceX (string) + + heartbeat_deviceX configuration parameter + + + + + Specifies the network device name for sending and receiving the heartbeat signals. + The number at the end of the parameter name is referred + as "pgpool node id", and it starts from 0 (e.g. heartbeat_device0). + You can specify multiple network devices by separating them using semicolon (;). + + + heartbeat_deviceX is only applicable if + Pgpool-II is started with root + privilege. If not, leave it as an empty string (''). + + + heartbeat_deviceX is only applicable if the is set to 'heartbeat' - - + + This parameter can only be set at server start. - - - + + + Heartbeat configuration + + If you have 3 pgpool nodes with hostname server1, server2 and server3, + you can configure , + and like below: + + heartbeat_hostname0 = 'server1' + heartbeat_port0 = 9694 + heartbeat_device0 = '' + + heartbeat_hostname1 = 'server2' + heartbeat_port1 = 9694 + heartbeat_device1 = '' + + heartbeat_hostname2 = 'server3' + heartbeat_port2 = 9694 + heartbeat_device2 = '' + + + + + - - wd_heartbeat_keepalive (integer) - + + wd_heartbeat_keepalive (integer) + wd_heartbeat_keepalive configuration parameter - - - - + + + + Specifies the interval time in seconds between sending the heartbeat signals. Default is 2. wd_heartbeat_keepalive is only applicable if the is set to 'heartbeat' - + - + This parameter can only be set at server start. - - - + + + - - wd_heartbeat_deadtime (integer) - + + wd_heartbeat_deadtime (integer) + wd_heartbeat_deadtime configuration parameter - - - - + + + + Specifies the time in seconds before marking the remote watchdog node as failed/dead node, if no heartbeat signal is received within that time. Default is 30 wd_heartbeat_deadtime is only applicable if the is set to 'heartbeat' - - - This parameter can only be set at server start. - - - - - - heartbeat_destination0 (string) - - heartbeat_destination configuration parameter - - - - - Specifies the IP address or hostname of destination the remote - Pgpool-II for sending the heartbeat signals. - Multiple destinations can be configured for the heartbeat singnals, - the number at the end of the parameter name is - referred as the "destination number", that starts from 0. - - - heartbeat_destination is only applicable if the - is set to 'heartbeat' - - - This parameter can only be set at server start. - - - - - - heartbeat_destination_port0 (integer) - - heartbeat_destination_port configuration parameter - - - - - Specifies the destination port number of the remote - Pgpool-II for sending the heartbeat signals. - Multiple destinations can be configured for the heartbeat singnals, - the number at the end of the parameter name is - referred as the "destination number", that starts from 0. - - - heartbeat_destination_port is only applicable if the - is set to 'heartbeat' - - - This parameter can only be set at server start. - - - - - - heartbeat_device0 (string) - - heartbeat_device configuration parameter - - - - - Specifies the network device name for sending the heartbeat signals to the destination specified by - heartbeat_destinationX:heartbeat_destination_portX - Different heartbeat devices can be configured for each heartbeat destination - by changing the value of X(destination number). - at the end of parameter name. The destination index number starts from 0. - - - heartbeat_device is only applicable if the - is set to 'heartbeat' - - + + This parameter can only be set at server start. - + - - - - + + + - - Lifecheck Query mode configuration + + Lifecheck Query mode configuration - - wd_life_point (integer) - + + wd_life_point (integer) + wd_life_point configuration parameter - - - - + + + + Specifies the number of times to retry a failed life check of pgpool-II. Valid value could be a number greater than or equal to 1. Default is 3. - - + + wd_life_point is only applicable if the is set to 'query' - - + + This parameter can only be set at server start. - + - + - - wd_lifecheck_query (string) - + + wd_lifecheck_query (string) + wd_lifecheck_query configuration parameter - - - - + + + + Specifies the query to use for the life check of remote Pgpool-II. Default is "SELECT 1". - - + + wd_lifecheck_query is only applicable if the is set to 'query' - - + + This parameter can only be set at server start. - + - + - - wd_lifecheck_dbname (string) - + + wd_lifecheck_dbname (string) + wd_lifecheck_dbname configuration parameter - - - - + + + + Specifies the database name for the connection used for the - life check of remote Pgpool-II. + life check of remote Pgpool-II. Default is "template1". - - + + wd_lifecheck_dbname is only applicable if the is set to 'query' - - + + This parameter can only be set at server start. - + - + - - wd_lifecheck_user (string) - + + wd_lifecheck_user (string) + wd_lifecheck_user configuration parameter - - - - + + + + Specifies the user name for the connection used for the life - check of remote Pgpool-II. - Default is "nobody". - - + check of remote Pgpool-II. + Default is ''(empty). + + wd_lifecheck_user is only applicable if the is set to 'query' - - + + This parameter can only be set at server start. - + - + - - wd_lifecheck_password (string) - + + wd_lifecheck_password (string) + wd_lifecheck_password configuration parameter - - - - + + + + Specifies the password for the user used for the life check of remote Pgpool-II. - - - If wd_lifecheck_password is left blank Pgpool-II - will first try to get the password for from - file before using the empty password. - - - You can also specify AES256-CBC encrypted password in wd_lifecheck_password field. - To specify the AES encrypted password, password string must be prefixed with - AES after encrypting (using aes-256-cbc algorithm) and - encoding to base64. - - - To specify the unencrypted clear text password, prefix the password string with - TEXT. For example if you want to set mypass as - a password, you should specify TEXTmypass in the password field. - In the absence of a valid prefix, Pgpool-II will considered - the string as a plain text password. - - - You can also use utility to create the correctly formatted - AES encrypted password strings. - - - Pgpool-II will require a valid decryption key at the - startup to use the encrypted passwords. - see for more details on providing the - decryption key to Pgpool-II - - - - + + + If wd_lifecheck_password is left blank Pgpool-II + will first try to get the password for from + file before using the empty password. + + + You can also specify AES256-CBC encrypted password in wd_lifecheck_password field. + To specify the AES encrypted password, password string must be prefixed with + AES after encrypting (using aes-256-cbc algorithm) and + encoding to base64. + + + To specify the unencrypted clear text password, prefix the password string with + TEXT. For example if you want to set mypass as + a password, you should specify TEXTmypass in the password field. + In the absence of a valid prefix, Pgpool-II will considered + the string as a plain text password. + + + You can also use utility to create the correctly formatted + AES encrypted password strings. + + + Pgpool-II will require a valid decryption key at the + startup to use the encrypted passwords. + see for more details on providing the + decryption key to Pgpool-II + + + + wd_lifecheck_password is only applicable if the is set to 'query' - - + + This parameter can only be set at server start. - - + + Default is ''(empty). - - - - - - - - - Watchdog servers configurations - - - - other_pgpool_hostname0 (string) - - other_pgpool_hostname configuration parameter - - - - - Specifies the hostname of remote Pgpool-II server for watchdog node. - The number at the end of the parameter name is referred as "server id", and it starts from 0. - - - This parameter can only be set at server start. - - - - - - other_pgpool_port0 (integer) - - other_pgpool_port configuration parameter - - - - - Specifies the port number of the remote Pgpool-II - server for watchdog node. - The number at the end of the parameter name is referred - as "server id", and it starts from 0. - - - This parameter can only be set at server start. - - - - - - other_wd_port0 (integer) - - other_wd_port0 configuration parameter - - - - - Specifies the watchdog port number of the remote - Pgpool-II server for watchdog node. - The number at the end of the parameter name is referred - as "server id", and it starts from 0. - - - This parameter can only be set at server start. - + - + - - + + diff --git a/install-sh b/install-sh deleted file mode 100755 index a9244eb07..000000000 --- a/install-sh +++ /dev/null @@ -1,527 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2011-01-19.21; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# 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 -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - # Protect names problematic for `test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for `test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for `test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/ltmain.sh b/ltmain.sh deleted file mode 100755 index c2852d856..000000000 --- a/ltmain.sh +++ /dev/null @@ -1,9661 +0,0 @@ - -# libtool (GNU libtool) 2.4.2 -# Written by Gordon Matzigkeit , 1996 - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010, 2011 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. - -# GNU Libtool 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 2 of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --no-quiet, --no-silent -# print informational messages (default) -# --no-warn don't display warning messages -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print more informational messages than default -# --no-verbose don't print the extra informational messages -# --version print version information -# -h, --help, --help-all print short, long, or detailed help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. When passed as first option, -# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to . -# GNU libtool home page: . -# General help using GNU software: . - -PROGRAM=libtool -PACKAGE=libtool -VERSION="2.4.2 Debian-2.4.2-1ubuntu1" -TIMESTAMP="" -package_revision=1.3337 - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - -# NLS nuisances: We save the old values to restore during execute mode. -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" - fi" -done -LC_ALL=C -LANGUAGE=C -export LANGUAGE LC_ALL - -$lt_unset CDPATH - - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - - - -: ${CP="cp -f"} -test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -exit_status=$EXIT_SUCCESS - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" - -dirname="s,/[^/]*$,," -basename="s,^.*/,," - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} # func_dirname may be replaced by extended shell implementation - - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} # func_basename may be replaced by extended shell implementation - - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} # func_dirname_and_basename may be replaced by extended shell implementation - - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname may be replaced by extended shell implementation - - -# These SED scripts presuppose an absolute path with a trailing slash. -pathcar='s,^/\([^/]*\).*$,\1,' -pathcdr='s,^/[^/]*,,' -removedotparts=':dotsl - s@/\./@/@g - t dotsl - s,/\.$,/,' -collapseslashes='s@/\{1,\}@/@g' -finalslash='s,/*$,/,' - -# func_normal_abspath PATH -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -# value returned in "$func_normal_abspath_result" -func_normal_abspath () -{ - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` - while :; do - # Processed it all yet? - if test "$func_normal_abspath_tpath" = / ; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result" ; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - -# func_relative_path SRCDIR DSTDIR -# generates a relative path from SRCDIR to DSTDIR, with a trailing -# slash if non-empty, suitable for immediately appending a filename -# without needing to append a separator. -# value returned in "$func_relative_path_result" -func_relative_path () -{ - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=${func_dirname_result} - if test "x$func_relative_path_tlibdir" = x ; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done - - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test "x$func_stripname_result" != x ; then - func_relative_path_result=${func_relative_path_result}/${func_stripname_result} - fi - - # Normalisation. If bindir is libdir, return empty string, - # else relative path ending with a slash; either way, target - # file name can be directly appended. - if test ! -z "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result/" - func_relative_path_result=$func_stripname_result - fi -} - -# The name of this program: -func_dirname_and_basename "$progpath" -progname=$func_basename_result - -# Make sure we have an absolute path for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=$func_dirname_result - progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" - ;; - *) - save_IFS="$IFS" - IFS=${PATH_SEPARATOR-:} - for progdir in $PATH; do - IFS="$save_IFS" - test -x "$progdir/$progname" && break - done - IFS="$save_IFS" - test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' - -# Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" - -# Standard options: -opt_dry_run=false -opt_help=false -opt_quiet=false -opt_verbose=false -opt_warning=: - -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }$*" -} - -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $opt_verbose && func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 -} - -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () -{ - $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 - - # bash bug again: - : -} - -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" -} -help="Try \`$progname --help' for more information." ## default - - -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - my_directory_path="$1" - my_dir_list= - - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then - - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" - - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` - done - my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` - - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" - - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi -} - - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - - $ECHO "$my_tmpdir" -} - - -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. -func_quote_for_eval () -{ - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac - - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac -} - - -# func_quote_for_expand arg -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - case $1 in - *[\\\`\"]*) - my_arg=`$ECHO "$1" | $SED \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; - *) - my_arg="$1" ;; - esac - - case $my_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" - ;; - esac - - func_quote_for_expand_result="$my_arg" -} - - -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - - -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - -# func_tr_sh -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} - - -# func_version -# Echo version message to standard output and exit. -func_version () -{ - $opt_debug - - $SED -n '/(C)/!b go - :more - /\./!{ - N - s/\n# / / - b more - } - :go - /^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? -} - -# func_usage -# Echo short help message to standard output and exit. -func_usage () -{ - $opt_debug - - $SED -n '/^# Usage:/,/^# *.*--help/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - echo - $ECHO "run \`$progname --help | more' for full usage" - exit $? -} - -# func_help [NOEXIT] -# Echo long help message to standard output and exit, -# unless 'noexit' is passed as argument. -func_help () -{ - $opt_debug - - $SED -n '/^# Usage:/,/# Report bugs to/ { - :print - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ - p - d - } - /^# .* home page:/b print - /^# General help using/b print - ' < "$progpath" - ret=$? - if test -z "$1"; then - exit $ret - fi -} - -# func_missing_arg argname -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - $opt_debug - - func_error "missing argument for $1." - exit_cmd=exit -} - - -# func_split_short_opt shortopt -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -func_split_short_opt () -{ - my_sed_short_opt='1s/^\(..\).*$/\1/;q' - my_sed_short_rest='1s/^..\(.*\)$/\1/;q' - - func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` - func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` -} # func_split_short_opt may be replaced by extended shell implementation - - -# func_split_long_opt longopt -# Set func_split_long_opt_name and func_split_long_opt_arg shell -# variables after splitting LONGOPT at the `=' sign. -func_split_long_opt () -{ - my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' - my_sed_long_arg='1s/^--[^=]*=//' - - func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` - func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` -} # func_split_long_opt may be replaced by extended shell implementation - -exit_cmd=: - - - - - -magic="%%%MAGIC variable%%%" -magic_exe="%%%MAGIC EXE variable%%%" - -# Global variables. -nonopt= -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "${1}=\$${1}\${2}" -} # func_append may be replaced by extended shell implementation - -# func_append_quoted var value -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -func_append_quoted () -{ - func_quote_for_eval "${2}" - eval "${1}=\$${1}\\ \$func_quote_for_eval_result" -} # func_append_quoted may be replaced by extended shell implementation - - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "${@}"` -} # func_arith may be replaced by extended shell implementation - - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` -} # func_len may be replaced by extended shell implementation - - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} # func_lo2o may be replaced by extended shell implementation - - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} # func_xform may be replaced by extended shell implementation - - -# func_fatal_configuration arg... -# Echo program name prefixed message to standard error, followed by -# a configuration failure hint, and exit. -func_fatal_configuration () -{ - func_error ${1+"$@"} - func_error "See the $PACKAGE documentation for more information." - func_fatal_error "Fatal configuration error." -} - - -# func_config -# Display the configuration for all the tags in this script. -func_config () -{ - re_begincf='^# ### BEGIN LIBTOOL' - re_endcf='^# ### END LIBTOOL' - - # Default configuration. - $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" - - # Now print the configurations for the tags. - for tagname in $taglist; do - $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" - done - - exit $? -} - -# func_features -# Display the features supported by this script. -func_features () -{ - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - - exit $? -} - -# func_enable_tag tagname -# Verify that TAGNAME is valid, and either flag an error and exit, or -# enable the TAGNAME tag. We also add TAGNAME to the global $taglist -# variable here. -func_enable_tag () -{ - # Global variable: - tagname="$1" - - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf="/$re_begincf/,/$re_endcf/p" - - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac - - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; - *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac -} - -# func_check_version_match -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF - fi - - exit $EXIT_MISMATCH - fi -} - - -# Shorthand for --mode=foo, only valid as the first argument -case $1 in -clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; -compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; -execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; -finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; -install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; -link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; -uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; -esac - - - -# Option defaults: -opt_debug=: -opt_dry_run=false -opt_config=false -opt_preserve_dup_deps=false -opt_features=false -opt_finish=false -opt_help=false -opt_help_all=false -opt_silent=: -opt_warning=: -opt_verbose=: -opt_silent=false -opt_verbose=false - - -# Parse options once, thoroughly. This comes as soon as possible in the -# script to make things like `--version' happen as quickly as we can. -{ - # this just eases exit handling - while test $# -gt 0; do - opt="$1" - shift - case $opt in - --debug|-x) opt_debug='set -x' - func_echo "enabling shell trace mode" - $opt_debug - ;; - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - --config) - opt_config=: -func_config - ;; - --dlopen|-dlopen) - optarg="$1" - opt_dlopen="${opt_dlopen+$opt_dlopen -}$optarg" - shift - ;; - --preserve-dup-deps) - opt_preserve_dup_deps=: - ;; - --features) - opt_features=: -func_features - ;; - --finish) - opt_finish=: -set dummy --mode finish ${1+"$@"}; shift - ;; - --help) - opt_help=: - ;; - --help-all) - opt_help_all=: -opt_help=': help-all' - ;; - --mode) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_mode="$optarg" -case $optarg in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; -esac - shift - ;; - --no-silent|--no-quiet) - opt_silent=false -func_append preserve_args " $opt" - ;; - --no-warning|--no-warn) - opt_warning=false -func_append preserve_args " $opt" - ;; - --no-verbose) - opt_verbose=false -func_append preserve_args " $opt" - ;; - --silent|--quiet) - opt_silent=: -func_append preserve_args " $opt" - opt_verbose=false - ;; - --verbose|-v) - opt_verbose=: -func_append preserve_args " $opt" -opt_silent=false - ;; - --tag) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_tag="$optarg" -func_append preserve_args " $opt $optarg" -func_enable_tag "$optarg" - shift - ;; - - -\?|-h) func_usage ;; - --help) func_help ;; - --version) func_version ;; - - # Separate optargs to long options: - --*=*) - func_split_long_opt "$opt" - set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-n*|-v*) - func_split_short_opt "$opt" - set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognized option \`$opt'" ;; - *) set dummy "$opt" ${1+"$@"}; shift; break ;; - esac - done - - # Validate options: - - # save first non-option argument - if test "$#" -gt 0; then - nonopt="$opt" - shift - fi - - # preserve --debug - test "$opt_debug" = : || func_append preserve_args " --debug" - - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac - - $opt_help || { - # Sanity checks first: - func_check_version_match - - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test "$opt_mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$opt_mode' for more information." - } - - - # Bail if the options were screwed - $exit_cmd $EXIT_FAILURE -} - - - - -## ----------- ## -## Main. ## -## ----------- ## - -# func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_lalib_p () -{ - test -f "$1" && - $SED -e 4q "$1" 2>/dev/null \ - | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 -} - -# func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function implements the same check as func_lalib_p without -# resorting to external programs. To this end, it redirects stdin and -# closes it afterwards, without saving the original file descriptor. -# As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. -func_lalib_unsafe_p () -{ - lalib_p=no - if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then - for lalib_p_l in 1 2 3 4 - do - read lalib_p_line - case "$lalib_p_line" in - \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; - esac - done - exec 0<&5 5<&- - fi - test "$lalib_p" = yes -} - -# func_ltwrapper_script_p file -# True iff FILE is a libtool wrapper script -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_script_p () -{ - func_lalib_p "$1" -} - -# func_ltwrapper_executable_p file -# True iff FILE is a libtool wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_executable_p () -{ - func_ltwrapper_exec_suffix= - case $1 in - *.exe) ;; - *) func_ltwrapper_exec_suffix=.exe ;; - esac - $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 -} - -# func_ltwrapper_scriptname file -# Assumes file is an ltwrapper_executable -# uses $file to determine the appropriate filename for a -# temporary ltwrapper_script. -func_ltwrapper_scriptname () -{ - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" -} - -# func_ltwrapper_p file -# True iff FILE is a libtool wrapper script or wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_p () -{ - func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" -} - - -# func_execute_cmds commands fail_cmd -# Execute tilde-delimited COMMANDS. -# If FAIL_CMD is given, eval that upon failure. -# FAIL_CMD may read-access the current command in variable CMD! -func_execute_cmds () -{ - $opt_debug - save_ifs=$IFS; IFS='~' - for cmd in $1; do - IFS=$save_ifs - eval cmd=\"$cmd\" - func_show_eval "$cmd" "${2-:}" - done - IFS=$save_ifs -} - - -# func_source file -# Source FILE, adding directory component if necessary. -# Note that it is not necessary on cygwin/mingw to append a dot to -# FILE even if both FILE and FILE.exe exist: automatic-append-.exe -# behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. -func_source () -{ - $opt_debug - case $1 in - */* | *\\*) . "$1" ;; - *) . "./$1" ;; - esac -} - - -# func_resolve_sysroot PATH -# Replace a leading = in PATH with a sysroot. Store the result into -# func_resolve_sysroot_result -func_resolve_sysroot () -{ - func_resolve_sysroot_result=$1 - case $func_resolve_sysroot_result in - =*) - func_stripname '=' '' "$func_resolve_sysroot_result" - func_resolve_sysroot_result=$lt_sysroot$func_stripname_result - ;; - esac -} - -# func_replace_sysroot PATH -# If PATH begins with the sysroot, replace it with = and -# store the result into func_replace_sysroot_result. -func_replace_sysroot () -{ - case "$lt_sysroot:$1" in - ?*:"$lt_sysroot"*) - func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result="=$func_stripname_result" - ;; - *) - # Including no sysroot. - func_replace_sysroot_result=$1 - ;; - esac -} - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - $opt_debug - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case "$@ " in - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" -# else -# func_verbose "using $tagname tagged configuration" - fi - ;; - esac - fi -} - - - -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () -{ - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' - else - write_lobj=none - fi - - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' - else - write_oldobj=none - fi - - $opt_dry_run || { - cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then - func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$lt_sed_naive_backslashify"` - else - func_convert_core_file_wine_to_w32_result= - fi - fi -} -# end: func_convert_core_file_wine_to_w32 - - -# func_convert_core_path_wine_to_w32 ARG -# Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. -# -# ARG is path to be converted from $build format to win32. -# Result is available in $func_convert_core_path_wine_to_w32_result. -# Unconvertible file (directory) names in ARG are skipped; if no directory names -# are convertible, then the result may be empty. -func_convert_core_path_wine_to_w32 () -{ - $opt_debug - # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result="" - if test -n "$1"; then - oldIFS=$IFS - IFS=: - for func_convert_core_path_wine_to_w32_f in $1; do - IFS=$oldIFS - func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result" ; then - if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" - else - func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" - fi - fi - done - IFS=$oldIFS - fi -} -# end: func_convert_core_path_wine_to_w32 - - -# func_cygpath ARGS... -# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when -# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) -# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or -# (2), returns the Cygwin file name or path in func_cygpath_result (input -# file name or path is assumed to be in w32 format, as previously converted -# from $build's *nix or MSYS format). In case (3), returns the w32 file name -# or path in func_cygpath_result (input file name or path is assumed to be in -# Cygwin format). Returns an empty string on error. -# -# ARGS are passed to cygpath, with the last one being the file name or path to -# be converted. -# -# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH -# environment variable; do not put it in $PATH. -func_cygpath () -{ - $opt_debug - if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then - func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` - if test "$?" -ne 0; then - # on failure, ensure result is empty - func_cygpath_result= - fi - else - func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" - fi -} -#end: func_cygpath - - -# func_convert_core_msys_to_w32 ARG -# Convert file name or path ARG from MSYS format to w32 format. Return -# result in func_convert_core_msys_to_w32_result. -func_convert_core_msys_to_w32 () -{ - $opt_debug - # awkward: cmd appends spaces to result - func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` -} -#end: func_convert_core_msys_to_w32 - - -# func_convert_file_check ARG1 ARG2 -# Verify that ARG1 (a file name in $build format) was converted to $host -# format in ARG2. Otherwise, emit an error message, but continue (resetting -# func_to_host_file_result to ARG1). -func_convert_file_check () -{ - $opt_debug - if test -z "$2" && test -n "$1" ; then - func_error "Could not determine host file name corresponding to" - func_error " \`$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_file_result="$1" - fi -} -# end func_convert_file_check - - -# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH -# Verify that FROM_PATH (a path in $build format) was converted to $host -# format in TO_PATH. Otherwise, emit an error message, but continue, resetting -# func_to_host_file_result to a simplistic fallback value (see below). -func_convert_path_check () -{ - $opt_debug - if test -z "$4" && test -n "$3"; then - func_error "Could not determine the host path corresponding to" - func_error " \`$3'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This is a deliberately simplistic "conversion" and - # should not be "improved". See libtool.info. - if test "x$1" != "x$2"; then - lt_replace_pathsep_chars="s|$1|$2|g" - func_to_host_path_result=`echo "$3" | - $SED -e "$lt_replace_pathsep_chars"` - else - func_to_host_path_result="$3" - fi - fi -} -# end func_convert_path_check - - -# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG -# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT -# and appending REPL if ORIG matches BACKPAT. -func_convert_path_front_back_pathsep () -{ - $opt_debug - case $4 in - $1 ) func_to_host_path_result="$3$func_to_host_path_result" - ;; - esac - case $4 in - $2 ) func_append func_to_host_path_result "$3" - ;; - esac -} -# end func_convert_path_front_back_pathsep - - -################################################## -# $build to $host FILE NAME CONVERSION FUNCTIONS # -################################################## -# invoked via `$to_host_file_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# Result will be available in $func_to_host_file_result. - - -# func_to_host_file ARG -# Converts the file name ARG from $build format to $host format. Return result -# in func_to_host_file_result. -func_to_host_file () -{ - $opt_debug - $to_host_file_cmd "$1" -} -# end func_to_host_file - - -# func_to_tool_file ARG LAZY -# converts the file name ARG from $build format to toolchain format. Return -# result in func_to_tool_file_result. If the conversion in use is listed -# in (the comma separated) LAZY, no conversion takes place. -func_to_tool_file () -{ - $opt_debug - case ,$2, in - *,"$to_tool_file_cmd",*) - func_to_tool_file_result=$1 - ;; - *) - $to_tool_file_cmd "$1" - func_to_tool_file_result=$func_to_host_file_result - ;; - esac -} -# end func_to_tool_file - - -# func_convert_file_noop ARG -# Copy ARG to func_to_host_file_result. -func_convert_file_noop () -{ - func_to_host_file_result="$1" -} -# end func_convert_file_noop - - -# func_convert_file_msys_to_w32 ARG -# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_file_result. -func_convert_file_msys_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_to_host_file_result="$func_convert_core_msys_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_w32 - - -# func_convert_file_cygwin_to_w32 ARG -# Convert file name ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_file_cygwin_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # because $build is cygwin, we call "the" cygpath in $PATH; no need to use - # LT_CYGPATH in this case. - func_to_host_file_result=`cygpath -m "$1"` - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_cygwin_to_w32 - - -# func_convert_file_nix_to_w32 ARG -# Convert file name ARG from *nix to w32 format. Requires a wine environment -# and a working winepath. Returns result in func_to_host_file_result. -func_convert_file_nix_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_w32 - - -# func_convert_file_msys_to_cygwin ARG -# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_file_msys_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_cygwin - - -# func_convert_file_nix_to_cygwin ARG -# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed -# in a wine environment, working winepath, and LT_CYGPATH set. Returns result -# in func_to_host_file_result. -func_convert_file_nix_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. - func_convert_core_file_wine_to_w32 "$1" - func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_cygwin - - -############################################# -# $build to $host PATH CONVERSION FUNCTIONS # -############################################# -# invoked via `$to_host_path_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# The result will be available in $func_to_host_path_result. -# -# Path separators are also converted from $build format to $host format. If -# ARG begins or ends with a path separator character, it is preserved (but -# converted to $host format) on output. -# -# All path conversion functions are named using the following convention: -# file name conversion function : func_convert_file_X_to_Y () -# path conversion function : func_convert_path_X_to_Y () -# where, for any given $build/$host combination the 'X_to_Y' value is the -# same. If conversion functions are added for new $build/$host combinations, -# the two new functions must follow this pattern, or func_init_to_host_path_cmd -# will break. - - -# func_init_to_host_path_cmd -# Ensures that function "pointer" variable $to_host_path_cmd is set to the -# appropriate value, based on the value of $to_host_file_cmd. -to_host_path_cmd= -func_init_to_host_path_cmd () -{ - $opt_debug - if test -z "$to_host_path_cmd"; then - func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd="func_convert_path_${func_stripname_result}" - fi -} - - -# func_to_host_path ARG -# Converts the path ARG from $build format to $host format. Return result -# in func_to_host_path_result. -func_to_host_path () -{ - $opt_debug - func_init_to_host_path_cmd - $to_host_path_cmd "$1" -} -# end func_to_host_path - - -# func_convert_path_noop ARG -# Copy ARG to func_to_host_path_result. -func_convert_path_noop () -{ - func_to_host_path_result="$1" -} -# end func_convert_path_noop - - -# func_convert_path_msys_to_w32 ARG -# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_path_result. -func_convert_path_msys_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from ARG. MSYS - # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; - # and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_msys_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_msys_to_w32 - - -# func_convert_path_cygwin_to_w32 ARG -# Convert path ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_path_cygwin_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_cygwin_to_w32 - - -# func_convert_path_nix_to_w32 ARG -# Convert path ARG from *nix to w32 format. Requires a wine environment and -# a working winepath. Returns result in func_to_host_file_result. -func_convert_path_nix_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_nix_to_w32 - - -# func_convert_path_msys_to_cygwin ARG -# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_path_msys_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_msys_to_cygwin - - -# func_convert_path_nix_to_cygwin ARG -# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a -# a wine environment, working winepath, and LT_CYGPATH set. Returns result in -# func_to_host_file_result. -func_convert_path_nix_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_nix_to_cygwin - - -# func_mode_compile arg... -func_mode_compile () -{ - $opt_debug - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - pie_flag= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - test -n "$libobj" && \ - func_fatal_error "you cannot specify \`-o' more than once" - arg_mode=target - continue - ;; - - -pie | -fpie | -fPIE) - func_append pie_flag " $arg" - continue - ;; - - -shared | -static | -prefer-pic | -prefer-non-pic) - func_append later " $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - func_append_quoted lastarg "$arg" - done - IFS="$save_ifs" - func_stripname ' ' '' "$lastarg" - lastarg=$func_stripname_result - - # Add the arguments to base_compile. - func_append base_compile " $lastarg" - continue - ;; - - *) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - func_append_quoted base_compile "$lastarg" - done # for arg - - case $arg_mode in - arg) - func_fatal_error "you must specify an argument for -Xcompile" - ;; - target) - func_fatal_error "you must specify a target with \`-o'" - ;; - *) - # Get the name of the library object. - test -z "$libobj" && { - func_basename "$srcfile" - libobj="$func_basename_result" - } - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - case $libobj in - *.[cCFSifmso] | \ - *.ada | *.adb | *.ads | *.asm | \ - *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) - func_xform "$libobj" - libobj=$func_xform_result - ;; - esac - - case $libobj in - *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; - *) - func_fatal_error "cannot determine name of library object from \`$libobj'" - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - continue - ;; - - -static) - build_libtool_libs=no - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ - && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." - func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname - - test -z "$base_compile" && \ - func_fatal_help "you must specify a compilation command" - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $ECHO "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - func_append removelist " $output_obj" - $ECHO "$srcfile" > "$lockfile" - fi - - $opt_dry_run || $RM $removelist - func_append removelist " $lockfile" - trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - - func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 - srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - func_mkdir_p "$xdir$objdir" - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - func_append command " -o $lobj" - fi - - func_show_eval_locale "$command" \ - 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - func_show_eval '$MV "$output_obj" "$lobj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - - # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then - suppress_output=' >/dev/null 2>&1' - fi - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $qsrcfile$pie_flag" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test "$compiler_c_o" = yes; then - func_append command " -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - func_append command "$suppress_output" - func_show_eval_locale "$command" \ - '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - func_show_eval '$MV "$output_obj" "$obj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - fi - - $opt_dry_run || { - func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - removelist=$lockfile - $RM "$lockfile" - fi - } - - exit $EXIT_SUCCESS -} - -$opt_help || { - test "$opt_mode" = compile && func_mode_compile ${1+"$@"} -} - -func_mode_help () -{ - # We need to display help for each of the modes. - case $opt_mode in - "") - # Generic help is extracted from the usage comments - # at the start of this file. - func_help - ;; - - clean) - $ECHO \ -"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - - compile) - $ECHO \ -"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -no-suppress do not suppress compiler output for multiple passes - -prefer-pic try to build PIC objects only - -prefer-non-pic try to build non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - - execute) - $ECHO \ -"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - - finish) - $ECHO \ -"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - - install) - $ECHO \ -"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The following components of INSTALL-COMMAND are treated specially: - - -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - - link) - $ECHO \ -"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -bindir BINDIR specify path to binaries directory (for systems where - libraries must be found in the PATH setting at runtime) - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -shared only do dynamic linking of libtool libraries - -shrext SUFFIX override the standard shared library file extension - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -weak LIBNAME declare that the target provides the LIBNAME interface - -Wc,FLAG - -Xcompiler FLAG pass linker-specific FLAG directly to the compiler - -Wl,FLAG - -Xlinker FLAG pass linker-specific FLAG directly to the linker - -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - - uninstall) - $ECHO \ -"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - - *) - func_fatal_help "invalid operation mode \`$opt_mode'" - ;; - esac - - echo - $ECHO "Try \`$progname --help' for more information about other modes." -} - -# Now that we've collected a possible --mode arg, show help if necessary -if $opt_help; then - if test "$opt_help" = :; then - func_mode_help - else - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - func_mode_help - done - } | sed -n '1p; 2,$s/^Usage:/ or: /p' - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - echo - func_mode_help - done - } | - sed '1d - /^When reporting/,/^Report/{ - H - d - } - $x - /information about other modes/d - /more detailed .*MODE/d - s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' - fi - exit $? -fi - - -# func_mode_execute arg... -func_mode_execute () -{ - $opt_debug - # The first argument is the command name. - cmd="$nonopt" - test -z "$cmd" && \ - func_fatal_help "you must specify a COMMAND" - - # Handle -dlopen flags immediately. - for file in $opt_dlopen; do - test -f "$file" \ - || func_fatal_help "\`$file' is not a file" - - dir= - case $file in - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" - - # Read the libtool library. - dlname= - library_names= - func_source "$file" - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" - continue - fi - - func_dirname "$file" "" "." - dir="$func_dirname_result" - - if test -f "$dir/$objdir/$dlname"; then - func_append dir "/$objdir" - else - if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - func_dirname "$file" "" "." - dir="$func_dirname_result" - ;; - - *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -* | *.la | *.lo ) ;; - *) - # Do a test to see if this is really a libtool program. - if func_ltwrapper_script_p "$file"; then - func_source "$file" - # Transform arg to wrapped name. - file="$progdir/$program" - elif func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - func_source "$func_ltwrapper_scriptname_result" - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - func_append_quoted args "$file" - done - - if test "X$opt_dry_run" = Xfalse; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = execute && func_mode_execute ${1+"$@"} - - -# func_mode_finish arg... -func_mode_finish () -{ - $opt_debug - libs= - libdirs= - admincmds= - - for opt in "$nonopt" ${1+"$@"} - do - if test -d "$opt"; then - func_append libdirs " $opt" - - elif test -f "$opt"; then - if func_lalib_unsafe_p "$opt"; then - func_append libs " $opt" - else - func_warning "\`$opt' is not a valid libtool archive" - fi - - else - func_fatal_error "invalid argument \`$opt'" - fi - done - - if test -n "$libs"; then - if test -n "$lt_sysroot"; then - sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` - sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" - else - sysroot_cmd= - fi - - # Remove sysroot references - if $opt_dry_run; then - for lib in $libs; do - echo "removing references to $lt_sysroot and \`=' prefixes from $lib" - done - else - tmpdir=`func_mktempdir` - for lib in $libs; do - sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ - > $tmpdir/tmp-la - mv -f $tmpdir/tmp-la $lib - done - ${RM}r "$tmpdir" - fi - fi - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - func_execute_cmds "$finish_cmds" 'admincmds="$admincmds -'"$cmd"'"' - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || func_append admincmds " - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $ECHO " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - - echo "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" - echo "pages." - ;; - *) - echo "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - echo "----------------------------------------------------------------------" - fi - exit $EXIT_SUCCESS -} - -test "$opt_mode" = finish && func_mode_finish ${1+"$@"} - - -# func_mode_install arg... -func_mode_install () -{ - $opt_debug - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac; then - # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " - arg=$1 - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" - install_shared_prog=$install_prog - case " $install_prog " in - *[\\\ /]cp\ *) install_cp=: ;; - *) install_cp=false ;; - esac - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - no_mode=: - for arg - do - arg2= - if test -n "$dest"; then - func_append files " $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - if $install_cp; then :; else - prev=$arg - fi - ;; - -g | -m | -o) - prev=$arg - ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - if test "x$prev" = x-m && test -n "$install_override_mode"; then - arg2=$install_override_mode - no_mode=false - fi - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" - if test -n "$arg2"; then - func_quote_for_eval "$arg2" - fi - func_append install_shared_prog " $func_quote_for_eval_result" - done - - test -z "$install_prog" && \ - func_fatal_help "you must specify an install program" - - test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" - - if test -n "$install_override_mode" && $no_mode; then - if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" - fi - fi - - if test -z "$files"; then - if test -z "$dest"; then - func_fatal_help "no file or destination specified" - else - func_fatal_help "you must specify a destination" - fi - fi - - # Strip any trailing slash from the destination. - func_stripname '' '/' "$dest" - dest=$func_stripname_result - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" - - # Not a directory, so check to see that there is only one file specified. - set dummy $files; shift - test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - func_fatal_help "\`$destdir' must be an absolute directory name" - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - func_append staticlibs " $file" - ;; - - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" - - library_names= - old_library= - relink_command= - func_source "$file" - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) func_append current_libdirs " $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) func_append future_libdirs " $libdir" ;; - esac - fi - - func_dirname "$file" "/" "" - dir="$func_dirname_result" - func_append dir "$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - func_warning "relinking \`$file'" - func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' - fi - - # See the names of the shared library. - set dummy $library_names; shift - if test -n "$1"; then - realname="$1" - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ - 'exit $?' - tstripme="$stripme" - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - case $realname in - *.dll.a) - tstripme="" - ;; - esac - ;; - esac - if test -n "$tstripme" && test -n "$striplib"; then - func_show_eval "$striplib $destdir/$realname" 'exit $?' - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - test "$linkname" != "$realname" \ - && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - func_execute_cmds "$postinstall_cmds" 'exit $?' - fi - - # Install the pseudo-library for information purposes. - func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i - func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' - - # Maybe install the static library, too. - test -n "$old_library" && func_append staticlibs " $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - func_lo2o "$destfile" - staticdest=$func_lo2o_result - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" - ;; - esac - - # Install the libtool object if requested. - test -n "$destfile" && \ - func_show_eval "$install_prog $file $destfile" 'exit $?' - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - func_lo2o "$file" - staticobj=$func_lo2o_result - func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - func_stripname '' '.exe' "$file" - file=$func_stripname_result - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin* | *mingw*) - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - wrapper=$func_ltwrapper_scriptname_result - else - func_stripname '' '.exe' "$file" - wrapper=$func_stripname_result - fi - ;; - *) - wrapper=$file - ;; - esac - if func_ltwrapper_script_p "$wrapper"; then - notinst_deplibs= - relink_command= - - func_source "$wrapper" - - # Check the variables that should have been set. - test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - func_source "$lib" - fi - libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no - fi - done - - relink_command= - func_source "$wrapper" - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - $opt_dry_run || { - if test "$finalize" = yes; then - tmpdir=`func_mktempdir` - func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - - $opt_silent || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" - } - if eval "$relink_command"; then : - else - func_error "error: relink \`$file' with the above command before installing it" - $opt_dry_run || ${RM}r "$tmpdir" - continue - fi - file="$outputname" - else - func_warning "cannot relink \`$file'" - fi - } - else - # Install the binary that we compiled earlier. - file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - func_stripname '' '.exe' "$destfile" - destfile=$func_stripname_result - ;; - esac - ;; - esac - func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' - $opt_dry_run || if test -n "$outputname"; then - ${RM}r "$tmpdir" - fi - ;; - esac - done - - for file in $staticlibs; do - func_basename "$file" - name="$func_basename_result" - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - - func_show_eval "$install_prog \$file \$oldlib" 'exit $?' - - if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $tool_oldlib" 'exit $?' - fi - - # Do each command in the postinstall commands. - func_execute_cmds "$old_postinstall_cmds" 'exit $?' - done - - test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = install && func_mode_install ${1+"$@"} - - -# func_generate_dlsyms outputname originator pic_p -# Extract symbols from dlprefiles and create ${outputname}S.o with -# a dlpreopen symbol table. -func_generate_dlsyms () -{ - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" - my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` - my_dlsyms= - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" - else - func_error "not configured to extract global symbols from dlpreopened files" - fi - fi - - if test -n "$my_dlsyms"; then - case $my_dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" - - func_show_eval "$RM $nlist ${nlist}S ${nlist}T" - - # Parse the name list into a source file. - func_verbose "creating $output_objdir/$my_dlsyms" - - $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#endif - -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" - - $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` - for progfile in $progfiles; do - func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" - $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $opt_dry_run || { - eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - if test -n "$export_symbols_regex"; then - $opt_dry_run || { - eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $opt_dry_run || { - $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - } - else - $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - } - fi - fi - - for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" - func_basename "$dlprefile" - name="$func_basename_result" - case $host in - *cygwin* | *mingw* | *cegcc* ) - # if an import library, we need to obtain dlname - if func_win32_import_lib_p "$dlprefile"; then - func_tr_sh "$dlprefile" - eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename="" - if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then - # Use subshell, to avoid clobbering current variable values - dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname" ; then - func_basename "$dlprefile_dlname" - dlprefile_dlbasename="$func_basename_result" - else - # no lafile. user explicitly requested -dlpreopen . - $sharedlib_from_linklib_cmd "$dlprefile" - dlprefile_dlbasename=$sharedlib_from_linklib_result - fi - fi - $opt_dry_run || { - if test -n "$dlprefile_dlbasename" ; then - eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' - else - func_warning "Could not compute DLL name from $name" - eval '$ECHO ": $name " >> "$nlist"' - fi - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" - } - else # not an import lib - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - fi - ;; - *) - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - ;; - esac - done - - $opt_dry_run || { - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $MV "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if $GREP -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - $GREP -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$my_dlsyms" - fi - - echo >> "$output_objdir/$my_dlsyms" "\ - -/* The mapping between symbol names and symbols. */ -typedef struct { - const char *name; - void *address; -} lt_dlsymlist; -extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; -LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," - - case $need_lib_prefix in - no) - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - *) - eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - esac - echo >> "$output_objdir/$my_dlsyms" "\ - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_${my_prefix}_LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - } # !$opt_dry_run - - pic_flag_for_symtable= - case "$compile_command " in - *" -static "*) ;; - *) - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; - *-*-hpux*) - pic_flag_for_symtable=" $pic_flag" ;; - *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi - ;; - esac - ;; - esac - symtab_cflags= - for arg in $LTCFLAGS; do - case $arg in - -pie | -fpie | -fPIE) ;; - *) func_append symtab_cflags " $arg" ;; - esac - done - - # Now compile the dynamic symbol file. - func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' - - # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' - - # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" - case $host in - *cygwin* | *mingw* | *cegcc* ) - if test -f "$output_objdir/$my_outputname.def"; then - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - else - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - fi - ;; - *) - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - ;; - esac - ;; - *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` - fi -} - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -# Despite the name, also deal with 64 bit binaries. -func_win32_libid () -{ - $opt_debug - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' - 1,100{ - / I /{ - s,.*,import, - p - q - } - }'` - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $ECHO "$win32_libid_type" -} - -# func_cygming_dll_for_implib ARG -# -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib () -{ - $opt_debug - sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` -} - -# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs -# -# The is the core of a fallback implementation of a -# platform-specific function to extract the name of the -# DLL associated with the specified import library LIBNAME. -# -# SECTION_NAME is either .idata$6 or .idata$7, depending -# on the platform and compiler that created the implib. -# -# Echos the name of the DLL associated with the -# specified import library. -func_cygming_dll_for_implib_fallback_core () -{ - $opt_debug - match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` - $OBJDUMP -s --section "$1" "$2" 2>/dev/null | - $SED '/^Contents of section '"$match_literal"':/{ - # Place marker at beginning of archive member dllname section - s/.*/====MARK====/ - p - d - } - # These lines can sometimes be longer than 43 characters, but - # are always uninteresting - /:[ ]*file format pe[i]\{,1\}-/d - /^In archive [^:]*:/d - # Ensure marker is printed - /^====MARK====/p - # Remove all lines with less than 43 characters - /^.\{43\}/!d - # From remaining lines, remove first 43 characters - s/^.\{43\}//' | - $SED -n ' - # Join marker and all lines until next marker into a single line - /^====MARK====/ b para - H - $ b para - b - :para - x - s/\n//g - # Remove the marker - s/^====MARK====// - # Remove trailing dots and whitespace - s/[\. \t]*$// - # Print - /./p' | - # we now have a list, one entry per line, of the stringified - # contents of the appropriate section of all members of the - # archive which possess that section. Heuristic: eliminate - # all those which have a first or second character that is - # a '.' (that is, objdump's representation of an unprintable - # character.) This should work for all archives with less than - # 0x302f exports -- but will fail for DLLs whose name actually - # begins with a literal '.' or a single character followed by - # a '.'. - # - # Of those that remain, print the first one. - $SED -e '/^\./d;/^.\./d;q' -} - -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - -# func_cygming_dll_for_implib_fallback ARG -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# -# This fallback implementation is for use when $DLLTOOL -# does not support the --identify-strict option. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib_fallback () -{ - $opt_debug - if func_cygming_gnu_implib_p "$1" ; then - # binutils import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1" ; then - # ms-generated import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` - else - # unknown - sharedlib_from_linklib_result="" - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - if test "$lock_old_archive_extraction" = yes; then - lockfile=$f_ex_an_ar_oldlib.lock - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - fi - func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ - 'stat=$?; rm -f "$lockfile"; exit $stat' - if test "$lock_old_archive_extraction" = yes; then - $opt_dry_run || rm -f "$lockfile" - fi - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" - fi -} - - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - $opt_debug - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - func_basename "$my_xlib" - my_xlib="$func_basename_result" - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - func_arith $extracted_serial + 1 - extracted_serial=$func_arith_result - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" - - func_mkdir_p "$my_xdir" - - case $host in - *-darwin*) - func_verbose "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - $opt_dry_run || { - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` - darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` - if test -n "$darwin_arches"; then - darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` - $LIPO -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - $RM -rf unfat-$$ - cd "$darwin_orig_dir" - else - cd $darwin_orig_dir - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - } # !$opt_dry_run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` - done - - func_extract_archives_result="$my_oldobjs" -} - - -# func_emit_wrapper [arg=no] -# -# Emit a libtool wrapper script on stdout. -# Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw -# wrapper executable. Must ONLY be called from within -# func_mode_link because it depends on a number of variables -# set therein. -# -# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR -# variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is -# the $objdir directory. This is a cygwin/mingw-specific -# behavior. -func_emit_wrapper () -{ - func_emit_wrapper_arg1=${1-no} - - $ECHO "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variables: - generated_by_libtool_version='$macro_version' - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$ECHO are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - file=\"\$0\"" - - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` - $ECHO "\ - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - ECHO=\"$qECHO\" - fi - -# Very basic option parsing. These options are (a) specific to -# the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ which is used only on -# windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options which match -# this pattern). -# -# There are only two supported options: --lt-debug and -# --lt-dump-script. There is, deliberately, no --lt-help. -# -# The first argument to this parsing function should be the -# script's $0 value, followed by "$@". -lt_option_debug= -func_parse_lt_options () -{ - lt_script_arg0=\$0 - shift - for lt_opt - do - case \"\$lt_opt\" in - --lt-debug) lt_option_debug=1 ;; - --lt-dump-script) - lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` - test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. - lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` - cat \"\$lt_dump_D/\$lt_dump_F\" - exit 0 - ;; - --lt-*) - \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 - exit 1 - ;; - esac - done - - # Print the debug banner immediately: - if test -n \"\$lt_option_debug\"; then - echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 - fi -} - -# Used when --lt-debug. Prints its arguments to stdout -# (redirection is the responsibility of the caller) -func_lt_dump_args () -{ - lt_dump_args_N=1; - for lt_arg - do - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" - lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` - done -} - -# Core function for launching the target application -func_exec_program_core () -{ -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $ECHO "\ - \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 - exit 1 -} - -# A function to encapsulate launching the target application -# Strips options in the --lt-* namespace from \$@ and -# launches target application with the remaining arguments. -func_exec_program () -{ - case \" \$* \" in - *\\ --lt-*) - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done ;; - esac - func_exec_program_core \${1+\"\$@\"} -} - - # Parse options - func_parse_lt_options \"\$0\" \${1+\"\$@\"} - - # Find the directory that this script lives in. - thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` - done - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 - if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then - # special case for '.' - if test \"\$thisdir\" = \".\"; then - thisdir=\`pwd\` - fi - # remove .libs from thisdir - case \"\$thisdir\" in - *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; - $objdir ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $ECHO "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $MKDIR \"\$progdir\" - else - $RM \"\$progdir/\$file\" - fi" - - $ECHO "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $ECHO \"\$relink_command_output\" >&2 - $RM \"\$progdir/\$file\" - exit 1 - fi - fi - - $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $RM \"\$progdir/\$program\"; - $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $RM \"\$progdir/\$file\" - fi" - else - $ECHO "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $ECHO "\ - - if test -f \"\$progdir/\$program\"; then" - - # fixup the dll searchpath if we need to. - # - # Fix the DLL searchpath if we need to. Do this before prepending - # to shlibpath, because on Windows, both are PATH and uninstalled - # libraries must come first. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $ECHO "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` - - export $shlibpath_var -" - fi - - $ECHO "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. - func_exec_program \${1+\"\$@\"} - fi - else - # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 - \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" -} - - -# func_emit_cwrapperexe_src -# emit the source code for a wrapper executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_cwrapperexe_src () -{ - cat < -#include -#ifdef _MSC_VER -# include -# include -# include -#else -# include -# include -# ifdef __CYGWIN__ -# include -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -/* declarations of non-ANSI functions */ -#if defined(__MINGW32__) -# ifdef __STRICT_ANSI__ -int _putenv (const char *); -# endif -#elif defined(__CYGWIN__) -# ifdef __STRICT_ANSI__ -char *realpath (const char *, char *); -int putenv (char *); -int setenv (const char *, const char *, int); -# endif -/* #elif defined (other platforms) ... */ -#endif - -/* portability defines, excluding path handling macros */ -#if defined(_MSC_VER) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -# define S_IXUSR _S_IEXEC -# ifndef _INTPTR_T_DEFINED -# define _INTPTR_T_DEFINED -# define intptr_t int -# endif -#elif defined(__MINGW32__) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -#elif defined(__CYGWIN__) -# define HAVE_SETENV -# define FOPEN_WB "wb" -/* #elif defined (other platforms) ... */ -#endif - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 0 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0 -#endif - -/* path handling portability macros */ -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# define FOPEN_WB "wb" -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#ifndef FOPEN_WB -# define FOPEN_WB "w" -#endif -#ifndef _O_BINARY -# define _O_BINARY 0 -#endif - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -#if defined(LT_DEBUGWRAPPER) -static int lt_debug = 1; -#else -static int lt_debug = 0; -#endif - -const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ - -void *xmalloc (size_t num); -char *xstrdup (const char *string); -const char *base_name (const char *name); -char *find_executable (const char *wrapper); -char *chase_symlinks (const char *pathspec); -int make_executable (const char *path); -int check_executable (const char *path); -char *strendzap (char *str, const char *pat); -void lt_debugprintf (const char *file, int line, const char *fmt, ...); -void lt_fatal (const char *file, int line, const char *message, ...); -static const char *nonnull (const char *s); -static const char *nonempty (const char *s); -void lt_setenv (const char *name, const char *value); -char *lt_extend_str (const char *orig_value, const char *add, int to_end); -void lt_update_exe_path (const char *name, const char *value); -void lt_update_lib_path (const char *name, const char *value); -char **prepare_spawn (char **argv); -void lt_dump_script (FILE *f); -EOF - - cat <= 0) - && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return 1; - else - return 0; -} - -int -make_executable (const char *path) -{ - int rval = 0; - struct stat st; - - lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", - nonempty (path)); - if ((!path) || (!*path)) - return 0; - - if (stat (path, &st) >= 0) - { - rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); - } - return rval; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise - Does not chase symlinks, even on platforms that support them. -*/ -char * -find_executable (const char *wrapper) -{ - int has_slash = 0; - const char *p; - const char *p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - int tmp_len; - char *concat_name; - - lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", - nonempty (wrapper)); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char *path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR (*q)) - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = - XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = - XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - return NULL; -} - -char * -chase_symlinks (const char *pathspec) -{ -#ifndef S_ISLNK - return xstrdup (pathspec); -#else - char buf[LT_PATHMAX]; - struct stat s; - char *tmp_pathspec = xstrdup (pathspec); - char *p; - int has_symlinks = 0; - while (strlen (tmp_pathspec) && !has_symlinks) - { - lt_debugprintf (__FILE__, __LINE__, - "checking path component for symlinks: %s\n", - tmp_pathspec); - if (lstat (tmp_pathspec, &s) == 0) - { - if (S_ISLNK (s.st_mode) != 0) - { - has_symlinks = 1; - break; - } - - /* search backwards for last DIR_SEPARATOR */ - p = tmp_pathspec + strlen (tmp_pathspec) - 1; - while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - p--; - if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - { - /* no more DIR_SEPARATORS left */ - break; - } - *p = '\0'; - } - else - { - lt_fatal (__FILE__, __LINE__, - "error accessing file \"%s\": %s", - tmp_pathspec, nonnull (strerror (errno))); - } - } - XFREE (tmp_pathspec); - - if (!has_symlinks) - { - return xstrdup (pathspec); - } - - tmp_pathspec = realpath (pathspec, buf); - if (tmp_pathspec == 0) - { - lt_fatal (__FILE__, __LINE__, - "could not follow symlinks for %s", pathspec); - } - return xstrdup (tmp_pathspec); -#endif -} - -char * -strendzap (char *str, const char *pat) -{ - size_t len, patlen; - - assert (str != NULL); - assert (pat != NULL); - - len = strlen (str); - patlen = strlen (pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp (str, pat) == 0) - *str = '\0'; - } - return str; -} - -void -lt_debugprintf (const char *file, int line, const char *fmt, ...) -{ - va_list args; - if (lt_debug) - { - (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); - va_start (args, fmt); - (void) vfprintf (stderr, fmt, args); - va_end (args); - } -} - -static void -lt_error_core (int exit_status, const char *file, - int line, const char *mode, - const char *message, va_list ap) -{ - fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *file, int line, const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); - va_end (ap); -} - -static const char * -nonnull (const char *s) -{ - return s ? s : "(null)"; -} - -static const char * -nonempty (const char *s) -{ - return (s && !*s) ? "(empty)" : nonnull (s); -} - -void -lt_setenv (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_setenv) setting '%s' to '%s'\n", - nonnull (name), nonnull (value)); - { -#ifdef HAVE_SETENV - /* always make a copy, for consistency with !HAVE_SETENV */ - char *str = xstrdup (value); - setenv (name, str, 1); -#else - int len = strlen (name) + 1 + strlen (value) + 1; - char *str = XMALLOC (char, len); - sprintf (str, "%s=%s", name, value); - if (putenv (str) != EXIT_SUCCESS) - { - XFREE (str); - } -#endif - } -} - -char * -lt_extend_str (const char *orig_value, const char *add, int to_end) -{ - char *new_value; - if (orig_value && *orig_value) - { - int orig_value_len = strlen (orig_value); - int add_len = strlen (add); - new_value = XMALLOC (char, add_len + orig_value_len + 1); - if (to_end) - { - strcpy (new_value, orig_value); - strcpy (new_value + orig_value_len, add); - } - else - { - strcpy (new_value, add); - strcpy (new_value + add_len, orig_value); - } - } - else - { - new_value = xstrdup (add); - } - return new_value; -} - -void -lt_update_exe_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - /* some systems can't cope with a ':'-terminated path #' */ - int len = strlen (new_value); - while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) - { - new_value[len-1] = '\0'; - } - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -void -lt_update_lib_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -EOF - case $host_os in - mingw*) - cat <<"EOF" - -/* Prepares an argument vector before calling spawn(). - Note that spawn() does not by itself call the command interpreter - (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : - ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&v); - v.dwPlatformId == VER_PLATFORM_WIN32_NT; - }) ? "cmd.exe" : "command.com"). - Instead it simply concatenates the arguments, separated by ' ', and calls - CreateProcess(). We must quote the arguments since Win32 CreateProcess() - interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a - special way: - - Space and tab are interpreted as delimiters. They are not treated as - delimiters if they are surrounded by double quotes: "...". - - Unescaped double quotes are removed from the input. Their only effect is - that within double quotes, space and tab are treated like normal - characters. - - Backslashes not followed by double quotes are not special. - - But 2*n+1 backslashes followed by a double quote become - n backslashes followed by a double quote (n >= 0): - \" -> " - \\\" -> \" - \\\\\" -> \\" - */ -#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -char ** -prepare_spawn (char **argv) -{ - size_t argc; - char **new_argv; - size_t i; - - /* Count number of arguments. */ - for (argc = 0; argv[argc] != NULL; argc++) - ; - - /* Allocate new argument vector. */ - new_argv = XMALLOC (char *, argc + 1); - - /* Put quoted arguments into the new argument vector. */ - for (i = 0; i < argc; i++) - { - const char *string = argv[i]; - - if (string[0] == '\0') - new_argv[i] = xstrdup ("\"\""); - else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) - { - int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); - size_t length; - unsigned int backslashes; - const char *s; - char *quoted_string; - char *p; - - length = 0; - backslashes = 0; - if (quote_around) - length++; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - length += backslashes + 1; - length++; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - length += backslashes + 1; - - quoted_string = XMALLOC (char, length + 1); - - p = quoted_string; - backslashes = 0; - if (quote_around) - *p++ = '"'; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - { - unsigned int j; - for (j = backslashes + 1; j > 0; j--) - *p++ = '\\'; - } - *p++ = c; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - { - unsigned int j; - for (j = backslashes; j > 0; j--) - *p++ = '\\'; - *p++ = '"'; - } - *p = '\0'; - - new_argv[i] = quoted_string; - } - else - new_argv[i] = (char *) string; - } - new_argv[argc] = NULL; - - return new_argv; -} -EOF - ;; - esac - - cat <<"EOF" -void lt_dump_script (FILE* f) -{ -EOF - func_emit_wrapper yes | - $SED -n -e ' -s/^\(.\{79\}\)\(..*\)/\1\ -\2/ -h -s/\([\\"]\)/\\\1/g -s/$/\\n/ -s/\([^\n]*\).*/ fputs ("\1", f);/p -g -D' - cat <<"EOF" -} -EOF -} -# end: func_emit_cwrapperexe_src - -# func_win32_import_lib_p ARG -# True if ARG is an import lib, as indicated by $file_magic_cmd -func_win32_import_lib_p () -{ - $opt_debug - case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in - *import*) : ;; - *) false ;; - esac -} - -# func_mode_link arg... -func_mode_link () -{ - $opt_debug - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args=$nonopt - base_compile="$nonopt $@" - compile_command=$nonopt - finalize_command=$nonopt - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - new_inherited_linker_flags= - - avoid_version=no - bindir= - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - weak_libs= - single_module="${wl}-single_module" - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - break - ;; - -all-static | -static | -static-libtool-libs) - case $arg in - -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - func_warning "complete static linking is impossible in this configuration" - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - func_append compile_command " @OUTPUT@" - func_append finalize_command " @OUTPUT@" - ;; - esac - - case $prev in - bindir) - bindir="$arg" - prev= - continue - ;; - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - func_append compile_command " @SYMFILE@" - func_append finalize_command " @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - func_append dlfiles " $arg" - else - func_append dlprefiles " $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - framework) - case $host in - *-*-darwin*) - case "$deplibs " in - *" $qarg.ltframework "*) ;; - *) func_append deplibs " $qarg.ltframework" # this is fixed later - ;; - esac - ;; - esac - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat "$save_arg"` - do -# func_append moreargs " $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - done - else - func_fatal_error "link input file \`$arg' does not exist" - fi - arg=$save_arg - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) func_append rpath " $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) func_append xrpath " $arg" ;; - esac - fi - prev= - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - weak) - func_append weak_libs " $arg" - prev= - continue - ;; - xcclinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xcompiler) - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xlinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $wl$qarg" - prev= - func_append compile_command " $wl$qarg" - func_append finalize_command " $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - # See comment for -static flag below, for more details. - func_append compile_command " $link_static_flag" - func_append finalize_command " $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -bindir) - prev=bindir - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - func_fatal_error "more than one -exported-symbols argument is not allowed" - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework) - prev=framework - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - func_append compile_command " $arg" - func_append finalize_command " $arg" - ;; - esac - continue - ;; - - -L*) - func_stripname "-L" '' "$arg" - if test -z "$func_stripname_result"; then - if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" - else - func_fatal_error "need path for \`-L' option" - fi - fi - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "* | *" $arg "*) - # Will only happen for absolute or sysroot arguments - ;; - *) - # Preserve sysroot, but never include relative directories - case $dir in - [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; - *) func_append deplibs " -L$dir" ;; - esac - func_append lib_search_path " $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - ::) dllsearchpath=$dir;; - *) func_append dllsearchpath ":$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - func_append deplibs " System.ltframework" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test "X$arg" = "X-lc" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - func_append deplibs " $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case "$new_inherited_linker_flags " in - *" $arg "*) ;; - * ) func_append new_inherited_linker_flags " $arg" ;; - esac - continue - ;; - - -multi_module) - single_module="${wl}-multi_module" - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - func_stripname '-R' '' "$arg" - dir=$func_stripname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - =*) - func_stripname '=' '' "$dir" - dir=$lt_sysroot$func_stripname_result - ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - continue - ;; - - -shared) - # The effects of -shared are defined in a previous loop. - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -weak) - prev=weak - continue - ;; - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Wl,*) - func_stripname '-Wl,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # -msg_* for osf cc - -msg_*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - # Flags to be passed through unchanged, with rationale: - # -64, -mips[0-9] enable 64-bit mode for the SGI compiler - # -r[0-9][0-9]* specify processor for the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler - # +DA*, +DD* enable 64-bit mode for the HP compiler - # -q* compiler args for the IBM compiler - # -m*, -t[45]*, -txscale* architecture-specific flags for GCC - # -F/path path to uninstalled frameworks, gcc on darwin - # -p, -pg, --coverage, -fprofile-* profiling flags for GCC - # @file GCC response files - # -tp=* Portland pgcc target processor selection - # --sysroot=* for sysroot support - # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - func_append compile_command " $arg" - func_append finalize_command " $arg" - func_append compiler_flags " $arg" - continue - ;; - - # Some other compiler flag. - -* | +*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - *.$objext) - # A standard object. - func_append objs " $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - ;; - - *.$libext) - # An archive. - func_append deplibs " $arg" - func_append old_deplibs " $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - func_resolve_sysroot "$arg" - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - func_append dlfiles " $func_resolve_sysroot_result" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - func_append dlprefiles " $func_resolve_sysroot_result" - prev= - else - func_append deplibs " $func_resolve_sysroot_result" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - done # argument parsing loop - - test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" - func_to_tool_file "$output_objdir/" - tool_output_objdir=$func_to_tool_file_result - # Create the object directory. - func_mkdir_p "$output_objdir" - - # Determine the type of output - case $output in - "") - func_fatal_help "you must specify an output file" - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if $opt_preserve_dup_deps ; then - case "$libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append libs " $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if $opt_duplicate_compiler_generated_deps; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; - esac - func_append pre_post_deps " $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - - case $linkmode in - lib) - passes="conv dlpreopen link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - - for pass in $passes; do - # The preopen pass in lib mode reverses $deplibs; put it back here - # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then - ## FIXME: Find the place where the list is rebuilt in the wrong - ## order, and fix it there properly - tmp_deplibs= - for deplib in $deplibs; do - tmp_deplibs="$deplib $tmp_deplibs" - done - deplibs="$tmp_deplibs" - fi - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) - libs="$deplibs %DEPLIBS%" - test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" - ;; - esac - fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then - # Collect and forward deplibs of preopened libtool libs - for lib in $dlprefiles; do - # Ignore non-libtool-libs - dependency_libs= - func_resolve_sysroot "$lib" - case $lib in - *.la) func_source "$func_resolve_sysroot_result" ;; - esac - - # Collect preopened libtool deplibs, except any this library - # has declared as weak libs - for deplib in $dependency_libs; do - func_basename "$deplib" - deplib_base=$func_basename_result - case " $weak_libs " in - *" $deplib_base "*) ;; - *) func_append deplibs " $deplib" ;; - esac - done - done - libs="$dlprefiles" - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append compiler_flags " $deplib" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" - continue - fi - func_stripname '-l' '' "$deplib" - name=$func_stripname_result - if test "$linkmode" = lib; then - searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" - else - searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" - fi - for searchdir in $searchdirs; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if func_lalib_p "$lib"; then - library_names= - old_library= - func_source "$lib" - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - *) - func_warning "\`-L' is ignored for archives/objects" - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - func_stripname '-R' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) - func_resolve_sysroot "$deplib" - lib=$func_resolve_sysroot_result - ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - # Linking convenience modules into shared libraries is allowed, - # but linking other static libraries is non-portable. - case " $dlpreconveniencelibs " in - *" $deplib "*) ;; - *) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - echo - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not use here." - else - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - ;; - esac - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - func_append newdlprefiles " $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append newdlfiles " $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" - - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - inherited_linker_flags= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - func_source "$lib" - - # Convert "-framework foo" to "foo.ltframework" - if test -n "$inherited_linker_flags"; then - tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` - for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do - case " $new_inherited_linker_flags " in - *" $tmp_inherited_linker_flag "*) ;; - *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; - esac - done - fi - dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && func_append dlfiles " $dlopen" - test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - # It is a libtool convenience library, so add in its objects. - func_append convenience " $ladir/$objdir/$old_library" - func_append old_convenience " $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - if test -n "$old_library" && - { test "$prefer_static_libs" = yes || - test "$prefer_static_libs,$installed" = "built,no"; }; then - linklib=$old_library - else - for l in $old_library $library_names; do - linklib="$l" - done - fi - if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - func_append dlprefiles " $lib $dependency_libs" - else - func_append newdlfiles " $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" - func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" - fi - ;; - esac - func_basename "$lib" - laname="$func_basename_result" - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$lt_sysroot$libdir" - absdir="$lt_sysroot$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - fi - fi # $installed = yes - func_stripname 'lib' '.la' "$laname" - name=$func_stripname_result - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" - fi - case "$host" in - # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) - # Linker will automatically link against shared library if both - # static and shared are present. Therefore, ensure we extract - # symbols from the import library if a shared library is present - # (otherwise, the dlopen module name will be incorrect). We do - # this by putting the import library name into $newdlprefiles. - # We recover the dlopen module name by 'saving' the la file - # name in a special purpose variable, and (later) extracting the - # dlname from the la file. - if test -n "$dlname"; then - func_tr_sh "$dir/$linklib" - eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" - func_append newdlprefiles " $dir/$linklib" - else - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - fi - ;; - * ) - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - func_append newdlprefiles " $dir/$dlname" - else - func_append newdlprefiles " $dir/$linklib" - fi - ;; - esac - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - func_append newlib_search_path " $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in - *"$absdir:"*) ;; - *) func_append temp_rpath "$absdir:" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then - use_static_libs=no - fi - if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc*) - # No point in relinking DLLs because paths are not encoded - func_append notinst_deplibs " $lib" - need_relink=no - ;; - *) - if test "$installed" = no; then - func_append notinst_deplibs " $lib" - need_relink=yes - fi - ;; - esac - # This is a shared library - - # Warn about portability, can't link against -module's on some - # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" - for dlpremoduletest in $dlprefiles; do - if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" - break - fi - done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then - echo - if test "$linkmode" = prog; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" - else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" - fi - $ECHO "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - shift - realname="$1" - shift - libname=`eval "\\$ECHO \"$libname_spec\""` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw* | *cegcc*) - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - func_basename "$soroot" - soname="$func_basename_result" - func_stripname 'lib' '.dll' "$soname" - newlib=libimp-$func_stripname_result.a - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - func_verbose "extracting exported symbol list from \`$soname'" - func_execute_cmds "$extract_expsyms_cmds" 'exit $?' - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" - func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$opt_mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not - # link against it, someone is ignoring the earlier warnings - if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then - if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - echo - echo "*** And there doesn't seem to be a static archive available" - echo "*** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - elif test -n "$old_library"; then - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$absdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - func_fatal_configuration "unsupported hardcode properties" - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) func_append compile_shlibpath "$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$opt_mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - $ECHO "*** Warning: This system can not link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) func_stripname '-R' '' "$libdir" - temp_xrpath=$func_stripname_result - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) func_append xrpath " $temp_xrpath";; - esac;; - *) func_append temp_deplibs " $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - func_append newlib_search_path " $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result";; - *) func_resolve_sysroot "$deplib" ;; - esac - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $func_resolve_sysroot_result "*) - func_append specialdeplibs " $func_resolve_sysroot_result" ;; - esac - fi - func_append tmp_libs " $func_resolve_sysroot_result" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - path= - case $deplib in - -L*) path="$deplib" ;; - *.la) - func_resolve_sysroot "$deplib" - deplib=$func_resolve_sysroot_result - func_dirname "$deplib" "" "." - dir=$func_dirname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" - fi - ;; - esac - if $GREP "^installed=no" $deplib > /dev/null; then - case $host in - *-*-darwin*) - depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - fi - func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" - path= - fi - fi - ;; - *) - path="-L$absdir/$objdir" - ;; - esac - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" - - path="-L$absdir" - fi - ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then - compile_deplibs="$new_inherited_linker_flags $compile_deplibs" - finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" - else - compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - fi - fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) func_append lib_search_path " $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) func_append tmp_libs " $deplib" ;; - esac - ;; - *) func_append tmp_libs " $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - func_append tmp_libs " $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" - - test -n "$release" && \ - func_warning "\`-release' is ignored for archives" - - test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - func_append objs "$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - func_stripname 'lib' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" - - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - func_stripname '' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - func_stripname '' '.la' "$outputname" - libname=$func_stripname_result - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" - else - echo - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" - func_append libobjs " $objs" - fi - fi - - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" - - set dummy $rpath - shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" - - install_libdir="$1" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" - - test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - shift - IFS="$save_ifs" - - test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$1" - number_minor="$2" - number_revision="$3" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - # correct linux to gnu/linux during the next big refactor - darwin|linux|osf|windows|none) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|qnx|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_minor" - lt_irix_increment=no - ;; - *) - func_fatal_configuration "$modename: unknown library version type \`$version_type'" - ;; - esac - ;; - no) - current="$1" - revision="$2" - age="$3" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - func_arith $current + 1 - minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current" - ;; - - irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then - func_arith $current - $age - else - func_arith $current - $age + 1 - fi - major=$func_arith_result - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - func_arith $revision - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) # correct to gnu/linux during the next big refactor - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - ;; - - osf) - func_arith $current - $age - major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - func_arith $current - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - func_append verstring ":${current}.0" - ;; - - qnx) - major=".$current" - versuffix=".$current" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - - *) - func_fatal_configuration "unknown library version type \`$version_type'" - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - - fi - - func_generate_dlsyms "$libname" "$libname" "yes" - func_append libobjs " $symfileobj" - test "X$libobjs" = "X " && libobjs= - - if test "$opt_mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$ECHO "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext | *.gcno) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - func_append removelist " $p" - ;; - *) ;; - esac - done - test -n "$removelist" && \ - func_show_eval "${RM}r \$removelist" - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - func_append oldlibs " $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` - # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` - # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - func_replace_sysroot "$libdir" - func_append temp_xrpath " -R$func_replace_sysroot_result" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) func_append dlfiles " $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) func_append dlprefiles " $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - func_append deplibs " System.ltframework" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - func_append deplibs " -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c </dev/null` - $nocaseglob - else - potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` - fi - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null | - $GREP " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | - $SED -e 10q | - $EGREP "$file_magic_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for file magic test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a file magic. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - func_append newdeplibs " $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ - $EGREP "$match_pattern_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a regex pattern. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` - done - fi - case $tmp_deplibs in - *[!\ \ ]*) - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - ;; - esac - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library with the System framework - newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - $ECHO "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - case $host in - *-*-darwin*) - newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - deplibs="$new_libs" - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - # Remove ${wl} instances when linking with ld. - # FIXME: should test the right _cmds variable. - case $archive_cmds in - *\$LD\ *) wl= ;; - esac - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$opt_mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - func_replace_sysroot "$libdir" - libdir=$func_replace_sysroot_result - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append dep_rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - shift - realname="$1" - shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - linknames= - for link - do - func_append linknames " $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` - test "X$libobjs" = "X " && libobjs= - - delfiles= - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" - func_append delfiles " $export_symbols" - fi - - orig_export_symbols= - case $host_os in - cygwin* | mingw* | cegcc*) - if test -n "$export_symbols" && test -z "$export_symbols_regex"; then - # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then - # and it's NOT already a .def file. Must figure out - # which of the given symbols are data symbols and tag - # them as such. So, trigger use of export_symbols_cmds. - # export_symbols gets reassigned inside the "prepare - # the list of exported symbols" if statement, so the - # include_expsyms logic still works. - orig_export_symbols="$export_symbols" - export_symbols= - always_export_symbols=yes - fi - fi - ;; - esac - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd1 in $cmds; do - IFS="$save_ifs" - # Take the normal branch if the nm_file_list_spec branch - # doesn't work or if tool conversion is not needed. - case $nm_file_list_spec~$to_tool_file_cmd in - *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) - try_normal_branch=yes - eval cmd=\"$cmd1\" - func_len " $cmd" - len=$func_len_result - ;; - *) - try_normal_branch=no - ;; - esac - if test "$try_normal_branch" = yes \ - && { test "$len" -lt "$max_cmd_len" \ - || test "$max_cmd_len" -le -1; } - then - func_show_eval "$cmd" 'exit $?' - skipped_export=false - elif test -n "$nm_file_list_spec"; then - func_basename "$output" - output_la=$func_basename_result - save_libobjs=$libobjs - save_output=$output - output=${output_objdir}/${output_la}.nm - func_to_tool_file "$output" - libobjs=$nm_file_list_spec$func_to_tool_file_result - func_append delfiles " $output" - func_verbose "creating $NM input file list: $output" - for obj in $save_libobjs; do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > "$output" - eval cmd=\"$cmd1\" - func_show_eval "$cmd" 'exit $?' - output=$save_output - libobjs=$save_libobjs - skipped_export=false - else - # The command line is too long to execute in one step. - func_verbose "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - func_append tmp_deplibs " $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && - test -z "$libobjs"; then - # extract the archives, so we have objects to list. - # TODO: could optimize this to just extract one archive. - whole_archive_flag_spec= - fi - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - else - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - func_append linker_flags " $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - func_len " $test_cmds" && - len=$func_len_result && - test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise - # or, if using GNU ld and skipped_export is not :, use a linker - # script. - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - func_basename "$output" - output_la=$func_basename_result - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - last_robj= - k=1 - - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript - func_verbose "creating GNU ld script: $output" - echo 'INPUT (' > $output - for obj in $save_libobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - echo ')' >> $output - func_append delfiles " $output" - func_to_tool_file "$output" - output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk - func_verbose "creating linker input file list: $output" - : > $output - set x $save_libobjs - shift - firstobj= - if test "$compiler_needs_object" = yes; then - firstobj="$1 " - shift - fi - for obj - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - func_append delfiles " $output" - func_to_tool_file "$output" - output=$firstobj\"$file_list_spec$func_to_tool_file_result\" - else - if test -n "$save_libobjs"; then - func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext - eval test_cmds=\"$reload_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - if test "X$objlist" = X || - test "$len" -lt "$max_cmd_len"; then - func_append objlist " $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - reload_objs=$objlist - eval concat_cmds=\"$reload_cmds\" - else - # All subsequent reloadable object files will link in - # the last one created. - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - func_arith $k + 1 - k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext - objlist=" $obj" - func_len " $last_robj" - func_arith $len0 + $func_len_result - len=$func_arith_result - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\${concat_cmds}$reload_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" - fi - func_append delfiles " $output" - - else - output= - fi - - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - libobjs=$output - # Append the command to create the export file. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - fi - - test -n "$save_libobjs" && - func_verbose "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - if test -n "$export_symbols_regex" && ${skipped_export-false}; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - - if ${skipped_export-false}; then - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - fi - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - fi - - if test -n "$delfiles"; then - # Append the command to remove temporary files to $cmds. - eval cmds=\"\$cmds~\$RM $delfiles\" - fi - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - func_show_eval '${RM}r "$gentop"' - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" - - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" - - test -n "$release" && \ - func_warning "\`-release' is ignored for objects" - - case $output in - *.lo) - test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" - - libobj=$output - func_lo2o "$libobj" - obj=$func_lo2o_result - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $opt_dry_run || $RM $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` - else - gentop="$output_objdir/${obj}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # If we're not building shared, we need to use non_pic_objs - test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - func_execute_cmds "$reload_cmds" 'exit $?' - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - func_execute_cmds "$reload_cmds" 'exit $?' - fi - - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) func_stripname '' '.exe' "$output" - output=$func_stripname_result.exe;; - esac - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" - - test -n "$release" && \ - func_warning "\`-release' is ignored for programs" - - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - case $host in - *-*-darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then - case ${MACOSX_DEPLOYMENT_TARGET-10.0} in - 10.[0123]) - func_append compile_command " ${wl}-bind_at_load" - func_append finalize_command " ${wl}-bind_at_load" - ;; - esac - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - compile_deplibs="$new_libs" - - - func_append compile_command " $compile_deplibs" - func_append finalize_command " $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - ::) dllsearchpath=$libdir;; - *) func_append dllsearchpath ":$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) func_append finalize_perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - fi - - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" - - # template prelinking step - if test -n "$prelink_cmds"; then - func_execute_cmds "$prelink_cmds" 'exit $?' - fi - - wrappers_required=yes - case $host in - *cegcc* | *mingw32ce*) - # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=no - ;; - *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - esac - if test "$wrappers_required" = no; then - # Replace the output file specification. - compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - exit_status=0 - func_show_eval "$link_command" 'exit_status=$?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' - fi - - exit $exit_status - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - func_append rpath "$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $opt_dry_run || $RM $output - # Link the executable and exit - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname - - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output_objdir/$outputname" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Now create the wrapper script. - func_verbose "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - fi - - # Only actually do things if not in dry run mode. - $opt_dry_run || { - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) func_stripname '' '.exe' "$output" - output=$func_stripname_result ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - func_stripname '' '.exe' "$outputname" - outputname=$func_stripname_result ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - func_dirname_and_basename "$output" "" "." - output_name=$func_basename_result - output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" - $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - func_emit_cwrapperexe_src > $cwrappersource - - # The wrapper executable is built using the $host compiler, - # because it contains $host paths and files. If cross- - # compiling, it, like the target executable, must be - # executed on the $host or under an emulation environment. - $opt_dry_run || { - $LTCC $LTCFLAGS -o $cwrapper $cwrappersource - $STRIP $cwrapper - } - - # Now, create the wrapper script for func_source use: - func_ltwrapper_scriptname $cwrapper - $RM $func_ltwrapper_scriptname_result - trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 - $opt_dry_run || { - # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then - $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result - else - func_emit_wrapper no > $func_ltwrapper_scriptname_result - fi - } - ;; - * ) - $RM $output - trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 - - func_emit_wrapper no > $output - chmod +x $output - ;; - esac - } - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - func_append oldobjs " $symfileobj" - fi - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $addlibs - func_append oldobjs " $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append oldobjs " $func_extract_archives_result" - fi - - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - func_basename "$obj" - $ECHO "$func_basename_result" - done | sort | sort -uc >/dev/null 2>&1); then - : - else - echo "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - func_mkdir_p "$gentop" - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - func_basename "$obj" - objbase="$func_basename_result" - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - func_arith $counter + 1 - counter=$func_arith_result - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - func_append oldobjs " $gentop/$newobj" - ;; - *) func_append oldobjs " $obj" ;; - esac - done - fi - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - eval cmds=\"$old_archive_cmds\" - - func_len " $cmds" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - elif test -n "$archiver_list_spec"; then - func_verbose "using command file archive linking..." - for obj in $oldobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > $output_objdir/$libname.libcmd - func_to_tool_file "$output_objdir/$libname.libcmd" - oldobjs=" $archiver_list_spec$func_to_tool_file_result" - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - func_verbose "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - oldobjs= - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - eval test_cmds=\"$old_archive_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - for obj in $save_oldobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - func_append objlist " $obj" - if test "$len" -lt "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - len=$len0 - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - func_execute_cmds "$cmds" 'exit $?' - done - - test -n "$generated" && \ - func_show_eval "${RM}r$generated" - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - func_verbose "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - # Only create the output if not a dry run. - $opt_dry_run || { - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - func_basename "$deplib" - name="$func_basename_result" - func_resolve_sysroot "$deplib" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" - ;; - -L*) - func_stripname -L '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -L$func_replace_sysroot_result" - ;; - -R*) - func_stripname -R '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -R$func_replace_sysroot_result" - ;; - *) func_append newdependency_libs " $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - - for lib in $dlfiles; do - case $lib in - *.la) - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" - ;; - *) func_append newdlfiles " $lib" ;; - esac - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - *.la) - # Only pass preopened files to the pseudo-archive (for - # eventual linking with the app. that links it) if we - # didn't already link the preopened objects directly into - # the library: - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" - ;; - esac - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlfiles " $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlprefiles " $abs" - done - dlprefiles="$newdlprefiles" - fi - $RM $output - # place dlname in correct position for cygwin - # In fact, it would be nice if we could use this code for all target - # systems that can't hard-code library paths into their executables - # and that have no shared library path variable independent of PATH, - # but it turns out we can't easily determine that from inspecting - # libtool variables, so we have to hard-code the OSs to which it - # applies here; at the moment, that means platforms that use the PE - # object format with DLL files. See the long comment at the top of - # tests/bindir.at for full details. - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) - # If a -bindir argument was supplied, place the dll there. - if test "x$bindir" != x ; - then - func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result$dlname - else - # Otherwise fall back on heuristic. - tdlname=../bin/$dlname - fi - ;; - esac - $ECHO > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags='$new_inherited_linker_flags' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Names of additional weak libraries provided by this library -weak_library_names='$weak_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $ECHO >> $output "\ -relink_command=\"$relink_command\"" - fi - done - } - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' - ;; - esac - exit $EXIT_SUCCESS -} - -{ test "$opt_mode" = link || test "$opt_mode" = relink; } && - func_mode_link ${1+"$@"} - - -# func_mode_uninstall arg... -func_mode_uninstall () -{ - $opt_debug - RM="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) func_append RM " $arg"; rmforce=yes ;; - -*) func_append RM " $arg" ;; - *) func_append files " $arg" ;; - esac - done - - test -z "$RM" && \ - func_fatal_help "you must specify an RM program" - - rmdirs= - - for file in $files; do - func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - odir="$objdir" - else - odir="$dir/$objdir" - fi - func_basename "$file" - name="$func_basename_result" - test "$opt_mode" = uninstall && odir="$dir" - - # Remember odir for removal later, being careful to avoid duplicates - if test "$opt_mode" = clean; then - case " $rmdirs " in - *" $odir "*) ;; - *) func_append rmdirs " $odir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if { test -L "$file"; } >/dev/null 2>&1 || - { test -h "$file"; } >/dev/null 2>&1 || - test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if func_lalib_p "$file"; then - func_source $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - func_append rmfiles " $odir/$n" - done - test -n "$old_library" && func_append rmfiles " $odir/$old_library" - - case "$opt_mode" in - clean) - case " $library_names " in - *" $dlname "*) ;; - *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; - esac - test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if func_lalib_p "$file"; then - - # Read the .lo file - func_source $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then - func_append rmfiles " $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then - func_append rmfiles " $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$opt_mode" = clean ; then - noexename=$name - case $file in - *.exe) - func_stripname '' '.exe' "$file" - file=$func_stripname_result - func_stripname '' '.exe' "$name" - noexename=$func_stripname_result - # $file with .exe has already been added to rmfiles, - # add $file without .exe - func_append rmfiles " $file" - ;; - esac - # Do a test to see if this is a libtool program. - if func_ltwrapper_p "$file"; then - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - relink_command= - func_source $func_ltwrapper_scriptname_result - func_append rmfiles " $func_ltwrapper_scriptname_result" - else - relink_command= - func_source $dir/$noexename - fi - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - func_append rmfiles " $odir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - func_append rmfiles " $odir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - func_show_eval "$RM $rmfiles" 'exit_status=1' - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - func_show_eval "rmdir $dir >/dev/null 2>&1" - fi - done - - exit $exit_status -} - -{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && - func_mode_uninstall ${1+"$@"} - -test -z "$opt_mode" && { - help="$generic_help" - func_fatal_help "you must specify a MODE" -} - -test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$opt_mode'" - -if test -n "$exec_cmd"; then - eval exec "$exec_cmd" - exit $EXIT_FAILURE -fi - -exit $exit_status - - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -# vi:sw=2 - diff --git a/m4/ax_check_docbook.m4 b/m4/ax_check_docbook.m4 deleted file mode 100644 index 5dcfe52b7..000000000 --- a/m4/ax_check_docbook.m4 +++ /dev/null @@ -1,65 +0,0 @@ -dnl --------------------------------------------------------------------------- -dnl Macro: AX_CHECK_DOCBOOK -dnl Check for availability of various DocBook utilities and perform necessary -dnl substitutions -dnl --------------------------------------------------------------------------- - -AC_DEFUN([AX_CHECK_DOCBOOK], [ -# It's just rude to go over the net to build -XSLTPROC_FLAGS=--nonet -DOCBOOK_ROOT= - -for i in /etc/xml/catalog /usr/local/etc/xml/catalog /opt/local/etc/xml/catalog ; -do - if test -f $i; then - XML_CATALOG="$i" - fi -done - -if test -z "$XML_CATALOG" ; then - for i in /usr/share/sgml/docbook/stylesheet/xsl/nwalsh /usr/share/sgml/docbook/xsl-stylesheets/ /opt/local/share/xsl/docbook-xsl/xhtml/ ; - do - if test -d "$i"; then - DOCBOOK_ROOT=$i - fi - done - - # Last resort - try net - if test -z "$DOCBOOK_ROOT"; then - XSLTPROC_FLAGS= - fi -else - CAT_ENTRY_START='' -fi - -AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,) -XSLTPROC_WORKS=no -if test -n "$XSLTPROC"; then - AC_MSG_CHECKING([whether xsltproc works]) - - if test -n "$XML_CATALOG"; then - DB_FILE="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl" - else - DB_FILE="$DOCBOOK_ROOT/docbook.xsl" - fi - - $XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END - - - - -END - if test "$?" = 0; then - XSLTPROC_WORKS=yes - fi - AC_MSG_RESULT($XSLTPROC_WORKS) -fi -AM_CONDITIONAL(have_xsltproc, test "$XSLTPROC_WORKS" = "yes") - -AC_SUBST(XML_CATALOG) -AC_SUBST(XSLTPROC_FLAGS) -AC_SUBST(DOCBOOK_ROOT) -AC_SUBST(CAT_ENTRY_START) -AC_SUBST(CAT_ENTRY_END) -]) diff --git a/m4/libtool.m4 b/m4/libtool.m4 deleted file mode 100644 index 828104cfd..000000000 --- a/m4/libtool.m4 +++ /dev/null @@ -1,8001 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool 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 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 57 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl - -_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl -dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_WITH_SYSROOT])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PREPARE_SED_QUOTE_VARS -# -------------------------- -# Define a few sed substitution that help us do robust quoting. -m4_defun([_LT_PREPARE_SED_QUOTE_VARS], -[# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' -]) - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - -## ------------------------------------- ## -## Accumulate code for creating libtool. ## -## ------------------------------------- ## - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - -## ------------------------ ## -## FIXME: Eliminate VARNAME ## -## ------------------------ ## - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$[]1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -_LT_OUTPUT_LIBTOOL_INIT -]) - -# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) -# ------------------------------------ -# Generate a child script FILE with all initialization necessary to -# reuse the environment learned by the parent script, and make the -# file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this -# macro, additional text can be appended to FILE to form the body of -# the child script. The macro ends with non-zero status if the -# file could not be fully written (such as if the disk is full). -m4_ifdef([AS_INIT_GENERATED], -[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], -[m4_defun([_LT_GENERATED_FILE_INIT], -[m4_require([AS_PREPARE])]dnl -[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl -[lt_write_fail=0 -cat >$1 <<_ASEOF || lt_write_fail=1 -#! $SHELL -# Generated by $as_me. -$2 -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$1 <<\_ASEOF || lt_write_fail=1 -AS_SHELL_SANITIZE -_AS_PREPARE -exec AS_MESSAGE_FD>&1 -_ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl -m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], -[# Run this file to recreate a libtool stub with the current configuration.]) - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2011 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec AS_MESSAGE_LOG_FD>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec AS_MESSAGE_LOG_FD>>config.log -$lt_cl_success || AS_EXIT(1) -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_REPLACE_SHELLFNS - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Go], [_LT_LANG(GO)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -m4_ifndef([AC_PROG_GO], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_GO. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ -m4_defun([AC_PROG_GO], -[AC_LANG_PUSH(Go)dnl -AC_ARG_VAR([GOC], [Go compiler command])dnl -AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl -_AC_ARG_VAR_LDFLAGS()dnl -AC_CHECK_TOOL(GOC, gccgo) -if test -z "$GOC"; then - if test -n "$ac_tool_prefix"; then - AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) - fi -fi -if test -z "$GOC"; then - AC_CHECK_PROG(GOC, gccgo, gccgo, false) -fi -])#m4_defun -])#m4_ifndef - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([AC_PROG_GO], - [LT_LANG(GO)], - [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) -dnl AC_DEFUN([AC_LIBTOOL_RC], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], - [lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD - echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD - $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES([TAG]) -# --------------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], - [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) -# ---------------------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -# Store the results from the different compilers for each TAGNAME. -# Allow to override them for all tags through lt_cv_aix_libpath. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], - [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ - lt_aix_libpath_sed='[ - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }]' - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi],[]) - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" - fi - ]) - aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) -fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[m4_divert_text([M4SH-INIT], [$1 -])])# _LT_SHELL_INIT - - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Find how we can fake an echo command that does not interpret backslash. -# In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -AC_MSG_CHECKING([how to print strings]) -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$[]1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -case "$ECHO" in - printf*) AC_MSG_RESULT([printf]) ;; - print*) AC_MSG_RESULT([print -r]) ;; - *) AC_MSG_RESULT([cat]) ;; -esac - -m4_ifdef([_AS_DETECT_SUGGESTED], -[_AS_DETECT_SUGGESTED([ - test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test "X`printf %s $ECHO`" = "X$ECHO" \ - || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) - -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_WITH_SYSROOT -# ---------------- -AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) -AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], -[], [with_sysroot=no]) - -dnl lt_sysroot will always be passed unquoted. We quote it here -dnl in case the user passed a directory name. -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - AC_MSG_RESULT([${with_sysroot}]) - AC_MSG_ERROR([The sysroot must be an absolute path.]) - ;; -esac - - AC_MSG_RESULT([${lt_sysroot:-no}]) -_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_PROG_AR -# ----------- -m4_defun([_LT_PROG_AR], -[AC_CHECK_TOOLS(AR, [ar], false) -: ${AR=ar} -: ${AR_FLAGS=cru} -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) - -AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], - [lt_cv_ar_at_file=no - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - ]) - ]) - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi -_LT_DECL([], [archiver_list_spec], [1], - [How to feed a file listing to the archiver]) -])# _LT_PROG_AR - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[_LT_PROG_AR - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -_LT_DECL([], [lock_old_archive_extraction], [0], - [Whether to use a lock for old archive extraction]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[23]].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[[3-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], - [lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [lt_cv_shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - ]) - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [install_override_mode], [1], - [Permission mode override for installation of shared libraries]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PROG_ECHO_BACKSLASH])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - 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. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname 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 - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method = "file_magic"]) -_LT_DECL([], [file_magic_glob], [1], - [How to find potential files when deplibs_check_method = "file_magic"]) -_LT_DECL([], [want_nocaseglob], [1], - [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - -# _LT_CHECK_SHAREDLIB_FROM_LINKLIB -# -------------------------------- -# how to determine the name of the shared library -# associated with a specific link library. -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -m4_require([_LT_DECL_DLLTOOL]) -AC_CACHE_CHECK([how to associate runtime and link libraries], -lt_cv_sharedlib_from_linklib_cmd, -[lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac -]) -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - -_LT_DECL([], [sharedlib_from_linklib_cmd], [1], - [Command to associate shared and link libraries]) -])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB - - -# _LT_PATH_MANIFEST_TOOL -# ---------------------- -# locate the manifest tool -m4_defun([_LT_PATH_MANIFEST_TOOL], -[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&AS_MESSAGE_LOG_FD - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi -_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl -])# _LT_PATH_MANIFEST_TOOL - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; - *) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; - esac - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT@&t@_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT@&t@_DLSYM_CONST -#else -# define LT@&t@_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT@&t@_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -_LT_DECL([], [nm_file_list_spec], [1], - [Specify filename containing input files for $NM]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - *Sun\ F* | *Sun*Fortran*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Intel*\ [[CF]]*Compiler*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - *Portland\ Group*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac - -AC_CACHE_CHECK([for $compiler option to produce PIC], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - ;; - esac - ;; - linux* | k*bsd*-gnu | gnu*) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu | gnu*) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; - *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - _LT_TAGVAR(link_all_deplibs, $1)=no - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - esac - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - m4_if($1, [], [ - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - _LT_LINKER_OPTION([if $CC understands -b], - _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], - [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], - [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE( - [AC_LANG_SOURCE( - [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], - [C++], [[int foo (void) { return 0; }]], - [Fortran 77], [[ - subroutine foo - end]], - [Fortran], [[ - subroutine foo - end]])])], - [lt_cv_irix_exported_symbol=yes], - [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_CACHE_CHECK([whether -lc should be explicitly linked in], - [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), - [$RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - ]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [postlink_cmds], [2], - [Commands necessary for finishing linking programs]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd2.*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" - _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_FUNC_STRIPNAME_CNF -# ---------------------- -# func_stripname_cnf prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# -# This function is identical to the (non-XSI) version of func_stripname, -# except this one can be used by m4 code that may be executed by configure, -# rather than the libtool script. -m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl -AC_REQUIRE([_LT_DECL_SED]) -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) -func_stripname_cnf () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname_cnf -])# _LT_FUNC_STRIPNAME_CNF - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF -package foo -func foo() { -} -_LT_EOF -]) - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; -esac - -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${F77-"f77"} - CFLAGS=$FFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_LANG_PUSH(Fortran) - -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${FC-"f95"} - CFLAGS=$FCFLAGS - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -CFLAGS=$GCJFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_GO_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Go compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GO_CONFIG], -[AC_REQUIRE([LT_PROG_GO])dnl -AC_LANG_SAVE - -# Source file extension for Go test sources. -ac_ext=go - -# Object file extension for compiled Go test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="package main; func main() { }" - -# Code to be used in simple link tests -lt_simple_link_test_code='package main; func main() { }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GOC-"gccgo"} -CFLAGS=$GOFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# Go did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GO_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -CFLAGS= -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_GO -# ---------- -AC_DEFUN([LT_PROG_GO], -[AC_CHECK_TOOL(GOC, gccgo,) -]) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - -# _LT_DECL_DLLTOOL -# ---------------- -# Ensure DLLTOOL variable is set. -m4_defun([_LT_DECL_DLLTOOL], -[AC_CHECK_TOOL(DLLTOOL, dlltool, false) -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) -AC_SUBST([DLLTOOL]) -]) - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - -# _LT_PATH_CONVERSION_FUNCTIONS -# ----------------------------- -# Determine which file name conversion functions should be used by -# func_to_host_file (and, implicitly, by func_to_host_path). These are needed -# for certain cross-compile configurations and native mingw. -m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_MSG_CHECKING([how to convert $build file names to $host format]) -AC_CACHE_VAL(lt_cv_to_host_file_cmd, -[case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac -]) -to_host_file_cmd=$lt_cv_to_host_file_cmd -AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) -_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], - [0], [convert $build file names to $host format])dnl - -AC_MSG_CHECKING([how to convert $build file names to toolchain format]) -AC_CACHE_VAL(lt_cv_to_tool_file_cmd, -[#assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac -]) -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) -_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], - [0], [convert $build files to toolchain format])dnl -])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4 deleted file mode 100644 index 5d9acd8e2..000000000 --- a/m4/ltoptions.m4 +++ /dev/null @@ -1,384 +0,0 @@ -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 7 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - ]) -])# _LT_SET_OPTIONS - - -## --------------------------------- ## -## Macros to handle LT_INIT options. ## -## --------------------------------- ## - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [1], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' -# LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for lt_pkg in $withval; do - IFS="$lt_save_ifs" - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - -## ----------------- ## -## LTDL_INIT Options ## -## ----------------- ## - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4 deleted file mode 100644 index 9000a057d..000000000 --- a/m4/ltsugar.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) diff --git a/m4/ltversion.m4 b/m4/ltversion.m4 deleted file mode 100644 index 07a8602d4..000000000 --- a/m4/ltversion.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# @configure_input@ - -# serial 3337 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.4.2]) -m4_define([LT_PACKAGE_REVISION], [1.3337]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.2' -macro_revision='1.3337' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4 deleted file mode 100644 index c573da90c..000000000 --- a/m4/lt~obsolete.m4 +++ /dev/null @@ -1,98 +0,0 @@ -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 5 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) -m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) -m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) -m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) -m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) -m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) -m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/missing b/missing deleted file mode 100755 index 86a8fc31e..000000000 --- a/missing +++ /dev/null @@ -1,331 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. - -scriptversion=2012-01-06.13; # UTC - -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. - -# 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 2, 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. - -# You should have received a copy of the GNU General Public License -# 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 -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch] - -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - -esac - -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/mkinstalldirs b/mkinstalldirs deleted file mode 100755 index 4191a45db..000000000 --- a/mkinstalldirs +++ /dev/null @@ -1,162 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy - -scriptversion=2009-04-28.21; # UTC - -# Original author: Noah Friedman -# Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' -IFS=" "" $nl" -errstatus=0 -dirmode= - -usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to ." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" - exit $? - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --version) - echo "$0 $scriptversion" - exit $? - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. -case $dirmode in - '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version - fi - ;; - *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done - fi - ;; -esac - -for file -do - case $file in - /*) pathcomp=/ ;; - *) pathcomp= ;; - esac - oIFS=$IFS - IFS=/ - set fnord $file - shift - IFS=$oIFS - - for d - do - test "x$d" = x && continue - - pathcomp=$pathcomp$d - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr= - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp=$pathcomp/ - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/src/Makefile.am b/src/Makefile.am index 7efe7f6d2..39588af58 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,8 @@ pgpool_SOURCES = main/main.c \ main/pool_globals.c \ main/pgpool_main.c \ main/health_check.c \ + main/pool_internal_comms.c \ + main/pgpool_logger.c \ config/pool_config.l \ config/pool_config_variables.c \ pcp_con/pcp_child.c \ @@ -20,6 +22,7 @@ pgpool_SOURCES = main/main.c \ auth/auth-scram.c \ protocol/pool_proto2.c \ protocol/child.c \ + protocol/pool_pg_utils.c \ protocol/pool_process_query.c \ protocol/pool_connection_pool.c \ protocol/pool_proto_modules.c \ @@ -32,6 +35,7 @@ pgpool_SOURCES = main/main.c \ rewrite/pool_timestamp.c \ rewrite/pool_lobj.c \ utils/pool_select_walker.c \ + utils/pool_track_table_mutation.c \ utils/strlcpy.c \ utils/psprintf.c \ utils/pool_params.c \ @@ -45,12 +49,13 @@ pgpool_SOURCES = main/main.c \ utils/pool_process_reporting.c \ utils/pool_ssl.c \ utils/pool_stream.c \ + utils/socket_stream.c \ utils/getopt_long.c \ utils/mmgr/mcxt.c \ utils/mmgr/aset.c \ utils/error/elog.c \ utils/error/assert.c \ - utils/pcp/pcp_stream.c \ + utils/pcp/pcp_stream.c \ utils/regex_array.c \ utils/json_writer.c \ utils/json.c \ @@ -58,19 +63,36 @@ pgpool_SOURCES = main/main.c \ utils/base64.c \ utils/sha2.c \ utils/ssl_utils.c \ - utils/statistics.c + utils/statistics.c \ + utils/pool_health_check_stats.c \ + utils/psqlscan.l \ + utils/pgstrcasecmp.c \ + utils/pg_strong_random.c \ + utils/pg_prng.c + +utils/psqlscan.c: utils/psqlscan.l + $(LEX) -o'utils/psqlscan.c' $< + +config/pool_config.c: config/pool_config.l + $(LEX) -o'config/pool_config.c' $< DEFS = @DEFS@ \ -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" \ - -DHEALTHCHECK_OPTS=$(HEALTHCHECK_DEBUG) + -DPGSQL_BIN_DIR=\"$(PGSQL_BIN_DIR)\" sysconf_DATA = sample/pgpool.conf.sample \ sample/pcp.conf.sample \ sample/pool_hba.conf.sample \ - sample/pgpool.conf.sample-replication \ - sample/pgpool.conf.sample-master-slave \ - sample/pgpool.conf.sample-stream \ - sample/pgpool.conf.sample-logical + sample/scripts/failover.sh.sample \ + sample/scripts/follow_primary.sh.sample \ + sample/scripts/pgpool_remote_start.sample \ + sample/scripts/recovery_1st_stage.sample \ + sample/scripts/replication_mode_recovery_1st_stage.sample \ + sample/scripts/replication_mode_recovery_2nd_stage.sample \ + sample/scripts/escalation.sh.sample \ + sample/scripts/aws_eip_if_cmd.sh.sample \ + sample/scripts/aws_rtb_if_cmd.sh.sample + pkgdata_DATA = sql/insert_lock.sql \ sample/pgpool.pam @@ -91,15 +113,26 @@ endif AM_YFLAGS = -d EXTRA_DIST = sample/pgpool.pam \ - sample/pgpool_remote_start sample/pgpool_recovery sample/pgpool_recovery_pitr \ + sample/scripts/failover.sh.sample \ + sample/scripts/follow_primary.sh.sample \ + sample/scripts/pgpool_remote_start.sample \ + sample/scripts/recovery_1st_stage.sample \ + sample/scripts/replication_mode_recovery_1st_stage.sample \ + sample/scripts/replication_mode_recovery_2nd_stage.sample \ + sample/scripts/escalation.sh.sample \ + sample/scripts/aws_eip_if_cmd.sh.sample \ + sample/scripts/aws_rtb_if_cmd.sh.sample \ sample/pgpool.conf.sample sample/pool_hba.conf.sample \ - sample/pgpool.conf.sample-replication sample/pgpool.conf.sample-master-slave \ - sample/pgpool.conf.sample-stream sample/pgpool.conf.sample-logical sample/pcp.conf.sample \ + sample/pcp.conf.sample \ sql/Makefile \ sql/insert_lock.sql \ sql/pgpool-recovery/pgpool-recovery.c \ sql/pgpool-recovery/pgpool-recovery.sql.in \ sql/pgpool-recovery/uninstall_pgpool-recovery.sql \ + sql/pgpool-recovery/pgpool_recovery--1.4.sql \ + sql/pgpool-recovery/pgpool_recovery--1.3--1.4.sql \ + sql/pgpool-recovery/pgpool_recovery--1.3.sql \ + sql/pgpool-recovery/pgpool_recovery--1.2--1.3.sql \ sql/pgpool-recovery/pgpool_recovery--1.2.sql \ sql/pgpool-recovery/pgpool_recovery--1.1--1.2.sql \ sql/pgpool-recovery/pgpool_recovery--1.1.sql \ @@ -117,6 +150,16 @@ EXTRA_DIST = sample/pgpool.pam \ sql/pgpool_adm/pgpool_adm--1.1.sql \ sql/pgpool_adm/pgpool_adm--1.0--1.1.sql \ sql/pgpool_adm/pgpool_adm--1.0.sql \ + sql/pgpool_adm/pgpool_adm--1.2.sql \ + sql/pgpool_adm/pgpool_adm--1.1--1.2.sql \ + sql/pgpool_adm/pgpool_adm--1.3.sql \ + sql/pgpool_adm/pgpool_adm--1.2--1.3.sql \ + sql/pgpool_adm/pgpool_adm--1.4.sql \ + sql/pgpool_adm/pgpool_adm--1.3--1.4.sql \ + sql/pgpool_adm/pgpool_adm--1.5.sql \ + sql/pgpool_adm/pgpool_adm--1.4--1.5.sql \ + sql/pgpool_adm/pgpool_adm--1.6.sql \ + sql/pgpool_adm/pgpool_adm--1.5--1.6.sql \ sql/pgpool_adm/Makefile \ test/parser/expected/copy.out test/parser/expected/create.out \ test/parser/expected/cursor.out test/parser/expected/delete.out \ @@ -146,11 +189,28 @@ EXTRA_DIST = sample/pgpool.pam \ test/pdo-test/pdotest.php test/pdo-test/regsql.inc \ test/pdo-test/SQLlist/test1.sql test/pdo-test/SQLlist/test2.sql \ test/pdo-test/mod/database.inc test/pdo-test/mod/errorhandler.inc \ - test/pgpool_setup test/regression \ + test/pgpool_setup.in test/watchdog_setup.in test/regression \ redhat/pgpool.init \ - redhat/pgpool_rhel7.sysconfig redhat/pgpool_rhel6.sysconfig \ + redhat/pgpool_rhel.sysconfig redhat/pgpool_rhel6.sysconfig \ redhat/pgpool.conf.sample.patch \ + redhat/pcp_unix_domain_path.patch \ + redhat/pgpool_log.patch \ redhat/pgpool.service \ + redhat/pgpool_socket_dir.patch \ + redhat/pgpool_sudoers.d \ + redhat/pgpool_tmpfiles.d \ pgpool.spec +bin_SCRIPTS = test/pgpool_setup test/watchdog_setup + +%: %.in + sed -e 's#[@][@]PGPOOL_INSTALL_DIR[@][@]#$(prefix)#g' \ + -e 's#[@][@]PGPOOL_CONFIG_DIR[@][@]#$(sysconfdir)#g' \ + -e 's#[@][@]PGSQL_BIN_DIR[@][@]#$(PGSQL_BIN_DIR)#g' \ + -e 's#[@][@]PGSQL_LIB_DIR[@][@]#$(PGSQL_LIB_DIR)#g' $^ > $@ + chmod +x $@ + +clean-local: + -rm -f test/pgpool_setup test/watchdog_setup + SUBDIRS = parser libs watchdog . tools include diff --git a/src/Makefile.in b/src/Makefile.in deleted file mode 100644 index f70b4593c..000000000 --- a/src/Makefile.in +++ /dev/null @@ -1,1131 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -bin_PROGRAMS = pgpool$(EXEEXT) -subdir = src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs config/pool_config.c \ - $(top_srcdir)/ylwrap -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" \ - "$(DESTDIR)$(sysconfdir)" -PROGRAMS = $(bin_PROGRAMS) -am__dirstamp = $(am__leading_dot)dirstamp -am_pgpool_OBJECTS = main/main.$(OBJEXT) main/pool_globals.$(OBJEXT) \ - main/pgpool_main.$(OBJEXT) main/health_check.$(OBJEXT) \ - config/pool_config.$(OBJEXT) \ - config/pool_config_variables.$(OBJEXT) \ - pcp_con/pcp_child.$(OBJEXT) pcp_con/pcp_worker.$(OBJEXT) \ - pcp_con/recovery.$(OBJEXT) auth/md5.$(OBJEXT) \ - auth/pool_auth.$(OBJEXT) auth/pool_passwd.$(OBJEXT) \ - auth/pool_hba.$(OBJEXT) auth/auth-scram.$(OBJEXT) \ - protocol/pool_proto2.$(OBJEXT) protocol/child.$(OBJEXT) \ - protocol/pool_process_query.$(OBJEXT) \ - protocol/pool_connection_pool.$(OBJEXT) \ - protocol/pool_proto_modules.$(OBJEXT) \ - query_cache/pool_memqcache.$(OBJEXT) \ - protocol/CommandComplete.$(OBJEXT) \ - context/pool_session_context.$(OBJEXT) \ - context/pool_process_context.$(OBJEXT) \ - context/pool_query_context.$(OBJEXT) \ - streaming_replication/pool_worker_child.$(OBJEXT) \ - rewrite/pool_timestamp.$(OBJEXT) rewrite/pool_lobj.$(OBJEXT) \ - utils/pool_select_walker.$(OBJEXT) utils/strlcpy.$(OBJEXT) \ - utils/psprintf.$(OBJEXT) utils/pool_params.$(OBJEXT) \ - utils/ps_status.$(OBJEXT) utils/pool_shmem.$(OBJEXT) \ - utils/pool_sema.$(OBJEXT) utils/pool_signal.$(OBJEXT) \ - utils/pool_path.$(OBJEXT) utils/pool_ip.$(OBJEXT) \ - utils/pool_relcache.$(OBJEXT) \ - utils/pool_process_reporting.$(OBJEXT) \ - utils/pool_ssl.$(OBJEXT) utils/pool_stream.$(OBJEXT) \ - utils/getopt_long.$(OBJEXT) utils/mmgr/mcxt.$(OBJEXT) \ - utils/mmgr/aset.$(OBJEXT) utils/error/elog.$(OBJEXT) \ - utils/error/assert.$(OBJEXT) utils/pcp/pcp_stream.$(OBJEXT) \ - utils/regex_array.$(OBJEXT) utils/json_writer.$(OBJEXT) \ - utils/json.$(OBJEXT) utils/scram-common.$(OBJEXT) \ - utils/base64.$(OBJEXT) utils/sha2.$(OBJEXT) \ - utils/ssl_utils.$(OBJEXT) utils/statistics.$(OBJEXT) -pgpool_OBJECTS = $(am_pgpool_OBJECTS) -pgpool_DEPENDENCIES = parser/libsql-parser.a parser/nodes.o \ - watchdog/lib-watchdog.a -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -pgpool_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(pgpool_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/include -depcomp = -am__depfiles_maybe = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -@MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ || -LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) -LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) -AM_V_LEX = $(am__v_LEX_@AM_V@) -am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) -am__v_LEX_0 = @echo " LEX " $@; -am__v_LEX_1 = -YLWRAP = $(top_srcdir)/ylwrap -SOURCES = $(pgpool_SOURCES) -DIST_SOURCES = $(pgpool_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -DATA = $(pkgdata_DATA) $(sysconf_DATA) -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" \ - -DHEALTHCHECK_OPTS=$(HEALTHCHECK_DEBUG) - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = subdir-objects -libs_dir = $(top_srcdir)/src/libs -AM_CPPFLAGS = -D_GNU_SOURCE -I @PGSQL_INCLUDE_DIR@ -HEALTHCHECK_DEBUG = 0 -pgpool_SOURCES = main/main.c \ - main/pool_globals.c \ - main/pgpool_main.c \ - main/health_check.c \ - config/pool_config.l \ - config/pool_config_variables.c \ - pcp_con/pcp_child.c \ - pcp_con/pcp_worker.c \ - pcp_con/recovery.c \ - auth/md5.c \ - auth/pool_auth.c \ - auth/pool_passwd.c \ - auth/pool_hba.c \ - auth/auth-scram.c \ - protocol/pool_proto2.c \ - protocol/child.c \ - protocol/pool_process_query.c \ - protocol/pool_connection_pool.c \ - protocol/pool_proto_modules.c \ - query_cache/pool_memqcache.c \ - protocol/CommandComplete.c \ - context/pool_session_context.c \ - context/pool_process_context.c \ - context/pool_query_context.c \ - streaming_replication/pool_worker_child.c \ - rewrite/pool_timestamp.c \ - rewrite/pool_lobj.c \ - utils/pool_select_walker.c \ - utils/strlcpy.c \ - utils/psprintf.c \ - utils/pool_params.c \ - utils/ps_status.c \ - utils/pool_shmem.c \ - utils/pool_sema.c \ - utils/pool_signal.c \ - utils/pool_path.c \ - utils/pool_ip.c \ - utils/pool_relcache.c \ - utils/pool_process_reporting.c \ - utils/pool_ssl.c \ - utils/pool_stream.c \ - utils/getopt_long.c \ - utils/mmgr/mcxt.c \ - utils/mmgr/aset.c \ - utils/error/elog.c \ - utils/error/assert.c \ - utils/pcp/pcp_stream.c \ - utils/regex_array.c \ - utils/json_writer.c \ - utils/json.c \ - utils/scram-common.c \ - utils/base64.c \ - utils/sha2.c \ - utils/ssl_utils.c \ - utils/statistics.c - -sysconf_DATA = sample/pgpool.conf.sample \ - sample/pcp.conf.sample \ - sample/pool_hba.conf.sample \ - sample/pgpool.conf.sample-replication \ - sample/pgpool.conf.sample-master-slave \ - sample/pgpool.conf.sample-stream \ - sample/pgpool.conf.sample-logical - -pkgdata_DATA = sql/insert_lock.sql \ - sample/pgpool.pam - - -# suggested by libtoolize -#ACLOCAL_AMFLAGS = -I m4 -pgpool_LDADD = -L@PGSQL_LIB_DIR@ -lpq parser/libsql-parser.a \ - parser/nodes.o \ - watchdog/lib-watchdog.a \ - -lpthread - -@enable_rpath_FALSE@pgpool_LDFLAGS = -@enable_rpath_TRUE@pgpool_LDFLAGS = -rpath @PGSQL_LIB_DIR@ -rpath $(libdir) -AM_YFLAGS = -d -EXTRA_DIST = sample/pgpool.pam \ - sample/pgpool_remote_start sample/pgpool_recovery sample/pgpool_recovery_pitr \ - sample/pgpool.conf.sample sample/pool_hba.conf.sample \ - sample/pgpool.conf.sample-replication sample/pgpool.conf.sample-master-slave \ - sample/pgpool.conf.sample-stream sample/pgpool.conf.sample-logical sample/pcp.conf.sample \ - sql/Makefile \ - sql/insert_lock.sql \ - sql/pgpool-recovery/pgpool-recovery.c \ - sql/pgpool-recovery/pgpool-recovery.sql.in \ - sql/pgpool-recovery/uninstall_pgpool-recovery.sql \ - sql/pgpool-recovery/pgpool_recovery--1.2.sql \ - sql/pgpool-recovery/pgpool_recovery--1.1--1.2.sql \ - sql/pgpool-recovery/pgpool_recovery--1.1.sql \ - sql/pgpool-recovery/pgpool_recovery.control \ - sql/pgpool-recovery/Makefile \ - sql/pgpool-regclass/pgpool-regclass.c \ - sql/pgpool-regclass/pgpool-regclass.sql.in \ - sql/pgpool-regclass/uninstall_pgpool-regclass.sql \ - sql/pgpool-regclass/pgpool_regclass--1.0.sql \ - sql/pgpool-regclass/pgpool_regclass.control \ - sql/pgpool-regclass/Makefile \ - sql/pgpool_adm/pgpool_adm.c \ - sql/pgpool_adm/pgpool_adm.h \ - sql/pgpool_adm/pgpool_adm.control \ - sql/pgpool_adm/pgpool_adm--1.1.sql \ - sql/pgpool_adm/pgpool_adm--1.0--1.1.sql \ - sql/pgpool_adm/pgpool_adm--1.0.sql \ - sql/pgpool_adm/Makefile \ - test/parser/expected/copy.out test/parser/expected/create.out \ - test/parser/expected/cursor.out test/parser/expected/delete.out \ - test/parser/expected/drop.out test/parser/expected/insert.out \ - test/parser/expected/misc.out test/parser/expected/prepare.out \ - test/parser/expected/privileges.out test/parser/expected/scanner.out \ - test/parser/expected/select.out \ - test/parser/expected/transaction.out test/parser/expected/update.out \ - test/parser/expected/v84.out test/parser/expected/v90.out \ - test/parser/expected/var.out \ - test/parser/input/alter.sql \ - test/parser/input/copy.sql test/parser/input/create.sql \ - test/parser/input/cursor.sql test/parser/input/delete.sql \ - test/parser/input/drop.sql test/parser/input/insert.sql \ - test/parser/input/misc.sql test/parser/input/prepare.sql \ - test/parser/input/privileges.sql test/parser/input/scanner.sql \ - test/parser/input/select.sql \ - test/parser/input/transaction.sql test/parser/input/update.sql \ - test/parser/input/v84.sql test/parser/input/v90.sql \ - test/parser/input/var.sql \ - test/parser/.cvsignore test/parser/Makefile \ - test/parser/README test/parser/main.c \ - test/parser/pool.h test/parser/run-test \ - test/parser/parse_schedule \ - test/C/Makefile test/C/test_extended.c \ - test/pdo-test/README.euc_jp test/pdo-test/collections.inc test/pdo-test/def.inc \ - test/pdo-test/pdotest.php test/pdo-test/regsql.inc \ - test/pdo-test/SQLlist/test1.sql test/pdo-test/SQLlist/test2.sql \ - test/pdo-test/mod/database.inc test/pdo-test/mod/errorhandler.inc \ - test/pgpool_setup test/regression \ - redhat/pgpool.init \ - redhat/pgpool_rhel7.sysconfig redhat/pgpool_rhel6.sysconfig \ - redhat/pgpool.conf.sample.patch \ - redhat/pgpool.service \ - pgpool.spec - -SUBDIRS = parser libs watchdog . tools include -all: all-recursive - -.SUFFIXES: -.SUFFIXES: .c .l .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps src/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -main/$(am__dirstamp): - @$(MKDIR_P) main - @: > main/$(am__dirstamp) -main/main.$(OBJEXT): main/$(am__dirstamp) -main/pool_globals.$(OBJEXT): main/$(am__dirstamp) -main/pgpool_main.$(OBJEXT): main/$(am__dirstamp) -main/health_check.$(OBJEXT): main/$(am__dirstamp) -config/$(am__dirstamp): - @$(MKDIR_P) config - @: > config/$(am__dirstamp) -config/pool_config.$(OBJEXT): config/$(am__dirstamp) -config/pool_config_variables.$(OBJEXT): config/$(am__dirstamp) -pcp_con/$(am__dirstamp): - @$(MKDIR_P) pcp_con - @: > pcp_con/$(am__dirstamp) -pcp_con/pcp_child.$(OBJEXT): pcp_con/$(am__dirstamp) -pcp_con/pcp_worker.$(OBJEXT): pcp_con/$(am__dirstamp) -pcp_con/recovery.$(OBJEXT): pcp_con/$(am__dirstamp) -auth/$(am__dirstamp): - @$(MKDIR_P) auth - @: > auth/$(am__dirstamp) -auth/md5.$(OBJEXT): auth/$(am__dirstamp) -auth/pool_auth.$(OBJEXT): auth/$(am__dirstamp) -auth/pool_passwd.$(OBJEXT): auth/$(am__dirstamp) -auth/pool_hba.$(OBJEXT): auth/$(am__dirstamp) -auth/auth-scram.$(OBJEXT): auth/$(am__dirstamp) -protocol/$(am__dirstamp): - @$(MKDIR_P) protocol - @: > protocol/$(am__dirstamp) -protocol/pool_proto2.$(OBJEXT): protocol/$(am__dirstamp) -protocol/child.$(OBJEXT): protocol/$(am__dirstamp) -protocol/pool_process_query.$(OBJEXT): protocol/$(am__dirstamp) -protocol/pool_connection_pool.$(OBJEXT): protocol/$(am__dirstamp) -protocol/pool_proto_modules.$(OBJEXT): protocol/$(am__dirstamp) -query_cache/$(am__dirstamp): - @$(MKDIR_P) query_cache - @: > query_cache/$(am__dirstamp) -query_cache/pool_memqcache.$(OBJEXT): query_cache/$(am__dirstamp) -protocol/CommandComplete.$(OBJEXT): protocol/$(am__dirstamp) -context/$(am__dirstamp): - @$(MKDIR_P) context - @: > context/$(am__dirstamp) -context/pool_session_context.$(OBJEXT): context/$(am__dirstamp) -context/pool_process_context.$(OBJEXT): context/$(am__dirstamp) -context/pool_query_context.$(OBJEXT): context/$(am__dirstamp) -streaming_replication/$(am__dirstamp): - @$(MKDIR_P) streaming_replication - @: > streaming_replication/$(am__dirstamp) -streaming_replication/pool_worker_child.$(OBJEXT): \ - streaming_replication/$(am__dirstamp) -rewrite/$(am__dirstamp): - @$(MKDIR_P) rewrite - @: > rewrite/$(am__dirstamp) -rewrite/pool_timestamp.$(OBJEXT): rewrite/$(am__dirstamp) -rewrite/pool_lobj.$(OBJEXT): rewrite/$(am__dirstamp) -utils/$(am__dirstamp): - @$(MKDIR_P) utils - @: > utils/$(am__dirstamp) -utils/pool_select_walker.$(OBJEXT): utils/$(am__dirstamp) -utils/strlcpy.$(OBJEXT): utils/$(am__dirstamp) -utils/psprintf.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_params.$(OBJEXT): utils/$(am__dirstamp) -utils/ps_status.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_shmem.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_sema.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_signal.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_path.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_ip.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_relcache.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_process_reporting.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_ssl.$(OBJEXT): utils/$(am__dirstamp) -utils/pool_stream.$(OBJEXT): utils/$(am__dirstamp) -utils/getopt_long.$(OBJEXT): utils/$(am__dirstamp) -utils/mmgr/$(am__dirstamp): - @$(MKDIR_P) utils/mmgr - @: > utils/mmgr/$(am__dirstamp) -utils/mmgr/mcxt.$(OBJEXT): utils/mmgr/$(am__dirstamp) -utils/mmgr/aset.$(OBJEXT): utils/mmgr/$(am__dirstamp) -utils/error/$(am__dirstamp): - @$(MKDIR_P) utils/error - @: > utils/error/$(am__dirstamp) -utils/error/elog.$(OBJEXT): utils/error/$(am__dirstamp) -utils/error/assert.$(OBJEXT): utils/error/$(am__dirstamp) -utils/pcp/$(am__dirstamp): - @$(MKDIR_P) utils/pcp - @: > utils/pcp/$(am__dirstamp) -utils/pcp/pcp_stream.$(OBJEXT): utils/pcp/$(am__dirstamp) -utils/regex_array.$(OBJEXT): utils/$(am__dirstamp) -utils/json_writer.$(OBJEXT): utils/$(am__dirstamp) -utils/json.$(OBJEXT): utils/$(am__dirstamp) -utils/scram-common.$(OBJEXT): utils/$(am__dirstamp) -utils/base64.$(OBJEXT): utils/$(am__dirstamp) -utils/sha2.$(OBJEXT): utils/$(am__dirstamp) -utils/ssl_utils.$(OBJEXT): utils/$(am__dirstamp) -utils/statistics.$(OBJEXT): utils/$(am__dirstamp) - -pgpool$(EXEEXT): $(pgpool_OBJECTS) $(pgpool_DEPENDENCIES) $(EXTRA_pgpool_DEPENDENCIES) - @rm -f pgpool$(EXEEXT) - $(AM_V_CCLD)$(pgpool_LINK) $(pgpool_OBJECTS) $(pgpool_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f auth/*.$(OBJEXT) - -rm -f config/*.$(OBJEXT) - -rm -f context/*.$(OBJEXT) - -rm -f main/*.$(OBJEXT) - -rm -f pcp_con/*.$(OBJEXT) - -rm -f protocol/*.$(OBJEXT) - -rm -f query_cache/*.$(OBJEXT) - -rm -f rewrite/*.$(OBJEXT) - -rm -f streaming_replication/*.$(OBJEXT) - -rm -f utils/*.$(OBJEXT) - -rm -f utils/error/*.$(OBJEXT) - -rm -f utils/mmgr/*.$(OBJEXT) - -rm -f utils/pcp/*.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -.c.o: - $(AM_V_CC)$(COMPILE) -c -o $@ $< - -.c.obj: - $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: - $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< - -.l.c: - $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-pkgdataDATA: $(pkgdata_DATA) - @$(NORMAL_INSTALL) - @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ - done - -uninstall-pkgdataDATA: - @$(NORMAL_UNINSTALL) - @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) -install-sysconfDATA: $(sysconf_DATA) - @$(NORMAL_INSTALL) - @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sysconfdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \ - done - -uninstall-sysconfDATA: - @$(NORMAL_UNINSTALL) - @list='$(sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir) - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile $(PROGRAMS) $(DATA) -installdirs: installdirs-recursive -installdirs-am: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(sysconfdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f auth/$(am__dirstamp) - -rm -f config/$(am__dirstamp) - -rm -f context/$(am__dirstamp) - -rm -f main/$(am__dirstamp) - -rm -f pcp_con/$(am__dirstamp) - -rm -f protocol/$(am__dirstamp) - -rm -f query_cache/$(am__dirstamp) - -rm -f rewrite/$(am__dirstamp) - -rm -f streaming_replication/$(am__dirstamp) - -rm -f utils/$(am__dirstamp) - -rm -f utils/error/$(am__dirstamp) - -rm -f utils/mmgr/$(am__dirstamp) - -rm -f utils/pcp/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -rm -f config/pool_config.c -clean: clean-recursive - -clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: install-pkgdataDATA - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: install-binPROGRAMS install-sysconfDATA - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-pkgdataDATA \ - uninstall-sysconfDATA - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-binPROGRAMS clean-generic clean-libtool \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-binPROGRAMS install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkgdataDATA install-ps \ - install-ps-am install-strip install-sysconfDATA installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ - uninstall-pkgdataDATA uninstall-sysconfDATA - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/auth/auth-scram.c b/src/auth/auth-scram.c index 953c34138..334e28f33 100644 --- a/src/auth/auth-scram.c +++ b/src/auth/auth-scram.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2020 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -109,6 +109,7 @@ #include "utils/sha2.h" #include "auth/pool_passwd.h" #include "auth/scram.h" +#include "auth/pool_auth.h" #include "utils/base64.h" #include "utils/elog.h" #include "utils/palloc.h" @@ -211,8 +212,8 @@ static char *build_client_first_message(fe_scram_state *state); static char *build_client_final_message(fe_scram_state *state); static bool verify_server_signature(fe_scram_state *state); static void calculate_client_proof(fe_scram_state *state, - const char *client_final_message_without_proof, - uint8 *result); + const char *client_final_message_without_proof, + uint8 *result); static void read_client_first_message(scram_state *state, char *input); static void read_client_final_message(scram_state *state, char *input); @@ -221,9 +222,9 @@ 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); + 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 *GetMockAuthenticationNonce(void); @@ -502,6 +503,9 @@ scram_verify_plain_password(const char *username, const char *password, { ereport(LOG, (errmsg("invalid SCRAM verifier for user \"%s\"", username))); + + pfree(encoded_salt); + pfree(salt); return false; } @@ -514,6 +518,7 @@ scram_verify_plain_password(const char *username, const char *password, * user-supplied password. */ pfree(encoded_salt); + pfree(salt); return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0; } @@ -592,6 +597,8 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt, if (decoded_len != SCRAM_KEY_LEN) goto invalid_verifier; + pfree(v); + return true; invalid_verifier: @@ -1131,7 +1138,7 @@ build_server_final_message(scram_state *state) char *server_signature_base64; int siglen; scram_HMAC_ctx ctx; - char *res; + char *res; /* calculate ServerSignature */ scram_HMAC_init(&ctx, state->ServerKey, SCRAM_KEY_LEN); @@ -1171,7 +1178,7 @@ build_server_final_message(scram_state *state) /* - * Determinisitcally generate salt for mock authentication, using a SHA256 + * Deterministically generate salt for mock authentication, using a SHA256 * hash based on the username and a cluster-level secret key. Returns a * pointer to a static buffer of size SCRAM_DEFAULT_SALT_LEN. */ diff --git a/src/auth/md5.c b/src/auth/md5.c index 9e598765b..c35a0bffb 100644 --- a/src/auth/md5.c +++ b/src/auth/md5.c @@ -347,7 +347,7 @@ bytesToHex(char *b, int len, 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/auth/pool_auth.c b/src/auth/pool_auth.c index 1f108fb77..675838d47 100644 --- a/src/auth/pool_auth.c +++ b/src/auth/pool_auth.c @@ -3,7 +3,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -21,9 +21,13 @@ */ #include "pool.h" +#include #include "context/pool_session_context.h" +#include "protocol/pool_process_query.h" +#include "protocol/pool_proto_modules.h" #include "utils/pool_stream.h" #include "pool_config.h" +#include "auth/pool_auth.h" #include "auth/pool_hba.h" #include "auth/pool_passwd.h" #include "auth/scram.h" @@ -31,10 +35,7 @@ #include "utils/palloc.h" #include "utils/memutils.h" #include "auth/md5.h" - -#ifdef HAVE_CRYPT_H -#include -#endif +#include #ifdef HAVE_SYS_TYPES_H #include @@ -57,45 +58,42 @@ #define MAX_SASL_PAYLOAD_LEN 1024 -static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, int key, int protoMajor); -static int do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); -static void pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp); -static int do_crypt(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); -static int do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor, - char *storedPassword, PasswordType passwordType); -static int do_md5_single_backend(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); -static void send_md5auth_request(POOL_CONNECTION * frontend, int protoMajor, char *salt); -static int read_password_packet(POOL_CONNECTION * frontend, int protoMajor, char *password, int *pwdSize); -static int send_password_packet(POOL_CONNECTION * backend, int protoMajor, char *password); -static int send_auth_ok(POOL_CONNECTION * frontend, int protoMajor); -static void sendAuthRequest(POOL_CONNECTION * frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen); -static long PostmasterRandom(void); - -static int pg_SASL_continue(POOL_CONNECTION * backend, char *payload, int payloadlen, void *sasl_state, bool final); -static void *pg_SASL_init(POOL_CONNECTION * backend, char *payload, int payloadlen, char *username, char *storedPassword); -static bool do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, int message_length, - char *username, char *storedPassword, PasswordType passwordType); -static void authenticate_frontend_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); -static void authenticate_frontend_cert(POOL_CONNECTION * frontend); -static void authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth); -static void authenticate_frontend_clear_text(POOL_CONNECTION * frontend); -static bool get_auth_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, - char **password, PasswordType *passwordType); +static void pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, + char *key, int32 keylen, int protoMajor); +static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); +static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); +static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor, + char *storedPassword, PasswordType passwordType); +static void send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt); +static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize); +static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password); +static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor); +static void sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen); + +static int pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void *sasl_state, bool final); +static void *pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *username, char *storedPassword); +static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoMajor, int message_length, + char *username, char *storedPassword, PasswordType passwordType); +static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); +static void authenticate_frontend_cert(POOL_CONNECTION *frontend); +static void authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth); +static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend); +static bool get_auth_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, + char **password, PasswordType *passwordType); +static void ProcessNegotiateProtocol(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); /* * Do authentication. Assuming the only caller is * make_persistent_db_connection(). */ void -connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) +connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) { char kind; int length; int auth_kind; char state; - char *p; - int pid, - key; + int pid; bool keydata_done; /* @@ -187,9 +185,18 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) buf = palloc0(2 * (MD5_PASSWD_LEN + 4)); /* hash + "md5" + '\0' */ - /* build md5 password */ + /* set buffer address for building md5 password */ buf1 = buf + MD5_PASSWD_LEN + 4; - pool_md5_encrypt(password, cp->sp->user, strlen(cp->sp->user), buf1); + + /* + * If the supplied password is already in md5 hash format, we just + * copy it. Otherwise calculate the md5 hash value. + */ + if (!strncmp("md5", password, 3) && (strlen(password) - 3) == MD5_PASSWD_LEN) + memcpy(buf1, password + 3, MD5_PASSWD_LEN + 1); + else + pool_md5_encrypt(password, cp->sp->user, strlen(cp->sp->user), buf1); + pool_md5_encrypt(buf1, salt, 4, buf + 3); memcpy(buf, "md5", 3); @@ -236,6 +243,9 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) switch (kind) { + char *p; + int32 keylen; + case 'K': /* backend key data */ keydata_done = true; ereport(DEBUG1, @@ -243,12 +253,14 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) /* read message length */ pool_read_with_error(cp->con, &length, sizeof(length), "message length for authentication kind 'K'"); - if (ntohl(length) != 12) + length = ntohl(length); + keylen = length - sizeof(int32) - sizeof(int32); + if (keylen > MAX_CANCELKEY_LENGTH) { ereport(ERROR, (errmsg("failed to authenticate"), - errdetail("invalid backend key data length. received %d bytes when expecting 12 bytes" - ,ntohl(length)))); + errdetail("invalid backend key data length. received %d bytes exceeding %d", + ntohl(length), MAX_CANCELKEY_LENGTH))); } /* read pid */ @@ -256,9 +268,9 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) cp->pid = pid; /* read key */ - pool_read_with_error(cp->con, &key, sizeof(key), - "key for authentication kind 'K'"); - cp->key = key; + keylen = length - sizeof(int32) - sizeof(int32); + p = pool_read2(cp->con, keylen); + memcpy(cp->key, p, keylen); break; case 'Z': /* Ready for query */ @@ -320,21 +332,23 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) * 0. */ int -pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) +pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { signed char kind; int pid; - int key; int protoMajor; int length; int authkind; int i; int message_length = 0; StartupPacket *sp; + int32 keylen; /* cancel key length */ + char cancel_key[MAX_CANCELKEY_LENGTH]; + char *p; + protoMajor = MAIN_CONNECTION(cp)->sp->major; - protoMajor = MASTER_CONNECTION(cp)->sp->major; - +read_kind: kind = pool_read_kind(cp); if (kind < 0) ereport(ERROR, @@ -358,6 +372,12 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) errdetail("backend response with kind \'E\' when expecting \'R\'"), errhint("This issue can be caused by version mismatch (current version %d)", protoMajor))); } + else if (kind == 'v') + { + /* NegotiateProtocolVersion received */ + ProcessNegotiateProtocol(frontend, cp); + goto read_kind; + } else if (kind != 'R') ereport(ERROR, (errmsg("backend authentication failed"), @@ -421,7 +441,7 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) msglen = htonl(0); pool_write_and_flush(frontend, &msglen, sizeof(msglen)); - MASTER(cp)->auth_kind = AUTH_REQ_OK; + MAIN(cp)->auth_kind = AUTH_REQ_OK; } /* clear text password authentication? */ @@ -451,30 +471,6 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) } } - /* crypt authentication? */ - else if (authkind == AUTH_REQ_CRYPT) - { - for (i = 0; i < NUM_BACKENDS; i++) - { - if (!VALID_BACKEND(i)) - continue; - - ereport(DEBUG1, - (errmsg("authentication backend"), - errdetail("trying crypt authentication"))); - - authkind = do_crypt(CONNECTION(cp, i), frontend, 0, protoMajor); - - if (authkind < 0) - { - pool_send_auth_fail(frontend, cp); - ereport(ERROR, - (errmsg("failed to authenticate with backend"), - errdetail("do_crypt_text_password failed in slot %d", i))); - } - } - } - /* md5 authentication? */ else if (authkind == AUTH_REQ_MD5) { @@ -484,41 +480,37 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) /* * check if we can use md5 authentication. */ - if (NUM_BACKENDS > 1) + if (get_auth_password(MAIN(cp), frontend, 0, + &password, &passwordType) == false) { - if (get_auth_password(MASTER(cp), frontend, 0, - &password, &passwordType) == false) + /* + * We do not have any password, we can still get the password from + * client using plain text authentication if it is allowed by user + */ + if (frontend->pool_hba == NULL && pool_config->allow_clear_text_frontend_auth) { - /* - * We do not have any passeord, we can still get the password - * from client using plain text authentication if it is - * allowed by user - */ - if (frontend->pool_hba == NULL && pool_config->allow_clear_text_frontend_auth) + ereport(LOG, + (errmsg("using clear text authentication with frontend"), + errdetail("backend will still use md5 auth"), + errhint("you can disable this behavior by setting allow_clear_text_frontend_auth to off"))); + authenticate_frontend_clear_text(frontend); + /* now check again if we have a password now */ + if (get_auth_password(MAIN(cp), frontend, 0, + &password, &passwordType) == false) { - ereport(LOG, - (errmsg("using clear text authentication with frontend"), - errdetail("backend will still use md5 auth"), - errhint("you can disable this behavior by setting allow_clear_text_frontend_auth to off"))); - authenticate_frontend_clear_text(frontend); - /* now check again if we have a password now */ - if (get_auth_password(MASTER(cp), frontend, 0, - &password, &passwordType) == false) - { - ereport(ERROR, - (errmsg("failed to authenticate with backend using md5"), - errdetail("unable to get the password"))); - } + ereport(ERROR, + (errmsg("failed to authenticate with backend using md5"), + errdetail("unable to get the password"))); } } - /* we have a password to use, validate the password type */ - if (passwordType != PASSWORD_TYPE_PLAINTEXT && passwordType != PASSWORD_TYPE_MD5 - && passwordType != PASSWORD_TYPE_AES) - { - ereport(ERROR, - (errmsg("failed to authenticate with backend using md5"), - errdetail("valid password not found"))); - } + } + /* we have a password to use, validate the password type */ + if (passwordType != PASSWORD_TYPE_PLAINTEXT && passwordType != PASSWORD_TYPE_MD5 + && passwordType != PASSWORD_TYPE_AES) + { + ereport(ERROR, + (errmsg("failed to authenticate with backend using md5"), + errdetail("valid password not found"))); } for (i = 0; i < NUM_BACKENDS; i++) @@ -548,7 +540,7 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) char *password; PasswordType passwordType = PASSWORD_TYPE_UNKNOWN; - if (get_auth_password(MASTER(cp), frontend, 0, + if (get_auth_password(MAIN(cp), frontend, 0, &password, &passwordType) == false) { /* @@ -563,7 +555,7 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) errhint("you can disable this behavior by setting allow_clear_text_frontend_auth to off"))); authenticate_frontend_clear_text(frontend); /* now check again if we have a password now */ - if (get_auth_password(MASTER(cp), frontend, 0, + if (get_auth_password(MAIN(cp), frontend, 0, &password, &passwordType) == false) { ereport(ERROR, @@ -617,8 +609,11 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) } - send_auth_ok(frontend, protoMajor); - authkind = 0; + if (kind == 'R') + { + send_auth_ok(frontend, protoMajor); + authkind = 0; + } } else @@ -663,7 +658,7 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) break; case 'N': - if (pool_extract_error_message(false, MASTER(cp), protoMajor, true, &message) == 1) + if (pool_extract_error_message(false, MAIN(cp), protoMajor, true, &message) == 1) { ereport(NOTICE, (errmsg("notice from backend"), @@ -681,7 +676,7 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) /* process error message */ case 'E': - if (pool_extract_error_message(false, MASTER(cp), protoMajor, true, &message) == 1) + if (pool_extract_error_message(false, MAIN(cp), protoMajor, true, &message) == 1) { ereport(LOG, (errmsg("backend throws an error message"), @@ -731,22 +726,28 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) } /* - * message length (V3 only) + * Read BackendKeyData message length. */ if (protoMajor == PROTO_MAJOR_V3) { - if ((length = pool_read_message_length(cp)) != 12) + length = pool_read_message_length(cp); + keylen = length - sizeof(int32) - sizeof(int32); + if (keylen > MAX_CANCELKEY_LENGTH) { ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid messages length(%d) for BackendKeyData", length))); + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("cancel key length exceeds 256 bytes"))); } } + else + keylen = 4; + + elog(DEBUG1, "cancel key length: %d", keylen); /* * OK, read pid and secret key */ - sp = MASTER_CONNECTION(cp)->sp; + sp = MAIN_CONNECTION(cp)->sp; pid = -1; for (i = 0; i < NUM_BACKENDS; i++) @@ -767,16 +768,29 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) CONNECTION_SLOT(cp, i)->pid = cp->info[i].pid = pid; /* read key */ - if (pool_read(CONNECTION(cp, i), &key, sizeof(key)) < 0) + p = pool_read2(CONNECTION(cp, i), keylen); + if (p == NULL) { ereport(ERROR, (errmsg("authentication failed"), - errdetail("failed to read key in slot %d", i))); + errdetail("failed to read key of length: %d in slot %d", keylen, i))); } - CONNECTION_SLOT(cp, i)->key = cp->info[i].key = key; + memcpy(CONNECTION_SLOT(cp, i)->key, p, keylen); + memcpy(cp->info[i].key, p, keylen); + memcpy(cancel_key, p, keylen); + CONNECTION_SLOT(cp, i)->keylen = cp->info[i].keylen = keylen; cp->info[i].major = sp->major; - cp->info[i].minor = sp->minor; + + /* + * If NegotiateProtocol message has been received, set the minor + * version. Othewise use the version in the StartupMessage. + */ + if (CONNECTION_SLOT(cp, i)->nplen > 0) + cp->info[i].minor = CONNECTION_SLOT(cp, i)->negotiated_minor; + else + cp->info[i].minor = sp->minor; + strlcpy(cp->info[i].database, sp->database, sizeof(cp->info[i].database)); strlcpy(cp->info[i].user, sp->user, sizeof(cp->info[i].user)); cp->info[i].counter = 1; @@ -791,30 +805,48 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) (errmsg("authentication failed"), errdetail("pool_do_auth: all backends are down"))); } - if (pool_send_backend_key_data(frontend, pid, key, protoMajor)) - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("failed to send backend data to frontend"))); + + /* + * We send the BackendKeyData to frontend, which belongs to the last + * backend in the backend group. + */ + pool_send_backend_key_data(frontend, pid, cancel_key, + MAIN_CONNECTION(cp)->keylen, protoMajor); return 0; } /* -* do re-authentication for reused connection. if success return 0 otherwise throws ereport. +* do re-authentication for reused connection. if success return 0 otherwise +* throws ereport. */ int -pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) +pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { int protoMajor; int msglen; + POOL_CONNECTION_POOL_SLOT *sp; protoMajor = MAJOR(cp); + /* + * If NegotiateProtocolMsg has been received from backend, forward it to + * frontend. If the frontend dislike it, it will disconnect the + * connection. Otherwise it will silently continue. + */ + sp = CONNECTION_SLOT(cp, MAIN_NODE_ID); + if (protoMajor == PROTO_MAJOR_V3 && sp->nplen > 0) + { + elog(DEBUG1, "negotiateProtocol message is forwarded to frontend at reauth"); + pool_write_and_flush(frontend, sp->negotiateProtocolMsg, + sp->nplen); + } + /* * if hba is enabled we would already have passed authentication */ if (!frontend->frontend_authenticated) { - switch (MASTER(cp)->auth_kind) + switch (MAIN(cp)->auth_kind) { case AUTH_REQ_OK: /* trust */ @@ -822,29 +854,29 @@ pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) case AUTH_REQ_PASSWORD: /* clear text password */ - do_clear_text_password(MASTER(cp), frontend, 1, protoMajor); - break; - - case AUTH_REQ_CRYPT: - /* crypt password */ - do_crypt(MASTER(cp), frontend, 1, protoMajor); + do_clear_text_password(MAIN(cp), frontend, 1, protoMajor); break; case AUTH_REQ_MD5: /* md5 password */ - authenticate_frontend_md5(MASTER(cp), frontend, 1, protoMajor); + authenticate_frontend_md5(MAIN(cp), frontend, 1, protoMajor); break; + case AUTH_REQ_SASL: /* SCRAM */ - authenticate_frontend_SCRAM(MASTER(cp), frontend, 1); + authenticate_frontend_SCRAM(MAIN(cp), frontend, 1); break; + default: ereport(ERROR, (errmsg("authentication failed"), - errdetail("unknown authentication request code %d", MASTER(cp)->auth_kind))); + errdetail("unknown authentication request code %d", MAIN(cp)->auth_kind))); } } + /* + * Send auth ok + */ pool_write(frontend, "R", 1); if (protoMajor == PROTO_MAJOR_V3) @@ -855,7 +887,11 @@ pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) msglen = htonl(0); pool_write_and_flush(frontend, &msglen, sizeof(msglen)); - pool_send_backend_key_data(frontend, MASTER_CONNECTION(cp)->pid, MASTER_CONNECTION(cp)->key, protoMajor); + + /* send BackendKeyData */ + pool_send_backend_key_data(frontend, MAIN_CONNECTION(cp)->pid, MAIN_CONNECTION(cp)->key, + MAIN_CONNECTION(cp)->keylen, protoMajor); + return 0; } @@ -863,7 +899,7 @@ pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) * send authentication failure message text to frontend */ static void -pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) +pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { int messagelen; char *errmessage; @@ -873,11 +909,11 @@ pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) protoMajor = MAJOR(cp); - messagelen = strlen(MASTER_CONNECTION(cp)->sp->user) + 100; + messagelen = strlen(MAIN_CONNECTION(cp)->sp->user) + 100; errmessage = (char *) palloc(messagelen + 1); snprintf(errmessage, messagelen, "password authentication failed for user \"%s\"", - MASTER_CONNECTION(cp)->sp->user); + MAIN_CONNECTION(cp)->sp->user); if (send_error_to_frontend) pool_send_fatal_message(frontend, protoMajor, "XX000", errmessage, "", "", __FILE__, __LINE__); @@ -885,33 +921,31 @@ pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) } /* - * Send backend key data to frontend. if success return 0 otherwise non 0. + * Send backend key data to frontend. */ -static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, int key, int protoMajor) +static void +pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, + char *key, int32 keylen, int protoMajor) { char kind; - int len; + int32 len; /* Send backend key data */ kind = 'K'; pool_write(frontend, &kind, 1); if (protoMajor == PROTO_MAJOR_V3) { - len = htonl(12); + len = htonl(sizeof(int32) + sizeof(int32) + keylen); pool_write(frontend, &len, sizeof(len)); } ereport(DEBUG1, - (errmsg("sending backend key data"), - errdetail("send pid %d to frontend", ntohl(pid)))); - + (errmsg("sending backend key data"))); pool_write(frontend, &pid, sizeof(pid)); - pool_write_and_flush(frontend, &key, sizeof(key)); - - return 0; + pool_write_and_flush(frontend, key, keylen); } static void -authenticate_frontend_clear_text(POOL_CONNECTION * frontend) +authenticate_frontend_clear_text(POOL_CONNECTION *frontend) { static int size; char password[MAX_PASSWORD_SIZE]; @@ -985,7 +1019,7 @@ authenticate_frontend_clear_text(POOL_CONNECTION * frontend) (errmsg("clear text authentication failed"), errdetail("password does not match"))); } - ereport(LOG, + ereport(DEBUG1, (errmsg("clear text authentication successful with frontend"))); if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_AES) @@ -998,24 +1032,62 @@ authenticate_frontend_clear_text(POOL_CONNECTION * frontend) * perform clear text password authentication */ static int -do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) +do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) { static int size; char *pwd = NULL; int kind; PasswordType passwordType = PASSWORD_TYPE_UNKNOWN; + bool rtn; if (reauth && frontend->frontend_authenticated) { /* frontend and backend are both authenticated already */ return 0; } - if (get_auth_password(backend, frontend, reauth, &pwd, &passwordType) == false) + + rtn = get_auth_password(backend, frontend, reauth, &pwd, &passwordType); + + /* + * If pool_hba.conf == "password", we should already have frontend + * password. When reauth, we want the password, rather than + * backend->password, which is returned by get_auth_password() if + * pool_passwd does not have an entry for the user. + */ + if (reauth && rtn && frontend->passwordMapping == NULL && + frontend->pwd_size > 0 && + frontend->passwordType == PASSWORD_TYPE_PLAINTEXT) { - ereport(FATAL, - (return_code(2), - errmsg("clear text password authentication failed"), - errdetail("unable to get the password for user: \"%s\"", frontend->username))); + pwd = frontend->password; + passwordType = frontend->passwordType; + } + + else if (!rtn || frontend->pwd_size == 0) + { + /* + * We do not have any password, we can still get the password from + * client using plain text authentication if it is allowed by user + */ + + if (frontend->pool_hba == NULL || + frontend->pool_hba->auth_method == uaPassword || + pool_config->allow_clear_text_frontend_auth) + { + ereport(DEBUG1, + (errmsg("using clear text authentication with frontend"), + errdetail("backend is using password authentication"))); + + authenticate_frontend_clear_text(frontend); + + /* now check again if we have a password now */ + if (get_auth_password(backend, frontend, 0, &pwd, &passwordType) == false) + { + ereport(FATAL, + (return_code(2), + errmsg("clear text password authentication failed"), + errdetail("unable to get the password for user: \"%s\"", frontend->username))); + } + } } if (passwordType == PASSWORD_TYPE_AES) @@ -1042,7 +1114,7 @@ do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, in return 0; } - size = pwd ? strlen(pwd) : 0; + size = strlen(pwd); /* connection reusing? */ if (reauth) @@ -1050,7 +1122,7 @@ do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, in if (size != backend->pwd_size) ereport(ERROR, (errmsg("clear text password authentication failed"), - errdetail("password size does not match"))); + errdetail("password does not match"))); if (memcmp(pwd, backend->password, backend->pwd_size) != 0) ereport(ERROR, @@ -1063,9 +1135,9 @@ do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, in kind = send_password_packet(backend, protoMajor, pwd); /* if authenticated, save info */ - if (!reauth && kind == AUTH_REQ_OK) + if (kind == AUTH_REQ_OK) { - if (IS_MASTER_NODE_ID(backend->db_node_id)) + if (IS_MAIN_NODE_ID(backend->db_node_id)) { send_auth_ok(frontend, protoMajor); } @@ -1078,163 +1150,12 @@ do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, in return kind; } -/* - * perform crypt authentication - */ -static int -do_crypt(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) -{ - char salt[2]; - static int size; - static char password[MAX_PASSWORD_SIZE]; - char response; - int kind; - int len; - - if (!reauth) - { - /* read salt */ - pool_read(backend, salt, sizeof(salt)); - } - else - { - memcpy(salt, backend->salt, sizeof(salt)); - } - - /* master? */ - if (IS_MASTER_NODE_ID(backend->db_node_id)) - { - pool_write(frontend, "R", 1); /* authentication */ - if (protoMajor == PROTO_MAJOR_V3) - { - len = htonl(10); - pool_write(frontend, &len, sizeof(len)); - } - kind = htonl(4); /* crypt authentication */ - pool_write(frontend, &kind, sizeof(kind)); /* indicating crypt - * authentication */ - pool_write_and_flush(frontend, salt, sizeof(salt)); /* salt */ - - /* read password packet */ - if (protoMajor == PROTO_MAJOR_V2) - { - pool_read(frontend, &size, sizeof(size)); - } - else - { - char k; - - pool_read(frontend, &k, sizeof(k)); - if (k != 'p') - { - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("invalid password packet. Packet does not starts with \"p\""))); - } - pool_read(frontend, &size, sizeof(size)); - } - - if ((ntohl(size) - 4) > sizeof(password)) - { - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("password is too long, password size is %d", ntohl(size) - 4))); - } - - pool_read(frontend, password, ntohl(size) - 4); - } - - /* connection reusing? */ - if (reauth) - { - ereport(DEBUG1, - (errmsg("performing crypt authentication"), - errdetail("size: %d saved_size: %d", (ntohl(size) - 4), backend->pwd_size))); - - if ((ntohl(size) - 4) != backend->pwd_size) - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("password size does not match"))); - - - if (memcmp(password, backend->password, backend->pwd_size) != 0) - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("password does not match"))); - - return 0; - } - - /* send password packet to backend */ - if (protoMajor == PROTO_MAJOR_V3) - pool_write(backend, "p", 1); - pool_write(backend, &size, sizeof(size)); - pool_write_and_flush(backend, password, ntohl(size) - 4); - pool_read(backend, &response, sizeof(response)); - - if (response != 'R') - { - if (response == 'E') /* Backend has thrown an error instead */ - { - char *message = NULL; - - if (pool_extract_error_message(false, backend, protoMajor, false, &message) == 1) - { - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("%s", message ? message : "backend throws authentication error"))); - } - if (message) - pfree(message); - } - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("invalid packet from backend. backend does not return R while processing clear text password authentication"))); - } - - if (protoMajor == PROTO_MAJOR_V3) - { - pool_read(backend, &len, sizeof(len)); - - if (ntohl(len) != 8) - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("invalid packet from backend. incorrect authentication packet size (%d)", ntohl(len)))); - } - - /* expect to read "Authentication OK" response. kind should be 0... */ - pool_read(backend, &kind, sizeof(kind)); - - /* if authenticated, save info */ - if (!reauth && kind == 0) - { - int msglen; - - pool_write(frontend, "R", 1); - - if (protoMajor == PROTO_MAJOR_V3) - { - msglen = htonl(8); - pool_write(frontend, &msglen, sizeof(msglen)); - } - - msglen = htonl(0); - pool_write_and_flush(frontend, &msglen, sizeof(msglen)); - - backend->auth_kind = 4; - backend->pwd_size = ntohl(size) - 4; - memcpy(backend->password, password, backend->pwd_size); - memcpy(backend->salt, salt, sizeof(salt)); - } - return kind; -} - /* * Do the SCRAM authentication with the frontend using the stored * password in the pool_passwd file. */ static void -authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth) +authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth) { void *scram_opaq; char *output = NULL; @@ -1249,7 +1170,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * fronten PasswordType storedPasswordType = PASSWORD_TYPE_UNKNOWN; char *storedPassword = NULL; - if (get_auth_password(backend, frontend, reauth,&storedPassword, &storedPasswordType) == false) + if (get_auth_password(backend, frontend, reauth, &storedPassword, &storedPasswordType) == false) { ereport(FATAL, (return_code(2), @@ -1283,7 +1204,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * fronten if (!shadow_pass) ereport(ERROR, (errmsg("authentication failed"), - errdetail("faild to build the scram verifier"))); + errdetail("failed to build the scram verifier"))); /* * SASL auth is not supported for protocol versions before 3, because it @@ -1414,8 +1335,11 @@ authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * fronten frontend->frontend_authenticated = true; } +/* + * Authenticate frontend using pool_hba.conf + */ void -authenticate_frontend(POOL_CONNECTION * frontend) +authenticate_frontend(POOL_CONNECTION *frontend) { switch (frontend->pool_hba->auth_method) { @@ -1443,13 +1367,17 @@ authenticate_frontend(POOL_CONNECTION * frontend) case uaPAM: break; #endif /* USE_PAM */ +#ifdef USE_LDAP + case uaLDAP: + break; +#endif /* USE_LDAP */ } } #ifdef USE_SSL static void -authenticate_frontend_cert(POOL_CONNECTION * frontend) +authenticate_frontend_cert(POOL_CONNECTION *frontend) { if (frontend->client_cert_loaded == true && frontend->cert_cn) { @@ -1476,7 +1404,7 @@ authenticate_frontend_cert(POOL_CONNECTION * frontend) } #else static void -authenticate_frontend_cert(POOL_CONNECTION * frontend) +authenticate_frontend_cert(POOL_CONNECTION *frontend) { ereport(ERROR, (errmsg("CERT authentication failed"), @@ -1485,7 +1413,7 @@ authenticate_frontend_cert(POOL_CONNECTION * frontend) #endif static void -authenticate_frontend_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) +authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) { char salt[4]; static int size; @@ -1497,14 +1425,7 @@ authenticate_frontend_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, PasswordType storedPasswordType = PASSWORD_TYPE_UNKNOWN; char *storedPassword = NULL; - if (RAW_MODE || NUM_BACKENDS == 1) - { - if (backend) - do_md5_single_backend(backend, frontend, reauth, protoMajor); - return; /* This will be handled later */ - } - - if (get_auth_password(backend, frontend, reauth,&storedPassword, &storedPasswordType) == false) + if (get_auth_password(backend, frontend, reauth, &storedPassword, &storedPasswordType) == false) { ereport(FATAL, (return_code(2), @@ -1566,88 +1487,21 @@ authenticate_frontend_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, (errmsg("md5 authentication failed"), errdetail("password does not match"))); } - ereport(LOG, + ereport(DEBUG1, (errmsg("md5 authentication successful with frontend"))); frontend->frontend_authenticated = true; } /* - * perform MD5 authentication + * Get user's password from various sources. Firstly try pool_passwd and + * return it if the user's password is there. If reauth == 0 (first time the + * user connect to pgpool) and the password is in frontend, return it. If + * reauth != 0 (reuse connection pool) and the password is in backendm return + * it. */ -static int -do_md5_single_backend(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) -{ - char salt[4]; - static int size; - static char password[MAX_PASSWORD_SIZE]; - int kind; - - if (!reauth) - { - /* read salt from backend */ - pool_read(backend, salt, sizeof(salt)); - ereport(DEBUG1, - (errmsg("performing md5 authentication"), - errdetail("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id, - salt[0], salt[1], salt[2], salt[3]))); - } - else - { - /* Use the saved salt */ - memcpy(salt, backend->salt, sizeof(salt)); - } - - /* Send md5 auth request to frontend */ - send_md5auth_request(frontend, protoMajor, salt); - - /* Read password packet */ - read_password_packet(frontend, protoMajor, password, &size); - - /* connection reusing? compare it with saved password */ - if (reauth) - { - if (backend->passwordType != PASSWORD_TYPE_MD5) - ereport(ERROR, - (errmsg("md5 authentication failed"), - errdetail("invalid password type"))); - - if (size != backend->pwd_size) - ereport(ERROR, - (errmsg("md5 authentication failed"), - errdetail("password does not match"))); - - if (memcmp(password, backend->password, backend->pwd_size) != 0) - ereport(ERROR, - (errmsg("md5 authentication failed"), - errdetail("password does not match"))); - return 0; - } - else - { - /* Send password packet to backend and receive auth response */ - kind = send_password_packet(backend, protoMajor, password); - if (kind < 0) - ereport(ERROR, - (errmsg("md5 authentication failed"), - errdetail("backend replied with invalid kind"))); - - /* If authenticated, reply back to frontend and save info */ - if (kind == AUTH_REQ_OK) - { - send_auth_ok(frontend, protoMajor); - backend->passwordType = PASSWORD_TYPE_MD5; - backend->auth_kind = AUTH_REQ_MD5; - backend->pwd_size = size; - memcpy(backend->password, password, backend->pwd_size); - memcpy(backend->salt, salt, sizeof(salt)); - } - } - return kind; -} - static bool -get_auth_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, +get_auth_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, char **password, PasswordType *passwordType) { /* First preference is to use the pool_passwd file */ @@ -1660,7 +1514,8 @@ get_auth_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int rea * check if we have password stored in the frontend connection. that * could come by using the clear text auth */ - if (frontend->pwd_size > 0 && frontend->passwordType == PASSWORD_TYPE_PLAINTEXT) + if (!reauth && + frontend->pwd_size > 0 && frontend->passwordType == PASSWORD_TYPE_PLAINTEXT) { *password = frontend->password; *passwordType = frontend->passwordType; @@ -1695,7 +1550,7 @@ get_auth_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int rea * perform MD5 authentication */ static int -do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor, +do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor, char *storedPassword, PasswordType passwordType) { char salt[4]; @@ -1705,9 +1560,6 @@ do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int pr char encbuf[POOL_PASSWD_LEN + 1]; char *pool_passwd = NULL; - if (NUM_BACKENDS == 1) - return do_md5_single_backend(backend, frontend, reauth, protoMajor); - if (passwordType == PASSWORD_TYPE_AES) { /* @@ -1741,16 +1593,16 @@ do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int pr errdetail("unable to get the password"))); } - /* master? */ - if (IS_MASTER_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false) + /* main? */ + if (IS_MAIN_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false) { /* * If frontend is not authenticated and do it it first. but if we have * already received the password from frontend using the clear text * auth, we may not need to authenticate it */ - if (pool_config->allow_clear_text_frontend_auth && - frontend->auth_kind == AUTH_REQ_PASSWORD && + if ((pool_config->allow_clear_text_frontend_auth || + frontend->auth_kind == AUTH_REQ_PASSWORD) && frontend->pwd_size > 0 && frontend->passwordType == PASSWORD_TYPE_PLAINTEXT) { @@ -1795,7 +1647,7 @@ do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int pr if (!reauth && kind == 0) { - if (IS_MASTER_NODE_ID(backend->db_node_id)) + if (IS_MAIN_NODE_ID(backend->db_node_id)) { /* Send auth ok to frontend */ send_auth_ok(frontend, protoMajor); @@ -1815,7 +1667,7 @@ do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int pr * Send an authentication request packet to the frontend. */ static void -sendAuthRequest(POOL_CONNECTION * frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen) +sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen) { int kind = htonl(auth_req_type); @@ -1838,7 +1690,7 @@ sendAuthRequest(POOL_CONNECTION * frontend, int protoMajor, int32 auth_req_type, * Send md5 authentication request packet to frontend */ static void -send_md5auth_request(POOL_CONNECTION * frontend, int protoMajor, char *salt) +send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt) { sendAuthRequest(frontend, protoMajor, AUTH_REQ_MD5, salt, 4); } @@ -1848,7 +1700,7 @@ send_md5auth_request(POOL_CONNECTION * frontend, int protoMajor, char *salt) * Read password packet from frontend */ static int -read_password_packet(POOL_CONNECTION * frontend, int protoMajor, char *password, int *pwdSize) +read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize) { int size; @@ -1901,7 +1753,7 @@ read_password_packet(POOL_CONNECTION * frontend, int protoMajor, char *password, * "password" must be null-terminated. */ static int -send_password_packet(POOL_CONNECTION * backend, int protoMajor, char *password) +send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) { int size; int len; @@ -1957,7 +1809,7 @@ send_password_packet(POOL_CONNECTION * backend, int protoMajor, char *password) * Send auth ok to frontend */ static int -send_auth_ok(POOL_CONNECTION * frontend, int protoMajor) +send_auth_ok(POOL_CONNECTION *frontend, int protoMajor) { int msglen; @@ -1975,218 +1827,15 @@ send_auth_ok(POOL_CONNECTION * frontend, int protoMajor) } /* - * read message length (V3 only) + * Generate random bytes */ -int -pool_read_message_length(POOL_CONNECTION_POOL * cp) -{ - int length, - length0; - int i; - - /* read message from master node */ - pool_read(CONNECTION(cp, MASTER_NODE_ID), &length0, sizeof(length0)); - length0 = ntohl(length0); - - ereport(DEBUG5, - (errmsg("reading message length"), - errdetail("slot: %d length: %d", MASTER_NODE_ID, length0))); - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i)) - { - continue; - } - - pool_read(CONNECTION(cp, i), &length, sizeof(length)); - - length = ntohl(length); - ereport(DEBUG5, - (errmsg("reading message length"), - errdetail("slot: %d length: %d", i, length))); - - if (length != length0) - ereport(ERROR, - (errmsg("unable to read message length"), - errdetail("message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0))); - - } - - if (length0 < 0) - ereport(ERROR, - (errmsg("unable to read message length"), - errdetail("invalid message length (%d)", length))); - - return length0; -} - -/* - * read message length2 (V3 only) - * unlike pool_read_message_length, this returns an array of message length. - * The array is in the static storage, thus it will be destroyed by subsequent calls. - */ -int * -pool_read_message_length2(POOL_CONNECTION_POOL * cp) -{ - int length, - length0; - int i; - static int length_array[MAX_CONNECTION_SLOTS]; - - /* read message from master node */ - pool_read(CONNECTION(cp, MASTER_NODE_ID), &length0, sizeof(length0)); - - length0 = ntohl(length0); - length_array[MASTER_NODE_ID] = length0; - ereport(DEBUG5, - (errmsg("reading message length"), - errdetail("master slot: %d length: %d", MASTER_NODE_ID, length0))); - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) - { - pool_read(CONNECTION(cp, i), &length, sizeof(length)); - - length = ntohl(length); - ereport(DEBUG5, - (errmsg("reading message length"), - errdetail("master slot: %d length: %d", i, length))); - - if (length != length0) - { - ereport(LOG, - (errmsg("reading message length"), - errdetail("message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0))); - } - - if (length < 0) - { - ereport(ERROR, - (errmsg("unable to read message length"), - errdetail("invalid message length (%d)", length))); - } - - length_array[i] = length; - } - - } - return &length_array[0]; -} - -signed char -pool_read_kind(POOL_CONNECTION_POOL * cp) -{ - char kind0, - kind; - int i; - - kind = -1; - kind0 = 0; - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (!VALID_BACKEND(i)) - { - continue; - } - - pool_read(CONNECTION(cp, i), &kind, sizeof(kind)); - - if (IS_MASTER_NODE_ID(i)) - { - kind0 = kind; - } - else - { - if (kind != kind0) - { - char *message; - - if (kind0 == 'E') - { - if (pool_extract_error_message(false, MASTER(cp), MAJOR(cp), true, &message) == 1) - { - ereport(LOG, - (errmsg("pool_read_kind: error message from master backend:%s", message))); - pfree(message); - } - } - else if (kind == 'E') - { - if (pool_extract_error_message(false, CONNECTION(cp, i), MAJOR(cp), true, &message) == 1) - { - ereport(LOG, - (errmsg("pool_read_kind: error message from %d th backend:%s", i, message))); - pfree(message); - } - } - ereport(ERROR, - (errmsg("unable to read message kind"), - errdetail("kind does not match between master(%x) slot[%d] (%x)", kind0, i, kind))); - } - } - } - - return kind; -} - -int -pool_read_int(POOL_CONNECTION_POOL * cp) -{ - int data0, - data; - int i; - - data = -1; - data0 = 0; - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (!VALID_BACKEND(i)) - { - continue; - } - pool_read(CONNECTION(cp, i), &data, sizeof(data)); - if (IS_MASTER_NODE_ID(i)) - { - data0 = data; - } - else - { - if (data != data0) - { - ereport(ERROR, - (errmsg("unable to read int value"), - errdetail("data does not match between between master(%x) slot[%d] (%x)", data0, i, data))); - - } - } - } - return data; -} - void pool_random(void *buf, size_t len) { - int ret = 0; -#ifdef USE_SSL - ret = RAND_bytes(buf, len); -#endif - /* if RND_bytes fails or not present use the old technique */ - if (ret == 0) - { - int i; - char *ptr = buf; - - for (i = 0; i < len; i++) - { - long rand = PostmasterRandom(); - - ptr[i] = (rand % 255) + 1; - } - } + if (!pg_strong_random(buf, len)) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("could not generate random bytes"))); } /* @@ -2198,47 +1847,8 @@ pool_random_salt(char *md5Salt) pool_random(md5Salt, 4); } -/* - * PostmasterRandom - */ -static long -PostmasterRandom(void) -{ - extern struct timeval random_start_time; - static unsigned int random_seed = 0; - - /* - * Select a random seed at the time of first receiving a request. - */ - if (random_seed == 0) - { - do - { - struct timeval random_stop_time; - - gettimeofday(&random_stop_time, NULL); - - /* - * We are not sure how much precision is in tv_usec, so we swap - * the high and low 16 bits of 'random_stop_time' and XOR them - * with 'random_start_time'. On the off chance that the result is - * 0, we loop until it isn't. - */ - random_seed = random_start_time.tv_usec ^ - ((random_stop_time.tv_usec << 16) | - ((random_stop_time.tv_usec >> 16) & 0xffff)); - } - while (random_seed == 0); - - srandom(random_seed); - } - - return random(); -} - - static bool -do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, int message_length, +do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoMajor, int message_length, char *username, char *storedPassword, PasswordType passwordType) { /* read the packet first */ @@ -2260,16 +1870,16 @@ do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, errdetail("password not found"))); } - /* master? */ - if (frontend && IS_MASTER_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false) + /* main? */ + if (frontend && IS_MAIN_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false) { /* * If frontend is not authenticated and do it it first. but if we have * already received the password from frontend using the clear text * auth, we may not need to authenticate it */ - if (pool_config->allow_clear_text_frontend_auth && - frontend->auth_kind == AUTH_REQ_PASSWORD && + if ((pool_config->allow_clear_text_frontend_auth || + frontend->auth_kind == AUTH_REQ_PASSWORD) && frontend->pwd_size > 0 && frontend->passwordType == PASSWORD_TYPE_PLAINTEXT) { @@ -2317,6 +1927,8 @@ do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, * The request contains the name (as assigned by IANA) of the * authentication mechanism. */ + if (sasl_state) + pg_fe_scram_free(sasl_state); sasl_state = pg_SASL_init(backend, payload, payload_len, username, storedPassword); if (!sasl_state) { @@ -2346,7 +1958,7 @@ do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, ereport(ERROR, (errmsg("invalid authentication request from server: unknown auth kind %d", auth_kind))); } - /* Read next packend */ + /* Read next backend */ pool_read(backend, &kind, sizeof(kind)); pool_read(backend, &len, sizeof(len)); if (kind != 'R') @@ -2354,7 +1966,7 @@ do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, (errmsg("backend authentication failed"), errdetail("backend response with kind \'%c\' when expecting \'R\'", kind))); message_length = ntohl(len); - if (len <= 8) + if (message_length < 8) ereport(ERROR, (errmsg("backend authentication failed"), errdetail("backend response with no data "))); @@ -2367,7 +1979,7 @@ do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, } static void * -pg_SASL_init(POOL_CONNECTION * backend, char *payload, int payloadlen, char *username, char *storedPassword) +pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *username, char *storedPassword) { char *initialresponse = NULL; int initialresponselen; @@ -2470,7 +2082,7 @@ pg_SASL_init(POOL_CONNECTION * backend, char *payload, int payloadlen, char *use * the protocol. */ static int -pg_SASL_continue(POOL_CONNECTION * backend, char *payload, int payloadlen, void *sasl_state, bool final) +pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void *sasl_state, bool final) { char *output; int outputlen; @@ -2520,3 +2132,93 @@ pg_SASL_continue(POOL_CONNECTION * backend, char *payload, int payloadlen, void return 0; } + +/* + * Forward NegotiateProtocol message to frontend. + * + * When this function is called, message kind has been already read. + */ +static void +ProcessNegotiateProtocol(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) +{ + int32 len; + int32 savelen; + int32 protoMajor; + int32 protoMinor; + int32 protov; + bool forwardMsg = false; + int i; + char *savep; + + elog(DEBUG1, "Forwarding NegotiateProtocol message to frontend"); + pool_write(frontend, "v", 1); /* forward message kind */ + savelen = len = pool_read_int(cp); /* message length including self */ + pool_write(frontend, &len, 4); /* forward message length */ + len = ntohl(len) - 4; /* length of rest of the message */ + protov = pool_read_int(cp); /* read protocol version */ + protoMajor = PG_PROTOCOL_MAJOR(ntohl(protov)); /* protocol major version */ + protoMinor = PG_PROTOCOL_MINOR(ntohl(protov)); /* protocol minor version */ + pool_write(frontend, &protov, 4); /* forward protocol version */ + elog(DEBUG1, "protocol verion offered: major: %d minor: %d", protoMajor, protoMinor); + len -= 4; + for (i = 0; i < NUM_BACKENDS; i++) + { + if (VALID_BACKEND(i)) + { + POOL_CONNECTION_POOL_SLOT *sp; + char *p; + char *np; + Size nplen; + + p = pool_read2(CONNECTION(cp, i), len); + if (!forwardMsg) + { + int32 num_unsupported; + StringInfoData buf; + + pool_write_and_flush(frontend, p, len); /* forward rest of + * message */ + forwardMsg = true; + savep = p; + + /* debug out unsuported messages */ + memcpy(&num_unsupported, p, sizeof(int32)); + num_unsupported = ntohl(num_unsupported); + p += sizeof(int32); + if (num_unsupported > 0) + { + initStringInfo(&buf); + for (int i = 0; i < num_unsupported; i++) + { + appendStringInfoString(&buf, p); + appendStringInfoChar(&buf, ' '); + p += strlen(p) + 1; + } + elog(DEBUG1, "unsupported options: %s", buf.data); + pfree(buf.data); + } + } + /* save negatiate protocol version */ + sp = CONNECTION_SLOT(cp, i); + sp->negotiated_major = protoMajor; + sp->negotiated_minor = protoMinor; + + /* save negatiate protocol message */ + nplen = 1 + /* message kind */ + sizeof(savelen) + /* message length */ + sizeof(protov) + /* protocol version */ + len; /* rest of message */ + /* allocate message area */ + sp->negotiateProtocolMsg = MemoryContextAlloc(TopMemoryContext, nplen); + np = sp->negotiateProtocolMsg; + sp->nplen = nplen; /* set message length */ + + *np++ = 'v'; + memcpy(np, &savelen, sizeof(savelen)); + np += sizeof(savelen); + memcpy(np, &protov, sizeof(protov)); + np += sizeof(protov); + memcpy(np, savep, len); + } + } +} diff --git a/src/auth/pool_hba.c b/src/auth/pool_hba.c index 06b372782..8daf74a97 100644 --- a/src/auth/pool_hba.c +++ b/src/auth/pool_hba.c @@ -30,11 +30,18 @@ #include #include +#ifdef __FreeBSD__ +#include +#endif + #include "pool.h" #include "auth/pool_hba.h" +#include "auth/pool_auth.h" +#include "protocol/pool_connection_pool.h" #include "utils/pool_path.h" #include "utils/pool_ip.h" #include "utils/pool_stream.h" +#include "utils/pool_signal.h" #include "pool_config.h" #include "pool_type.h" #include "utils/palloc.h" @@ -42,6 +49,12 @@ #include "utils/elog.h" #include "parser/pg_list.h" #include "auth/pool_passwd.h" +#include "protocol/pool_process_query.h" + +#ifdef USE_LDAP +#define LDAP_DEPRECATED 1 +#include +#endif #define MULTI_VALUE_SEP "\001" /* delimiter for multi-valued column strings */ @@ -96,38 +109,37 @@ static HbaToken *copy_hba_token(HbaToken *in); static HbaToken *make_hba_token(const char *token, bool quoted); static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, - int elevel, char **err_msg); + int elevel, char **err_msg); static MemoryContext tokenize_file(const char *filename, FILE *file, - List **tok_lines, int elevel); -static void sendAuthRequest(POOL_CONNECTION * frontend, AuthRequest areq); -static void auth_failed(POOL_CONNECTION * frontend); -static void close_all_backend_connections(void); -static bool hba_getauthmethod(POOL_CONNECTION * frontend); -static bool check_hba(POOL_CONNECTION * frontend); + List **tok_lines, int elevel); +static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq); +static void auth_failed(POOL_CONNECTION *frontend); +static bool hba_getauthmethod(POOL_CONNECTION *frontend); +static bool check_hba(POOL_CONNECTION *frontend); static bool check_user(char *user, List *tokens); static bool check_db(const char *dbname, const char *user, List *tokens); static List *tokenize_inc_file(List *tokens, - const char *outer_filename, - const char *inc_filename, - int elevel, - char **err_msg); + const char *outer_filename, + const char *inc_filename, + int elevel, + char **err_msg); static bool - check_hostname(POOL_CONNECTION * frontend, const char *hostname); + check_hostname(POOL_CONNECTION *frontend, const char *hostname); static bool check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask); static bool check_same_host_or_net(SockAddr *raddr, IPCompareMethod method); static void check_network_callback(struct sockaddr *addr, struct sockaddr *netmask, - void *cb_data); + void *cb_data); static HbaLine *parse_hba_line(TokenizedLine *tok_line, int elevel); static bool pg_isblank(const char c); static bool next_token(char **lineptr, char *buf, int bufsz, - bool *initial_quote, bool *terminating_comma, - int elevel, char **err_msg); + bool *initial_quote, bool *terminating_comma, + int elevel, char **err_msg); static List *next_field_expand(const char *filename, char **lineptr, - int elevel, char **err_msg); + int elevel, char **err_msg); #ifdef NOT_USED static POOL_STATUS CheckUserExist(char *username); #endif @@ -142,27 +154,43 @@ static POOL_STATUS CheckUserExist(char *username); #define PGPOOL_PAM_SERVICE "pgpool" /* Service name passed to PAM */ -static POOL_STATUS CheckPAMAuth(POOL_CONNECTION * frontend, char *user, char *password); +static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password); static int pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); -/* - * recv_password_packet is usually used with authentications that require a client - * password. However, pgpool's hba function only uses it for PAM authentication, - * so declare a prototype here in "#ifdef USE_PAM" to avoid compilation warning. - */ -static char *recv_password_packet(POOL_CONNECTION * frontend); - -static struct pam_conv pam_passw_conv = { +static struct pam_conv pam_passwd_conv = { &pam_passwd_conv_proc, NULL }; static char *pam_passwd = NULL; /* Workaround for Solaris 2.6 brokenness */ -static POOL_CONNECTION * pam_frontend_kludge; /* Workaround for passing +static POOL_CONNECTION *pam_frontend_kludge; /* Workaround for passing * POOL_CONNECTION *frontend * into pam_passwd_conv_proc */ #endif /* USE_PAM */ +#ifdef USE_LDAP +#define LDAP_DEPRECATED 1 +#include + +static POOL_STATUS CheckLDAPAuth(POOL_CONNECTION *frontend); + +/* LDAP_OPT_DIAGNOSTIC_MESSAGE is the newer spelling */ +#ifndef LDAP_OPT_DIAGNOSTIC_MESSAGE +#define LDAP_OPT_DIAGNOSTIC_MESSAGE LDAP_OPT_ERROR_STRING +#endif + +#endif /* USE_LDAP */ + + +#if defined(USE_PAM) || defined(USE_LDAP) +/* + * recv_password_packet is usually used with authentications that require a client + * password. However, pgpool's hba function uses it for PAM or LDAP authentication, + * so declare a prototype here in "#if defined(USE_PAM or USE_LDAP)" to avoid + * compilation warning. + */ +static char *recv_password_packet(POOL_CONNECTION *frontend); +#endif /* USE_PAM or USE_LDAP */ /* * Read the config file and create a List of HbaLine records for the contents. @@ -268,6 +296,56 @@ load_hba(char *hbapath) return true; } +/* + * Macros used to check and report on invalid configuration options. + * On error: log a message at level elevel, set *err_msg, and exit the function. + * These macros are not as general-purpose as they look, because they know + * what the calling function's error-exit value is. + * + * INVALID_AUTH_OPTION = reports when an option is specified for a method where it's + * not supported. + * REQUIRE_AUTH_OPTION = same as INVALID_AUTH_OPTION, except it also checks if the + * method is actually the one specified. Used as a shortcut when + * the option is only valid for one authentication method. + * MANDATORY_AUTH_ARG = check if a required option is set for an authentication method, + * reporting error if it's not. + */ +#define INVALID_AUTH_OPTION(optname, validmethods) \ +do { \ + ereport(elevel, \ + (errcode(ERRCODE_CONFIG_FILE_ERROR), \ + /* translator: the second %s is a list of auth methods */ \ + errmsg("authentication option \"%s\" is only valid for authentication methods %s", \ + optname, _(validmethods)), \ + errcontext("line %d of configuration file \"%s\"", \ + line_num, HbaFileName))); \ + *err_msg = psprintf("authentication option \"%s\" is only valid for authentication methods %s", \ + optname, validmethods); \ + return false; \ +} while (0) + +#define REQUIRE_AUTH_OPTION(methodval, optname, validmethods) \ +do { \ + if (hbaline->auth_method != methodval) \ + INVALID_AUTH_OPTION(optname, validmethods); \ +} while (0) + +#define MANDATORY_AUTH_ARG(argvar, argname, authname) \ +do { \ + if (argvar == NULL) { \ + ereport(elevel, \ + (errcode(ERRCODE_CONFIG_FILE_ERROR), \ + errmsg("authentication method \"%s\" requires argument \"%s\" to be set", \ + authname, argname), \ + errcontext("line %d of configuration file \"%s\"", \ + line_num, HbaFileName))); \ + *err_msg = psprintf("authentication method \"%s\" requires argument \"%s\" to be set", \ + authname, argname); \ + return NULL; \ + } \ +} while (0) + + static HbaLine * parse_hba_line(TokenizedLine *tok_line, int elevel) { @@ -360,7 +438,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, @@ -380,7 +458,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } /* Get the users. */ - field = lnext(field); + field = lnext(tok_line->fields, field); if (!field) { ereport(elevel, @@ -402,7 +480,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, @@ -525,7 +603,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, @@ -586,7 +664,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, @@ -626,6 +704,10 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) #ifdef USE_PAM else if (strcmp(token->string, "pam") == 0) parsedline->auth_method = uaPAM; +#endif +#ifdef USE_LDAP + else if (strcmp(token->string, "ldap") == 0) + parsedline->auth_method = uaLDAP; #endif else { @@ -640,7 +722,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) return NULL; } /* Parse remaining arguments */ - while ((field = lnext(field)) != NULL) + while ((field = lnext(tok_line->fields, field)) != NULL) { tokens = lfirst(field); foreach(tokencell, tokens) @@ -678,6 +760,72 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } } +#ifdef USE_LDAP + + /* + * Check if the selected authentication method has any mandatory arguments + * that are not set. + */ + 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 + * ldapprefix and ldapsuffix, or using a search+bind, using + * ldapbasedn, ldapbinddn, ldapbindpasswd and one of + * ldapsearchattribute or ldapsearchfilter. Disallow mixing these + * parameters. + */ + if (parsedline->ldapprefix || parsedline->ldapsuffix) + { + if (parsedline->ldapbasedn || + parsedline->ldapbinddn || + parsedline->ldapbindpasswd || + parsedline->ldapsearchattribute || + parsedline->ldapsearchfilter) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + 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"; + return NULL; + } + } + else if (!parsedline->ldapbasedn) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set"), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set"; + return NULL; + } + + /* + * When using search+bind, you can either use a simple attribute + * (defaulting to "uid") or a fully custom search filter. You can't + * do both. + */ + if (parsedline->ldapsearchattribute && parsedline->ldapsearchfilter) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("cannot use ldapsearchattribute together with ldapsearchfilter"), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "cannot use ldapsearchattribute together with ldapsearchfilter"; + return NULL; + } + } +#endif + return parsedline; } @@ -693,6 +841,10 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, { int line_num = hbaline->linenumber; +#ifdef USE_LDAP + hbaline->ldapscope = LDAP_SCOPE_SUBTREE; +#endif + if (strcmp(name, "pamservice") == 0) { #ifdef USE_PAM @@ -744,6 +896,258 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, *err_msg = "pamservice authentication option cannot be used because PAM is not supported by this build"; #endif + } + else if (strcmp(name, "ldapurl") == 0) + { +#ifdef USE_LDAP +#ifdef LDAP_API_FEATURE_X_OPENLDAP + LDAPURLDesc *urldata; + int rc; +#endif + REQUIRE_AUTH_OPTION(uaLDAP, "ldapurl", "ldap"); + +#ifdef LDAP_API_FEATURE_X_OPENLDAP + rc = ldap_url_parse(val, &urldata); + if (rc != LDAP_SUCCESS) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("could not parse LDAP URL \"%s\": %s", val, ldap_err2string(rc)))); + *err_msg = psprintf("could not parse LDAP URL \"%s\": %s", + val, ldap_err2string(rc)); + return false; + } + + if (strcmp(urldata->lud_scheme, "ldap") != 0 && + strcmp(urldata->lud_scheme, "ldaps") != 0) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("unsupported LDAP URL scheme: %s", urldata->lud_scheme))); + *err_msg = psprintf("unsupported LDAP URL scheme: %s", + urldata->lud_scheme); + ldap_free_urldesc(urldata); + return false; + } + + if (urldata->lud_scheme) + hbaline->ldapscheme = pstrdup(urldata->lud_scheme); + if (urldata->lud_host) + hbaline->ldapserver = pstrdup(urldata->lud_host); + hbaline->ldapport = urldata->lud_port; + if (urldata->lud_dn) + hbaline->ldapbasedn = pstrdup(urldata->lud_dn); + + if (urldata->lud_attrs) + hbaline->ldapsearchattribute = pstrdup(urldata->lud_attrs[0]); /* only use first one */ + hbaline->ldapscope = urldata->lud_scope; + if (urldata->lud_filter) + hbaline->ldapsearchfilter = pstrdup(urldata->lud_filter); + ldap_free_urldesc(urldata); +#else /* not OpenLDAP */ + ereport(elevel, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("LDAP URLs not supported on this platform"))); + *err_msg = "LDAP URLs not supported on this platform"; +#endif /* not OpenLDAP */ +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldaptls") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldaptls", "ldap"); + if (strcmp(val, "1") == 0) + hbaline->ldaptls = true; + else + hbaline->ldaptls = false; +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapscheme") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapscheme", "ldap"); + if (strcmp(val, "ldap") != 0 && strcmp(val, "ldaps") != 0) + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("invalid ldapscheme value: \"%s\"", val), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + hbaline->ldapscheme = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapserver") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapserver", "ldap"); + hbaline->ldapserver = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapport") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapport", "ldap"); + hbaline->ldapport = atoi(val); + if (hbaline->ldapport == 0) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("invalid LDAP port number: \"%s\"", val), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = psprintf("invalid LDAP port number: \"%s\"", val); + return false; + } +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapbinddn") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapbinddn", "ldap"); + hbaline->ldapbinddn = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapbindpasswd") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapbindpasswd", "ldap"); + hbaline->ldapbindpasswd = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapsearchattribute") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapsearchattribute", "ldap"); + hbaline->ldapsearchattribute = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapsearchfilter") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapsearchfilter", "ldap"); + hbaline->ldapsearchfilter = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapbasedn") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapbasedn", "ldap"); + hbaline->ldapbasedn = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapprefix") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapprefix", "ldap"); + hbaline->ldapprefix = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "ldapsuffix") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap"); + hbaline->ldapsuffix = pstrdup(val); +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ + } + else if (strcmp(name, "backend_use_passwd") == 0) + { +#ifdef USE_LDAP + REQUIRE_AUTH_OPTION(uaLDAP, "backend_use_passwd", "ldap"); + if (strcmp(val, "1") == 0) + hbaline->backend_use_passwd = true; + else + hbaline->backend_use_passwd = false; +#else /* USE_LDAP */ + ereport(elevel, + (errmsg("ldap authentication option can only be configured for authentication method \"ldap\""), + errhint("Compile with --with-ldap to use LDAP authentication."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "ldap authentication option cannot be used because LDAP is not supported by this build"; +#endif /* USE_LDAP */ } else { @@ -763,7 +1167,7 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, * do frontend <-> pgpool authentication based on pool_hba.conf */ void -ClientAuthentication(POOL_CONNECTION * frontend) +ClientAuthentication(POOL_CONNECTION *frontend) { POOL_STATUS status = POOL_END; MemoryContext oldContext; @@ -779,10 +1183,9 @@ ClientAuthentication(POOL_CONNECTION * frontend) /* * Get the password for the user if it is stored in the pool_password - * file - * authentication process is called in the temporary memory - * context, but password mappings has to live till the life time - * of frontend connection, so call the pool_get_user_credentials in + * file authentication process is called in the temporary memory + * context, but password mappings has to live till the life time of + * frontend connection, so call the pool_get_user_credentials in * ProcessLoopContext memory context */ oldContext = MemoryContextSwitchTo(ProcessLoopContext); @@ -812,7 +1215,7 @@ ClientAuthentication(POOL_CONNECTION * frontend) #ifdef USE_SSL ereport(FATAL, - (return_code(2), + (return_code(2), errmsg("client authentication failed"), errdetail("no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s", hostinfo, frontend->username, frontend->database, @@ -890,6 +1293,12 @@ ClientAuthentication(POOL_CONNECTION * frontend) break; #endif /* USE_PAM */ +#ifdef USE_LDAP + case uaLDAP: + status = CheckLDAPAuth(frontend); + break; +#endif /* USE_LDAP */ + case uaTrust: status = POOL_CONTINUE; break; @@ -905,6 +1314,7 @@ ClientAuthentication(POOL_CONNECTION * frontend) if (status == POOL_CONTINUE) { sendAuthRequest(frontend, AUTH_REQ_OK); + /* do authentication against frontend */ authenticate_frontend(frontend); } else @@ -913,7 +1323,7 @@ ClientAuthentication(POOL_CONNECTION * frontend) static void -sendAuthRequest(POOL_CONNECTION * frontend, AuthRequest areq) +sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq) { int wsize; /* number of bytes to write */ int areq_nbo; /* areq in network byte order */ @@ -953,7 +1363,7 @@ sendAuthRequest(POOL_CONNECTION * frontend, AuthRequest areq) } -#ifdef USE_PAM /* see the prototype comment */ +#if defined(USE_PAM) || defined(USE_LDAP) /* * Collect password response packet from frontend. @@ -961,7 +1371,7 @@ sendAuthRequest(POOL_CONNECTION * frontend, AuthRequest areq) * Returns NULL if couldn't get password, else palloc'd string. */ static char * -recv_password_packet(POOL_CONNECTION * frontend) +recv_password_packet(POOL_CONNECTION *frontend) { int rsize; char *passwd; @@ -1005,13 +1415,13 @@ recv_password_packet(POOL_CONNECTION * frontend) return returnVal; } -#endif /* USE_PAM */ +#endif /* USE_PAM or USE_LDAP */ /* * Tell the user the authentication failed. */ static void -auth_failed(POOL_CONNECTION * frontend) +auth_failed(POOL_CONNECTION *frontend) { int messagelen; char *errmessage; @@ -1077,7 +1487,14 @@ auth_failed(POOL_CONNECTION * frontend) "PAM authentication with pgpool failed for user \"%s\"", frontend->username); break; -#endif /* USE_PAM */ +#endif /* USE_LDAP */ +#ifdef USE_LDAP + case uaLDAP: + snprintf(errmessage, messagelen, + "LDAP authentication with pgpool failed for user \"%s\"", + frontend->username); + break; +#endif /* USE_LDAP */ default: snprintf(errmessage, messagelen, "authentication with pgpool failed for user \"%s\": invalid authentication method", @@ -1094,34 +1511,6 @@ auth_failed(POOL_CONNECTION * frontend) } -/* - * Close all of the cached backend connections. - * - * This is exactly the same as send_frontend_exits() in child.c. - */ -static void -close_all_backend_connections(void) -{ - int i; - POOL_CONNECTION_POOL *p = pool_connection_pool; - - pool_sigset_t oldmask; - - POOL_SETMASK2(&BlockSig, &oldmask); - - for (i = 0; i < pool_config->max_pool; i++, p++) - { - if (!MASTER_CONNECTION(p)) - continue; - if (MASTER_CONNECTION(p)->sp->user == NULL) - continue; - pool_send_frontend_exits(p); - } - - POOL_SETMASK(&oldmask); -} - - /* * Determine what authentication method should be used when accessing database * "database" from frontend "raddr", user "user". Return the method and @@ -1132,7 +1521,7 @@ close_all_backend_connections(void) * we return true and method = uaReject. */ static bool -hba_getauthmethod(POOL_CONNECTION * frontend) +hba_getauthmethod(POOL_CONNECTION *frontend) { if (check_hba(frontend)) return true; @@ -1146,7 +1535,7 @@ hba_getauthmethod(POOL_CONNECTION * frontend) * request. */ static bool -check_hba(POOL_CONNECTION * frontend) +check_hba(POOL_CONNECTION *frontend) { ListCell *line; HbaLine *hba; @@ -1283,7 +1672,7 @@ hostname_match(const char *pattern, const char *actual_hostname) * Check to see if a connecting IP matches a given host name. */ static bool -check_hostname(POOL_CONNECTION * frontend, const char *hostname) +check_hostname(POOL_CONNECTION *frontend, const char *hostname) { struct addrinfo *gai_result, *gai; @@ -1958,7 +2347,7 @@ pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, } /* - * PAM will free this memory in * pam_end() Do not use Palloc and freinds + * PAM will free this memory in * pam_end() Do not use Palloc and friends * to allocate this memory, Since the PAM library will be freeing this * memory who knowns nothing about our MemoryManager */ @@ -1974,7 +2363,8 @@ pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, /* * Check authentication against PAM. */ -static POOL_STATUS CheckPAMAuth(POOL_CONNECTION * frontend, char *user, char *password) +static POOL_STATUS +CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password) { int retval; pam_handle_t *pamh = NULL; @@ -1990,16 +2380,16 @@ static POOL_STATUS CheckPAMAuth(POOL_CONNECTION * frontend, char *user, char *pa * 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_passwd_conv.appdata_ptr = (char *) password; /* from password above, + * not allocated */ /* Optionally, one can set the service name in pool_hba.conf */ if (frontend->pool_hba->pamservice && frontend->pool_hba->pamservice[0] != '\0') retval = pam_start(frontend->pool_hba->pamservice, "pgpool@", - &pam_passw_conv, &pamh); + &pam_passwd_conv, &pamh); else retval = pam_start(PGPOOL_PAM_SERVICE, "pgpool@", - &pam_passw_conv, &pamh); + &pam_passwd_conv, &pamh); if (retval != PAM_SUCCESS) { @@ -2020,7 +2410,7 @@ static POOL_STATUS CheckPAMAuth(POOL_CONNECTION * frontend, char *user, char *pa errdetail("pam_set_item(PAM_USER) failed: %s", pam_strerror(pamh, retval)))); } - retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv); + retval = pam_set_item(pamh, PAM_CONV, &pam_passwd_conv); if (retval != PAM_SUCCESS) { pam_passwd = NULL; /* Unset pam_passwd */ @@ -2065,8 +2455,480 @@ static POOL_STATUS CheckPAMAuth(POOL_CONNECTION * frontend, char *user, char *pa #endif /* USE_PAM */ +#ifdef USE_LDAP + +/* + * Add a detail error message text to the current error if one can be + * constructed from the LDAP 'diagnostic message'. + */ +static int +errdetail_for_ldap(LDAP *ldap) +{ + char *message; + int rc; + + rc = ldap_get_option(ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, &message); + if (rc == LDAP_SUCCESS && message != NULL) + { + errdetail("LDAP diagnostics: %s", message); + ldap_memfree(message); + } + + return 0; +} + + +static int +InitializeLDAPConnection(POOL_CONNECTION *frontend, LDAP **ldap) +{ + const char *scheme; + int ldapversion = LDAP_VERSION3; + int r; + + scheme = frontend->pool_hba->ldapscheme; + if (scheme == NULL) + scheme = "ldap"; +#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. + */ + { + StringInfoData uris; + char *hostlist = NULL; + char *p; + bool append_port; + + /* 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 (!frontend->pool_hba->ldapserver || frontend->pool_hba->ldapserver[0] == '\0') + { + char *domain; + + /* ou=blah,dc=foo,dc=bar -> foo.bar */ + if (ldap_dn2domain(frontend->pool_hba->ldapbasedn, &domain)) + { + ereport(LOG, + (errmsg("could not extract domain name from ldapbasedn"))); + return -1; + } + + /* 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 -1; + } + 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 = frontend->pool_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", frontend->pool_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, + (errmsg("could not initialize LDAP: %s", + ldap_err2string(r)))); + + return -1; + } + } +#else + if (strcmp(scheme, "ldaps") == 0) + { + ereport(LOG, + (errmsg("ldaps not supported with this LDAP library"))); + + return -1; + } + *ldap = ldap_init(frontend->pool_hba->ldapserver, frontend->pool_hba->ldapport); + if (!*ldap) + { + ereport(LOG, + (errmsg("could not initialize LDAP: %m"))); + + return -1; + } +#endif + + if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("could not set LDAP protocol version: %s", + ldap_err2string(r)), + errdetail_for_ldap(*ldap))); + ldap_unbind(*ldap); + return -1; + } + + if (frontend->pool_hba->ldaptls) + { + if ((r = ldap_start_tls_s(*ldap, NULL, NULL)) != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("could not start LDAP TLS session: %s", + ldap_err2string(r)), + errdetail_for_ldap(*ldap))); + ldap_unbind(*ldap); + return -1; + } + } + + return 0; +} + +/* Placeholders recognized by FormatSearchFilter. For now just one. */ +#define LPH_USERNAME "$username" +#define LPH_USERNAME_LEN (sizeof(LPH_USERNAME) - 1) + +/* Not all LDAP implementations define this. */ +#ifndef LDAP_NO_ATTRS +#define LDAP_NO_ATTRS "1.1" +#endif + +/* Not all LDAP implementations define this. */ +#ifndef LDAPS_PORT +#define LDAPS_PORT 636 +#endif + +/* + * Return a newly allocated C string copied from "pattern" with all + * occurrences of the placeholder "$username" replaced with "user_name". + */ +static char * +FormatSearchFilter(const char *pattern, const char *user_name) +{ + StringInfoData output; + + initStringInfo(&output); + while (*pattern != '\0') + { + if (strncmp(pattern, LPH_USERNAME, LPH_USERNAME_LEN) == 0) + { + appendStringInfoString(&output, user_name); + pattern += LPH_USERNAME_LEN; + } + else + appendStringInfoChar(&output, *pattern++); + } + + return output.data; +} + + + +/* + * Check authentication against LDAP. + */ +static POOL_STATUS +CheckLDAPAuth(POOL_CONNECTION *frontend) +{ + char *passwd; + 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 ((!frontend->pool_hba->ldapserver || frontend->pool_hba->ldapserver[0] == '\0') && + (!frontend->pool_hba->ldapbasedn || frontend->pool_hba->ldapbasedn[0] == '\0')) + { + ereport(LOG, + (errmsg("LDAP server not specified, and no ldapbasedn"))); + return -1; + } +#else + if (!frontend->pool_hba->ldapserver || frontend->pool_hba->ldapserver[0] == '\0') + { + ereport(LOG, + (errmsg("LDAP server not specified"))); + return -1; + } +#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 = frontend->pool_hba->ldapserver ? frontend->pool_hba->ldapserver : ""; + + if (frontend->pool_hba->ldapport == 0) + { + if (frontend->pool_hba->ldapscheme != NULL && + strcmp(frontend->pool_hba->ldapscheme, "ldaps") == 0) + frontend->pool_hba->ldapport = LDAPS_PORT; + else + frontend->pool_hba->ldapport = LDAP_PORT; + } + + sendAuthRequest(frontend, AUTH_REQ_PASSWORD); + + passwd = recv_password_packet(frontend); + if (passwd == NULL) + return -2; /* client wouldn't send password */ + + if (InitializeLDAPConnection(frontend, &ldap) == -1) + { + /* Error message already sent */ + pfree(passwd); + return -1; + } + + if (frontend->pool_hba->backend_use_passwd) + { + frontend->pwd_size = strlen(passwd); + memcpy(frontend->password, passwd, frontend->pwd_size); + frontend->passwordType = PASSWORD_TYPE_PLAINTEXT; + } + + if (frontend->pool_hba->ldapbasedn) + { + /* + * First perform an LDAP search to find the DN for the user we are + * trying to log in as. + */ + char *filter; + LDAPMessage *search_message; + LDAPMessage *entry; + char *attributes[] = {LDAP_NO_ATTRS, NULL}; + char *dn; + char *c; + int count; + + /* + * Disallow any characters that we would otherwise need to escape, + * since they aren't really reasonable in a username anyway. Allowing + * them would make it possible to inject any kind of custom filters in + * the LDAP filter. + */ + for (c = frontend->username; *c; c++) + { + if (*c == '*' || + *c == '(' || + *c == ')' || + *c == '\\' || + *c == '/') + { + ereport(LOG, + (errmsg("invalid character in user name for LDAP authentication"))); + ldap_unbind(ldap); + pfree(passwd); + return -1; + } + } + + /* + * Bind with a pre-defined username/password (if available) for + * searching. If none is specified, this turns into an anonymous bind. + */ + r = ldap_simple_bind_s(ldap, + frontend->pool_hba->ldapbinddn ? frontend->pool_hba->ldapbinddn : "", + frontend->pool_hba->ldapbindpasswd ? frontend->pool_hba->ldapbindpasswd : ""); + if (r != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s", + frontend->pool_hba->ldapbinddn ? frontend->pool_hba->ldapbinddn : "", + server_name, + ldap_err2string(r)), + errdetail_for_ldap(ldap))); + ldap_unbind(ldap); + pfree(passwd); + return -1; + } + + /* Build a custom filter or a single attribute filter? */ + if (frontend->pool_hba->ldapsearchfilter) + filter = FormatSearchFilter(frontend->pool_hba->ldapsearchfilter, frontend->username); + else if (frontend->pool_hba->ldapsearchattribute) + filter = psprintf("(%s=%s)", frontend->pool_hba->ldapsearchattribute, frontend->username); + else + filter = psprintf("(uid=%s)", frontend->username); + + r = ldap_search_s(ldap, + frontend->pool_hba->ldapbasedn, + frontend->pool_hba->ldapscope, + filter, + attributes, + 0, + &search_message); + + if (r != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("could not search LDAP for filter \"%s\" on server \"%s\": %s", + filter, server_name, ldap_err2string(r)), + errdetail_for_ldap(ldap))); + ldap_unbind(ldap); + pfree(passwd); + pfree(filter); + return -1; + } + + count = ldap_count_entries(ldap, search_message); + if (count != 1) + { + if (count == 0) + ereport(LOG, + (errmsg("LDAP user \"%s\" does not exist", frontend->username), + errdetail("LDAP search for filter \"%s\" on server \"%s\" returned no entries.", + filter, server_name))); + else + ereport(LOG, + (errmsg("LDAP user \"%s\" is not unique", frontend->username), + 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, server_name, count))); + + ldap_unbind(ldap); + pfree(passwd); + pfree(filter); + ldap_msgfree(search_message); + return -1; + } + + entry = ldap_first_entry(ldap, search_message); + dn = ldap_get_dn(ldap, entry); + if (dn == NULL) + { + int error; + + (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, server_name, + ldap_err2string(error)), + errdetail_for_ldap(ldap))); + ldap_unbind(ldap); + pfree(passwd); + pfree(filter); + ldap_msgfree(search_message); + return -1; + } + fulluser = pstrdup(dn); + + pfree(filter); + ldap_memfree(dn); + ldap_msgfree(search_message); + + /* Unbind and disconnect from the LDAP server */ + r = ldap_unbind_s(ldap); + if (r != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("could not unbind after searching for user \"%s\" on server \"%s\"", + fulluser, server_name))); + pfree(passwd); + pfree(fulluser); + return -1; + } + + /* + * Need to re-initialize the LDAP connection, so that we can bind to + * it with a different username. + */ + if (InitializeLDAPConnection(frontend, &ldap) == -1) + { + pfree(passwd); + pfree(fulluser); + + /* Error message already sent */ + return -1; + } + } + else + fulluser = psprintf("%s%s%s", + frontend->pool_hba->ldapprefix ? frontend->pool_hba->ldapprefix : "", + frontend->username, + frontend->pool_hba->ldapsuffix ? frontend->pool_hba->ldapsuffix : ""); + + r = ldap_simple_bind_s(ldap, fulluser, passwd); + + if (r != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("LDAP login failed for user \"%s\" on server \"%s\": %s", + fulluser, server_name, ldap_err2string(r)), + errdetail_for_ldap(ldap))); + ldap_unbind(ldap); + pfree(passwd); + pfree(fulluser); + return -1; + } + + ldap_unbind(ldap); + pfree(passwd); + pfree(fulluser); + + return 0; +} + + +#endif /* USE_LDAP */ + #ifdef NOT_USED -static POOL_STATUS CheckUserExist(char *username) +static POOL_STATUS +CheckUserExist(char *username) { char *passwd; diff --git a/src/auth/pool_passwd.c b/src/auth/pool_passwd.c index c84136bb4..91b0efd00 100644 --- a/src/auth/pool_passwd.c +++ b/src/auth/pool_passwd.c @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2020 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -56,6 +56,13 @@ pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) if (passwd_fd) return; + if (pool_passwd_filename == NULL) + { + saved_passwd_filename[0] = '\0'; /* indicate pool_passwd is + * disabled */ + return; + } + pool_passwd_mode = mode; if (saved_passwd_filename[0] == '\0') @@ -83,7 +90,7 @@ pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) } ereport(ERROR, (errmsg("initializing pool password, failed to open file:\"%s\"", pool_passwd_filename), - errdetail("file open failed with error:\"%s\"", strerror(errno)))); + errdetail("file open failed with error:\"%m\""))); } } @@ -96,10 +103,10 @@ pool_create_passwdent(char *username, char *passwd) { #define LINE_LEN \ MAX_USER_NAME_LEN + 1 + MAX_POOL_PASSWD_LEN + 2 - char linebuf[LINE_LEN]; - char *writebuf = NULL; - int len; - bool updated = false; + char linebuf[LINE_LEN]; + char *writebuf = NULL; + int len; + bool updated = false; if (!passwd_fd) ereport(ERROR, @@ -118,8 +125,8 @@ pool_create_passwdent(char *username, char *passwd) while (!feof(passwd_fd) && !ferror(passwd_fd)) { - char *t = linebuf; - int len; + char *t = linebuf; + int len; if (fgets(linebuf, sizeof(linebuf), passwd_fd) == NULL) break; @@ -156,7 +163,7 @@ pool_create_passwdent(char *username, char *passwd) strcat(writebuf, linebuf); } - if(!writebuf) + if (!writebuf) return 0; fclose(passwd_fd); @@ -194,8 +201,13 @@ pool_get_passwd(char *username) (errmsg("unable to get password, username is NULL"))); if (!passwd_fd) - ereport(ERROR, - (errmsg("unable to get password, password file descriptor is NULL"))); + { + if (strlen(saved_passwd_filename)) + ereport(ERROR, + (errmsg("unable to get password, password file descriptor is NULL"))); + else + return NULL; + } rewind(passwd_fd); name[0] = '\0'; @@ -329,7 +341,7 @@ userMatchesString(char *buf, char *user) } /* - * user:passwod[:user:password] + * user:password[:user:password] */ PasswordMapping * pool_get_user_credentials(char *username) @@ -340,13 +352,14 @@ pool_get_user_credentials(char *username) if (!username) ereport(ERROR, (errmsg("unable to get password, username is NULL"))); - if (!passwd_fd) { - ereport(WARNING, - (errmsg("unable to get password, password file descriptor is NULL"))); + if (strlen(saved_passwd_filename)) + ereport(WARNING, + (errmsg("unable to get password, password file descriptor is NULL"))); return NULL; } + rewind(passwd_fd); while (!feof(passwd_fd) && !ferror(passwd_fd)) @@ -388,13 +401,15 @@ pool_get_user_credentials(char *username) char *pwd; t = getNextToken(t, &pwd); - if (tok) + if (pwd) { pwdMapping->backendUser.password = pwd; pwdMapping->backendUser.userName = tok; pwdMapping->backendUser.passwordType = get_password_type(pwdMapping->backendUser.password); pwdMapping->mappedUser = true; } + else + pfree(tok); } break; } @@ -402,7 +417,7 @@ pool_get_user_credentials(char *username) } void -delete_passwordMapping(PasswordMapping * pwdMapping) +delete_passwordMapping(PasswordMapping *pwdMapping) { if (!pwdMapping) return; @@ -449,10 +464,10 @@ pool_reopen_passwd_file(void) } /* - * function first uses the password in the argument, if the - * argument is empty string or NULL, it looks for the password - * for uset in pool_passwd file. - * The returned password is always in plain text and palloc'd (if not null) + * function first uses the password in the argument, if the argument is empty + * string or NULL, it looks for the password for user in pool_passwd file. + * The returned password is always in plain text or md5 hashed and palloc'd + * (if not null) */ char * get_pgpool_config_user_password(char *username, char *password_in_config) @@ -462,8 +477,8 @@ get_pgpool_config_user_password(char *username, char *password_in_config) PasswordMapping *password_mapping = NULL; /* - * if the password specified in confg is empty strin or NULL look for the - * password in pool_passwd file + * if the password specified in config is empty string or NULL look for + * the password in pool_passwd file */ if (password_in_config == NULL || strlen(password_in_config) == 0) { @@ -511,14 +526,16 @@ get_pgpool_config_user_password(char *username, char *password_in_config) /* convert the TEXT prefixed password to plain text password */ passwordType = PASSWORD_TYPE_PLAINTEXT; if (password) - password = (char*)(password + strlen(PASSWORD_TEXT_PREFIX)); + password = (char *) (password + strlen(PASSWORD_TEXT_PREFIX)); } - if (password && strlen(password) && passwordType != PASSWORD_TYPE_PLAINTEXT) + if (password && strlen(password) && (passwordType != PASSWORD_TYPE_PLAINTEXT && + passwordType != PASSWORD_TYPE_MD5)) { /* - * Could not find plain text password in pool_passwd corresponding to the user. - * This is normal. Just use empty password in pgpool.conf. + * Could not find either plain text or md5 hashed password in + * pool_passwd corresponding to the user. This is normal. Just use + * empty password in pgpool.conf. */ ereport(DEBUG5, (errmsg("could not get the password for user:%s", username), @@ -617,14 +634,28 @@ read_pool_key(char *key_file_path) if (strlen(key_file_path) == 0) return NULL; + /* + * To prevent file-swapping due to file race conditions, we open the key + * file before checking it by stat(). + */ /* If password file cannot be opened, ignore it. */ - if (stat(key_file_path, &stat_buf) != 0) + if ((fp = fopen(key_file_path, "r")) == NULL) return NULL; + if (fstat(fileno(fp), &stat_buf) != 0) + { + ereport(WARNING, + (errmsg("failed to stat pool key file"), + errdetail("fstat failed with reason: \"%m\""))); + fclose(fp); + return NULL; + } + if (!S_ISREG(stat_buf.st_mode)) { ereport(WARNING, (errmsg("pool key file \"%s\" is not a plain file\n", key_file_path))); + fclose(fp); return NULL; } @@ -632,16 +663,13 @@ read_pool_key(char *key_file_path) if (stat_buf.st_mode & (S_IRWXG | S_IRWXO)) { ereport(WARNING, - (errmsg("pool key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n", + (errmsg("pool key file \"%s\" has group or world access; permissions should be u=rw (0600) or less", key_file_path))); /* do we want to allow unsecure pool key file ? */ + /* fclose(fp); */ /* return NULL; */ } - fp = fopen(key_file_path, "r"); - if (fp == NULL) - return NULL; - while (!feof(fp) && !ferror(fp)) { int len; @@ -665,3 +693,46 @@ read_pool_key(char *key_file_path) #undef LINELEN } + +/* + * Check password type is md5 hashed or not. recovery_password and + * wd_lifecheck_password are not allowed to be md5 hashed format. + * The kind of returns of this function is follow; + * 0: password is not md5 hashed + * -1: password is md5 hashed + * -2: password is not found + */ +int +check_password_type_is_not_md5(char *username, char *password_in_config) +{ + PasswordType passwordType = PASSWORD_TYPE_UNKNOWN; + + /* + * if the password specified in config is empty string or NULL look for + * the password in pool_passwd file + */ + if (password_in_config == NULL || strlen(password_in_config) == 0) + { + PasswordMapping *password_mapping = NULL; + + password_mapping = pool_get_user_credentials(username); + if (password_mapping == NULL) + { + return -2; + } + passwordType = password_mapping->pgpoolUser.passwordType; + delete_passwordMapping(password_mapping); + } + else + { + passwordType = get_password_type(password_in_config); + } + + /* if the password type is MD5 hash return -1 */ + if (passwordType == PASSWORD_TYPE_MD5) + { + return -1; + } + + return 0; +} diff --git a/src/config/.gitignore b/src/config/.gitignore index 0638d7514..5cf07b3d1 100644 --- a/src/config/.gitignore +++ b/src/config/.gitignore @@ -1 +1,2 @@ .dirstamp +pool_config.c diff --git a/src/config/README b/src/config/README index f8bfecc55..e89820ba4 100644 --- a/src/config/README +++ b/src/config/README @@ -37,7 +37,7 @@ defined above to src/include/pool_config.h. * will not be load balanced until the session ends. */ -Step3: Add config_emum_entry array to src/config/pool_config.c. +Step3: Add config_enum_entry array to src/config/pool_config.c. ================================================================ static const struct config_enum_entry disable_load_balance_on_write_options[] = { @@ -87,11 +87,11 @@ struct config_generic GucSource *sources; /* source of the current actual value, For array type config elements - * it contains the corosponding source of each individual element */ + * it contains the corresponding source of each individual element */ GucSource *reset_sources; /* source of the reset value, For array type config elements - * it contains the corosponding source of each individual element */ + * it contains the corresponding source of each individual element */ ConfigContext *scontexts; /* context that set the current value, For array type config elements - * it contains the corosponding context of each individual element */ + * it contains the corresponding context of each individual element */ }; @@ -162,5 +162,5 @@ Step6: add the new config parameter to the report program. StrNCpy(status[i].desc, "Load balance behavior when write query is received", POOLCONFIG_MAXDESCLEN); i++; -Step7: remeber to add documents and tests! -========================================== +Step7: remember to add documents and tests! +=========================================== diff --git a/src/config/pool_config.c b/src/config/pool_config.c deleted file mode 100644 index 9536d425d..000000000 --- a/src/config/pool_config.c +++ /dev/null @@ -1,2347 +0,0 @@ - -#line 3 "config/pool_config.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern yy_size_t yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -yy_size_t yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart (FILE *input_file ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -void yy_delete_buffer (YY_BUFFER_STATE b ); -void yy_flush_buffer (YY_BUFFER_STATE b ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state (void ); - -static void yyensure_buffer_stack (void ); -static void yy_load_buffer_state (void ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); - -void *yyalloc (yy_size_t ); -void *yyrealloc (void *,yy_size_t ); -void yyfree (void * ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define yywrap() 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -typedef int yy_state_type; - -extern int yylineno; - -int yylineno = 1; - -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 11 -#define YY_END_OF_BUFFER 12 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[38] = - { 0, - 0, 0, 12, 10, 2, 1, 10, 10, 10, 8, - 7, 7, 9, 4, 2, 0, 3, 0, 5, 0, - 8, 7, 7, 8, 0, 0, 6, 4, 4, 0, - 5, 0, 0, 8, 7, 6, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 4, 1, 1, 1, 5, 1, - 1, 1, 6, 1, 7, 8, 9, 10, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 9, 1, 1, - 12, 1, 1, 1, 13, 13, 13, 13, 14, 13, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 1, 16, 1, 1, 17, 1, 13, 13, 13, 13, - - 14, 13, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, - 15, 15, 1, 1, 1, 1, 1, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15 - } ; - -static yyconst flex_int32_t yy_meta[19] = - { 0, - 1, 1, 2, 1, 1, 1, 3, 3, 3, 4, - 4, 1, 5, 4, 3, 1, 3, 3 - } ; - -static yyconst flex_int16_t yy_base[45] = - { 0, - 0, 0, 61, 86, 58, 86, 55, 14, 23, 43, - 10, 46, 86, 28, 47, 40, 86, 16, 86, 22, - 28, 0, 0, 0, 40, 0, 24, 45, 0, 24, - 39, 43, 12, 14, 0, 22, 86, 62, 67, 22, - 70, 75, 77, 80 - } ; - -static yyconst flex_int16_t yy_def[45] = - { 0, - 37, 1, 37, 37, 37, 37, 38, 39, 37, 40, - 9, 9, 37, 41, 37, 38, 37, 39, 37, 42, - 40, 11, 12, 21, 37, 43, 44, 41, 28, 39, - 39, 42, 37, 37, 43, 44, 0, 37, 37, 37, - 37, 37, 37, 37 - } ; - -static yyconst flex_int16_t yy_nxt[105] = - { 0, - 4, 5, 6, 7, 8, 9, 9, 10, 4, 11, - 12, 13, 14, 14, 14, 4, 14, 14, 19, 23, - 19, 34, 34, 34, 34, 24, 31, 26, 19, 20, - 21, 20, 22, 23, 27, 27, 27, 32, 36, 20, - 36, 25, 17, 19, 29, 33, 33, 31, 15, 34, - 34, 27, 27, 27, 20, 23, 25, 17, 32, 15, - 37, 29, 16, 16, 16, 16, 16, 18, 37, 18, - 18, 18, 28, 28, 28, 30, 37, 30, 30, 30, - 35, 35, 27, 27, 27, 3, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - - 37, 37, 37, 37 - } ; - -static yyconst flex_int16_t yy_chk[105] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 8, 11, - 18, 33, 33, 34, 34, 40, 20, 11, 30, 8, - 9, 18, 9, 9, 14, 14, 14, 20, 36, 30, - 27, 21, 16, 31, 14, 25, 25, 32, 15, 25, - 25, 28, 28, 28, 31, 12, 10, 7, 32, 5, - 3, 28, 38, 38, 38, 38, 38, 39, 0, 39, - 39, 39, 41, 41, 41, 42, 0, 42, 42, 42, - 43, 43, 44, 44, 44, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - - 37, 37, 37, 37 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "pool_config.l" -/* -*-pgsql-c-*- */ -/* - * - * $Header$ - * - * pgpool: a language independent connection pool server for PostgreSQL - * written by Tatsuo Ishii - * - * Copyright (c) 2003-2016 PgPool Global Development Group - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that the above copyright notice appear in all - * copies and that both that copyright notice and this permission - * notice appear in supporting documentation, and that the name of the - * author not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. The author makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * pool_config.l: read configuration file - * - */ -#line 27 "pool_config.l" -#include -#include -#include -#include -#include "pool.h" -#include "pool_config.h" -#include "pool_config_variables.h" -#include "utils/regex_array.h" -#ifndef POOL_PRIVATE -#include "utils/elog.h" -#else -#include "utils/fe_ports.h" -#endif - -/* to shut off compiler warnings */ -int yylex(void); - -POOL_CONFIG g_pool_config; /* configuration values */ -POOL_CONFIG *pool_config = &g_pool_config; /* for lagacy reason pointer to the above struct */ -static unsigned Lineno; - -typedef enum { - POOL_KEY = 1, - POOL_INTEGER, - POOL_REAL, - POOL_STRING, - POOL_UNQUOTED_STRING, - POOL_EQUALS, - POOL_EOL, - POOL_PARSE_ERROR -} POOL_TOKEN; - -static char *extract_string(char *value, POOL_TOKEN token); -static void FreeConfigVariable(ConfigVariable *item); -static bool ParseConfigFile( const char *config_file, int elevel, - ConfigVariable **head_p, ConfigVariable **tail_p); - -#define YY_NO_INPUT 1 -#line 550 "config/pool_config.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals (void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * out_str ); - -yy_size_t yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (void ); -#else -extern int yywrap (void ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 89 "pool_config.l" - - -#line 733 "config/pool_config.c" - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 38 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 37 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -/* rule 1 can match eol */ -YY_RULE_SETUP -#line 91 "pool_config.l" -Lineno++; return POOL_EOL; - YY_BREAK -case 2: -YY_RULE_SETUP -#line 92 "pool_config.l" -/* eat whitespace */ - YY_BREAK -case 3: -*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ -(yy_c_buf_p) = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 93 "pool_config.l" -/* eat comment */ - YY_BREAK -case 4: -YY_RULE_SETUP -#line 95 "pool_config.l" -return POOL_KEY; - YY_BREAK -case 5: -YY_RULE_SETUP -#line 96 "pool_config.l" -return POOL_STRING; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 97 "pool_config.l" -return POOL_UNQUOTED_STRING; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 98 "pool_config.l" -return POOL_INTEGER; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 99 "pool_config.l" -return POOL_REAL; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 100 "pool_config.l" -return POOL_EQUALS; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 102 "pool_config.l" -return POOL_PARSE_ERROR; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 104 "pool_config.l" -ECHO; - YY_BREAK -#line 871 "config/pool_config.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 38 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - register int yy_is_jam; - register char *yy_cp = (yy_c_buf_p); - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 38 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 37); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return EOF; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ); - - yyfree((void *) b ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -{ - - return yy_scan_bytes(yystr,strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -yy_size_t yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param line_number - * - */ -void yyset_lineno (int line_number ) -{ - - yylineno = line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str ) -{ - yyin = in_str ; -} - -void yyset_out (FILE * out_str ) -{ - yyout = out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int bdebug ) -{ - yy_flex_debug = bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - (yy_buffer_stack) = 0; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 104 "pool_config.l" - - - -int pool_init_config(void) -{ - memset(pool_config, 0, sizeof(POOL_CONFIG)); - -#ifndef POOL_PRIVATE - g_pool_config.backend_desc = pool_shared_memory_create(sizeof(BackendDesc)); - memset(g_pool_config.backend_desc, 0, sizeof(BackendDesc)); -#else - g_pool_config.backend_desc = palloc0(sizeof(BackendDesc)); -#endif - g_pool_config.health_check_params = palloc0(MAX_NUM_BACKENDS*sizeof(HealthCheckParams)); - - InitializeConfigOptions(); - - return 0; -} - -/* - * Add regex expression to patterns array - * The supported type are: black_function_list and white_function_list - * Return 0 on error, 1 on success - */ -int add_regex_pattern(const char *type, char *s) -{ - int regex_flags = REG_NOSUB; - RegPattern currItem; - /* force case insensitive pattern matching */ - regex_flags |= REG_ICASE; - /* Add extended regex search */ - regex_flags |= REG_EXTENDED; - /* Fill the pattern type */ - if (strcmp(type, "black_function_list") == 0 || - strcmp(type, "black_query_pattern_list") == 0 || - strcmp(type, "black_memqcache_table_list") == 0) - { - currItem.type = BLACKLIST; - } - else if (strcmp(type, "white_function_list") == 0 || - strcmp(type, "white_memqcache_table_list") == 0) - { - currItem.type = WHITELIST; - } - else - { - ereport(WARNING, - (errmsg("unable to add regex pattern, bad pattern type %s", type))); - return 0; - } - /* Fill the pattern flag */ - currItem.flag = regex_flags; - - /* Fill pattern array */ - currItem.pattern = palloc(sizeof(char)*(strlen(s)+3)); - /* Force exact matching of function name with ^ and $ on the regex - if required to prevent partial matching. It also allow backward - compatibility. - */ - if (strncmp(s, "^", 1) != 0) { - strncpy(currItem.pattern, "^", 2); - strncat(currItem.pattern, s, strlen(s) + 1); - } else { - strncpy(currItem.pattern, s, strlen(s) + 1); - } - if (s[strlen(s)-1] != '$') { - strncat(currItem.pattern, "$", 2); - } - ereport(DEBUG1, - (errmsg("initializing pool configuration"), - errdetail("adding regex pattern for \"%s\" pattern: %s",type, currItem.pattern))); - - /* compile our regex */ - if (regcomp(&currItem.regexv, currItem.pattern, currItem.flag) != 0) - { - ereport(WARNING, - (errmsg("unable to add regex pattern for \"%s\", invalid pattern: \"%s\"", type,currItem.pattern))); - } - else if ((strcmp(type, "white_function_list") == 0 || - strcmp(type, "black_function_list") == 0) && - growFunctionPatternArray(currItem) < 0) - { - ereport(WARNING, - (errmsg("unable to add regex pattern for \"%s\", unable to allocate new pattern", type))); - return 0; - } - else if ((strcmp(type, "white_memqcache_table_list") == 0 || - strcmp(type, "black_memqcache_table_list") == 0) && - growMemqcacheTablePatternArray(currItem) < 0) - { - ereport(WARNING, - (errmsg("unable to add regex pattern for \"%s\", unable to allocate new pattern", type))); - return 0; - } - else if (strcmp(type, "black_query_pattern_list") == 0 && - growQueryPatternArray(currItem) < 0) - { - ereport(WARNING, - (errmsg("unable to add regex pattern for \"%s\", unable to allocate new pattern", type))); - return 0; - } - - return 1; -} - -/* - * Dynamically grow the regex pattern array - * The array start with PATTERN_ARR_SIZE storage place, if required - * it will grow of PATTERN_ARR_SIZE more each time. - */ -int growFunctionPatternArray(RegPattern item) -{ - void *_tmp = NULL; - if (pool_config->pattc == pool_config->current_pattern_size) - { - pool_config->current_pattern_size += PATTERN_ARR_SIZE; - _tmp = repalloc(pool_config->lists_patterns, - (pool_config->current_pattern_size * sizeof(RegPattern))); - if (!_tmp) - { - return(-1); - } - - pool_config->lists_patterns = (RegPattern*)_tmp; - } - pool_config->lists_patterns[pool_config->pattc] = item; - pool_config->pattc++; - - return(pool_config->pattc); -} - -int growMemqcacheTablePatternArray(RegPattern item) -{ - void *_tmp = NULL; - if (pool_config->memqcache_table_pattc == pool_config->current_memqcache_table_pattern_size) - { - pool_config->current_memqcache_table_pattern_size += PATTERN_ARR_SIZE; - _tmp = repalloc(pool_config->lists_memqcache_table_patterns, - (pool_config->current_memqcache_table_pattern_size * sizeof(RegPattern))); - if (!_tmp) - { - return(-1); - } - - pool_config->lists_memqcache_table_patterns = (RegPattern*)_tmp; - } - pool_config->lists_memqcache_table_patterns[pool_config->memqcache_table_pattc] = item; - pool_config->memqcache_table_pattc++; - - return(pool_config->memqcache_table_pattc); -} - -int growQueryPatternArray(RegPattern item) -{ - void *_tmp = NULL; - if (pool_config->query_pattc == pool_config->current_query_pattern_size) - { - pool_config->current_query_pattern_size += PATTERN_ARR_SIZE; - _tmp = repalloc(pool_config->lists_query_patterns, - (pool_config->current_query_pattern_size * sizeof(RegPattern))); - if (!_tmp) - { - return(-1); - } - - pool_config->lists_query_patterns = (RegPattern*)_tmp; - } - pool_config->lists_query_patterns[pool_config->query_pattc] = item; - pool_config->query_pattc++; - - return(pool_config->query_pattc); -} - -/* - * Free a single ConfigVariable - */ -static void -FreeConfigVariable(ConfigVariable *item) -{ - if (item->name) - pfree(item->name); - if (item->value) - pfree(item->value); - pfree(item); -} - -/* - * Free a list of ConfigVariables, including the names and the values - */ -static void -FreeConfigVariables(ConfigVariable *list) -{ - ConfigVariable *item; - - item = list; - while (item) - { - ConfigVariable *next = item->next; - FreeConfigVariable(item); - item = next; - } -} - -/* - * Read and parse a single configuration file. - * - * Input parameters: - * config_file: absolute or relative path name of the configuration file - * elevel: error logging level to use - * Input/Output parameters: - * head_p, tail_p: head and tail of linked list of name/value pairs - * - * *head_p and *tail_p must be initialized, either to NULL or valid pointers - * to a ConfigVariable list, before calling the outer recursion level. Any - * name-value pairs read from the input file(s) will be appended to the list. - * - * Note: if elevel >= ERROR then an error will not return control to the - * caller, so there is no need to check the return value in that case. - * - */ -static bool -ParseConfigFile(const char *config_file, int elevel, - ConfigVariable **head_p, ConfigVariable **tail_p) -{ - - FILE *fd; - int token; - char *key; - char *val; - ConfigVariable *item; - - *head_p = NULL; - - /* open config file */ - fd = fopen(config_file, "r"); - if (!fd) - { - ereport(WARNING, - (errmsg("could not open configuration file: \"%s\"",config_file), - errdetail("using default configuration parameter values"))); - return false; - } - - yyin = fd; - Lineno = 1; - - for(;;) - { - token = yylex(); - - if (token == 0) - break; - - if (token == POOL_EOL) - continue; - - if (token == POOL_PARSE_ERROR) - goto parse_error; - - if (token != POOL_KEY) - goto parse_error; - - key = pstrdup(yytext); - - token = yylex(); - - /* next we have an optional equal sign; discard if present */ - if (token == POOL_EQUALS) - token = yylex(); - - val = extract_string(yytext,token); - - ereport(DEBUG5, - (errmsg("key: \"%s\" value: \"%s\" kind: %d",key, val, token))); - - /* Add this to the list */ - item = palloc(sizeof(ConfigVariable)); - item->name = key; - item->value = val; - item->sourceline = Lineno; - item->next = NULL; - if (*head_p == NULL) - *head_p = item; - else - (*tail_p)->next = item; - *tail_p = item; - } - - fclose(fd); - return true; - -parse_error: - - fclose(fd); - FreeConfigVariables(*head_p); - *head_p = NULL; - *tail_p = NULL; - ereport(elevel, - (errmsg("syntex error in configuration file \"%s\"",config_file), - errdetail("parse error at line %d '%s' token = %d", Lineno, yytext,token))); - - return false; -} - -/* - * Read the configuration file and load the values of all parameters - */ -bool pool_get_config(const char *config_file, ConfigContext context) -{ - ConfigVariable *head_p = NULL; - ConfigVariable *tail_p = NULL; - bool res; - int elevel = (context == CFGCXT_INIT)?FATAL:WARNING; - - res = ParseConfigFile(config_file, elevel, &head_p, &tail_p); - if (res == false || head_p == NULL) - return false; - - res = set_config_options(head_p, context, PGC_S_FILE, elevel); - FreeConfigVariables(head_p); - return res; -} - - -static char *extract_string(char *value, POOL_TOKEN token) -{ - char *ret = NULL; - - if (token == POOL_STRING) - { - ret = pstrdup(value+1); - ret[strlen(ret)-1] = '\0'; - } - else - ret = pstrdup(value); - - return ret; -} - -/* - * Try to interpret value as boolean value. Valid values are: true, - * false, yes, no, on, off, 1, 0; as well as unique prefixes thereof. - * If the string parses okay, return true, else false. - * If okay and result is not NULL, return the value in *result. - * This function copied from PostgreSQL source code. - */ -static bool parse_bool_with_len(const char *value, size_t len, bool *result) -{ - switch (*value) - { - case 't': - case 'T': - if (strncasecmp(value, "true", len) == 0) - { - if (result) - *result = true; - return true; - } - break; - case 'f': - case 'F': - if (strncasecmp(value, "false", len) == 0) - { - if (result) - *result = false; - return true; - } - break; - case 'y': - case 'Y': - if (strncasecmp(value, "yes", len) == 0) - { - if (result) - *result = true; - return true; - } - break; - case 'n': - case 'N': - if (strncasecmp(value, "no", len) == 0) - { - if (result) - *result = false; - return true; - } - break; - case 'o': - case 'O': - /* 'o' is not unique enough */ - if (strncasecmp(value, "on", (len > 2 ? len : 2)) == 0) - { - if (result) - *result = true; - return true; - } - else if (strncasecmp(value, "off", (len > 2 ? len : 2)) == 0) - { - if (result) - *result = false; - return true; - } - break; - case '1': - if (len == 1) - { - if (result) - *result = true; - return true; - } - break; - case '0': - if (len == 1) - { - if (result) - *result = false; - return true; - } - break; - default: - break; - } - - if (result) - *result = false; /* suppress compiler warning */ - return false; -} - -int eval_logical(const char *str) -{ - bool result; - - if (!parse_bool_with_len(str, strlen(str), &result)) - return -1; - - return (result ? 1 : 0); -} - - -#ifdef DEBUG -static void print_host_entry(int slot) -{ - ereport(DEBUG1, - (errmsg("initializing pool configuration"), - errdetail("slot: %d host: %s port: %d status: %d weight: %f", - slot, - pool_config->server_hostnames[slot], - pool_config->server_ports[slot], - pool_config->server_status[slot], - pool_config->server_weights[slot]))); -} -#endif - - -/* - * Translate binary form of backend flag to string. - * The returned data is in static buffer, and it will be destroyed - * at the next call to this function. - */ -char *pool_flag_to_str(unsigned short flag) -{ - static char buf[1024]; /* should be large enough */ - - *buf = '\0'; - - if (POOL_ALLOW_TO_FAILOVER(flag)) - snprintf(buf, sizeof(buf), "ALLOW_TO_FAILOVER"); - else if (POOL_DISALLOW_TO_FAILOVER(flag)) - snprintf(buf, sizeof(buf), "DISALLOW_TO_FAILOVER"); - - if (POOL_ALWAYS_MASTER & flag) - { - if (*buf == '\0') - snprintf(buf, sizeof(buf), "ALWAYS_MASTER"); - else - snprintf(buf+strlen(buf), sizeof(buf), "|ALWAYS_MASTER"); - } - - return buf; -} - -/* - * Translate the BACKEND_STATUS enum value to string. - * the function returns the constant string so should not be freed - */ -char* backend_status_to_str(BackendInfo *bi) -{ - char *statusName; - - switch (bi->backend_status) { - - case CON_UNUSED: - statusName = BACKEND_STATUS_CON_UNUSED; - break; - - case CON_CONNECT_WAIT: - statusName = BACKEND_STATUS_CON_CONNECT_WAIT; - break; - - case CON_UP: - statusName = BACKEND_STATUS_CON_UP; - break; - - case CON_DOWN: - { - if (bi->quarantine) - statusName = BACKEND_STATUS_QUARANTINE; - else - statusName = BACKEND_STATUS_CON_DOWN; - } - break; - - default: - statusName = "unknown"; - break; - } - return statusName; -} - diff --git a/src/config/pool_config.l b/src/config/pool_config.l index ddff3af2e..a75cedb16 100644 --- a/src/config/pool_config.l +++ b/src/config/pool_config.l @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2016 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -32,6 +32,7 @@ #include "pool_config.h" #include "pool_config_variables.h" #include "utils/regex_array.h" +#include "utils/pool_path.h" #ifndef POOL_PRIVATE #include "utils/elog.h" #else @@ -42,8 +43,9 @@ int yylex(void); POOL_CONFIG g_pool_config; /* configuration values */ -POOL_CONFIG *pool_config = &g_pool_config; /* for lagacy reason pointer to the above struct */ +POOL_CONFIG *pool_config = &g_pool_config; /* for legacy reason pointer to the above struct */ static unsigned Lineno; +char config_file_dir[POOLMAXPATHLEN + 1]; /* directory path of config file pgpool.conf */ typedef enum { POOL_KEY = 1, @@ -58,8 +60,12 @@ typedef enum { static char *extract_string(char *value, POOL_TOKEN token); static void FreeConfigVariable(ConfigVariable *item); -static bool ParseConfigFile( const char *config_file, int elevel, - ConfigVariable **head_p, ConfigVariable **tail_p); +static bool ParseConfigFile(const char *config_file, const char *calling_file, + int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p); + +static int growFunctionPatternArray(RegPattern item); +static int growMemqcacheTablePatternArray(RegPattern item); +static int growQueryPatternArray(RegPattern item); %} @@ -73,7 +79,8 @@ SIGN ("-"|"+") DIGIT [0-9] HEXDIGIT [0-9a-fA-F] -INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+) +UNIT_LETTER [a-zA-Z] +INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}* EXPONENT [Ee]{SIGN}?{DIGIT}+ REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}? @@ -107,12 +114,7 @@ int pool_init_config(void) { memset(pool_config, 0, sizeof(POOL_CONFIG)); -#ifndef POOL_PRIVATE - g_pool_config.backend_desc = pool_shared_memory_create(sizeof(BackendDesc)); - memset(g_pool_config.backend_desc, 0, sizeof(BackendDesc)); -#else g_pool_config.backend_desc = palloc0(sizeof(BackendDesc)); -#endif g_pool_config.health_check_params = palloc0(MAX_NUM_BACKENDS*sizeof(HealthCheckParams)); InitializeConfigOptions(); @@ -122,28 +124,30 @@ int pool_init_config(void) /* * Add regex expression to patterns array - * The supported type are: black_function_list and white_function_list + * The supported type are: write_function_list and read_only_function_list * Return 0 on error, 1 on success */ int add_regex_pattern(const char *type, char *s) { int regex_flags = REG_NOSUB; RegPattern currItem; + int pattern_len; + /* force case insensitive pattern matching */ regex_flags |= REG_ICASE; /* Add extended regex search */ regex_flags |= REG_EXTENDED; /* Fill the pattern type */ - if (strcmp(type, "black_function_list") == 0 || - strcmp(type, "black_query_pattern_list") == 0 || - strcmp(type, "black_memqcache_table_list") == 0) + if (strcmp(type, "write_function_list") == 0 || + strcmp(type, "primary_routing_query_pattern_list") == 0 || + strcmp(type, "cache_unsafe_memqcache_table_list") == 0) { - currItem.type = BLACKLIST; + currItem.type = WRITELIST; } - else if (strcmp(type, "white_function_list") == 0 || - strcmp(type, "white_memqcache_table_list") == 0) + else if (strcmp(type, "read_only_function_list") == 0 || + strcmp(type, "cache_safe_memqcache_table_list") == 0) { - currItem.type = WHITELIST; + currItem.type = READONLYLIST; } else { @@ -155,18 +159,24 @@ int add_regex_pattern(const char *type, char *s) currItem.flag = regex_flags; /* Fill pattern array */ - currItem.pattern = palloc(sizeof(char)*(strlen(s)+3)); + pattern_len = sizeof(char)*(strlen(s)+3); + currItem.pattern = palloc(pattern_len); + /* Force exact matching of function name with ^ and $ on the regex if required to prevent partial matching. It also allow backward compatibility. */ - if (strncmp(s, "^", 1) != 0) { + if (strncmp(s, "^", 1) != 0) + { strncpy(currItem.pattern, "^", 2); - strncat(currItem.pattern, s, strlen(s) + 1); - } else { - strncpy(currItem.pattern, s, strlen(s) + 1); + strncat(currItem.pattern, s, pattern_len - 2); + } + else + { + strncpy(currItem.pattern, s, pattern_len); } - if (s[strlen(s)-1] != '$') { + if (s[strlen(s)-1] != '$') + { strncat(currItem.pattern, "$", 2); } ereport(DEBUG1, @@ -179,23 +189,23 @@ int add_regex_pattern(const char *type, char *s) ereport(WARNING, (errmsg("unable to add regex pattern for \"%s\", invalid pattern: \"%s\"", type,currItem.pattern))); } - else if ((strcmp(type, "white_function_list") == 0 || - strcmp(type, "black_function_list") == 0) && + else if ((strcmp(type, "read_only_function_list") == 0 || + strcmp(type, "write_function_list") == 0) && growFunctionPatternArray(currItem) < 0) { ereport(WARNING, (errmsg("unable to add regex pattern for \"%s\", unable to allocate new pattern", type))); return 0; } - else if ((strcmp(type, "white_memqcache_table_list") == 0 || - strcmp(type, "black_memqcache_table_list") == 0) && + else if ((strcmp(type, "cache_safe_memqcache_table_list") == 0 || + strcmp(type, "cache_unsafe_memqcache_table_list") == 0) && growMemqcacheTablePatternArray(currItem) < 0) { ereport(WARNING, (errmsg("unable to add regex pattern for \"%s\", unable to allocate new pattern", type))); return 0; } - else if (strcmp(type, "black_query_pattern_list") == 0 && + else if (strcmp(type, "primary_routing_query_pattern_list") == 0 && growQueryPatternArray(currItem) < 0) { ereport(WARNING, @@ -211,7 +221,8 @@ int add_regex_pattern(const char *type, char *s) * The array start with PATTERN_ARR_SIZE storage place, if required * it will grow of PATTERN_ARR_SIZE more each time. */ -int growFunctionPatternArray(RegPattern item) +static int +growFunctionPatternArray(RegPattern item) { void *_tmp = NULL; if (pool_config->pattc == pool_config->current_pattern_size) @@ -232,7 +243,8 @@ int growFunctionPatternArray(RegPattern item) return(pool_config->pattc); } -int growMemqcacheTablePatternArray(RegPattern item) +static int +growMemqcacheTablePatternArray(RegPattern item) { void *_tmp = NULL; if (pool_config->memqcache_table_pattc == pool_config->current_memqcache_table_pattern_size) @@ -253,7 +265,8 @@ int growMemqcacheTablePatternArray(RegPattern item) return(pool_config->memqcache_table_pattc); } -int growQueryPatternArray(RegPattern item) +static int +growQueryPatternArray(RegPattern item) { void *_tmp = NULL; if (pool_config->query_pattc == pool_config->current_query_pattern_size) @@ -309,6 +322,9 @@ FreeConfigVariables(ConfigVariable *list) * * Input parameters: * config_file: absolute or relative path name of the configuration file + * calling_file: absolute path of file containing the "include" directive, + * or NULL at outer level (config_file must be absolute at outer level) + * depth: recursion depth (used only to prevent infinite recursion) * elevel: error logging level to use * Input/Output parameters: * head_p, tail_p: head and tail of linked list of name/value pairs @@ -322,33 +338,75 @@ FreeConfigVariables(ConfigVariable *list) * */ static bool -ParseConfigFile(const char *config_file, int elevel, - ConfigVariable **head_p, ConfigVariable **tail_p) +ParseConfigFile(const char *config_file, const char *calling_file, + int depth, int elevel, ConfigVariable **head_p, + ConfigVariable **tail_p) { FILE *fd; + YY_BUFFER_STATE lex_buffer; int token; char *key; char *val; ConfigVariable *item; - - *head_p = NULL; + char buf[POOLMAXPATHLEN + 1]; + char *config_filepath; + + /* + * Reject too-deep include nesting depth. + */ + if (depth > 10) + ereport(elevel, + (errmsg("could not open configuration file \"%s\": maximum nesting depth exceeded", + config_file))); + + if (depth == 0) + { + /* get directory path of config file pgpool.conf */ + strlcpy(buf, config_file, sizeof(buf)); + get_parent_directory(buf); + strlcpy(config_file_dir, buf, sizeof(config_file_dir)); + } + + + if (calling_file == NULL || is_absolute_path(config_file)) + { + /* absolute path is taken as-is */ + config_filepath = (char *) palloc(strlen(config_file) + 1); + strcpy(config_filepath, config_file); + config_filepath[strlen(config_file)] = '\0'; + } + else + { + /* relative path is relative to dir of calling file */ + config_filepath = (char *) palloc(strlen(config_file) + 1 + + strlen(calling_file) + 1); + strcpy(config_filepath, calling_file); + get_parent_directory(config_filepath); + join_path_components(config_filepath, config_filepath, config_file); + canonicalize_path(config_filepath); + } /* open config file */ - fd = fopen(config_file, "r"); + fd = fopen(config_filepath, "r"); if (!fd) { ereport(WARNING, - (errmsg("could not open configuration file: \"%s\"",config_file), + (errmsg("could not open configuration file: \"%s\"",config_filepath), errdetail("using default configuration parameter values"))); return false; } + lex_buffer = yy_create_buffer(fd, YY_BUF_SIZE); + yy_switch_to_buffer(lex_buffer); + yyin = fd; Lineno = 1; for(;;) { + key = NULL; + token = yylex(); if (token == 0) @@ -376,17 +434,36 @@ ParseConfigFile(const char *config_file, int elevel, ereport(DEBUG5, (errmsg("key: \"%s\" value: \"%s\" kind: %d",key, val, token))); - /* Add this to the list */ - item = palloc(sizeof(ConfigVariable)); - item->name = key; - item->value = val; - item->sourceline = Lineno; - item->next = NULL; - if (*head_p == NULL) - *head_p = item; + if (strcmp(key, "include") == 0) + { + /* + * An include directive isn't a variable and should be processed + * immediately. + */ + unsigned save_Lineno = Lineno; + + if (!ParseConfigFile(val, config_filepath, depth + 1, elevel, head_p, tail_p)) + { + goto parse_error; + } + yy_switch_to_buffer(lex_buffer); + Lineno = save_Lineno; + } else - (*tail_p)->next = item; - *tail_p = item; + { + /* Add this to the list */ + item = palloc(sizeof(ConfigVariable)); + item->name = key; + item->value = val; + item->sourceline = Lineno; + item->next = NULL; + + if (*head_p == NULL) + *head_p = item; + else + (*tail_p)->next = item; + *tail_p = item; + } } fclose(fd); @@ -394,12 +471,14 @@ ParseConfigFile(const char *config_file, int elevel, parse_error: + if (key) + pfree(key); fclose(fd); FreeConfigVariables(*head_p); *head_p = NULL; *tail_p = NULL; ereport(elevel, - (errmsg("syntex error in configuration file \"%s\"",config_file), + (errmsg("syntax error in configuration file \"%s\"", config_filepath), errdetail("parse error at line %d '%s' token = %d", Lineno, yytext,token))); return false; @@ -415,7 +494,7 @@ bool pool_get_config(const char *config_file, ConfigContext context) bool res; int elevel = (context == CFGCXT_INIT)?FATAL:WARNING; - res = ParseConfigFile(config_file, elevel, &head_p, &tail_p); + res = ParseConfigFile(config_file, NULL, 0, elevel, &head_p, &tail_p); if (res == false || head_p == NULL) return false; @@ -570,12 +649,12 @@ char *pool_flag_to_str(unsigned short flag) else if (POOL_DISALLOW_TO_FAILOVER(flag)) snprintf(buf, sizeof(buf), "DISALLOW_TO_FAILOVER"); - if (POOL_ALWAYS_MASTER & flag) + if (POOL_ALWAYS_PRIMARY & flag) { if (*buf == '\0') - snprintf(buf, sizeof(buf), "ALWAYS_MASTER"); + snprintf(buf, sizeof(buf), "ALWAYS_PRIMARY"); else - snprintf(buf+strlen(buf), sizeof(buf), "|ALWAYS_MASTER"); + strncat(buf, "|ALWAYS_PRIMARY", 16); } return buf; diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c index 8a6c83b73..3039e32f0 100644 --- a/src/config/pool_config_variables.c +++ b/src/config/pool_config_variables.c @@ -1,9 +1,34 @@ +/* -*-pgsql-c-*- */ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2026 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool_config_variables.c. + * + */ + #include #include #include #include #include #include +#include +#include #include "pool.h" #include "pool_config.h" @@ -24,7 +49,11 @@ #endif #define default_reset_query_list "ABORT;DISCARD ALL" -#define default_black_function_list "nextval,setval" +#define default_listen_addresses_list "localhost" +#define default_pcp_listen_addresses_list "localhost" +#define default_unix_socket_directories_list "/tmp" +#define default_read_only_function_list "" +#define default_write_function_list "" #define EMPTY_CONFIG_GENERIC {NULL, 0, 0, NULL, 0, false, 0, 0, 0, 0, NULL, NULL} #define EMPTY_CONFIG_BOOL {EMPTY_CONFIG_GENERIC, NULL, false, NULL, NULL, NULL, false} @@ -56,19 +85,23 @@ static bool config_post_processor(ConfigContext context, int elevel); static void sort_config_vars(void); static bool setConfigOptionArrayVarWithConfigDefault(struct config_generic *record, const char *name, - const char *value, ConfigContext context, int elevel); + const char *value, ConfigContext context, int elevel); static bool setConfigOption(const char *name, const char *value, - ConfigContext context, GucSource source, int elevel); + ConfigContext context, GucSource source, int elevel); static bool setConfigOptionVar(struct config_generic *record, const char *name, int index_val, - const char *value, ConfigContext context, GucSource source, int elevel); + const char *value, ConfigContext context, GucSource source, int elevel); static bool get_index_in_var_name(struct config_generic *record, - const char *name, int *index, int elevel); + const char *name, int *index, int elevel); +static bool MakeUserRedirectListRegex(char *newval, int elevel); static bool MakeDBRedirectListRegex(char *newval, int elevel); static bool MakeAppRedirectListRegex(char *newval, int elevel); +static bool MakeDMLAdaptiveObjectRelationList(char *newval, int elevel); +static char *getParsedToken(char *token, DBObjectTypes *object_type); + static bool check_redirect_node_spec(char *node_spec); static char **get_list_from_string(const char *str, const char *delimi, int *n); static char **get_list_from_string_regex_delim(const char *str, const char *delimi, int *n); @@ -76,9 +109,11 @@ static char **get_list_from_string_regex_delim(const char *str, const char *deli /*show functions */ static const char *IntValueShowFunc(int value); +static const char *FilePermissionShowFunc(int value); +static const char *UnixSockPermissionsShowFunc(void); static const char *HBDestinationPortShowFunc(int index); -static const char *HBDestinationShowFunc(int index); static const char *HBDeviceShowFunc(int index); +static const char *HBHostnameShowFunc(int index); static const char *OtherWDPortShowFunc(int index); static const char *OtherPPPortShowFunc(int index); static const char *OtherPPHostShowFunc(int index); @@ -87,6 +122,7 @@ static const char *BackendDataDirShowFunc(int index); static const char *BackendHostShowFunc(int index); static const char *BackendPortShowFunc(int index); static const char *BackendWeightShowFunc(int index); +static const char *BackendAppNameShowFunc(int index); static const char *HealthCheckPeriodShowFunc(int index); static const char *HealthCheckTimeOutShowFunc(int index); @@ -105,14 +141,17 @@ static bool BackendSlotEmptyCheckFunc(int index); /*variable custom assign functions */ static bool FailOverOnBackendErrorAssignMessage(ConfigContext scontext, bool newval, int elevel); +static bool DelegateIPAssignMessage(ConfigContext scontext, char *newval, int elevel); +static bool LogDirAssignMessage(ConfigContext scontext, char *newval, int elevel); static bool BackendPortAssignFunc(ConfigContext context, int newval, int index, int elevel); static bool BackendHostAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool BackendDataDirAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool BackendFlagsAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool BackendWeightAssignFunc(ConfigContext context, double newval, int index, int elevel); -static bool HBDestinationAssignFunc(ConfigContext context, char *newval, int index, int elevel); +static bool BackendAppNameAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool HBDestinationPortAssignFunc(ConfigContext context, int newval, int index, int elevel); static bool HBDeviceAssignFunc(ConfigContext context, char *newval, int index, int elevel); +static bool HBHostnameAssignFunc(ConfigContext context, char *newval, int index, int elevel); static bool OtherWDPortAssignFunc(ConfigContext context, int newval, int index, int elevel); static bool OtherPPPortAssignFunc(ConfigContext context, int newval, int index, int elevel); static bool OtherPPHostAssignFunc(ConfigContext context, char *newval, int index, int elevel); @@ -130,14 +169,24 @@ static bool HealthCheckDatabaseAssignFunc(ConfigContext context, char *newval, i static bool LogDestinationProcessFunc(char *newval, int elevel); static bool SyslogIdentProcessFunc(char *newval, int elevel); static bool SyslogFacilityProcessFunc(int newval, int elevel); +static bool SetHBDestIfFunc(int elevel); +static bool SetPgpoolNodeId(int elevel); static struct config_generic *get_index_free_record_if_any(struct config_generic *record); +static bool parse_int(const char *value, int64 *result, int flags, const char **hintmsg, int64 MaxVal); +static bool convert_to_base_unit(double value, const char *unit, + int base_unit, double *base_value); #ifndef POOL_PRIVATE + +static void convert_int_from_base_unit(int64 base_value, int base_unit, + int64 *value, const char **unit); + + /* These functions are used to provide Hints for enum type config parameters and - * to output the vslues of the parameters. - * These functuons are not available for tools since they use the stringInfo that is + * to output the values of the parameters. + * These functions are not available for tools since they use the stringInfo that is * not present for tools. */ @@ -146,12 +195,12 @@ static const char *config_enum_lookup_by_value(struct config_enum *record, int v static char *ShowOption(struct config_generic *record, int index, int elevel); static char *config_enum_get_options(struct config_enum *record, const char *prefix, - const char *suffix, const char *separator); -static void send_row_description_for_detail_view(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -static int send_grouped_type_variable_to_frontend(struct config_grouped_array_var *grouped_record, - POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -static int send_array_type_variable_to_frontend(struct config_generic *record, - POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); + const char *suffix, const char *separator); +static void send_row_description_for_detail_view(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +static int send_grouped_type_variable_to_frontend(struct config_grouped_array_var *grouped_record, + POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +static int send_array_type_variable_to_frontend(struct config_generic *record, + POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); #endif @@ -179,14 +228,29 @@ static const struct config_enum_entry server_message_level_options[] = { {NULL, 0, false} }; +static const struct config_enum_entry backend_clustering_mode_options[] = { + {"streaming_replication", CM_STREAMING_REPLICATION, false}, + {"native_replication", CM_NATIVE_REPLICATION, false}, + {"logical_replication", CM_LOGICAL_REPLICATION, false}, + {"raw", CM_RAW, false}, + {"snapshot_isolation", CM_SNAPSHOT_ISOLATION, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry process_management_mode_options[] = { + {"static", PM_STATIC, false}, + {"dynamic", PM_DYNAMIC, false}, -static const struct config_enum_entry master_slave_sub_mode_options[] = { - {"slony", SLONY_MODE, false}, - {"stream", STREAM_MODE, false}, - {"logical", LOGICAL_MODE, false}, {NULL, 0, false} }; +static const struct config_enum_entry process_management_strategy_options[] = { + {"aggressive", PM_STRATEGY_AGGRESSIVE, false}, + {"gentle", PM_STRATEGY_GENTLE, false}, + {"lazy", PM_STRATEGY_LAZY, false}, + + {NULL, 0, false} +}; static const struct config_enum_entry log_standby_delay_options[] = { {"always", LSD_ALWAYS, false}, @@ -225,9 +289,114 @@ static const struct config_enum_entry disable_load_balance_on_write_options[] = {"transaction", DLBOW_TRANSACTION, false}, {"trans_transaction", DLBOW_TRANS_TRANSACTION, false}, {"always", DLBOW_ALWAYS, false}, + {"dml_adaptive", DLBOW_DML_ADAPTIVE, false}, + {"dml_adaptive_global", DLBOW_DML_ADAPTIVE_GLOBAL, false}, + {NULL, 0, false} +}; + +static const struct config_enum_entry relcache_query_target_options[] = { + {"primary", RELQTARGET_PRIMARY, false}, + {"load_balance_node", RELQTARGET_LOAD_BALANCE_NODE, false}, {NULL, 0, false} }; +static const struct config_enum_entry check_temp_table_options[] = { + {"catalog", CHECK_TEMP_CATALOG, false}, /* search system catalogs */ + {"trace", CHECK_TEMP_TRACE, false}, /* tracing temp tables */ + {"none", CHECK_TEMP_NONE, false}, /* do not check temp tables */ + {"on", CHECK_TEMP_ON, false}, /* same as CHECK_TEMP_CATALOG. Just for + * backward compatibility. */ + {"off", CHECK_TEMP_OFF, false}, /* same as CHECK_TEMP_NONE. Just for + * backward compatibility. */ + {NULL, 0, false} +}; + +static const struct config_enum_entry log_backend_messages_options[] = { + {"none", BGMSG_NONE, false}, /* turn off logging */ + {"terse", BGMSG_TERSE, false}, /* terse logging (repeated messages are + * collapsed into count */ + {"verbose", BGMSG_VERBOSE, false}, /* always log each message */ + {NULL, 0, false} +}; + +/* From PostgreSQL's guc.c */ +/* + * Unit conversion tables. + * + * There are two tables, one for memory units, and another for time units. + * For each supported conversion from one unit to another, we have an entry + * in the table. + * + * 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 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 */ + +typedef struct +{ + char unit[MAX_UNIT_LEN + 1]; /* unit, as a string, like "kB" or + * "min" */ + int base_unit; /* GUC_UNIT_XXX */ + double multiplier; /* Factor for converting unit -> base_unit */ +} unit_conversion; + +static const char *memory_units_hint = "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"."; + +static const unit_conversion memory_unit_conversion_table[] = +{ + {"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)}, + + {""} /* end of table marker */ +}; + +static const char *time_units_hint = "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"."; + +static const unit_conversion time_unit_conversion_table[] = +{ + {"d", GUC_UNIT_MS, 1000 * 60 * 60 * 24}, + {"h", GUC_UNIT_MS, 1000 * 60 * 60}, + {"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, 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, 1.0 / 60}, + {"ms", GUC_UNIT_MIN, 1.0 / (1000 * 60)}, + {"us", GUC_UNIT_MIN, 1.0 / (1000 * 1000 * 60)}, + + {""} /* end of table marker */ +}; static struct config_bool ConfigureNamesBool[] = { { @@ -247,16 +416,16 @@ static struct config_bool ConfigureNamesBool[] = CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.failover_when_quorum_exists, - false, + true, NULL, NULL, NULL }, { {"failover_require_consensus", CFGCXT_INIT, FAILOVER_CONFIG, - "Only do failover when majority aggrees.", + "Only do failover when majority agrees.", CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.failover_require_consensus, - false, + true, NULL, NULL, NULL }, { @@ -269,7 +438,25 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, { - {"log_connections", CFGCXT_RELOAD, LOGING_CONFIG, + {"enable_consensus_with_half_votes", CFGCXT_INIT, FAILOVER_CONFIG, + "apply majority rule for consensus and quorum computation at 50% of votes in a cluster with an even number of nodes.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.enable_consensus_with_half_votes, + false, + NULL, NULL, NULL + }, + { + {"wd_remove_shutdown_nodes", CFGCXT_RELOAD, WATCHDOG_CONFIG, + "Revoke the cluster membership of properly shutdown watchdog nodes.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.wd_remove_shutdown_nodes, + false, + NULL, NULL, NULL + }, + { + {"log_connections", CFGCXT_RELOAD, LOGGING_CONFIG, "Logs each successful connection.", CONFIG_VAR_TYPE_BOOL, false, 0 }, @@ -279,7 +466,27 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"log_hostname", CFGCXT_RELOAD, LOGING_CONFIG, + {"log_disconnections", CFGCXT_RELOAD, LOGGING_CONFIG, + "Logs end of a session.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.log_disconnections, + false, + NULL, NULL, NULL + }, + + { + {"log_pcp_processes", CFGCXT_RELOAD, LOGGING_CONFIG, + "Logs PCP process forks and a normal exit status to the log", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.log_pcp_processes, + false, + NULL, NULL, NULL + }, + + { + {"log_hostname", CFGCXT_RELOAD, LOGGING_CONFIG, "Logs the host name in the connection logs.", CONFIG_VAR_TYPE_BOOL, false, 0 }, @@ -299,7 +506,7 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"replication_mode", CFGCXT_INIT, LOGING_CONFIG, + {"replication_mode", CFGCXT_INIT, LOGGING_CONFIG, "Enables replication mode.", CONFIG_VAR_TYPE_BOOL, false, 0 }, @@ -314,13 +521,13 @@ static struct config_bool ConfigureNamesBool[] = CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.load_balance_mode, - false, + true, NULL, NULL, NULL }, { {"replication_stop_on_mismatch", CFGCXT_RELOAD, REPLICATION_CONFIG, - "Starts degeneration and stops replication, If there's a data mismatch between master and secondary.", + "Starts degeneration and stops replication, If there's a data mismatch between primary and secondary.", CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.replication_stop_on_mismatch, @@ -330,7 +537,7 @@ static struct config_bool ConfigureNamesBool[] = { {"failover_if_affected_tuples_mismatch", CFGCXT_RELOAD, REPLICATION_CONFIG, - "Starts degeneration, If there's a data mismatch between master and secondary.", + "Starts degeneration, If there's a data mismatch between primary and secondary.", CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.failover_if_affected_tuples_mismatch, @@ -349,11 +556,11 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"master_slave_mode", CFGCXT_INIT, MASTER_SLAVE_CONFIG, - "Enables Master/Slave mode.", + {"prefer_lower_delay_standby", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, + "If the load balance node is delayed over delay_threshold on SR, pgpool find another standby node which is lower delayed.", CONFIG_VAR_TYPE_BOOL, false, 0 }, - &g_pool_config.master_slave_mode, + &g_pool_config.prefer_lower_delay_standby, false, NULL, NULL, NULL }, @@ -388,6 +595,16 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"failover_on_backend_shutdown", CFGCXT_RELOAD, FAILOVER_CONFIG, + "Triggers fail over when backend is shutdown.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.failover_on_backend_shutdown, + false, + NULL, NULL, NULL + }, + { {"detach_false_primary", CFGCXT_RELOAD, FAILOVER_CONFIG, "Automatically detaches false primary node.", @@ -419,7 +636,7 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"log_statement", CFGCXT_SESSION, LOGING_CONFIG, + {"log_statement", CFGCXT_SESSION, LOGGING_CONFIG, "Logs all statements in the pgpool logs.", CONFIG_VAR_TYPE_BOOL, false, 0 }, @@ -429,7 +646,7 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"log_per_node_statement", CFGCXT_SESSION, LOGING_CONFIG, + {"log_per_node_statement", CFGCXT_SESSION, LOGGING_CONFIG, "Logs per node detailed SQL statements.", CONFIG_VAR_TYPE_BOOL, false, 0 }, @@ -439,7 +656,17 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"log_client_messages", CFGCXT_SESSION, LOGING_CONFIG, + {"notice_per_node_statement", CFGCXT_SESSION, LOGGING_CONFIG, + "Logs notice message for per node detailed SQL statements.", + CONFIG_VAR_TYPE_ENUM, false, 0 + }, + &g_pool_config.notice_per_node_statement, + false, + NULL, NULL, NULL + }, + + { + {"log_client_messages", CFGCXT_SESSION, LOGGING_CONFIG, "Logs any client messages in the pgpool logs.", CONFIG_VAR_TYPE_BOOL, false, 0 }, @@ -460,11 +687,11 @@ static struct config_bool ConfigureNamesBool[] = { {"clear_memqcache_on_escalation", CFGCXT_RELOAD, WATCHDOG_CONFIG, - "Clears the query cache in the shared memory when pgpool-II escaltes to master watchdog node.", + "Clears the query cache in the shared memory when pgpool-II escalates to leader watchdog node.", CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.clear_memqcache_on_escalation, - false, + true, NULL, NULL, NULL }, @@ -479,12 +706,12 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"check_temp_table", CFGCXT_SESSION, GENERAL_CONFIG, - "Enables temporary table check.", + {"ssl_prefer_server_ciphers", CFGCXT_RELOAD, SSL_CONFIG, + "Use server's SSL cipher preferences, rather than the client's", CONFIG_VAR_TYPE_BOOL, false, 0 }, - &g_pool_config.check_temp_table, - true, + &g_pool_config.ssl_prefer_server_ciphers, + false, NULL, NULL, NULL }, @@ -499,7 +726,7 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"memory_cache_enabled", CFGCXT_RELOAD, CACHE_CONFIG, + {"memory_cache_enabled", CFGCXT_INIT, CACHE_CONFIG, "Enables the memory cache functionality.", CONFIG_VAR_TYPE_BOOL, false, 0 }, @@ -508,6 +735,16 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"enable_shared_relcache", CFGCXT_INIT, CACHE_CONFIG, + "relation cache stored in memory cache.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.enable_shared_relcache, + true, + NULL, NULL, NULL + }, + { {"memqcache_auto_cache_invalidation", CFGCXT_RELOAD, CACHE_CONFIG, "Automatically deletes the cache related to the updated tables.", @@ -537,6 +774,54 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"statement_level_load_balance", CFGCXT_RELOAD, LOAD_BALANCE_CONFIG, + "Enables statement level load balancing", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.statement_level_load_balance, + false, + NULL, NULL, NULL + }, + + { + {"auto_failback", CFGCXT_RELOAD, FAILOVER_CONFIG, + "Enables nodes automatically reattach, when detached node continue streaming replication.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.auto_failback, + false, + NULL, NULL, NULL + }, + { + {"logging_collector", CFGCXT_INIT, LOGGING_CONFIG, + "Enable capturing of stderr into log files.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.logging_collector, + false, + NULL, NULL, NULL + }, + { + {"log_truncate_on_rotation", CFGCXT_RELOAD, LOGGING_CONFIG, + "If on, an existing log file gets truncated on time based log rotation.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.log_truncate_on_rotation, + false, + NULL, NULL, NULL + }, + + { + {"health_check_test", CFGCXT_INIT, HEALTH_CHECK_CONFIG, + "If on, enable health check testing.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + &g_pool_config.health_check_test, + false, + NULL, NULL, NULL + }, + /* End-of-list marker */ EMPTY_CONFIG_BOOL @@ -544,6 +829,19 @@ static struct config_bool ConfigureNamesBool[] = static struct config_string ConfigureNamesString[] = { + { + {"user_redirect_preference_list", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, + "redirect by user name.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.user_redirect_preference_list, /* variable */ + NULL, /* boot value */ + NULL, /* assign_func */ + NULL, /* check_func */ + MakeUserRedirectListRegex, /* process func */ + NULL /* show hook */ + }, + { {"database_redirect_preference_list", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, "redirect by database name.", @@ -569,42 +867,23 @@ static struct config_string ConfigureNamesString[] = }, { - {"listen_addresses", CFGCXT_INIT, CONNECTION_CONFIG, - "hostname or IP address on which pgpool will listen on.", - CONFIG_VAR_TYPE_STRING, false, 0 - }, - &g_pool_config.listen_addresses, - "localhost", - NULL, NULL, NULL, NULL - }, - - { - {"pcp_listen_addresses", CFGCXT_INIT, CONNECTION_CONFIG, - "hostname(s) or IP address(es) on which pcp will listen on.", - CONFIG_VAR_TYPE_STRING, false, 0 - }, - &g_pool_config.pcp_listen_addresses, - "*", - NULL, NULL, NULL, NULL - }, - - { - {"socket_dir", CFGCXT_INIT, CONNECTION_CONFIG, - "The directory to create the UNIX domain socket for accepting pgpool-II client connections.", + {"dml_adaptive_object_relationship_list", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, + "list of relationships between objects.", CONFIG_VAR_TYPE_STRING, false, 0 }, - &g_pool_config.socket_dir, - DEFAULT_SOCKET_DIR, - NULL, NULL, NULL, NULL + &g_pool_config.dml_adaptive_object_relationship_list, + NULL, + NULL, NULL, + MakeDMLAdaptiveObjectRelationList, NULL }, { - {"pcp_socket_dir", CFGCXT_INIT, CONNECTION_CONFIG, - "The directory to create the UNIX domain socket for accepting pgpool-II PCP connections.", + {"unix_socket_group", CFGCXT_INIT, CONNECTION_CONFIG, + "The owning user of the sockets that always starts the server.", CONFIG_VAR_TYPE_STRING, false, 0 }, - &g_pool_config.pcp_socket_dir, - DEFAULT_SOCKET_DIR, + &g_pool_config.unix_socket_group, + "", NULL, NULL, NULL, NULL }, @@ -619,7 +898,7 @@ static struct config_string ConfigureNamesString[] = }, { - {"log_destination", CFGCXT_RELOAD, LOGING_CONFIG, + {"log_destination", CFGCXT_RELOAD, LOGGING_CONFIG, "destination of pgpool-II log", CONFIG_VAR_TYPE_STRING, false, 0 }, @@ -631,7 +910,7 @@ static struct config_string ConfigureNamesString[] = }, { - {"syslog_ident", CFGCXT_RELOAD, LOGING_CONFIG, + {"syslog_ident", CFGCXT_RELOAD, LOGGING_CONFIG, "syslog program ident string.", CONFIG_VAR_TYPE_STRING, false, 0 }, @@ -663,12 +942,12 @@ static struct config_string ConfigureNamesString[] = }, { - {"log_line_prefix", CFGCXT_RELOAD, LOGING_CONFIG, + {"log_line_prefix", CFGCXT_RELOAD, LOGGING_CONFIG, "printf-style string to output at beginning of each log line.", CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.log_line_prefix, - "%t: pid %p: ", + "%m: %a pid %p: ", NULL, NULL, NULL, NULL }, @@ -678,7 +957,7 @@ static struct config_string ConfigureNamesString[] = CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.sr_check_user, - "nobody", + "", NULL, NULL, NULL, NULL }, @@ -702,6 +981,16 @@ static struct config_string ConfigureNamesString[] = NULL, NULL, NULL, NULL }, + { + {"replication_delay_source_cmd", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, + "External command to retrieve replication delay information.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.replication_delay_source_cmd, + "", + NULL, NULL, NULL, NULL + }, + { {"failback_command", CFGCXT_RELOAD, FAILOVER_CONFIG, "Command to execute when backend node is attached.", @@ -713,11 +1002,11 @@ static struct config_string ConfigureNamesString[] = }, { - {"follow_master_command", CFGCXT_RELOAD, FAILOVER_CONFIG, - "Command to execute in master/slave streaming replication mode after a master node failover.", + {"follow_primary_command", CFGCXT_RELOAD, FAILOVER_CONFIG, + "Command to execute in streaming replication mode after a primary node failover.", CONFIG_VAR_TYPE_STRING, false, 0 }, - &g_pool_config.follow_master_command, + &g_pool_config.follow_primary_command, "", NULL, NULL, NULL, NULL }, @@ -752,6 +1041,16 @@ static struct config_string ConfigureNamesString[] = NULL, NULL, NULL, NULL }, + { + {"recovery_database", CFGCXT_RELOAD, RECOVERY_CONFIG, + "The database name for online recovery.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.recovery_database, + "postgres", + NULL, NULL, NULL, NULL + }, + { {"recovery_1st_stage_command", CFGCXT_RELOAD, RECOVERY_CONFIG, "Command to execute in first stage recovery.", @@ -784,7 +1083,7 @@ static struct config_string ConfigureNamesString[] = { {"wd_escalation_command", CFGCXT_RELOAD, WATCHDOG_CONFIG, - "Command to execute when watchdog node becomes cluster master/leader node.", + "Command to execute when watchdog node becomes cluster leader node.", CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_escalation_command, @@ -794,7 +1093,7 @@ static struct config_string ConfigureNamesString[] = { {"wd_de_escalation_command", CFGCXT_RELOAD, WATCHDOG_CONFIG, - "Command to execute when watchdog node resigns from the cluster master/leader node.", + "Command to execute when watchdog node resigns from the cluster leader node.", CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_de_escalation_command, @@ -813,21 +1112,31 @@ static struct config_string ConfigureNamesString[] = }, { - {"delegate_IP", CFGCXT_INIT, WATCHDOG_CONFIG, - "Delegate IP address to be used when pgpool node become a watchdog cluster master/leader.", + {"trusted_server_command", CFGCXT_RELOAD, WATCHDOG_CONFIG, + "Command to excute when communicate with trusted server.", CONFIG_VAR_TYPE_STRING, false, 0 }, - &g_pool_config.delegate_IP, - "", + &g_pool_config.trusted_server_command, + "ping -q -c3 %h", NULL, NULL, NULL, NULL }, { - {"wd_hostname", CFGCXT_INIT, WATCHDOG_CONFIG, - "Host name or IP address of this watchdog.", + {"delegate_IP", CFGCXT_INIT, WATCHDOG_CONFIG, + "Old config parameter for delegate_ip.", + CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_IN_SHOW_ALL + }, + NULL, + "", + DelegateIPAssignMessage, NULL, NULL, NULL + }, + + { + {"delegate_ip", CFGCXT_INIT, WATCHDOG_CONFIG, + "Delegate IP address to be used when pgpool node become a watchdog cluster leader.", CONFIG_VAR_TYPE_STRING, false, 0 }, - &g_pool_config.wd_hostname, + &g_pool_config.delegate_ip, "", NULL, NULL, NULL, NULL }, @@ -858,7 +1167,7 @@ static struct config_string ConfigureNamesString[] = CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.if_up_cmd, - "ip addr add $_IP_$/24 dev eth0 label eth0:0", + "/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev eth0 label eth0:0", NULL, NULL, NULL, NULL }, @@ -868,7 +1177,7 @@ static struct config_string ConfigureNamesString[] = CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.if_down_cmd, - "ip addr del $_IP_$/24 dev eth0", + "/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev eth0", NULL, NULL, NULL, NULL }, @@ -888,7 +1197,7 @@ static struct config_string ConfigureNamesString[] = CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.arping_cmd, - "arping -U $_IP_$ -w 1", + "/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I eth0", NULL, NULL, NULL, NULL }, @@ -908,7 +1217,7 @@ static struct config_string ConfigureNamesString[] = CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_lifecheck_dbname, - "postgres", + "template1", NULL, NULL, NULL, NULL }, @@ -918,7 +1227,7 @@ static struct config_string ConfigureNamesString[] = CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_lifecheck_user, - "nobody", + "", NULL, NULL, NULL, NULL }, @@ -928,7 +1237,7 @@ static struct config_string ConfigureNamesString[] = CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_VALUE }, &g_pool_config.wd_lifecheck_password, - "postgres", + "", NULL, NULL, NULL, NULL }, @@ -943,8 +1252,28 @@ static struct config_string ConfigureNamesString[] = }, { - {"ssl_cert", CFGCXT_INIT, SSL_CONFIG, - "Path to the SSL public certificate file.", + {"wd_listen_address", CFGCXT_INIT, WATCHDOG_CONFIG, + "hostname(s) or IP address which watchdog will listen on.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.wd_listen_address, + "", + NULL, NULL, NULL, NULL + }, + + { + {"wd_heartbeat_listen_addresses", CFGCXT_INIT, WATCHDOG_LIFECHECK, + "hostname(s) or IP address(es) which heartbeat will listen on.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.wd_heartbeat_listen_addresses, + "", + NULL, NULL, NULL, NULL + }, + + { + {"ssl_cert", CFGCXT_RELOAD, SSL_CONFIG, + "SSL public certificate file.", CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.ssl_cert, @@ -953,8 +1282,8 @@ static struct config_string ConfigureNamesString[] = }, { - {"ssl_key", CFGCXT_INIT, SSL_CONFIG, - "Path to the SSL private key file.", + {"ssl_key", CFGCXT_RELOAD, SSL_CONFIG, + "SSL private key file.", CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.ssl_key, @@ -963,8 +1292,8 @@ static struct config_string ConfigureNamesString[] = }, { - {"ssl_ca_cert", CFGCXT_INIT, SSL_CONFIG, - "Path to a single PEM format file.", + {"ssl_ca_cert", CFGCXT_RELOAD, SSL_CONFIG, + "Single PEM format file containing CA root certificate(s).", CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.ssl_ca_cert, @@ -973,7 +1302,7 @@ static struct config_string ConfigureNamesString[] = }, { - {"ssl_ca_cert_dir", CFGCXT_INIT, SSL_CONFIG, + {"ssl_ca_cert_dir", CFGCXT_RELOAD, SSL_CONFIG, "Directory containing CA root certificate(s).", CONFIG_VAR_TYPE_STRING, false, 0 }, @@ -982,9 +1311,60 @@ static struct config_string ConfigureNamesString[] = NULL, NULL, NULL, NULL }, + { + {"ssl_crl_file", CFGCXT_RELOAD, SSL_CONFIG, + "SSL certificate revocation list file", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.ssl_crl_file, + "", + NULL, NULL, NULL, NULL + }, + + { + {"ssl_ciphers", CFGCXT_RELOAD, SSL_CONFIG, + "Allowed SSL ciphers.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.ssl_ciphers, + "HIGH:MEDIUM:+3DES:!aNULL", + NULL, NULL, NULL, NULL + }, + + { + {"ssl_ecdh_curve", CFGCXT_RELOAD, SSL_CONFIG, + "The curve to use in ECDH key exchange.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.ssl_ecdh_curve, + "prime256v1", + NULL, NULL, NULL, NULL + }, + + { + {"ssl_dh_params_file", CFGCXT_RELOAD, SSL_CONFIG, + "Path to the Diffie-Hellman parameters contained file", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.ssl_dh_params_file, + "", + NULL, NULL, NULL, NULL + }, + + { + {"ssl_passphrase_command", CFGCXT_RELOAD, SSL_CONFIG, + "Path to the Diffie-Hellman parameters contained file", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.ssl_passphrase_command, + "", + NULL, NULL, NULL, NULL + }, + + { {"memqcache_oiddir", CFGCXT_INIT, CACHE_CONFIG, - "Tempory directory to record table oids.", + "Temporary directory to record table oids.", CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.memqcache_oiddir, @@ -1003,15 +1383,45 @@ static struct config_string ConfigureNamesString[] = }, { - {"logdir", CFGCXT_INIT, LOGING_CONFIG, - "PgPool status file logging directory.", + {"logdir", CFGCXT_INIT, LOGGING_CONFIG, + "Old config parameter for work_dir.", + CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_IN_SHOW_ALL + }, + NULL, + "", + LogDirAssignMessage, NULL, NULL, NULL + }, + + { + {"work_dir", CFGCXT_INIT, LOGGING_CONFIG, + "directory to create pgpool_status and lock files.", CONFIG_VAR_TYPE_STRING, false, 0 }, - &g_pool_config.logdir, + &g_pool_config.work_dir, DEFAULT_LOGDIR, NULL, NULL, NULL, NULL }, + { + {"log_directory", CFGCXT_RELOAD, LOGGING_CONFIG, + "directory where log files are written.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.log_directory, + "/tmp/pgpool_logs", + NULL, NULL, NULL, NULL + }, + + { + {"log_filename", CFGCXT_RELOAD, LOGGING_CONFIG, + "log file name pattern.", + CONFIG_VAR_TYPE_STRING, false, 0 + }, + &g_pool_config.log_filename, + "pgpool-%Y-%m-%d_%H%M%S.log", + NULL, NULL, NULL, NULL + }, + /* End-of-list marker */ EMPTY_CONFIG_STRING }; @@ -1026,43 +1436,95 @@ static struct config_string_list ConfigureNamesStringList[] = &g_pool_config.reset_query_list, /* variable */ &g_pool_config.num_reset_queries, /* item count var */ (const char *) default_reset_query_list, /* boot value */ - ";", /* token seperator */ + ";", /* token separator */ false, /* compute_regex ? */ NULL, NULL, NULL /* assign, check, show funcs */ }, { - {"white_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, - "list of functions that does not writes to database.", + {"listen_addresses", CFGCXT_INIT, CONNECTION_CONFIG, + "hostname(s) or IP address(es) on which pgpool will listen on.", CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, - &g_pool_config.white_function_list, - &g_pool_config.num_white_function_list, - NULL, + &g_pool_config.listen_addresses, + &g_pool_config.num_listen_addresses, + (const char *) default_listen_addresses_list, + ",", + false, + NULL, NULL, NULL + }, + + { + {"pcp_listen_addresses", CFGCXT_INIT, CONNECTION_CONFIG, + "hostname(s) or IP address(es) on which pcp will listen on.", + CONFIG_VAR_TYPE_STRING_LIST, false, 0 + }, + &g_pool_config.pcp_listen_addresses, + &g_pool_config.num_pcp_listen_addresses, + (const char *) default_pcp_listen_addresses_list, + ",", + false, + NULL, NULL, NULL + }, + + { + {"unix_socket_directories", CFGCXT_INIT, CONNECTION_CONFIG, + "The directories to create the UNIX domain sockets for accepting pgpool-II client connections.", + CONFIG_VAR_TYPE_STRING_LIST, false, 0 + }, + &g_pool_config.unix_socket_directories, + &g_pool_config.num_unix_socket_directories, + (const char *) default_unix_socket_directories_list, + ",", + false, + NULL, NULL, NULL + }, + + { + {"pcp_socket_dir", CFGCXT_INIT, CONNECTION_CONFIG, + "The directories to create the UNIX domain socket for accepting pgpool-II PCP connections.", + CONFIG_VAR_TYPE_STRING_LIST, false, 0 + }, + &g_pool_config.pcp_socket_dir, + &g_pool_config.num_pcp_socket_directories, + (const char *) default_unix_socket_directories_list, + ",", + false, + NULL, NULL, NULL + }, + + { + {"read_only_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, + "list of functions that does not writes to database.", + CONFIG_VAR_TYPE_STRING_LIST, false, 0 + }, + &g_pool_config.read_only_function_list, + &g_pool_config.num_read_only_function_list, + (const char *) default_read_only_function_list, ",", true, NULL, NULL, NULL }, { - {"black_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, + {"write_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, "list of functions that writes to database.", CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, - &g_pool_config.black_function_list, - &g_pool_config.num_black_function_list, - (const char *) default_black_function_list, + &g_pool_config.write_function_list, + &g_pool_config.num_write_function_list, + (const char *) default_write_function_list, ",", true, NULL, NULL, NULL }, { - {"white_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG, + {"cache_safe_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG, "list of tables to be cached.", CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, - &g_pool_config.white_memqcache_table_list, - &g_pool_config.num_white_memqcache_table_list, + &g_pool_config.cache_safe_memqcache_table_list, + &g_pool_config.num_cache_safe_memqcache_table_list, NULL, ",", true, @@ -1070,12 +1532,12 @@ static struct config_string_list ConfigureNamesStringList[] = }, { - {"black_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG, + {"cache_unsafe_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG, "list of tables should not be cached.", CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, - &g_pool_config.black_memqcache_table_list, - &g_pool_config.num_black_memqcache_table_list, + &g_pool_config.cache_unsafe_memqcache_table_list, + &g_pool_config.num_cache_unsafe_memqcache_table_list, NULL, ",", true, @@ -1083,12 +1545,12 @@ static struct config_string_list ConfigureNamesStringList[] = }, { - {"black_query_pattern_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, + {"primary_routing_query_pattern_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, "list of query patterns that should be sent to primary node.", CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, - &g_pool_config.black_query_pattern_list, - &g_pool_config.num_black_query_pattern_list, + &g_pool_config.primary_routing_query_pattern_list, + &g_pool_config.num_primary_routing_query_pattern_list, NULL, ";", true, @@ -1117,8 +1579,8 @@ static struct config_long ConfigureNamesLong[] = { { {"delay_threshold", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, - "standby delay threshold.", - CONFIG_VAR_TYPE_LONG, false, 0 + "standby delay threshold in bytes.", + CONFIG_VAR_TYPE_LONG, false, GUC_UNIT_BYTE }, &g_pool_config.delay_threshold, 0, @@ -1129,7 +1591,7 @@ static struct config_long ConfigureNamesLong[] = { {"relcache_expire", CFGCXT_INIT, CACHE_CONFIG, "Relation cache expiration time in seconds.", - CONFIG_VAR_TYPE_LONG, false, 0 + CONFIG_VAR_TYPE_LONG, false, GUC_UNIT_S }, &g_pool_config.relcache_expire, 0, @@ -1140,7 +1602,7 @@ static struct config_long ConfigureNamesLong[] = { {"memqcache_total_size", CFGCXT_INIT, CACHE_CONFIG, "Total memory size in bytes for storing memory cache.", - CONFIG_VAR_TYPE_LONG, false, 0 + CONFIG_VAR_TYPE_LONG, false, GUC_UNIT_BYTE }, &g_pool_config.memqcache_total_size, (int64) 67108864, @@ -1169,8 +1631,8 @@ static struct config_int_array ConfigureNamesIntArray[] = }, { - {"heartbeat_destination_port", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, - "Destination port for sending heartbeat.", + {"heartbeat_port", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, + "Port for sending heartbeat.", CONFIG_VAR_TYPE_INT_ARRAY, true, 0, WD_MAX_IF_NUM }, NULL, @@ -1181,7 +1643,7 @@ static struct config_int_array ConfigureNamesIntArray[] = }, { - {"other_wd_port", CFGCXT_RELOAD, WATCHDOG_CONFIG, + {"wd_port", CFGCXT_RELOAD, WATCHDOG_CONFIG, "tcp/ip watchdog port number of other pgpool node for watchdog connection..", CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_WATCHDOG_NUM }, @@ -1193,7 +1655,7 @@ static struct config_int_array ConfigureNamesIntArray[] = }, { - {"other_pgpool_port", CFGCXT_RELOAD, WATCHDOG_CONFIG, + {"pgpool_port", CFGCXT_RELOAD, WATCHDOG_CONFIG, "tcp/ip pgpool port number of other pgpool node for watchdog connection.", CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_WATCHDOG_NUM }, @@ -1207,7 +1669,7 @@ static struct config_int_array ConfigureNamesIntArray[] = { {"health_check_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Backend node health check timeout value in seconds.", - CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, GUC_UNIT_S, MAX_NUM_BACKENDS }, NULL, 20, @@ -1228,7 +1690,7 @@ static struct config_int_array ConfigureNamesIntArray[] = { {"health_check_period", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Time interval in seconds between the health checks.", - CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, GUC_UNIT_S, MAX_NUM_BACKENDS }, NULL, 0, @@ -1270,7 +1732,7 @@ static struct config_int_array ConfigureNamesIntArray[] = { {"health_check_retry_delay", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "The amount of time in seconds to wait between failed health check retries.", - CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, GUC_UNIT_S, MAX_NUM_BACKENDS }, NULL, 1, @@ -1291,7 +1753,7 @@ static struct config_int_array ConfigureNamesIntArray[] = { {"connect_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Timeout in milliseconds before giving up connecting to backend.", - CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, GUC_UNIT_MS, MAX_NUM_BACKENDS }, NULL, 10000, @@ -1316,6 +1778,19 @@ static struct config_int_array ConfigureNamesIntArray[] = static struct config_double ConfigureNamesDouble[] = { + { + {"track_table_mutation_ttl_factor", + CFGCXT_RELOAD, LOAD_BALANCE_CONFIG, + "TTL multiplier for track table mutation " + "(TTL = replication_delay * factor)", + CONFIG_VAR_TYPE_DOUBLE, false, 0 + }, + &g_pool_config.track_table_mutation_ttl_factor, + 5.0, /* boot value: 5x replication delay */ + 1.0, 100.0, /* min, max */ + NULL, NULL, NULL + }, + /* End-of-list marker */ EMPTY_CONFIG_DOUBLE }; @@ -1364,6 +1839,17 @@ static struct config_string_array ConfigureNamesStringArray[] = BackendDataDirAssignFunc, NULL, BackendDataDirShowFunc, BackendSlotEmptyCheckFunc }, + { + {"backend_application_name", CFGCXT_RELOAD, CONNECTION_CONFIG, + "application_name of the backend.", + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS + }, + NULL, + "", + EMPTY_CONFIG_STRING, + BackendAppNameAssignFunc, NULL, BackendAppNameShowFunc, BackendSlotEmptyCheckFunc + }, + { {"backend_flag", CFGCXT_RELOAD, CONNECTION_CONFIG, "Controls various backend behavior.", @@ -1376,30 +1862,46 @@ static struct config_string_array ConfigureNamesStringArray[] = }, { + /* + * There are two entries of "backend_flag" for "ALLOW_TO_FAILOVER" and + * "ALWAYS_PRIMARY". This is mostly ok but "pgpool show all" command + * displayed both backend_flag entries, which looks redundant. The + * reason for this is, report_all_variables() shows grouped variables + * first then other variables except already shown as grouped + * variables. Unfortunately build_variable groups() is not smart + * enough to build grouped variable data: it only registers the first + * backend_flag entry and leaves the second entry. since the second + * entry is not a grouped variable, backend_flag is shown firstly as a + * grouped variable and then is show as a non grouped variable in + * report_all_variables(). To fix this, mark that the second variable + * is also a grouped variable (the flag is set by + * build_config_variables()). See bug 728 for the report of the + * problem. + */ {"backend_flag", CFGCXT_RELOAD, CONNECTION_CONFIG, "Controls various backend behavior.", - CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, VAR_PART_OF_GROUP, MAX_NUM_BACKENDS }, NULL, - "ALWAYS_MASTER", + "", /* for ALWAYS_PRIMARY */ EMPTY_CONFIG_STRING, BackendFlagsAssignFunc, NULL, BackendFlagsShowFunc, BackendSlotEmptyCheckFunc }, { - {"heartbeat_destination", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, - "destination host for sending heartbeat signal.", + {"heartbeat_hostname", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, + "Hostname for sending heartbeat signal.", CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, WD_MAX_IF_NUM }, NULL, "", EMPTY_CONFIG_STRING, - HBDestinationAssignFunc, NULL, HBDestinationShowFunc, WdIFSlotEmptyCheckFunc + HBHostnameAssignFunc, NULL, HBHostnameShowFunc, WdIFSlotEmptyCheckFunc }, { {"heartbeat_device", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, - "Name of NIC device for sending hearbeat.", + "Name of NIC device for sending heartbeat.", CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, WD_MAX_IF_NUM }, NULL, @@ -1409,8 +1911,8 @@ static struct config_string_array ConfigureNamesStringArray[] = }, { - {"other_pgpool_hostname", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, - "Hostname of other pgpool node for watchdog connection.", + {"hostname", CFGCXT_RELOAD, WATCHDOG_CONFIG, + "Hostname of pgpool node for watchdog connection.", CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_WATCHDOG_NUM }, NULL, @@ -1425,14 +1927,14 @@ static struct config_string_array ConfigureNamesStringArray[] = CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, - "nobody", + "", { {"health_check_user", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default PostgreSQL user name to perform health check on node for which health_check_user[node-id] is not specified.", CONFIG_VAR_TYPE_STRING, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_user, - "nobody", + "", NULL, NULL, NULL, NULL }, HealthCheckUserAssignFunc, NULL, HealthCheckUserShowFunc, BackendSlotEmptyCheckFunc @@ -1508,9 +2010,20 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"unix_socket_permissions", CFGCXT_INIT, CONNECTION_CONFIG, + "The access permissions of the Unix domain sockets.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.unix_socket_permissions, + 0777, + 0000, 0777, + NULL, NULL, UnixSockPermissionsShowFunc + }, + { {"num_init_children", CFGCXT_INIT, CONNECTION_POOL_CONFIG, - "Number of children pre-forked for client connections.", + "Maximim number of child process to handle client connections.", CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.num_init_children, @@ -1519,6 +2032,28 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"min_spare_children", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, + "Minimum number of spare child processes.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.min_spare_children, + 5, + 1, INT_MAX, + NULL, NULL, NULL + }, + + { + {"max_spare_children", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, + "Maximum number of spare child processes.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.max_spare_children, + 10, + 1, INT_MAX, + NULL, NULL, NULL + }, + { {"reserved_connections", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "Number of reserved connections.", @@ -1536,7 +2071,7 @@ static struct config_int ConfigureNamesInt[] = CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.listen_backlog_multiplier, - 32, + 2, 1, INT_MAX, NULL, NULL, NULL }, @@ -1544,7 +2079,7 @@ static struct config_int ConfigureNamesInt[] = { {"child_life_time", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "pgpool-II child process life time in seconds.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.child_life_time, 300, @@ -1555,7 +2090,7 @@ static struct config_int ConfigureNamesInt[] = { {"client_idle_limit", CFGCXT_SESSION, CONNECTION_POOL_CONFIG, "idle time in seconds to disconnects a client.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.client_idle_limit, 0, @@ -1566,7 +2101,7 @@ static struct config_int ConfigureNamesInt[] = { {"connection_life_time", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "Cached connections expiration time in seconds.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.connection_life_time, 0, @@ -1588,10 +2123,10 @@ static struct config_int ConfigureNamesInt[] = { {"authentication_timeout", CFGCXT_INIT, CONNECTION_CONFIG, "Time out value in seconds for client authentication.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.authentication_timeout, - 0, + 60, 0, INT_MAX, NULL, NULL, NULL }, @@ -1610,10 +2145,10 @@ static struct config_int ConfigureNamesInt[] = { {"sr_check_period", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, "Time interval in seconds between the streaming replication delay checks.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.sr_check_period, - 0, + 10, 0, INT_MAX, NULL, NULL, NULL }, @@ -1621,7 +2156,7 @@ static struct config_int ConfigureNamesInt[] = { {"recovery_timeout", CFGCXT_RELOAD, RECOVERY_CONFIG, "Maximum time in seconds to wait for the recovering PostgreSQL node.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.recovery_timeout, 90, @@ -1632,7 +2167,7 @@ static struct config_int ConfigureNamesInt[] = { {"client_idle_limit_in_recovery", CFGCXT_SESSION, RECOVERY_CONFIG, "Time limit is seconds for the child connection, before it is terminated during the 2nd stage recovery.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.client_idle_limit_in_recovery, 0, @@ -1643,7 +2178,7 @@ static struct config_int ConfigureNamesInt[] = { {"search_primary_node_timeout", CFGCXT_RELOAD, FAILOVER_CONFIG, "Max time in seconds to search for primary node after failover.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.search_primary_node_timeout, 300, @@ -1651,17 +2186,6 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, - { - {"wd_port", CFGCXT_INIT, WATCHDOG_CONFIG, - "tcp/IP port number on which watchdog of process of pgpool will listen on.", - CONFIG_VAR_TYPE_INT, false, 0 - }, - &g_pool_config.wd_port, - 9000, - 1024, INT_MAX, - NULL, NULL, NULL - }, - { {"wd_priority", CFGCXT_INIT, WATCHDOG_CONFIG, "Watchdog node priority for leader election.", @@ -1676,40 +2200,49 @@ static struct config_int ConfigureNamesInt[] = { {"wd_interval", CFGCXT_INIT, WATCHDOG_CONFIG, "Time interval in seconds between life check.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.wd_interval, 10, 0, INT_MAX, NULL, NULL, NULL }, - { - {"wd_life_point", CFGCXT_INIT, WATCHDOG_CONFIG, - "Maximum number of retries before failing the life check.", - CONFIG_VAR_TYPE_INT, false, 0 + {"wd_lost_node_removal_timeout", CFGCXT_RELOAD, WATCHDOG_CONFIG, + "Timeout in seconds to revoke the cluster membership of LOST watchdog nodes.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, - &g_pool_config.wd_life_point, - 3, + &g_pool_config.wd_lost_node_removal_timeout, + 0, + 0, INT_MAX, + NULL, NULL, NULL + }, + { + {"wd_no_show_node_removal_timeout", CFGCXT_RELOAD, WATCHDOG_CONFIG, + "Timeout in seconds to revoke the cluster membership of NO-SHOW watchdog nodes.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S + }, + &g_pool_config.wd_no_show_node_removal_timeout, + 0, 0, INT_MAX, NULL, NULL, NULL }, { - {"wd_heartbeat_port", CFGCXT_INIT, WATCHDOG_CONFIG, - "Port number for receiving heartbeat signal.", + {"wd_life_point", CFGCXT_INIT, WATCHDOG_CONFIG, + "Maximum number of retries before failing the life check.", CONFIG_VAR_TYPE_INT, false, 0 }, - &g_pool_config.wd_heartbeat_port, - 9694, - 1024, 65535, + &g_pool_config.wd_life_point, + 3, + 0, INT_MAX, NULL, NULL, NULL }, { {"wd_heartbeat_keepalive", CFGCXT_INIT, WATCHDOG_CONFIG, - "Time interval in seconds between sending the heartbeat siganl.", - CONFIG_VAR_TYPE_INT, false, 0 + "Time interval in seconds between sending the heartbeat signal.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.wd_heartbeat_keepalive, 2, @@ -1719,8 +2252,8 @@ static struct config_int ConfigureNamesInt[] = { {"wd_heartbeat_deadtime", CFGCXT_INIT, WATCHDOG_CONFIG, - "Deadtime interval in seconds for heartbeat siganl.", - CONFIG_VAR_TYPE_INT, false, 0 + "Deadtime interval in seconds for heartbeat signal.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.wd_heartbeat_deadtime, 30, @@ -1728,6 +2261,28 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"wd_listen_port", CFGCXT_INIT, WATCHDOG_CONFIG, + "tcp/IP port number which watchdog will listen on.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.wd_listen_port, + 0, + 1024, 65535, + NULL, NULL, NULL + }, + + { + {"wd_heartbeat_listen_port", CFGCXT_INIT, WATCHDOG_LIFECHECK, + "tcp/IP port number which heartbeat will listen on.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.wd_heartbeat_listen_port, + 0, + 0, INT_MAX, + NULL, NULL, NULL + }, + { {"relcache_size", CFGCXT_INIT, CACHE_CONFIG, "Number of relation cache entry.", @@ -1764,7 +2319,7 @@ static struct config_int ConfigureNamesInt[] = { {"memqcache_expire", CFGCXT_INIT, CACHE_CONFIG, "Memory cache entry life time specified in seconds.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S }, &g_pool_config.memqcache_expire, 0, @@ -1775,7 +2330,7 @@ static struct config_int ConfigureNamesInt[] = { {"memqcache_maxcache", CFGCXT_INIT, CACHE_CONFIG, "Maximum SELECT result size in bytes.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_BYTE }, &g_pool_config.memqcache_maxcache, 409600, @@ -1786,7 +2341,7 @@ static struct config_int ConfigureNamesInt[] = { {"memqcache_cache_block_size", CFGCXT_INIT, CACHE_CONFIG, "Cache block size in bytes.", - CONFIG_VAR_TYPE_INT, false, 0 + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_BYTE }, &g_pool_config.memqcache_cache_block_size, 1048576, @@ -1794,6 +2349,119 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"auto_failback_interval", CFGCXT_RELOAD, FAILOVER_CONFIG, + "min interval of executing auto_failback in seconds", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_S + }, + &g_pool_config.auto_failback_interval, + 60, + 0, INT_MAX, + NULL, NULL, NULL + }, + { + {"log_rotation_age", CFGCXT_RELOAD, LOGGING_CONFIG, + "Automatic rotation of logfiles will happen after that (minutes) time.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_MIN + }, + &g_pool_config.log_rotation_age, + 1440, /* 1 day */ + 0, INT_MAX, + NULL, NULL, NULL + }, + { + {"log_rotation_size", CFGCXT_RELOAD, LOGGING_CONFIG, + "Automatic rotation of logfiles will happen after that much (kilobytes) log output.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_KB + }, + &g_pool_config.log_rotation_size, + 10 * 1024, + 0, INT_MAX / 1024, + NULL, NULL, NULL + }, + { + {"log_file_mode", CFGCXT_RELOAD, LOGGING_CONFIG, + "creation mode for log files.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.log_file_mode, + 0600, + 0, INT_MAX, + NULL, NULL, NULL + }, + { + {"delay_threshold_by_time", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, + "standby delay threshold by time.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_MS, + }, + &g_pool_config.delay_threshold_by_time, + 0, + 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"replication_delay_source_timeout", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, + "Timeout for external replication delay command execution in seconds.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.replication_delay_source_timeout, + 10, + 1, 3600, + NULL, NULL, NULL + }, + + { + {"track_table_mutation_max_staleness", + CFGCXT_RELOAD, LOAD_BALANCE_CONFIG, + "Maximum duration in milliseconds that a " + "table can be marked stale from its first " + "write. 0 disables the cap.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_MS + }, + &g_pool_config.track_table_mutation_max_staleness, + 60000, /* 60 seconds */ + 0, 3600000, /* 0 to 1 hour */ + NULL, NULL, NULL + }, + + { + {"track_table_mutation_cold_start_duration", + CFGCXT_RELOAD, LOAD_BALANCE_CONFIG, + "Duration in milliseconds to force queries " + "to primary after child process starts.", + CONFIG_VAR_TYPE_INT, false, GUC_UNIT_MS + }, + &g_pool_config.track_table_mutation_cold_start_duration, + 2000, /* 2 seconds */ + 0, 60000, /* 0 to 60 seconds */ + NULL, NULL, NULL + }, + + { + {"track_table_mutation_table_buckets", + CFGCXT_INIT, LOAD_BALANCE_CONFIG, + "Number of hash buckets for track table mutation.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.track_table_mutation_table_buckets, + 1024, + 64, 65536, + NULL, NULL, NULL + }, + + { + {"track_table_mutation_table_size", + CFGCXT_INIT, LOAD_BALANCE_CONFIG, + "Maximum number of entries in track table mutation.", + CONFIG_VAR_TYPE_INT, false, 0 + }, + &g_pool_config.track_table_mutation_table_size, + 2048, + 128, 131072, + NULL, NULL, NULL + }, + /* End-of-list marker */ EMPTY_CONFIG_INT }; @@ -1801,8 +2469,41 @@ static struct config_int ConfigureNamesInt[] = static struct config_enum ConfigureNamesEnum[] = { { - {"syslog_facility", CFGCXT_RELOAD, LOGING_CONFIG, - "syslog local faclity.", + {"backend_clustering_mode", CFGCXT_INIT, MAIN_REPLICA_CONFIG, + "backend clustering mode.", + CONFIG_VAR_TYPE_ENUM, false, 0 + }, + (int *) &g_pool_config.backend_clustering_mode, + CM_STREAMING_REPLICATION, + backend_clustering_mode_options, + NULL, NULL, NULL, NULL + }, + + { + {"process_management_mode", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, + "child process management mode.", + CONFIG_VAR_TYPE_ENUM, false, 0 + }, + (int *) &g_pool_config.process_management, + PM_STATIC, + process_management_mode_options, + NULL, NULL, NULL, NULL + }, + + { + {"process_management_strategy", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, + "child process management strategy.", + CONFIG_VAR_TYPE_ENUM, false, 0 + }, + (int *) &g_pool_config.process_management_strategy, + PM_STRATEGY_GENTLE, + process_management_strategy_options, + NULL, NULL, NULL, NULL + }, + + { + {"syslog_facility", CFGCXT_RELOAD, LOGGING_CONFIG, + "syslog local facility.", CONFIG_VAR_TYPE_ENUM, false, 0 }, &g_pool_config.syslog_facility, @@ -1814,7 +2515,7 @@ static struct config_enum ConfigureNamesEnum[] = }, { - {"log_error_verbosity", CFGCXT_SESSION, LOGING_CONFIG, + {"log_error_verbosity", CFGCXT_SESSION, LOGGING_CONFIG, "How much details about error should be emitted.", CONFIG_VAR_TYPE_ENUM, false, 0 }, @@ -1825,7 +2526,7 @@ static struct config_enum ConfigureNamesEnum[] = }, { - {"client_min_messages", CFGCXT_SESSION, LOGING_CONFIG, + {"client_min_messages", CFGCXT_SESSION, LOGGING_CONFIG, "Which messages should be sent to client.", CONFIG_VAR_TYPE_ENUM, false, 0 }, @@ -1836,7 +2537,7 @@ static struct config_enum ConfigureNamesEnum[] = }, { - {"log_min_messages", CFGCXT_SESSION, LOGING_CONFIG, + {"log_min_messages", CFGCXT_SESSION, LOGGING_CONFIG, "Which messages should be emitted to server log.", CONFIG_VAR_TYPE_ENUM, false, 0 }, @@ -1847,24 +2548,24 @@ static struct config_enum ConfigureNamesEnum[] = }, { - {"master_slave_sub_mode", CFGCXT_INIT, MASTER_SLAVE_CONFIG, - "master/slave sub mode.", + {"log_standby_delay", CFGCXT_RELOAD, MAIN_REPLICA_CONFIG, + "When to log standby delay.", CONFIG_VAR_TYPE_ENUM, false, 0 }, - (int *) &g_pool_config.master_slave_sub_mode, - STREAM_MODE, - master_slave_sub_mode_options, + (int *) &g_pool_config.log_standby_delay, + LSD_OVER_THRESHOLD, + log_standby_delay_options, NULL, NULL, NULL, NULL }, { - {"log_standby_delay", CFGCXT_RELOAD, MASTER_SLAVE_CONFIG, - "When to log standby delay.", + {"log_backend_messages", CFGCXT_SESSION, LOGGING_CONFIG, + "Logs any backend messages in the pgpool logs.", CONFIG_VAR_TYPE_ENUM, false, 0 }, - (int *) &g_pool_config.log_standby_delay, - LSD_NONE, - log_standby_delay_options, + &g_pool_config.log_backend_messages, + BGMSG_NONE, + log_backend_messages_options, NULL, NULL, NULL, NULL }, @@ -1901,6 +2602,28 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL, NULL }, + { + {"relcache_query_target", CFGCXT_RELOAD, LOAD_BALANCE_CONFIG, + "Target node to send relache queries.", + CONFIG_VAR_TYPE_ENUM, false, 0 + }, + (int *) &g_pool_config.relcache_query_target, + RELQTARGET_PRIMARY, + relcache_query_target_options, + NULL, NULL, NULL, NULL + }, + + { + {"check_temp_table", CFGCXT_RELOAD, GENERAL_CONFIG, + "Enables temporary table check.", + CONFIG_VAR_TYPE_BOOL, false, 0 + }, + (int *) &g_pool_config.check_temp_table, + CHECK_TEMP_CATALOG, + check_temp_table_options, + NULL, NULL, NULL, NULL + }, + /* End-of-list marker */ EMPTY_CONFIG_ENUM }; @@ -1917,7 +2640,7 @@ static struct config_grouped_array_var ConfigureVarGroups[] = NULL }, { - {"other_pgpool", CFGCXT_BOOT, WATCHDOG_CONFIG, + {"watchdog", CFGCXT_BOOT, WATCHDOG_CONFIG, "watchdog nodes configuration group.", CONFIG_VAR_TYPE_GROUP, false, 0 }, @@ -2145,7 +2868,7 @@ build_variable_groups(void) { /* we build these by hand */ /* group 1. Backend config vars */ - ConfigureVarGroups[0].var_count = 5; + ConfigureVarGroups[0].var_count = 6; ConfigureVarGroups[0].var_list = palloc0(sizeof(struct config_generic *) * ConfigureVarGroups[0].var_count); ConfigureVarGroups[0].var_list[0] = find_option("backend_hostname", FATAL); ConfigureVarGroups[0].var_list[0]->flags |= VAR_PART_OF_GROUP; @@ -2155,19 +2878,21 @@ build_variable_groups(void) ConfigureVarGroups[0].var_list[2]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[0].var_list[3] = find_option("backend_data_directory", FATAL); ConfigureVarGroups[0].var_list[3]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[0].var_list[4] = find_option("backend_flag", FATAL); + ConfigureVarGroups[0].var_list[4] = find_option("backend_application_name", FATAL); ConfigureVarGroups[0].var_list[4]->flags |= VAR_PART_OF_GROUP; + ConfigureVarGroups[0].var_list[5] = find_option("backend_flag", FATAL); + ConfigureVarGroups[0].var_list[5]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[0].gen.max_elements = ConfigureVarGroups[0].var_list[0]->max_elements; /* group 2. other_pgpool config vars */ ConfigureVarGroups[1].var_count = 3; ConfigureVarGroups[1].var_list = palloc0(sizeof(struct config_generic *) * ConfigureVarGroups[1].var_count); /* backend hostname */ - ConfigureVarGroups[1].var_list[0] = find_option("other_pgpool_hostname", FATAL); + ConfigureVarGroups[1].var_list[0] = find_option("hostname", FATAL); ConfigureVarGroups[1].var_list[0]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[1].var_list[1] = find_option("other_pgpool_port", FATAL); + ConfigureVarGroups[1].var_list[1] = find_option("pgpool_port", FATAL); ConfigureVarGroups[1].var_list[1]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[1].var_list[2] = find_option("other_wd_port", FATAL); + ConfigureVarGroups[1].var_list[2] = find_option("wd_port", FATAL); ConfigureVarGroups[1].var_list[2]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[1].gen.max_elements = ConfigureVarGroups[1].var_list[0]->max_elements; @@ -2178,9 +2903,9 @@ build_variable_groups(void) /* backend hostname */ ConfigureVarGroups[2].var_list[0] = find_option("heartbeat_device", FATAL); ConfigureVarGroups[2].var_list[0]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[2].var_list[1] = find_option("heartbeat_destination", FATAL); + ConfigureVarGroups[2].var_list[1] = find_option("heartbeat_hostname", FATAL); ConfigureVarGroups[2].var_list[1]->flags |= VAR_PART_OF_GROUP; - ConfigureVarGroups[2].var_list[2] = find_option("heartbeat_destination_port", FATAL); + ConfigureVarGroups[2].var_list[2] = find_option("heartbeat_port", FATAL); ConfigureVarGroups[2].var_list[2]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[2].gen.max_elements = ConfigureVarGroups[2].var_list[0]->max_elements; @@ -2465,13 +3190,13 @@ initialize_variables_with_default(struct config_generic *gconf) } else { - if (strcmp(gconf->name, "black_query_pattern_list") == 0) + if (strcmp(gconf->name, "primary_routing_query_pattern_list") == 0) { - *conf->variable = get_list_from_string_regex_delim(newval, conf->seperator, conf->list_elements_count); + *conf->variable = get_list_from_string_regex_delim(newval, conf->separator, conf->list_elements_count); } else { - *conf->variable = get_list_from_string(newval, conf->seperator, conf->list_elements_count); + *conf->variable = get_list_from_string(newval, conf->separator, conf->list_elements_count); } if (conf->compute_regex) @@ -2523,6 +3248,20 @@ get_list_from_string(const char *str, const char *delimi, int *n) for (token = strtok(temp_string, delimi); token != NULL; token = strtok(NULL, delimi)) { + int i; + + /* skip leading whitespace */ + while (isspace(*token)) + token++; + + /* skip trailing whitespace */ + i = strlen(token) - 1; + while (i >= 0 && isspace(token[i])) + { + token[i] = '\0'; + i--; + } + tokens[*n] = pstrdup(token); ereport(DEBUG3, (errmsg("initializing pool configuration"), @@ -2554,7 +3293,6 @@ get_list_from_string_regex_delim(const char *input, const char *delimi, int *n) { #ifndef POOL_PRIVATE int j = 0; - char *output; char *str; char *buf, *str_temp; @@ -2591,12 +3329,13 @@ get_list_from_string_regex_delim(const char *input, const char *delimi, int *n) } else if (*str_temp == *delimi) { - output = (char *) palloc(j + 1); + char *output = (char *) palloc(j + 1); + StrNCpy(output, buf, j + 1); /* replace escape character of "'" */ tokens[*n] = string_replace(output, "\\'", "'"); - + pfree(output); ereport(DEBUG3, (errmsg("initializing pool configuration"), errdetail("extracting string tokens [token[%d]: %s]", *n, tokens[*n]))); @@ -2627,7 +3366,7 @@ get_list_from_string_regex_delim(const char *input, const char *delimi, int *n) } /* - * Memory of the array type variables must be initialized befor calling this function + * Memory of the array type variables must be initialized before calling this function */ void InitializeConfigOptions(void) @@ -2658,7 +3397,7 @@ InitializeConfigOptions(void) /* * returns the index value postfixed with the variable name * for example if the if name contains "backend_hostname11" and - * the record name must be for the variable nameed "backend_hostname" + * the record name must be for the variable named "backend_hostname" * if the index is not present at end of the name the function * will return true and out parameter index will be assigned with -ve value */ @@ -2709,7 +3448,7 @@ find_option(const char *name, int elevel) /* * For dynamic array type vars the key also have the index at the - * end e.g. backend_hostname0 so we only comapare the key's name + * end e.g. backend_hostname0 so we only compare the key's name * part */ if (!strncmp(gconf->name, name, index_start_index)) @@ -3047,7 +3786,19 @@ setConfigOptionVar(struct config_generic *record, const char *name, int index_va if (value != NULL) { - newval = atoi(value); + int64 newval64; + const char *hintmsg; + + if (!parse_int(value, &newval64, + conf->gen.flags, &hintmsg, INT_MAX)) + { + ereport(elevel, + (errmsg("invalid value for parameter \"%s\": \"%s\"", + name, value), + hintmsg ? errhint("%s", _(hintmsg)) : 0)); + return false; + } + newval = (int) newval64; } else if (source == PGC_S_DEFAULT) { @@ -3145,7 +3896,19 @@ setConfigOptionVar(struct config_generic *record, const char *name, int index_va if (value != NULL) { - newval = atoi(value); + int64 newval64; + const char *hintmsg; + + if (!parse_int(value, &newval64, + conf->gen.flags, &hintmsg, INT_MAX)) + { + ereport(elevel, + (errmsg("invalid value for parameter \"%s\": \"%s\"", + name, value), + hintmsg ? errhint("%s", _(hintmsg)) : 0)); + return false; + } + newval = (int) newval64; } else if (source == PGC_S_DEFAULT) { @@ -3245,10 +4008,20 @@ setConfigOptionVar(struct config_generic *record, const char *name, int index_va if (value != NULL) { - newval = pool_atoi64(value); - } - else if (source == PGC_S_DEFAULT) - { + const char *hintmsg; + + if (!parse_int(value, &newval, + conf->gen.flags, &hintmsg, conf->max)) + { + ereport(elevel, + (errmsg("invalid value for parameter \"%s\": \"%s\"", + name, value), + hintmsg ? errhint("%s", _(hintmsg)) : 0)); + return false; + } + } + else if (source == PGC_S_DEFAULT) + { newval = conf->boot_val; } else @@ -3422,13 +4195,13 @@ setConfigOptionVar(struct config_generic *record, const char *name, int index_va pfree(*conf->variable); } - if (strcmp(name, "black_query_pattern_list") == 0) + if (strcmp(name, "primary_routing_query_pattern_list") == 0) { - *conf->variable = get_list_from_string_regex_delim(newval, conf->seperator, conf->list_elements_count); + *conf->variable = get_list_from_string_regex_delim(newval, conf->separator, conf->list_elements_count); } else { - *conf->variable = get_list_from_string(newval, conf->seperator, conf->list_elements_count); + *conf->variable = get_list_from_string(newval, conf->separator, conf->list_elements_count); } if (conf->compute_regex) @@ -3690,24 +4463,16 @@ static bool BackendFlagsAssignFunc(ConfigContext context, char *newval, int index, int elevel) { - unsigned short flag = 0; + unsigned short flag; int i, n; bool allow_to_failover_is_specified = false; bool disallow_to_failover_is_specified = false; char **flags; - flags = get_list_from_string(newval, "|", &n); - if (!flags || n < 0) - { - if (flags) - pfree(flags); + flag = g_pool_config.backend_desc->backend_info[index].flag; - ereport(elevel, - (errmsg("invalid configuration for key \"backend_flag%d\"", index), - errdetail("unable to get backend flags"))); - return false; - } + flags = get_list_from_string(newval, "|", &n); for (i = 0; i < n; i++) { @@ -3747,9 +4512,9 @@ BackendFlagsAssignFunc(ConfigContext context, char *newval, int index, int eleve disallow_to_failover_is_specified = true; } - else if ((!strcmp(flags[i], "ALWAYS_MASTER"))) + else if ((!strcmp(flags[i], "ALWAYS_PRIMARY"))) { - flag |= POOL_ALWAYS_MASTER; + flag |= POOL_ALWAYS_PRIMARY; } else @@ -3768,7 +4533,18 @@ BackendFlagsAssignFunc(ConfigContext context, char *newval, int index, int eleve g_pool_config.backend_desc->backend_info[index].flag = flag; ereport(DEBUG1, (errmsg("setting \"backend_flag%d\" flag: %04x ", index, flag))); - pfree(flags); + if (flags) + pfree(flags); + return true; +} + +static bool +BackendAppNameAssignFunc(ConfigContext context, char *newval, int index, int elevel) +{ + if (newval == NULL || strlen(newval) == 0) + g_pool_config.backend_desc->backend_info[index].backend_application_name[0] = '\0'; + else + strlcpy(g_pool_config.backend_desc->backend_info[index].backend_application_name, newval, NAMEDATALEN - 1); return true; } @@ -3861,6 +4637,21 @@ IntValueShowFunc(int value) return buffer; } +static const char * +FilePermissionShowFunc(int value) +{ + static char buffer[10]; + + snprintf(buffer, sizeof(buffer), "%04o", value); + return buffer; +} + +static const char * +UnixSockPermissionsShowFunc(void) +{ + return FilePermissionShowFunc(g_pool_config.unix_socket_permissions); +} + static const char * BackendWeightShowFunc(int index) { @@ -3888,15 +4679,15 @@ BackendDataDirShowFunc(int index) static const char * BackendFlagsShowFunc(int index) { - static char buffer[21]; - unsigned short flag = g_pool_config.backend_desc->backend_info[index].flag; - if (POOL_ALLOW_TO_FAILOVER(flag)) - snprintf(buffer, sizeof(buffer), "ALLOW_TO_FAILOVER"); - else if (POOL_DISALLOW_TO_FAILOVER(flag)) - snprintf(buffer, sizeof(buffer), "DISALLOW_TO_FAILOVER"); - return buffer; + return pool_flag_to_str(flag); +} + +static const char * +BackendAppNameShowFunc(int index) +{ + return g_pool_config.backend_desc->backend_info[index].backend_application_name; } static bool @@ -3908,50 +4699,49 @@ BackendSlotEmptyCheckFunc(int index) static bool WdSlotEmptyCheckFunc(int index) { - return (g_pool_config.wd_remote_nodes.wd_remote_node_info[index].pgpool_port == 0); + return (g_pool_config.wd_nodes.wd_node_info[index].pgpool_port == 0); } static bool WdIFSlotEmptyCheckFunc(int index) { - - return (index >= g_pool_config.num_hb_if); + return (g_pool_config.hb_ifs[index].dest_port == 0); } static const char * OtherPPHostShowFunc(int index) { - return g_pool_config.wd_remote_nodes.wd_remote_node_info[index].hostname; + return g_pool_config.wd_nodes.wd_node_info[index].hostname; } static const char * OtherPPPortShowFunc(int index) { - return IntValueShowFunc(g_pool_config.wd_remote_nodes.wd_remote_node_info[index].pgpool_port); + return IntValueShowFunc(g_pool_config.wd_nodes.wd_node_info[index].pgpool_port); } static const char * OtherWDPortShowFunc(int index) { - return IntValueShowFunc(g_pool_config.wd_remote_nodes.wd_remote_node_info[index].wd_port); + return IntValueShowFunc(g_pool_config.wd_nodes.wd_node_info[index].wd_port); } static const char * HBDeviceShowFunc(int index) { - return g_pool_config.hb_if[index].if_name; + return g_pool_config.hb_ifs[index].if_name; } static const char * -HBDestinationShowFunc(int index) +HBHostnameShowFunc(int index) { - return g_pool_config.hb_if[index].addr; + return g_pool_config.hb_ifs[index].addr; } static const char * HBDestinationPortShowFunc(int index) { - return IntValueShowFunc(g_pool_config.hb_if[index].dest_port); + return IntValueShowFunc(g_pool_config.hb_ifs[index].dest_port); } static const char * @@ -4075,31 +4865,31 @@ HealthCheckDatabaseAssignFunc(ConfigContext context, char *newval, int index, in return true; } -/* Watchdog Assign functions */ -/*other_pgpool_hostname*/ +/* Watchdog hostname and heartbeat hostname assign functions */ +/* hostname */ static bool OtherPPHostAssignFunc(ConfigContext context, char *newval, int index, int elevel) { if (newval == NULL || strlen(newval) == 0) - g_pool_config.wd_remote_nodes.wd_remote_node_info[index].hostname[0] = '\0'; + g_pool_config.wd_nodes.wd_node_info[index].hostname[0] = '\0'; else - strlcpy(g_pool_config.wd_remote_nodes.wd_remote_node_info[index].hostname, newval, MAX_DB_HOST_NAMELEN - 1); + strlcpy(g_pool_config.wd_nodes.wd_node_info[index].hostname, newval, MAX_DB_HOST_NAMELEN - 1); return true; } -/*other_pgpool_port*/ +/* pgpool_port */ static bool OtherPPPortAssignFunc(ConfigContext context, int newval, int index, int elevel) { - g_pool_config.wd_remote_nodes.wd_remote_node_info[index].pgpool_port = newval; + g_pool_config.wd_nodes.wd_node_info[index].pgpool_port = newval; return true; } -/*other_wd_port*/ +/* wd_port */ static bool OtherWDPortAssignFunc(ConfigContext context, int newval, int index, int elevel) { - g_pool_config.wd_remote_nodes.wd_remote_node_info[index].wd_port = newval; + g_pool_config.wd_nodes.wd_node_info[index].wd_port = newval; return true; } @@ -4108,28 +4898,28 @@ static bool HBDeviceAssignFunc(ConfigContext context, char *newval, int index, int elevel) { if (newval == NULL || strlen(newval) == 0) - g_pool_config.hb_if[index].if_name[0] = '\0'; + g_pool_config.hb_ifs[index].if_name[0] = '\0'; else - strlcpy(g_pool_config.hb_if[index].if_name, newval, WD_MAX_IF_NAME_LEN); + strlcpy(g_pool_config.hb_ifs[index].if_name, newval, WD_MAX_IF_NAME_LEN - 1); return true; } -/*heartbeat_destination*/ +/*heartbeat_hostname*/ static bool -HBDestinationAssignFunc(ConfigContext context, char *newval, int index, int elevel) +HBHostnameAssignFunc(ConfigContext context, char *newval, int index, int elevel) { if (newval == NULL || strlen(newval) == 0) - g_pool_config.hb_if[index].addr[0] = '\0'; + g_pool_config.hb_ifs[index].addr[0] = '\0'; else - strlcpy(g_pool_config.hb_if[index].addr, newval, WD_MAX_HOST_NAMELEN - 1); + strlcpy(g_pool_config.hb_ifs[index].addr, newval, WD_MAX_HOST_NAMELEN - 1); return true; } -/*heartbeat_destination_port*/ +/*heartbeat_port*/ static bool HBDestinationPortAssignFunc(ConfigContext context, int newval, int index, int elevel) { - g_pool_config.hb_if[index].dest_port = newval; + g_pool_config.hb_ifs[index].dest_port = newval; return true; } @@ -4143,10 +4933,53 @@ FailOverOnBackendErrorAssignMessage(ConfigContext scontext, bool newval, int ele if (scontext != CFGCXT_BOOT) ereport(WARNING, (errmsg("fail_over_on_backend_error is changed to failover_on_backend_error"), - errdetail("setting failover_on_backend_error has no effect"), - errhint("use failover_on_backend_error instead"))); + errdetail("if fail_over_on_backend_error is specified, the value will be set to failover_on_backend_error"))); + g_pool_config.failover_on_backend_error = newval; return true; } + +/* + * Throws warning for if someone uses the removed delegate_IP + * configuration parameter and set the value to delegate_ip + */ +static bool +DelegateIPAssignMessage(ConfigContext scontext, char *newval, int elevel) +{ + if (scontext != CFGCXT_BOOT) + ereport(WARNING, + (errmsg("delegate_IP is changed to delegate_ip"), + errdetail("if delegate_IP is specified, the value will be set to delegate_ip"))); + if (g_pool_config.delegate_ip) + pfree(g_pool_config.delegate_ip); + if (newval) + g_pool_config.delegate_ip = pstrdup(newval); + else + g_pool_config.delegate_ip = NULL; + return true; +} + +/* + * Throws warning for if someone uses the removed logdir + * configuration parameter and set the value to work_dir + */ +static bool +LogDirAssignMessage(ConfigContext scontext, char *newval, int elevel) +{ + if (scontext != CFGCXT_BOOT) + ereport(WARNING, + (errmsg("logdir is changed to work_dir"), + errdetail("if logdir is specified, the value will be set to work_dir"))); + + if (newval != NULL && strlen(newval) != 0) + { + if (g_pool_config.work_dir) + pfree(g_pool_config.work_dir); + + g_pool_config.work_dir = pstrdup(newval); + } + return true; +} + /* * Check DB node spec. node spec should be either "primary", "standby" or * numeric DB node id. @@ -4192,9 +5025,12 @@ config_post_processor(ConfigContext context, int elevel) sig_atomic_t local_num_backends = 0; int i; + /* read from pgpool_node_id */ + SetPgpoolNodeId(elevel); + if (context == CFGCXT_BOOT) { - char localhostname[256]; + char localhostname[128]; int res = gethostname(localhostname, sizeof(localhostname)); if (res != 0) @@ -4204,7 +5040,7 @@ config_post_processor(ConfigContext context, int elevel) errdetail("failed to get the local hostname"))); return false; } - g_pool_config.wd_hostname = pstrdup(localhostname); + strcpy(g_pool_config.wd_nodes.wd_node_info[g_pool_config.pgpool_node_id].hostname, localhostname); return true; } for (i = 0; i < MAX_CONNECTION_SLOTS; i++) @@ -4265,23 +5101,29 @@ config_post_processor(ConfigContext context, int elevel) } /* Set the number of configured Watchdog nodes */ - g_pool_config.wd_remote_nodes.num_wd = 0; - for (i = 0; i < MAX_WATCHDOG_NUM; i++) + g_pool_config.wd_nodes.num_wd = 0; + + if (g_pool_config.use_watchdog) { - WdRemoteNodeInfo *wdNode = &g_pool_config.wd_remote_nodes.wd_remote_node_info[i]; + for (i = 0; i < MAX_WATCHDOG_NUM; i++) + { + WdNodeInfo *wdNode = &g_pool_config.wd_nodes.wd_node_info[i]; - if (wdNode->wd_port > 0) - g_pool_config.wd_remote_nodes.num_wd = i + 1; - } + if (i == g_pool_config.pgpool_node_id && wdNode->wd_port <= 0) + { + ereport(elevel, + (errmsg("invalid watchdog configuration"), + errdetail("no watchdog configuration for local pgpool node, pgpool node id: %d ", g_pool_config.pgpool_node_id))); + return false; + } - /* Set the number of configured heartbeat interfaces */ - g_pool_config.num_hb_if = 0; - for (i = 0; i < WD_MAX_IF_NUM; i++) - { - if (g_pool_config.hb_if[i].dest_port > 0) - g_pool_config.num_hb_if = i + 1; + if (wdNode->wd_port > 0) + g_pool_config.wd_nodes.num_wd = i + 1; + } } + /* Set configured heartbeat destination interfaces */ + SetHBDestIfFunc(elevel); if (strcmp(pool_config->recovery_1st_stage_command, "") || strcmp(pool_config->recovery_2nd_stage_command, "")) @@ -4300,9 +5142,131 @@ config_post_processor(ConfigContext context, int elevel) } } + /* + * Quarantine state in native replication mode is dangerous and it can + * potentially cause data inconsistency. So as per the discussions, we + * agreed on disallowing setting failover_when_quorum_exists in native + * replication mode + */ + + if (pool_config->failover_when_quorum_exists && pool_config->replication_mode) + { + pool_config->failover_when_quorum_exists = false; + ereport(elevel, + (errmsg("invalid configuration, failover_when_quorum_exists is not allowed in native replication mode"))); + return false; + } + + /* + * Verify the minimum and maximum number of spare children configuration + * when dynamic process management is enabled + */ + + if (g_pool_config.process_management == PM_DYNAMIC) + { + if (pool_config->min_spare_children >= pool_config->max_spare_children) + { + ereport(elevel, + (errmsg("invalid configuration, max_spare_children:%d must be greater than min_spare_children:%d", + pool_config->max_spare_children, pool_config->min_spare_children))); + return false; + } + if (pool_config->num_init_children < pool_config->max_spare_children) + { + ereport(elevel, + (errmsg("invalid configuration, max_spare_children:%d can't be greater than num_init_children:%d", + pool_config->max_spare_children, pool_config->num_init_children))); + return false; + } + } + return true; +} + +static bool +MakeDMLAdaptiveObjectRelationList(char *newval, int elevel) +{ + int i; + int elements_count = 0; + char **rawList = get_list_from_string(newval, ",", &elements_count); + + if (rawList == NULL || elements_count == 0) + { + pool_config->parsed_dml_adaptive_object_relationship_list = NULL; + return true; + } + pool_config->parsed_dml_adaptive_object_relationship_list = palloc(sizeof(DBObjectRelation) * (elements_count + 1)); + + for (i = 0; i < elements_count; i++) + { + char *kvstr = rawList[i]; + char *left_token = strtok(kvstr, ":"); + char *right_token = strtok(NULL, ":"); + DBObjectTypes object_type; + + ereport(DEBUG5, + (errmsg("dml_adaptive_init"), + errdetail("%s -- left_token[%s] right_token[%s]", kvstr, left_token, right_token))); + + pool_config->parsed_dml_adaptive_object_relationship_list[i].left_token.name = + getParsedToken(left_token, &object_type); + pool_config->parsed_dml_adaptive_object_relationship_list[i].left_token.object_type = object_type; + + pool_config->parsed_dml_adaptive_object_relationship_list[i].right_token.name = + getParsedToken(right_token, &object_type); + pool_config->parsed_dml_adaptive_object_relationship_list[i].right_token.object_type = object_type; + pfree(kvstr); + } + pool_config->parsed_dml_adaptive_object_relationship_list[i].left_token.name = NULL; + pool_config->parsed_dml_adaptive_object_relationship_list[i].left_token.object_type = OBJECT_TYPE_UNKNOWN; + pool_config->parsed_dml_adaptive_object_relationship_list[i].right_token.name = NULL; + pool_config->parsed_dml_adaptive_object_relationship_list[i].right_token.object_type = OBJECT_TYPE_UNKNOWN; + + pfree(rawList); return true; } +/* + * Identify the object type for dml adaptive object + * the function is very primitive and just looks for token + * ending with (). + * We also remove the trailing spaces from the function type token + * and return the palloc'd copy of token in new_token + */ +static char * +getParsedToken(char *token, DBObjectTypes *object_type) +{ + int len; + + *object_type = OBJECT_TYPE_UNKNOWN; + + if (!token) + return NULL; + + len = strlen(token); + if (len > strlen("*()")) + { + int namelen = len - 2; + + /* check if token ends with () */ + if (strcmp(token + namelen, "()") == 0) + { + /* + * Remove the Parentheses from end of token name + */ + char *new_token; + int new_len = strlen(token) - 2; + + new_token = palloc(new_len + 1); + strncpy(new_token, token, new_len); + new_token[new_len] = '\0'; + *object_type = OBJECT_TYPE_FUNCTION; + return new_token; + } + } + *object_type = OBJECT_TYPE_RELATION; + return pstrdup(token); +} + static bool MakeAppRedirectListRegex(char *newval, int elevel) { @@ -4389,6 +5353,261 @@ MakeDBRedirectListRegex(char *newval, int elevel) return true; } +static bool +MakeUserRedirectListRegex(char *newval, int elevel) +{ + /* TODO Deal with the memory */ + int i; + Left_right_tokens *lrtokens; + + if (newval == NULL) + { + pool_config->redirect_usernames = NULL; + pool_config->user_redirect_tokens = NULL; + return true; + } + + lrtokens = create_lrtoken_array(); + extract_string_tokens2(newval, ",", ':', lrtokens); + + pool_config->redirect_usernames = create_regex_array(); + pool_config->user_redirect_tokens = lrtokens; + + for (i = 0; i < lrtokens->pos; i++) + { + if (!check_redirect_node_spec(lrtokens->token[i].right_token)) + { + ereport(elevel, + (errmsg("invalid configuration for key \"user_redirect_preference_list\""), + errdetail("wrong redirect db node spec: \"%s\"", lrtokens->token[i].right_token))); + return false; + } + + if (*(lrtokens->token[i].left_token) == '\0' || + add_regex_array(pool_config->redirect_usernames, lrtokens->token[i].left_token)) + { + ereport(elevel, + (errmsg("invalid configuration for key \"user_redirect_preference_list\""), + errdetail("wrong redirect user name regular expression: \"%s\"", lrtokens->token[i].left_token))); + return false; + } + } + return true; +} + +/* Read the pgpool_node_id file */ +static bool +SetPgpoolNodeId(int elevel) +{ + char pgpool_node_id_file[POOLMAXPATHLEN + 1]; + FILE *fd; + int length; + int i; + + if (g_pool_config.use_watchdog) + { + snprintf(pgpool_node_id_file, sizeof(pgpool_node_id_file), "%s/%s", config_file_dir, NODE_ID_FILE_NAME); + +#define MAXLINE 10 + char readbuf[MAXLINE]; + + fd = fopen(pgpool_node_id_file, "r"); + if (!fd) + { + ereport(elevel, + (errmsg("Pgpool node id file %s does not exist", pgpool_node_id_file), + errdetail("If watchdog is enable, pgpool_node_id file is required"))); + return false; + } + + readbuf[MAXLINE - 1] = '\0'; + if (fgets(readbuf, MAXLINE - 1, fd) == 0) + { + ereport(elevel, + (errmsg("pgpool_node_id file is empty"), + errdetail("If watchdog is enable, we need to specify pgpool node id in %s file", pgpool_node_id_file))); + fclose(fd); + return false; + } + + length = strlen(readbuf); + if (length > 0 && readbuf[length - 1] == '\n') + { + readbuf[length - 1] = '\0'; + + length = strlen(readbuf); + if (length <= 0) + { + ereport(elevel, + (errmsg("pgpool_node_id file is empty"), + errdetail("If watchdog is enable, we need to specify pgpool node id in %s file", pgpool_node_id_file))); + fclose(fd); + return false; + } + } + + for (i = 0; i < length; i++) + { + if (!isdigit((int) readbuf[i])) + { + ereport(elevel, + (errmsg("pgpool_node_id is not a numeric value"), + errdetail("Please specify a numeric value in %s file", pgpool_node_id_file))); + fclose(fd); + return false; + } + } + + g_pool_config.pgpool_node_id = atoi(readbuf); + + if (g_pool_config.pgpool_node_id < 0 || g_pool_config.pgpool_node_id > MAX_WATCHDOG_NUM) + { + ereport(elevel, + (errmsg("Invalid pgpool node id \"%d\", must be between 0 and %d", + g_pool_config.pgpool_node_id, MAX_WATCHDOG_NUM))); + fclose(fd); + return false; + } + else + { + ereport(DEBUG1, + (errmsg("read pgpool node id file %s", pgpool_node_id_file), + errdetail("pgpool node id: %s", readbuf))); + } + + fclose(fd); + } + + return true; +} + +/* Set configured heartbeat destination interfaces */ +static bool +SetHBDestIfFunc(int elevel) +{ + int dest_if_idx = 0; + int local_if_idx = 0; + char **addrs; + char **if_names; + int i, + j, + k, + n_addr, + n_if_name; + + g_pool_config.num_hb_local_if = 0; + g_pool_config.num_hb_dest_if = 0; + + if (g_pool_config.wd_lifecheck_method != LIFECHECK_BY_HB) + { + return true; + } + + /* + * g_pool_config.hb_ifs is the information for sending/receiving heartbeat + * for all nodes specified in pgpool.conf. g_pool_config.hb_local_if is + * the local node information. g_pool_config.hb_dest_if is the heartbeat + * destination information. + */ + for (i = 0; i < WD_MAX_IF_NUM; i++) + { + if (g_pool_config.hb_ifs[i].dest_port > 0) + { + WdHbIf *hbNodeInfo = &g_pool_config.hb_ifs[i]; + + /* + * For the local pgpool node, use wd_heartbeat_listen_addresses if + * it is configured; otherwise use heartbeat_hostname. + */ + if (g_pool_config.wd_heartbeat_listen_addresses != NULL && + strlen(g_pool_config.wd_heartbeat_listen_addresses) != 0 && + i == g_pool_config.pgpool_node_id) + addrs = get_list_from_string(g_pool_config.wd_heartbeat_listen_addresses, ";", &n_addr); + else + addrs = get_list_from_string(hbNodeInfo->addr, ";", &n_addr); + if_names = get_list_from_string(hbNodeInfo->if_name, ";", &n_if_name); + + if (!addrs || n_addr < 0) + { + if (i == g_pool_config.pgpool_node_id) + g_pool_config.hb_local_if[local_if_idx].addr[0] = '\0'; + else + g_pool_config.hb_dest_if[dest_if_idx].addr[0] = '\0'; + + if (addrs) + pfree(addrs); + if (if_names) + pfree(if_names); + + ereport(elevel, + (errmsg("invalid watchdog configuration"), + errdetail("heartbeat_hostname%d is not defined", i))); + + return false; + } + + for (j = 0; j < n_addr; j++) + { + /* local pgpool node */ + if (i == g_pool_config.pgpool_node_id) + { + for (k = 0; k < g_pool_config.wd_nodes.num_wd - 1; k++) + { + strlcpy(g_pool_config.hb_local_if[local_if_idx].addr, addrs[j], WD_MAX_HOST_NAMELEN - 1); + + /* + * For the local pgpool node, use + * wd_heartbeat_listen_port if it is configured; + * otherwise use heartbeat_port. + */ + if (g_pool_config.wd_heartbeat_listen_port > 0) + g_pool_config.hb_local_if[local_if_idx].dest_port = g_pool_config.wd_heartbeat_listen_port; + else + g_pool_config.hb_local_if[local_if_idx].dest_port = hbNodeInfo->dest_port; + + if (n_if_name > j) + strlcpy(g_pool_config.hb_local_if[local_if_idx].if_name, if_names[j], WD_MAX_IF_NAME_LEN - 1); + else + g_pool_config.hb_local_if[local_if_idx].if_name[0] = '\0'; + + g_pool_config.num_hb_local_if = local_if_idx + 1; + local_if_idx++; + } + + if (n_if_name > j) + pfree(if_names[j]); + + pfree(addrs[j]); + + } + /* destination pgpool node */ + else + { + strlcpy(g_pool_config.hb_dest_if[dest_if_idx].addr, addrs[j], WD_MAX_HOST_NAMELEN - 1); + g_pool_config.hb_dest_if[dest_if_idx].dest_port = hbNodeInfo->dest_port; + if (n_if_name > j) + { + strlcpy(g_pool_config.hb_dest_if[dest_if_idx].if_name, if_names[j], WD_MAX_IF_NAME_LEN - 1); + pfree(if_names[j]); + } + else + g_pool_config.hb_dest_if[dest_if_idx].if_name[0] = '\0'; + + g_pool_config.num_hb_dest_if = dest_if_idx + 1; + dest_if_idx++; + pfree(addrs[j]); + } + } + + if (addrs) + pfree(addrs); + if (if_names) + pfree(if_names); + } + } + return true; +} + static struct config_generic * get_index_free_record_if_any(struct config_generic *record) { @@ -4428,8 +5647,206 @@ get_index_free_record_if_any(struct config_generic *record) return ret; } +/* + * Try to parse value as an integer. The accepted formats are the + * 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. + */ +static bool +parse_int(const char *value, int64 *result, int flags, const char **hintmsg, int64 MaxVal) +{ + /* + * 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 */ + if (result) + *result = 0; + if (hintmsg) + *hintmsg = NULL; + + /* + * 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 == '.' || *endptr == 'e' || *endptr == 'E' || + errno == ERANGE) + { + errno = 0; + val = strtod(value, &endptr); + } + + 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') + { + 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; + } + } + + /* Round to int, then check for overflow */ + val = rint(val); + + if (val > MaxVal || val < INT_MIN) + { + if (hintmsg) + *hintmsg = "Value exceeds allowed range."; + return false; + } + + if (result) + *result = (int64) val; + return true; +} + +/* + * 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 (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(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 + table = time_unit_conversion_table; + + for (i = 0; *table[i].unit; i++) + { + if (base_unit == table[i].base_unit && + strcmp(unitstr, table[i].unit) == 0) + { + 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; + } + } + return false; +} #ifndef POOL_PRIVATE +/* + * 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_int_from_base_unit(int64 base_value, int base_unit, + int64 *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. We + * assume that the conversions for each base unit are ordered from + * greatest unit to the smallest! + */ + if (table[i].multiplier <= 1.0 || + base_value % (int64) table[i].multiplier == 0) + { + *value = (int64) rint(base_value / table[i].multiplier); + *unit = table[i].unit; + break; + } + } + } + + Assert(*unit != NULL); +} + /* * Lookup the name for an enum option with the selected value. * The returned string is a pointer to static data and not @@ -4469,8 +5886,10 @@ ShowOption(struct config_generic *record, int index, int elevel) if (conf->show_hook) val = (*conf->show_hook) (); - else + else if (conf->variable) val = *conf->variable ? "on" : "off"; + else + val = ""; } break; @@ -4482,10 +5901,23 @@ ShowOption(struct config_generic *record, int index, int elevel) val = (*conf->show_hook) (); else { - int result = *conf->variable; - snprintf(buffer, sizeof(buffer), "%d", - result); + /* + * Use int64 arithmetic to avoid overflows in units + * conversion. + */ + int64 result = (int64) *conf->variable; + const char *unit; + + if (result > 0 && (record->flags & GUC_UNIT)) + convert_int_from_base_unit(result, + record->flags & GUC_UNIT, + &result, &unit); + else + unit = ""; + + snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s", + result, unit); val = buffer; } } @@ -4500,9 +5932,17 @@ ShowOption(struct config_generic *record, int index, int elevel) else { int64 result = (int64) *conf->variable; + const char *unit; - snprintf(buffer, sizeof(buffer), INT64_FORMAT, - result); + if (result > 0 && (record->flags & GUC_UNIT)) + convert_int_from_base_unit(result, + record->flags & GUC_UNIT, + &result, &unit); + else + unit = ""; + + snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s", + result, unit); val = buffer; } } @@ -4529,7 +5969,7 @@ ShowOption(struct config_generic *record, int index, int elevel) if (conf->show_hook) val = (*conf->show_hook) (); - else if (*conf->variable && **conf->variable) + else if (conf->variable && *conf->variable && **conf->variable) val = *conf->variable; else val = ""; @@ -4699,7 +6139,7 @@ value_slot_for_config_record_is_empty(struct config_generic *record, int index) } bool -set_config_option_for_session(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *name, const char *value) +set_config_option_for_session(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *name, const char *value) { bool ret; MemoryContext oldCxt = MemoryContextSwitchTo(TopMemoryContext); @@ -4714,7 +6154,7 @@ set_config_option_for_session(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * } bool -reset_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) +reset_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { int i; int elevel = (frontend == NULL) ? FATAL : FRONTEND_ONLY_ERROR; @@ -4779,8 +6219,11 @@ reset_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) return true; } +/* + * Handle "pgpool show all" command. +*/ bool -report_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) +report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { int i; int num_rows = 0; @@ -4834,9 +6277,11 @@ report_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) return true; } - +/* + * Handle "pgpool show" command. +*/ bool -report_config_variable(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *var_name) +report_config_variable(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *var_name) { int index = 0; char *value; @@ -4884,7 +6329,7 @@ report_config_variable(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backen * value config variable */ ereport(DEBUG3, - (errmsg("show parameter \"%s\" with out index", var_name))); + (errmsg("show parameter \"%s\" without index", var_name))); send_row_description_for_detail_view(frontend, backend); num_rows = send_array_type_variable_to_frontend(record, frontend, backend); if (num_rows < 0) @@ -4910,7 +6355,7 @@ report_config_variable(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backen } static int -send_array_type_variable_to_frontend(struct config_generic *record, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) +send_array_type_variable_to_frontend(struct config_generic *record, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { if (record->dynamic_array_var) { @@ -4951,7 +6396,7 @@ send_array_type_variable_to_frontend(struct config_generic *record, POOL_CONNECT } static int -send_grouped_type_variable_to_frontend(struct config_grouped_array_var *grouped_record, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) +send_grouped_type_variable_to_frontend(struct config_grouped_array_var *grouped_record, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { int k, index; @@ -5002,7 +6447,7 @@ send_grouped_type_variable_to_frontend(struct config_grouped_array_var *grouped_ } static void -send_row_description_for_detail_view(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) +send_row_description_for_detail_view(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { static char *field_names[] = {"item", "value", "description"}; diff --git a/src/context/pool_process_context.c b/src/context/pool_process_context.c index baa4d7090..da2913b6d 100644 --- a/src/context/pool_process_context.c +++ b/src/context/pool_process_context.c @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2017 PgPool Global Development Group + * Copyright (c) 2003-2021 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -23,13 +23,14 @@ #include #include +#include #include "pool.h" #include "utils/elog.h" #include "context/pool_process_context.h" #include "pool_config.h" /* remove me afterwards */ static POOL_PROCESS_CONTEXT process_context_d; -static POOL_PROCESS_CONTEXT * process_context; +static POOL_PROCESS_CONTEXT *process_context; /* * Initialize per process context @@ -90,7 +91,7 @@ pool_get_my_process_info(void) * Increment local session id */ void -pool_incremnet_local_session_id(void) +pool_increment_local_session_id(void) { POOL_PROCESS_CONTEXT *p = pool_get_process_context(); @@ -104,10 +105,10 @@ pool_incremnet_local_session_id(void) /* * Return byte size of connection info(ConnectionInfo) on shmem. */ -int +size_t pool_coninfo_size(void) { - int size; + size_t size; size = pool_config->num_init_children * pool_config->max_pool * @@ -115,7 +116,7 @@ pool_coninfo_size(void) sizeof(ConnectionInfo); ereport(DEBUG1, - (errmsg("pool_coninfo_size: num_init_children (%d) * max_pool (%d) * MAX_NUM_BACKENDS (%d) * sizeof(ConnectionInfo) (%zu) = %d bytes requested for shared memory", + (errmsg("pool_coninfo_size: num_init_children (%d) * max_pool (%d) * MAX_NUM_BACKENDS (%d) * sizeof(ConnectionInfo) (%zu) = %zu bytes requested for shared memory", pool_config->num_init_children, pool_config->max_pool, MAX_NUM_BACKENDS, @@ -229,25 +230,30 @@ pool_coninfo_backend_pid(int backend_pid, int *backend_node_id) for (child = 0; child < pool_config->num_init_children; child++) { int pool; - ProcessInfo *pi = pool_get_process_info(process_info[child].pid); - for (pool = 0; pool < pool_config->max_pool; pool++) + if (process_info[child].pid) { - int backend_id; + ProcessInfo *pi = pool_get_process_info(process_info[child].pid); - for (backend_id = 0; backend_id < NUM_BACKENDS; backend_id++) + for (pool = 0; pool < pool_config->max_pool; pool++) { - int poolBE = pool * MAX_NUM_BACKENDS + backend_id; + int backend_id; - if (ntohl(pi->connection_info[poolBE].pid) == backend_pid) + for (backend_id = 0; backend_id < NUM_BACKENDS; backend_id++) { - ereport(DEBUG1, - (errmsg("found for the connection with backend pid:%d on backend node %d", backend_pid, backend_id))); - *backend_node_id = backend_id; - return &pi->connection_info[poolBE]; + int poolBE = pool * MAX_NUM_BACKENDS + backend_id; + + if (ntohl(pi->connection_info[poolBE].pid) == backend_pid) + { + ereport(DEBUG1, + (errmsg("found the connection with backend pid:%d on backend node %d", backend_pid, backend_id))); + *backend_node_id = backend_id; + return &pi->connection_info[poolBE]; + } } } } + } return NULL; } @@ -258,13 +264,13 @@ pool_coninfo_backend_pid(int backend_pid, int *backend_node_id) * This flag is used to handle pg_terminate_backend() */ void -pool_set_connection_will_be_terminated(ConnectionInfo * connInfo) +pool_set_connection_will_be_terminated(ConnectionInfo *connInfo) { connInfo->swallow_termination = 1; } void -pool_unset_connection_will_be_terminated(ConnectionInfo * connInfo) +pool_unset_connection_will_be_terminated(ConnectionInfo *connInfo) { connInfo->swallow_termination = 0; } @@ -291,6 +297,7 @@ pool_coninfo_set_frontend_connected(int proc_id, int pool_index) return; } con->connected = true; + con->client_connection_time = time(NULL); } } @@ -316,6 +323,7 @@ pool_coninfo_unset_frontend_connected(int proc_id, int pool_index) return; } con->connected = false; + con->client_disconnection_time = time(NULL); } } diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c index 1d5ed1975..16ac34825 100644 --- a/src/context/pool_query_context.c +++ b/src/context/pool_query_context.c @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -21,11 +21,15 @@ #include "pool.h" #include "pool_config.h" #include "protocol/pool_proto_modules.h" +#include "protocol/pool_process_query.h" +#include "protocol/pool_pg_utils.h" #include "utils/palloc.h" #include "utils/memutils.h" #include "utils/elog.h" +#include "utils/statistics.h" #include "utils/pool_select_walker.h" #include "utils/pool_stream.h" +#include "utils/pool_track_table_mutation.h" #include "context/pool_session_context.h" #include "context/pool_query_context.h" #include "parser/nodes.h" @@ -33,6 +37,8 @@ #include #include #include +#include +#include /* * Where to send query @@ -43,7 +49,7 @@ typedef enum POOL_STANDBY, POOL_EITHER, POOL_BOTH -} POOL_DEST; +} POOL_DEST; #define CHECK_QUERY_CONTEXT_IS_VALID \ do { \ @@ -52,9 +58,22 @@ typedef enum (errmsg("setting db node for query to be sent, no query context")));\ } while (0) -static POOL_DEST send_to_where(Node *node, char *query); -static void where_to_send_deallocate(POOL_QUERY_CONTEXT * query_context, Node *node); +static POOL_DEST send_to_where(Node *node); +static void where_to_send_deallocate(POOL_QUERY_CONTEXT *query_context, Node *node); +static void where_to_send_main_replica(POOL_QUERY_CONTEXT *query_context, char *query, Node *node); +static void where_to_send_native_replication(POOL_QUERY_CONTEXT *query_context, char *query, Node *node); + static char *remove_read_write(int len, const char *contents, int *rewritten_len); +static void set_load_balance_info(POOL_QUERY_CONTEXT *query_context); + +static bool is_in_list(char *name, List *list); +static bool is_select_object_in_temp_write_list(Node *node, void *context); +static bool add_object_into_temp_write_list(Node *node, void *context); +static void dml_adaptive(Node *node, char *query); +static char *get_associated_object_from_dml_adaptive_relations + (char *left_token, DBObjectTypes object_type); +static void where_to_send_dml_adaptive_global(POOL_QUERY_CONTEXT *query_context, + char *query, Node *node, POOL_DEST dest); /* * Create and initialize per query session context @@ -62,15 +81,35 @@ static char *remove_read_write(int len, const char *contents, int *rewritten_len POOL_QUERY_CONTEXT * pool_init_query_context(void) { - MemoryContext memory_context = AllocSetContextCreate(QueryContext, - "QueryContextMemoryContext", - ALLOCSET_SMALL_MINSIZE, - ALLOCSET_SMALL_INITSIZE, - ALLOCSET_SMALL_MAXSIZE); - - MemoryContext oldcontext = MemoryContextSwitchTo(memory_context); + POOL_SESSION_CONTEXT *session_context; + MemoryContext parent; + MemoryContext memory_context; + MemoryContext oldcontext; POOL_QUERY_CONTEXT *qc; + /* + * Parent the query context under the session memory context rather than + * the per-iteration QueryContext. A query context is referenced from the + * session scoped sent message list and pending message list. These lists + * outlive the QueryContext, which do_child() resets between the + * iterations of its query processing loop (for instance when + * pool_process_query() returns after a backend node was shut down). If + * the query context lived in QueryContext, such a reset would free it + * while the message lists still reference it, resulting in a + * use-after-free. When there is no session context (e.g. internal + * queries issued before a session exists), fall back to QueryContext. + */ + session_context = pool_get_session_context(true); + parent = session_context ? session_context->memory_context : QueryContext; + + memory_context = AllocSetContextCreate(parent, + "QueryContextMemoryContext", + ALLOCSET_SMALL_MINSIZE, + ALLOCSET_SMALL_INITSIZE, + ALLOCSET_SMALL_MAXSIZE); + + oldcontext = MemoryContextSwitchTo(memory_context); + qc = palloc0(sizeof(*qc)); qc->memory_context = memory_context; MemoryContextSwitchTo(oldcontext); @@ -81,7 +120,7 @@ pool_init_query_context(void) * Destroy query context */ void -pool_query_context_destroy(POOL_QUERY_CONTEXT * query_context) +pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context) { POOL_SESSION_CONTEXT *session_context; @@ -90,7 +129,8 @@ pool_query_context_destroy(POOL_QUERY_CONTEXT * query_context) MemoryContext memory_context = query_context->memory_context; ereport(DEBUG5, - (errmsg("pool_query_context_destroy: query context:%p", query_context))); + (errmsg("pool_query_context_destroy: query context:%p query: \"%s\"", + query_context, query_context->original_query))); session_context = pool_get_session_context(false); pool_unset_query_in_progress(); @@ -112,7 +152,7 @@ pool_query_context_destroy(POOL_QUERY_CONTEXT * query_context) * Perform shallow copy of given query context. Used in parse_before_bind. */ POOL_QUERY_CONTEXT * -pool_query_context_shallow_copy(POOL_QUERY_CONTEXT * query_context) +pool_query_context_shallow_copy(POOL_QUERY_CONTEXT *query_context) { POOL_QUERY_CONTEXT *qc; MemoryContext memory_context; @@ -128,7 +168,7 @@ pool_query_context_shallow_copy(POOL_QUERY_CONTEXT * query_context) * Start query */ void -pool_start_query(POOL_QUERY_CONTEXT * query_context, char *query, int len, Node *node) +pool_start_query(POOL_QUERY_CONTEXT *query_context, char *query, int len, Node *node) { POOL_SESSION_CONTEXT *session_context; @@ -143,13 +183,16 @@ pool_start_query(POOL_QUERY_CONTEXT * query_context, char *query, int len, Node query_context->original_query = pstrdup(query); query_context->rewritten_query = NULL; query_context->parse_tree = node; - query_context->virtual_master_node_id = my_master_node_id; + query_context->virtual_main_node_id = my_main_node_id; + query_context->load_balance_node_id = my_main_node_id; query_context->is_cache_safe = false; query_context->num_original_params = -1; if (pool_config->memory_cache_enabled) query_context->temp_cache = pool_create_temp_query_cache(query); pool_set_query_in_progress(); query_context->skip_cache_commit = false; + query_context->atEnd = false; + query_context->partial_fetch = false; session_context->query_context = query_context; MemoryContextSwitchTo(old_context); } @@ -159,7 +202,7 @@ pool_start_query(POOL_QUERY_CONTEXT * query_context, char *query, int len, Node * Specify DB node to send query */ void -pool_set_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) +pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) { CHECK_QUERY_CONTEXT_IS_VALID; @@ -174,10 +217,10 @@ pool_set_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) } /* - * Unspecify DB node to send query + * Unspecified DB node to send query */ void -pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) +pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) { CHECK_QUERY_CONTEXT_IS_VALID; @@ -195,7 +238,7 @@ pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) * Clear DB node map */ void -pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) +pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) { CHECK_QUERY_CONTEXT_IS_VALID; @@ -207,7 +250,7 @@ pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) * Set all DB node map entry */ void -pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) +pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) { int i; POOL_SESSION_CONTEXT *sc; @@ -221,14 +264,33 @@ pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) if (private_backend_status[i] == CON_UP || (private_backend_status[i] == CON_CONNECT_WAIT)) { - /* - * In streaming replication mode, if the node is not primary node - * nor load balance node, there's no point to send query. - */ - if (SL_MODE && - i != PRIMARY_NODE_ID && i != sc->load_balance_node_id) + if (SL_MODE) { - continue; + /* + * If load balance mode is disabled, only send to the primary + * node. If primary node does not exist, send to the main + * node. + */ + if (!pool_config->load_balance_mode) + { + if (i == PRIMARY_NODE_ID || + (PRIMARY_NODE_ID < 0 && MAIN_NODE_ID == i)) + { + query_context->where_to_send[i] = true; + break; + } + continue; + } + else + + /* + * If the node is not primary node nor load balance node, + * there's no point to send query except statement level + * load balance is enabled. + */ + if (!pool_config->statement_level_load_balance && + i != PRIMARY_NODE_ID && i != sc->load_balance_node_id) + continue; } query_context->where_to_send[i] = true; } @@ -240,7 +302,7 @@ pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) * Return true if multiple nodes are targets */ bool -pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) +pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) { int i; int cnt = 0; @@ -267,7 +329,7 @@ pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) * Return if the DB node is needed to send query */ bool -pool_is_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) +pool_is_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) { CHECK_QUERY_CONTEXT_IS_VALID; @@ -289,7 +351,7 @@ pool_is_node_to_be_sent_in_current_query(int node_id) POOL_SESSION_CONTEXT *sc; if (RAW_MODE) - return node_id == REAL_MASTER_NODE_ID; + return node_id == REAL_MAIN_NODE_ID; sc = pool_get_session_context(true); if (!sc) @@ -303,45 +365,87 @@ pool_is_node_to_be_sent_in_current_query(int node_id) } /* - * Returns virtual master DB node id, + * Returns virtual main DB node id, */ int -pool_virtual_master_db_node_id(void) +pool_virtual_main_db_node_id(void) { + volatile POOL_REQUEST_INFO *my_req; POOL_SESSION_CONTEXT *sc; + /* + * Check whether failover is in progress and we are child process. If so, + * we will wait for failover to finish. + */ + my_req = Req_info; + if (processType == PT_CHILD && my_req->switching) + { +#ifdef NOT_USED + POOL_SETMASK(&BlockSig); + ereport(WARNING, + (errmsg("failover/failback is in progress"), + errdetail("executing failover or failback on backend"), + errhint("In a moment you should be able to reconnect to the database"))); + POOL_SETMASK(&UnBlockSig); +#endif + + /* + * Wait for failover to finish + */ + if (wait_for_failover_to_finish() == -2) + + /* + * Waiting for failover/failback to finish was timed out. Time to + * exit this process (and session disconnection). + */ + child_exit(POOL_EXIT_AND_RESTART); + } + sc = pool_get_session_context(true); if (!sc) { - return REAL_MASTER_NODE_ID; + /* + * We used to return REAL_MAIN_NODE_ID here. Problem with it is, it + * is possible that REAL_MAIN_NODE_ID could be changed anytime. + * Suppose REAL_MAIN_NODE_ID == my_main_node_id == 1. Then due to + * failback, REAL_MAIN_NODE_ID is changed to 0. Then + * MAIN_CONNECTION(cp) will return NULL and any reference to it will + * cause segmentation fault. To prevent the issue we should return + * my_main_node_id instead. + */ + return my_main_node_id; } if (sc->in_progress && sc->query_context) { - int node_id = sc->query_context->virtual_master_node_id; + int node_id = sc->query_context->virtual_main_node_id; if (SL_MODE) { /* - * Make sure that virtual_master_node_id is either primary node id + * Make sure that virtual_main_node_id is either primary node id * or load balance node id. If not, it is likely that - * virtual_master_node_id is not set up yet. Let's use the primary - * node id. except for the special case where we need to send the + * virtual_main_node_id is not set up yet. Let's use the primary + * node id except for the special case where we need to send the * query to the node which is not primary nor the load balance * node. Currently there is only one special such case that is * handling of pg_terminate_backend() function, which may refer to * the backend connection that is neither hosted by the primary or * load balance node for current child process, but the query must * be forwarded to that node. Since only that backend node can - * handle that pg_terminate_backend query - * + * handle that pg_terminate_backend query. Another exception is, + * processing "Sync" message. We create a special query context + * marked "sync_msg == true". If so, it is possible that the main + * node id could not be either ordinarily main node (the first + * alive node) nor the load balance node. So we check the flag. */ ereport(DEBUG5, - (errmsg("pool_virtual_master_db_node_id: virtual_master_node_id:%d load_balance_node_id:%d PRIMARY_NODE_ID:%d", - node_id, sc->load_balance_node_id, PRIMARY_NODE_ID))); + (errmsg("pool_virtual_main_db_node_id: virtual_main_node_id:%d load_balance_node_id:%d PRIMARY_NODE_ID:%d sync_msg:%d", + node_id, sc->load_balance_node_id, PRIMARY_NODE_ID, sc->query_context->sync_msg))); - if (node_id != sc->load_balance_node_id && node_id != PRIMARY_NODE_ID) + if (!sc->query_context->sync_msg && node_id != sc->query_context->load_balance_node_id && + node_id != PRIMARY_NODE_ID) { /* * Only return the primary node id if we are not processing @@ -356,318 +460,82 @@ pool_virtual_master_db_node_id(void) } /* - * No query context exists. If in master/slave mode, returns primary node - * if exists. Otherwise returns my_master_node_id, which represents the - * last REAL_MASTER_NODE_ID. + * No query context exists. If in streaming replication mode, returns + * primary node if exists. Otherwise returns my_main_node_id, which + * represents the last REAL_MAIN_NODE_ID. */ - if (MASTER_SLAVE) + if (MAIN_REPLICA) { return PRIMARY_NODE_ID; } - return my_master_node_id; + return my_main_node_id; } /* - * The function sets the destination for the current query to the specific backend node + * Set the destination for the current query to the specific backend node. */ void -pool_force_query_node_to_backend(POOL_QUERY_CONTEXT * query_context, int backend_id) +pool_force_query_node_to_backend(POOL_QUERY_CONTEXT *query_context, int backend_id) { - int i; - CHECK_QUERY_CONTEXT_IS_VALID; ereport(DEBUG1, (errmsg("forcing query destination node to backend node:%d", backend_id))); pool_set_node_to_be_sent(query_context, backend_id); - for (i = 0; i < NUM_BACKENDS; i++) - { - if (query_context->where_to_send[i]) - { - query_context->virtual_master_node_id = i; - break; - } - } + set_virtual_main_node(query_context); } /* * Decide where to send queries(thus expecting response) */ void -pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node) +pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *node) { - POOL_SESSION_CONTEXT *session_context; - POOL_CONNECTION_POOL *backend; - int i; - CHECK_QUERY_CONTEXT_IS_VALID; - session_context = pool_get_session_context(false); - backend = session_context->backend; - /* * Zap out DB node map */ pool_clear_node_to_be_sent(query_context); /* - * When query match the query patterns in black_query_pattern_list, we - * send only to master node. - */ - if (MASTER_SLAVE && pattern_compare(query, BLACKLIST, "black_query_pattern_list") == 1) - { - pool_set_node_to_be_sent(query_context, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID); - return; - } - - /* - * If there is "NO LOAD BALANCE" comment, we send only to master node. - */ - if (!strncasecmp(query, NO_LOAD_BALANCE, NO_LOAD_BALANCE_COMMENT_SZ)) - { - pool_set_node_to_be_sent(query_context, - MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID); - for (i = 0; i < NUM_BACKENDS; i++) - { - if (query_context->where_to_send[i]) - { - query_context->virtual_master_node_id = i; - break; - } - } - return; - } - - /* - * In raw mode, we send only to master node. Simple enough. + * In raw mode, we send only to main node. Simple enough. */ if (RAW_MODE) { - pool_set_node_to_be_sent(query_context, REAL_MASTER_NODE_ID); + pool_set_node_to_be_sent(query_context, REAL_MAIN_NODE_ID); } - else if (MASTER_SLAVE && query_context->is_multi_statement) + else if (MAIN_REPLICA) { - /* - * If we are in master/slave mode and we have multi statement query, - * we should send it to primary server only. Otherwise it is possible - * to send a write query to standby servers because we only use the - * first element of the multi statement query and don't care about the - * rest. Typical situation where we are bugged by this is, - * "BEGIN;DELETE FROM table;END". Note that from pgpool-II 3.1.0 - * transactional statements such as "BEGIN" is unconditionally sent to - * all nodes(see send_to_where() for more details). Someday we might - * be able to understand all part of multi statement queries, but - * until that day we need this band aid. - */ if (query_context->is_multi_statement) { + /* + * If we are in streaming replication mode and we have multi + * statement query, we should send it to primary server only. + * Otherwise it is possible to send a write query to standby + * servers because we only use the first element of the multi + * statement query and don't care about the rest. Typical + * situation where we are bugged by this is, "BEGIN;DELETE FROM + * table;END". Note that from pgpool-II 3.1.0 transactional + * statements such as "BEGIN" is unconditionally sent to all + * nodes(see send_to_where() for more details). Someday we might + * be able to understand all part of multi statement queries, but + * until that day we need this band aid. + */ pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); } - } - else if (MASTER_SLAVE) - { - POOL_DEST dest; - - dest = send_to_where(node, query); - - ereport(DEBUG1, - (errmsg("decide where to send the query"), - errdetail("destination = %d for query= \"%s\"", dest, query))); - - /* Should be sent to primary only? */ - if (dest == POOL_PRIMARY) - { - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - /* Should be sent to both primary and standby? */ - else if (dest == POOL_BOTH) - { - pool_setall_node_to_be_sent(query_context); - } - else if (pool_is_writing_transaction() && - pool_config->disable_load_balance_on_write == DLBOW_ALWAYS) - { - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - - /* - * Ok, we might be able to load balance the SELECT query. - */ else - { - if (pool_config->load_balance_mode && - is_select_query(node, query) && - MAJOR(backend) == PROTO_MAJOR_V3) - { - /* - * If (we are outside of an explicit transaction) OR (the - * transaction has not issued a write query yet, AND - * transaction isolation level is not SERIALIZABLE) we might - * be able to load balance. - */ - - ereport(DEBUG1, - (errmsg("checking load balance precondtions. TSTATE:%c wrting_trancation:%d failed_transaction:%d isolation:%d", - TSTATE(backend, PRIMARY_NODE_ID), - pool_is_writing_transaction(), - pool_is_failed_transaction(), - pool_get_transaction_isolation()), - errdetail("destination = %d for query= \"%s\"", dest, query))); - - if (TSTATE(backend, PRIMARY_NODE_ID) == 'I' || - (!pool_is_writing_transaction() && - !pool_is_failed_transaction() && - pool_get_transaction_isolation() != POOL_SERIALIZABLE)) - { - BackendInfo *bkinfo = pool_get_node_info(session_context->load_balance_node_id); - - /* - * Load balance if possible - */ - - /* - * If replication delay is too much, we prefer to send to - * the primary. - */ - if (STREAM && - pool_config->delay_threshold && - bkinfo->standby_delay > pool_config->delay_threshold) - { - ereport(DEBUG1, - (errmsg("could not load balance because of too much replication delay"), - errdetail("destination = %d for query= \"%s\"", dest, query))); - - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - - /* - * If a writing function call is used, we prefer to send - * to the primary. - */ - else if (pool_has_function_call(node)) - { - ereport(DEBUG1, - (errmsg("could not load balance because writing functions are used"), - errdetail("destination = %d for query= \"%s\"", dest, query))); - - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - - /* - * If system catalog is used in the SELECT, we prefer to - * send to the primary. Example: SELECT * FROM pg_class - * WHERE relname = 't1'; Because 't1' is a constant, it's - * hard to recognize as table name. Most use case such - * query is against system catalog, and the table name can - * be a temporary table, it's best to query against - * primary system catalog. Please note that this test must - * be done *before* test using pool_has_temp_table. - */ - else if (pool_has_system_catalog(node)) - { - ereport(DEBUG1, - (errmsg("could not load balance because systems catalogs are used"), - errdetail("destination = %d for query= \"%s\"", dest, query))); - - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - - /* - * If temporary table is used in the SELECT, we prefer to - * send to the primary. - */ - else if (pool_config->check_temp_table && pool_has_temp_table(node)) - { - ereport(DEBUG1, - (errmsg("could not load balance because temporary tables are used"), - errdetail("destination = %d for query= \"%s\"", dest, query))); - - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - - /* - * If unlogged table is used in the SELECT, we prefer to - * send to the primary. - */ - else if (pool_config->check_unlogged_table && pool_has_unlogged_table(node)) - { - ereport(DEBUG1, - (errmsg("could not load balance because unlogged tables are used"), - errdetail("destination = %d for query= \"%s\"", dest, query))); - - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - - else - { - pool_set_node_to_be_sent(query_context, - session_context->load_balance_node_id); - } - } - else - { - /* Send to the primary only */ - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - } - else - { - /* Send to the primary only */ - pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); - } - } + where_to_send_main_replica(query_context, query, node); } else if (REPLICATION) { - if (pool_config->load_balance_mode && - is_select_query(node, query) && - MAJOR(backend) == PROTO_MAJOR_V3) + if (query_context->is_multi_statement) { - /* - * If a writing function call is used or replicate_select is true, - * we prefer to send to all nodes. - */ - if (pool_has_function_call(node) || pool_config->replicate_select) - { - pool_setall_node_to_be_sent(query_context); - } - - /* - * If (we are outside of an explicit transaction) OR (the - * transaction has not issued a write query yet, AND transaction - * isolation level is not SERIALIZABLE) we might be able to load - * balance. - */ - else if (TSTATE(backend, MASTER_NODE_ID) == 'I' || - (!pool_is_writing_transaction() && - !pool_is_failed_transaction() && - pool_get_transaction_isolation() != POOL_SERIALIZABLE)) - { - /* load balance */ - pool_set_node_to_be_sent(query_context, - session_context->load_balance_node_id); - } - else - { - /* only send to master node */ - pool_set_node_to_be_sent(query_context, REAL_MASTER_NODE_ID); - } + pool_setall_node_to_be_sent(query_context); } else - { - if (is_select_query(node, query) && !pool_config->replicate_select && - !pool_has_function_call(node)) - { - /* only send to master node */ - pool_set_node_to_be_sent(query_context, REAL_MASTER_NODE_ID); - } - else - { - /* send to all nodes */ - pool_setall_node_to_be_sent(query_context); - } - } + where_to_send_native_replication(query_context, query, node); } else { @@ -677,36 +545,15 @@ pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node) } /* - * EXECUTE? - */ - if (IsA(node, ExecuteStmt)) - { - POOL_SENT_MESSAGE *msg; - - msg = pool_get_sent_message('Q', ((ExecuteStmt *) node)->name, POOL_SENT_MESSAGE_CREATED); - if (!msg) - msg = pool_get_sent_message('P', ((ExecuteStmt *) node)->name, POOL_SENT_MESSAGE_CREATED); - if (msg) - pool_copy_prep_where(msg->query_context->where_to_send, - query_context->where_to_send); - } - - /* - * DEALLOCATE? + * DEALLOCATE or EXECUTE? */ - else if (IsA(node, DeallocateStmt)) + if (IsA(node, DeallocateStmt) || IsA(node, ExecuteStmt)) { where_to_send_deallocate(query_context, node); } - for (i = 0; i < NUM_BACKENDS; i++) - { - if (query_context->where_to_send[i]) - { - query_context->virtual_master_node_id = i; - break; - } - } + /* Set virtual main node according to the where_to_send map. */ + set_virtual_main_node(query_context); return; } @@ -719,7 +566,7 @@ pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node) * >0: send to this node_id */ POOL_STATUS -pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, +pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, int send_type, int node_id) { POOL_SESSION_CONTEXT *session_context; @@ -740,10 +587,10 @@ pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, string = NULL; /* - * If the query is BEGIN READ WRITE or BEGIN ... SERIALIZABLE in - * master/slave mode, we send BEGIN to slaves/standbys instead. - * original_query which is BEGIN READ WRITE is sent to primary. - * rewritten_query which is BEGIN is sent to standbys. + * If the query is BEGIN READ WRITE or BEGIN ... SERIALIZABLE in streaming + * replication mode, we send BEGIN to standbys instead. The original_query + * which is BEGIN READ WRITE is sent to primary. The rewritten_query BEGIN + * is sent to standbys. */ if (pool_need_to_treat_as_if_default_transaction(query_context)) { @@ -774,10 +621,11 @@ pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, continue; /* - * If in master/slave mode, we do not send COMMIT/ABORT to - * slaves/standbys if it's in I(idle) state. + * If we are in streaming replication mode or logical replication + * mode, we do not send COMMIT/ABORT to standbys if it's in I (idle) + * state. */ - if (is_commit && MASTER_SLAVE && !IS_MASTER_NODE_ID(i) && TSTATE(backend, i) == 'I') + if (is_commit && MAIN_REPLICA && !IS_MAIN_NODE_ID(i) && TSTATE(backend, i) == 'I') { pool_unset_node_to_be_sent(query_context, i); continue; @@ -808,6 +656,7 @@ pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, } per_node_statement_log(backend, i, string); + per_node_statement_notice(backend, i, string); stat_count_up(i, query_context->parse_tree); send_simplequery_message(CONNECTION(backend, i), len, string, MAJOR(backend)); } @@ -825,10 +674,10 @@ pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, #ifdef NOT_USED /* - * If in master/slave mode, we do not send COMMIT/ABORT to - * slaves/standbys if it's in I(idle) state. + * If in native replication mode, we do not send COMMIT/ABORT to + * standbys if it's in I(idle) state. */ - if (is_commit && MASTER_SLAVE && !IS_MASTER_NODE_ID(i) && TSTATE(backend, i) == 'I') + if (is_commit && MAIN_REPLICA && !IS_MAIN_NODE_ID(i) && TSTATE(backend, i) == 'I') { continue; } @@ -845,15 +694,23 @@ pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, wait_for_query_response_with_trans_cleanup(frontend, CONNECTION(backend, i), MAJOR(backend), - MASTER_CONNECTION(backend)->pid, - MASTER_CONNECTION(backend)->key); + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, + MAIN_CONNECTION(backend)->keylen); /* * Check if some error detected. If so, emit log. This is useful when * invalid encoding error occurs. In this case, PostgreSQL does not * report what statement caused that error and make users confused. + * Also set reset_query_error to true in ERROR case. This does + * anything in normal query processing but when processing reset + * queries, this is important because it might mean DISCARD ALL + * command fails. If so, we need to discard the connection cache so + * that any session object (i.e. named statement) does not remain in + * the last session. */ - per_node_error_log(backend, i, string, "pool_send_and_wait: Error or notice message from backend: ", true); + if (per_node_error_log(backend, i, string, "pool_send_and_wait: Error or notice message from backend", true) == 'E') + reset_query_error = true; } return POOL_CONTINUE; @@ -867,7 +724,7 @@ pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, * >0: send to this node_id */ POOL_STATUS -pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, +pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *kind, int len, char *contents, int send_type, int node_id, bool nowait) { @@ -893,10 +750,10 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, rewritten_begin = NULL; /* - * If the query is BEGIN READ WRITE or BEGIN ... SERIALIZABLE in - * master/slave mode, we send BEGIN to slaves/standbys instead. - * original_query which is BEGIN READ WRITE is sent to primary. - * rewritten_query which is BEGIN is sent to standbys. + * If the query is BEGIN READ WRITE or BEGIN ... SERIALIZABLE in streaming + * replication mode, we send BEGIN to standbys instead. The original_query + * which is BEGIN READ WRITE is sent to primary. The rewritten_query BEGIN + * is sent to standbys. */ if (pool_need_to_treat_as_if_default_transaction(query_context)) { @@ -951,7 +808,7 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, char msgbuf[QUERY_STRING_BUFFER_LEN]; char *stmt; - if (*kind == 'P' || *kind == 'E') + if (*kind == 'P' || *kind == 'E' || *kind == 'B') { if (query_context->rewritten_query) { @@ -974,6 +831,8 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, if (*kind == 'P') snprintf(msgbuf, sizeof(msgbuf), "Parse: %s", stmt); + else if (*kind == 'B') + snprintf(msgbuf, sizeof(msgbuf), "Bind: %s", stmt); else snprintf(msgbuf, sizeof(msgbuf), "Execute: %s", stmt); } @@ -983,6 +842,7 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, } per_node_statement_log(backend, i, msgbuf); + per_node_statement_notice(backend, i, msgbuf); } /* if Execute message, count up stats count */ @@ -991,6 +851,7 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, stat_count_up(i, query_context->parse_tree); } + set_sync_map(session_context, i); send_extended_protocol_message(backend, i, kind, str_len, str); if ((*kind == 'P' || *kind == 'E' || *kind == 'C') && STREAM) @@ -1033,10 +894,10 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, continue; /* - * If in master/slave mode, we do not send COMMIT/ABORT to - * slaves/standbys if it's in I(idle) state. + * If in native replication mode, we do not send COMMIT/ABORT to + * standbys if it's in I(idle) state. */ - if (is_commit && MASTER_SLAVE && !IS_MASTER_NODE_ID(i) && TSTATE(backend, i) == 'I') + if (is_commit && MAIN_REPLICA && !IS_MAIN_NODE_ID(i) && TSTATE(backend, i) == 'I') { continue; } @@ -1052,8 +913,9 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, wait_for_query_response_with_trans_cleanup(frontend, CONNECTION(backend, i), MAJOR(backend), - MASTER_CONNECTION(backend)->pid, - MASTER_CONNECTION(backend)->key); + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, + MAIN_CONNECTION(backend)->keylen); /* * Check if some error detected. If so, emit log. This is useful @@ -1061,7 +923,7 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, * does not report what statement caused that error and make users * confused. */ - per_node_error_log(backend, i, str, "pool_send_and_wait: Error or notice message from backend: ", true); + per_node_error_log(backend, i, str, "pool_send_and_wait: Error or notice message from backend", true); } } @@ -1072,9 +934,10 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, /* * From syntactically analysis decide the statement to be sent to the - * primary, the standby or either or both in master/slave+HR/SR mode. + * primary, the standby or either or both in native replication+HR/SR mode. */ -static POOL_DEST send_to_where(Node *node, char *query) +static POOL_DEST +send_to_where(Node *node) { /* From storage/lock.h */ @@ -1090,387 +953,328 @@ static POOL_DEST send_to_where(Node *node, char *query) #define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR UPDATE */ #define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM FULL, * and unqualified LOCK TABLE */ - -/* From 9.5 include/nodes/node.h ("TAGS FOR STATEMENT NODES" part) */ - static NodeTag nodemap[] = { - T_RawStmt, - T_Query, - T_PlannedStmt, - T_InsertStmt, - T_DeleteStmt, - T_UpdateStmt, - T_SelectStmt, - T_AlterTableStmt, - T_AlterTableCmd, - T_AlterDomainStmt, - T_SetOperationStmt, - T_GrantStmt, - T_GrantRoleStmt, - T_AlterDefaultPrivilegesStmt, - T_ClosePortalStmt, - T_ClusterStmt, - T_CopyStmt, - T_CreateStmt, /* CREATE TABLE */ - T_DefineStmt, /* CREATE AGGREGATE, OPERATOR, TYPE */ - T_DropStmt, /* DROP TABLE etc. */ - T_TruncateStmt, - T_CommentStmt, - T_FetchStmt, - T_IndexStmt, /* CREATE INDEX */ - T_CreateFunctionStmt, - T_AlterFunctionStmt, - T_DoStmt, - T_RenameStmt, /* ALTER AGGREGATE etc. */ - T_RuleStmt, /* CREATE RULE */ - T_NotifyStmt, - T_ListenStmt, - T_UnlistenStmt, - T_TransactionStmt, - T_ViewStmt, /* CREATE VIEW */ - T_LoadStmt, - T_CreateDomainStmt, - T_CreatedbStmt, - T_DropdbStmt, - T_VacuumStmt, - T_ExplainStmt, - T_CreateTableAsStmt, - T_CreateSeqStmt, - T_AlterSeqStmt, - T_VariableSetStmt, /* SET */ - T_VariableShowStmt, - T_DiscardStmt, - T_CreateTrigStmt, - T_CreatePLangStmt, - T_CreateRoleStmt, - T_AlterRoleStmt, - T_DropRoleStmt, - T_LockStmt, - T_ConstraintsSetStmt, - T_ReindexStmt, - T_CheckPointStmt, - T_CreateSchemaStmt, - T_AlterDatabaseStmt, - T_AlterDatabaseSetStmt, - T_AlterRoleSetStmt, - T_CreateConversionStmt, - T_CreateCastStmt, - T_CreateOpClassStmt, - T_CreateOpFamilyStmt, - T_AlterOpFamilyStmt, - T_PrepareStmt, - T_ExecuteStmt, - T_DeallocateStmt, /* DEALLOCATE */ - T_DeclareCursorStmt, /* DECLARE */ - T_CreateTableSpaceStmt, - T_DropTableSpaceStmt, - T_AlterObjectSchemaStmt, - T_AlterOwnerStmt, - T_DropOwnedStmt, - T_ReassignOwnedStmt, - T_CompositeTypeStmt, /* CREATE TYPE */ - T_CreateEnumStmt, - T_CreateRangeStmt, - T_AlterEnumStmt, - T_AlterTSDictionaryStmt, - T_AlterTSConfigurationStmt, - T_CreateFdwStmt, - T_AlterFdwStmt, - T_CreateForeignServerStmt, - T_AlterForeignServerStmt, - T_CreateUserMappingStmt, - T_AlterUserMappingStmt, - T_DropUserMappingStmt, - T_AlterTableSpaceOptionsStmt, - T_AlterTableMoveAllStmt, - T_SecLabelStmt, - T_CreateForeignTableStmt, - T_ImportForeignSchemaStmt, - T_CreateExtensionStmt, - T_AlterExtensionStmt, - T_AlterExtensionContentsStmt, - T_CreateEventTrigStmt, - T_AlterEventTrigStmt, - T_RefreshMatViewStmt, - T_ReplicaIdentityStmt, - T_AlterSystemStmt, - T_CreatePolicyStmt, - T_AlterPolicyStmt, - T_CreateTransformStmt, - T_CreateAmStmt, - T_CreatePublicationStmt, - T_AlterPublicationStmt, - T_CreateSubscriptionStmt, - T_DropSubscriptionStmt, - T_CreateStatsStmt, - T_AlterCollationStmt, - }; - - if (bsearch(&nodeTag(node), nodemap, sizeof(nodemap) / sizeof(nodemap[0]), - sizeof(NodeTag), compare) != NULL) + /* + * SELECT INTO SELECT FOR SHARE or UPDATE + */ + if (IsA(node, SelectStmt)) { - /* - * SELECT INTO SELECT FOR SHARE or UPDATE - */ - if (IsA(node, SelectStmt)) + /* SELECT INTO or SELECT FOR SHARE or UPDATE ? */ + if (pool_has_insertinto_or_locking_clause(node)) + return POOL_PRIMARY; + + /* non-SELECT query in WITH clause ? */ + if (((SelectStmt *) node)->withClause) { - /* SELECT INTO or SELECT FOR SHARE or UPDATE ? */ - if (pool_has_insertinto_or_locking_clause(node)) - return POOL_PRIMARY; + List *ctes = ((SelectStmt *) node)->withClause->ctes; + ListCell *cte_item; - /* non-SELECT query in WITH clause ? */ - if (((SelectStmt *) node)->withClause) + foreach(cte_item, ctes) { - List *ctes = ((SelectStmt *) node)->withClause->ctes; - ListCell *cte_item; + CommonTableExpr *cte = (CommonTableExpr *) lfirst(cte_item); - foreach(cte_item, ctes) - { - CommonTableExpr *cte = (CommonTableExpr *) lfirst(cte_item); - - if (!IsA(cte->ctequery, SelectStmt)) - return POOL_PRIMARY; - } + if (!IsA(cte->ctequery, SelectStmt)) + return POOL_PRIMARY; } - - return POOL_EITHER; } - /* - * COPY - */ - else if (IsA(node, CopyStmt)) + return POOL_EITHER; + } + + /* + * COPY + */ + else if (IsA(node, CopyStmt)) + { + if (((CopyStmt *) node)->is_from) + return POOL_PRIMARY; + else { - if (((CopyStmt *) node)->is_from) - return POOL_PRIMARY; + if (((CopyStmt *) node)->query == NULL) + return POOL_EITHER; else - { - if (((CopyStmt *) node)->query == NULL) - return POOL_EITHER; - else - return (IsA(((CopyStmt *) node)->query, SelectStmt)) ? POOL_EITHER : POOL_PRIMARY; - } + return (IsA(((CopyStmt *) node)->query, SelectStmt)) ? POOL_EITHER : POOL_PRIMARY; } + } - /* - * LOCK - */ - else if (IsA(node, LockStmt)) - { - return (((LockStmt *) node)->mode >= RowExclusiveLock) ? POOL_PRIMARY : POOL_BOTH; - } + /* + * LOCK + */ + else if (IsA(node, LockStmt)) + { + return (((LockStmt *) node)->mode >= RowExclusiveLock) ? POOL_PRIMARY : POOL_BOTH; + } + /* + * Transaction commands + */ + else if (IsA(node, TransactionStmt)) + { /* - * Transaction commands + * Check "BEGIN READ WRITE" "START TRANSACTION READ WRITE" */ - else if (IsA(node, TransactionStmt)) + if (is_start_transaction_query(node)) { /* - * Check "BEGIN READ WRITE" "START TRANSACTION READ WRITE" + * But actually, we send BEGIN to standby if it's BEGIN READ WRITE + * or START TRANSACTION READ WRITE */ - if (is_start_transaction_query(node)) - { - /* - * But actually, we send BEGIN to standby if it's BEGIN READ - * WRITE or START TRANSACTION READ WRITE - */ - if (is_read_write((TransactionStmt *) node)) - return POOL_BOTH; - - /* - * Other TRANSACTION start commands are sent to both primary - * and standby - */ - else - return POOL_BOTH; - } - /* SAVEPOINT related commands are sent to both primary and standby */ - else if (is_savepoint_query(node)) - return POOL_BOTH; + if (is_read_write((TransactionStmt *) node)) + return POOL_BOTH; /* - * 2PC commands + * Other TRANSACTION start commands are sent to both primary and + * standby */ - else if (is_2pc_transaction_query(node)) - return POOL_PRIMARY; else - /* COMMIT etc. */ return POOL_BOTH; } - - /* - * SET - */ - else if (IsA(node, VariableSetStmt)) + /* SAVEPOINT related commands are sent to both primary and standby */ + else if (is_savepoint_query(node)) { - ListCell *list_item; - bool ret = POOL_BOTH; - - /* - * SET transaction_read_only TO off - */ - if (((VariableSetStmt *) node)->kind == VAR_SET_VALUE && - !strcmp(((VariableSetStmt *) node)->name, "transaction_read_only")) - { - List *options = ((VariableSetStmt *) node)->args; - - foreach(list_item, options) - { - A_Const *v = (A_Const *) lfirst(list_item); - - switch (v->val.type) - { - case T_String: - if (!strcasecmp(v->val.val.str, "off") || - !strcasecmp(v->val.val.str, "f") || - !strcasecmp(v->val.val.str, "false")) - ret = POOL_PRIMARY; - break; - case T_Integer: - if (v->val.val.ival) - ret = POOL_PRIMARY; - default: - break; - } - } - return ret; - } - - /* - * SET TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET SESSION - * CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE or - * SET transaction_isolation TO 'serializable' SET - * default_transaction_isolation TO 'serializable' - */ - else if (is_set_transaction_serializable(node)) - { - return POOL_PRIMARY; - } - - /* - * Check "SET TRANSACTION READ WRITE" "SET SESSION CHARACTERISTICS - * AS TRANSACTION READ WRITE" - */ - else if (((VariableSetStmt *) node)->kind == VAR_SET_MULTI && - (!strcmp(((VariableSetStmt *) node)->name, "TRANSACTION") || - !strcmp(((VariableSetStmt *) node)->name, "SESSION CHARACTERISTICS"))) - { - List *options = ((VariableSetStmt *) node)->args; - - foreach(list_item, options) - { - DefElem *opt = (DefElem *) lfirst(list_item); - - if (!strcmp("transaction_read_only", opt->defname)) - { - bool read_only; - - read_only = ((A_Const *) opt->arg)->val.val.ival; - if (!read_only) - return POOL_PRIMARY; - } - } - return POOL_BOTH; - } - else + if (SL_MODE && is_tx_started_by_multi_statement_query()) { /* - * All other SET command sent to both primary and standby + * But in streaming replication mode, if a transaction was + * started by a multi statement query, SAVEPOINT should be + * sent to primary because the transaction was started on + * primary only. */ - return POOL_BOTH; + return POOL_PRIMARY; } + return POOL_BOTH; } /* - * DISCARD + * 2PC commands */ - else if (IsA(node, DiscardStmt)) - { + else if (is_2pc_transaction_query(node)) + return POOL_PRIMARY; + else + /* COMMIT etc. */ return POOL_BOTH; - } + } + + /* + * SET + */ + else if (IsA(node, VariableSetStmt)) + { + ListCell *list_item; + POOL_DEST ret = POOL_BOTH; /* - * PREPARE + * SET transaction_read_only TO off */ - else if (IsA(node, PrepareStmt)) + if (((VariableSetStmt *) node)->kind == VAR_SET_VALUE && + !strcmp(((VariableSetStmt *) node)->name, "transaction_read_only")) { - PrepareStmt *prepare_statement = (PrepareStmt *) node; + List *options = ((VariableSetStmt *) node)->args; - char *string = nodeToString(prepare_statement->query); + foreach(list_item, options) + { + A_Const *v = (A_Const *) lfirst(list_item); - /* Note that this is a recursive call */ - return send_to_where((Node *) (prepare_statement->query), string); + switch (nodeTag(&v->val)) + { + case T_String: + if (!strcasecmp(v->val.sval.sval, "off") || + !strcasecmp(v->val.sval.sval, "f") || + !strcasecmp(v->val.sval.sval, "false")) + ret = POOL_PRIMARY; + break; + case T_Integer: + if (!v->val.ival.ival) + ret = POOL_PRIMARY; + default: + break; + } + } + return ret; } /* - * EXECUTE + * SET TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET SESSION + * CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET + * transaction_isolation TO 'serializable' SET + * default_transaction_isolation TO 'serializable' */ - else if (IsA(node, ExecuteStmt)) + else if (is_set_transaction_serializable(node)) { - /* - * This is temporary decision. where_to_send will inherit same - * destination AS PREPARE. - */ return POOL_PRIMARY; } /* - * DEALLOCATE + * Check "SET TRANSACTION READ WRITE" "SET SESSION CHARACTERISTICS AS + * TRANSACTION READ WRITE" */ - else if (IsA(node, DeallocateStmt)) + else if (((VariableSetStmt *) node)->kind == VAR_SET_MULTI && + (!strcmp(((VariableSetStmt *) node)->name, "TRANSACTION") || + !strcmp(((VariableSetStmt *) node)->name, "SESSION CHARACTERISTICS"))) + { + List *options = ((VariableSetStmt *) node)->args; + + foreach(list_item, options) + { + DefElem *opt = (DefElem *) lfirst(list_item); + + if (!strcmp("transaction_read_only", opt->defname)) + { + bool read_only; + + read_only = ((A_Const *) opt->arg)->val.ival.ival; + if (!read_only) + return POOL_PRIMARY; + } + } + return POOL_BOTH; + } + else { /* - * This is temporary decision. where_to_send will inherit same - * destination AS PREPARE. + * All other SET command sent to both primary and standby */ - return POOL_PRIMARY; + return POOL_BOTH; } + } + + /* + * DISCARD + */ + else if (IsA(node, DiscardStmt)) + { + return POOL_BOTH; + } + + /* + * PREPARE + */ + else if (IsA(node, PrepareStmt)) + { + PrepareStmt *prepare_statement = (PrepareStmt *) node; + + /* Note that this is a recursive call */ + return send_to_where((Node *) (prepare_statement->query)); + } + /* + * EXECUTE + */ + else if (IsA(node, ExecuteStmt)) + { /* - * SHOW + * This is a temporary decision. where_to_send will inherit same + * destination as PREPARE. */ - else if (IsA(node, VariableShowStmt)) - { - return POOL_EITHER; - } + return POOL_PRIMARY; + } + /* + * DEALLOCATE + */ + else if (IsA(node, DeallocateStmt)) + { /* - * Other statements are sent to primary + * This is temporary decision. where_to_send will inherit same + * destination AS PREPARE. */ return POOL_PRIMARY; } /* - * All unknown statements are sent to primary + * SHOW + */ + else if (IsA(node, VariableShowStmt)) + { + return POOL_EITHER; + } + + /* + * All other statements are sent to primary */ return POOL_PRIMARY; } +/* + * Decide where to send given message. + * "node" must be a parse tree of either DEALLOCATE or EXECUTE. + */ static void -where_to_send_deallocate(POOL_QUERY_CONTEXT * query_context, Node *node) +where_to_send_deallocate(POOL_QUERY_CONTEXT *query_context, Node *node) { - DeallocateStmt *d = (DeallocateStmt *) node; + DeallocateStmt *d = NULL; + ExecuteStmt *e = NULL; + char *name; POOL_SENT_MESSAGE *msg; + if (IsA(node, DeallocateStmt)) + { + d = (DeallocateStmt *) node; + name = d->name; + } + else if (IsA(node, ExecuteStmt)) + { + e = (ExecuteStmt *) node; + name = e->name; + } + else + { + ereport(ERROR, + (errmsg("invalid node type for where_to_send_deallocate"))); + return; + } + /* DEALLOCATE ALL? */ - if (d->name == NULL) + if (d && (name == NULL)) { + /* send to all backend node */ pool_setall_node_to_be_sent(query_context); + return; } + + /* ordinary DEALLOCATE or EXECUTE */ else { - msg = pool_get_sent_message('Q', d->name, POOL_SENT_MESSAGE_CREATED); + /* check if message was created by SQL PREPARE */ + msg = pool_get_sent_message('Q', name, POOL_SENT_MESSAGE_CREATED); if (!msg) - msg = pool_get_sent_message('P', d->name, POOL_SENT_MESSAGE_CREATED); + /* message may be created by Parse message */ + msg = pool_get_sent_message('P', name, POOL_SENT_MESSAGE_CREATED); if (msg) { - /* Inherit same map from PREPARE or PARSE */ + /* Inherit same map from PREPARE or Parse */ pool_copy_prep_where(msg->query_context->where_to_send, query_context->where_to_send); - return; + + /* copy load balance node id as well */ + query_context->load_balance_node_id = msg->query_context->load_balance_node_id; + } + else + { + /* + * prepared statement was not found. There are two cases when this + * could happen. (1) mistakes by client. In this case backend will + * return ERROR anyway. (2) previous query was issued as + * multi-statement query. e.g. SELECT 1\;PREPARE foo AS SELECT 1; + * In this case pgpool does not know anything about the prepared + * statement "foo". + */ + if (SL_MODE) + { + /* + * In streaming replication or logical replication, sent to + * primary node only. + */ + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + else + { + /* + * In other mode, sent to all node. + */ + pool_setall_node_to_be_sent(query_context); + } } - /* prepared statement was not found */ - pool_setall_node_to_be_sent(query_context); } } @@ -1540,10 +1344,10 @@ is_set_transaction_serializable(Node *node) { A_Const *v = (A_Const *) lfirst(list_item); - switch (v->val.type) + switch (nodeTag(&v->val)) { case T_String: - if (!strcasecmp(v->val.val.str, "serializable")) + if (!strcasecmp(v->val.sval.sval, "serializable")) return true; break; default: @@ -1568,7 +1372,7 @@ is_set_transaction_serializable(Node *node) { A_Const *v = (A_Const *) opt->arg; - if (!strcasecmp(v->val.val.str, "serializable")) + if (!strcasecmp(v->val.sval.sval, "serializable")) return true; } } @@ -1610,7 +1414,7 @@ is_read_write(TransactionStmt *node) { bool read_only; - read_only = ((A_Const *) opt->arg)->val.val.ival; + read_only = ((A_Const *) opt->arg)->val.ival.ival; if (read_only) return false; /* TRANSACTION READ ONLY */ else @@ -1645,8 +1449,8 @@ is_serializable(TransactionStmt *node) if (!strcmp("transaction_isolation", opt->defname) && IsA(opt->arg, A_Const) && - ((A_Const *) opt->arg)->val.type == T_String && - !strcmp("serializable", ((A_Const *) opt->arg)->val.val.str)) + IsA(&((A_Const *) opt->arg)->val, String) && + !strcmp("serializable", ((A_Const *) opt->arg)->val.sval.sval)) return true; } return false; @@ -1654,15 +1458,15 @@ is_serializable(TransactionStmt *node) /* * If the query is BEGIN READ WRITE or - * BEGIN ... SERIALIZABLE in master/slave mode, - * we send BEGIN to slaves/standbys instead. - * original_query which is BEGIN READ WRITE is sent to primary. - * rewritten_query which is BEGIN is sent to standbys. + * BEGIN ... SERIALIZABLE in streaming replication mode, + * we send BEGIN to standbys instead. + * The original_query which is BEGIN READ WRITE is sent to primary. + * The rewritten_query BEGIN is sent to standbys. */ bool -pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT * query_context) +pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT *query_context) { - return (MASTER_SLAVE && + return (MAIN_REPLICA && is_start_transaction_query(query_context->parse_tree) && (is_read_write((TransactionStmt *) query_context->parse_tree) || is_serializable((TransactionStmt *) query_context->parse_tree))); @@ -1700,7 +1504,7 @@ is_2pc_transaction_query(Node *node) * Set query state, if a current state is before it than the specified state. */ void -pool_set_query_state(POOL_QUERY_CONTEXT * query_context, POOL_QUERY_STATE state) +pool_set_query_state(POOL_QUERY_CONTEXT *query_context, POOL_QUERY_STATE state) { int i; @@ -1929,16 +1733,16 @@ pool_is_transaction_read_only(Node *node) { A_Const *v = (A_Const *) lfirst(list_item); - switch (v->val.type) + switch (nodeTag(&v->val)) { case T_String: - if (!strcasecmp(v->val.val.str, "on") || - !strcasecmp(v->val.val.str, "t") || - !strcasecmp(v->val.val.str, "true")) + if (!strcasecmp(v->val.sval.sval, "on") || + !strcasecmp(v->val.sval.sval, "t") || + !strcasecmp(v->val.sval.sval, "true")) ret = true; break; case T_Integer: - if (v->val.val.ival) + if (v->val.ival.ival) ret = true; default: break; @@ -1964,7 +1768,7 @@ pool_is_transaction_read_only(Node *node) { bool read_only; - read_only = ((A_Const *) opt->arg)->val.val.ival; + read_only = ((A_Const *) opt->arg)->val.ival.ival; if (read_only) { ret = true; @@ -1975,3 +1779,835 @@ pool_is_transaction_read_only(Node *node) } return ret; } + +/* + * Set virtual main node according to the where_to_send map. If there are + * multiple sending requests are in the map, the first node id is set to the + * virtual_main_node_id. + */ +void +set_virtual_main_node(POOL_QUERY_CONTEXT *query_context) +{ + int i; + + for (i = 0; i < NUM_BACKENDS; i++) + { + if (query_context->where_to_send[i]) + { + query_context->virtual_main_node_id = i; + break; + } + } +} + +/* + * Set load balance info. + */ +static void +set_load_balance_info(POOL_QUERY_CONTEXT *query_context) +{ + POOL_SESSION_CONTEXT *session_context; + + session_context = pool_get_session_context(false); + + if (pool_config->statement_level_load_balance) + session_context->load_balance_node_id = select_load_balancing_node(); + + session_context->query_context->load_balance_node_id = session_context->load_balance_node_id; + + pool_set_node_to_be_sent(query_context, + query_context->load_balance_node_id); +} + +/* + * Check if the name is in the list. + */ +static bool +is_in_list(char *name, List *list) +{ + if (name == NULL || list == NIL) + return false; + + ListCell *cell; + + foreach(cell, list) + { + char *cell_name = (char *) lfirst(cell); + + if (strcasecmp(name, cell_name) == 0) + { + ereport(DEBUG1, + (errmsg("[%s] is in list", name))); + return true; + } + } + + return false; +} + +/* + * Check if the relname of SelectStmt is in the temp write list. + */ +static bool +is_select_object_in_temp_write_list(Node *node, void *context) +{ + if (node == NULL || + !DLBOW_IS_DML_ADAPTIVE(pool_config->disable_load_balance_on_write)) + return false; + + if (IsA(node, RangeVar)) + { + RangeVar *rgv = (RangeVar *) node; + POOL_SESSION_CONTEXT *session_context; + + session_context = pool_get_session_context(false); + + if (session_context->is_in_transaction) + { + ereport(DEBUG1, + (errmsg("is_select_object_in_temp_write_list: \"%s\", found relation \"%s\"", + (char *) context, rgv->relname))); + + return is_in_list(rgv->relname, + session_context->transaction_temp_write_list); + } + } + + return raw_expression_tree_walker(node, is_select_object_in_temp_write_list, context); +} + +static char *get_associated_object_from_dml_adaptive_relations + (char *left_token, DBObjectTypes object_type) +{ + int i; + char *right_token = NULL; + + if (!pool_config->parsed_dml_adaptive_object_relationship_list) + return NULL; + for (i = 0;; i++) + { + if (pool_config->parsed_dml_adaptive_object_relationship_list[i].left_token.name == NULL) + break; + + if (pool_config->parsed_dml_adaptive_object_relationship_list[i].left_token.object_type != object_type) + continue; + + if (strcasecmp(pool_config->parsed_dml_adaptive_object_relationship_list[i].left_token.name, left_token) == 0) + { + right_token = pool_config->parsed_dml_adaptive_object_relationship_list[i].right_token.name; + break; + } + } + return right_token; +} + +/* + * Check the object relationship list. + * If find the name in the list, will add related objects to the transaction temp write list. + */ +void +check_object_relationship_list(char *name, bool is_func_name) +{ + bool is_adaptive; + + is_adaptive = + (pool_config->disable_load_balance_on_write == + DLBOW_DML_ADAPTIVE); + + if (is_adaptive && + pool_config->parsed_dml_adaptive_object_relationship_list) + { + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); + + if (session_context->is_in_transaction) + { + char *right_token = + get_associated_object_from_dml_adaptive_relations + (name, is_func_name ? OBJECT_TYPE_FUNCTION : OBJECT_TYPE_RELATION); + + if (right_token) + { + MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); + + session_context->transaction_temp_write_list = + lappend(session_context->transaction_temp_write_list, pstrdup(right_token)); + MemoryContextSwitchTo(old_context); + } + } + + } +} + +/* + * Find the relname and add it to the transaction temp write list. + */ +static bool +add_object_into_temp_write_list(Node *node, void *context) +{ + if (node == NULL) + return false; + + if (IsA(node, RangeVar)) + { + RangeVar *rgv = (RangeVar *) node; + + ereport(DEBUG5, + (errmsg("add_object_into_temp_write_list: \"%s\", found relation \"%s\"", (char *) context, rgv->relname))); + + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); + MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); + + if (!is_in_list(rgv->relname, session_context->transaction_temp_write_list)) + { + ereport(DEBUG1, + (errmsg("add \"%s\" into transaction_temp_write_list", rgv->relname))); + + session_context->transaction_temp_write_list = lappend(session_context->transaction_temp_write_list, pstrdup(rgv->relname)); + } + + MemoryContextSwitchTo(old_context); + + check_object_relationship_list(rgv->relname, false); + } + + return raw_expression_tree_walker(node, add_object_into_temp_write_list, context); +} + +/* + * dml adaptive. + * + * Collect/discard information for disable_load_balance_on_write = + * dml_adaptive case. + */ +static void +dml_adaptive(Node *node, char *query) +{ + if (DLBOW_IS_DML_ADAPTIVE(pool_config->disable_load_balance_on_write)) + { + /* Set/Unset transaction status flags */ + if (IsA(node, TransactionStmt)) + { + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); + MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); + + if (is_start_transaction_query(node)) + { + session_context->is_in_transaction = true; + + if (session_context->transaction_temp_write_list != NIL) + list_free_deep(session_context->transaction_temp_write_list); + session_context->transaction_temp_write_list = NIL; + + if (session_context->transaction_temp_write_oid_list != NIL) + list_free(session_context->transaction_temp_write_oid_list); + session_context->transaction_temp_write_oid_list = NIL; + session_context->transaction_temp_write_dboid = 0; + } + else if (is_commit_or_rollback_query(node)) + { + session_context->is_in_transaction = false; + + /* The name list is only used during the transaction. */ + if (session_context->transaction_temp_write_list != NIL) + list_free_deep(session_context->transaction_temp_write_list); + session_context->transaction_temp_write_list = NIL; + + /* + * For dml_adaptive_global the resolved write OIDs must be + * flushed to shared memory only after the backend confirms + * the COMMIT succeeded. This code runs while routing the + * COMMIT, before it is sent to the backend, so the COMMIT may + * still fail (e.g. a deferred constraint violation), rolling + * back the writes -- which must then not be recorded. We + * therefore keep transaction_temp_write_oid_list intact on + * COMMIT and let handle_query_context() flush it on success + * (a failed COMMIT leaves it to be discarded by the next + * BEGIN). + * + * In every other case (plain dml_adaptive, or ROLLBACK) + * discard it now. + */ + if (!(pool_config->disable_load_balance_on_write == DLBOW_DML_ADAPTIVE_GLOBAL && + is_commit_query(node))) + { + if (session_context->transaction_temp_write_oid_list != NIL) + list_free(session_context->transaction_temp_write_oid_list); + session_context->transaction_temp_write_oid_list = NIL; + session_context->transaction_temp_write_dboid = 0; + } + } + + MemoryContextSwitchTo(old_context); + return; + } + + /* + * If non-selectStmt, find the relname and add it to the transaction + * temp write list. + */ + if (!is_select_query(node, query)) + { + add_object_into_temp_write_list(node, query); + + /* + * For dml_adaptive_global, resolve the OIDs of the tables + * actually written by this statement now, while we are routing it + * and the backend connection is idle so do_query (used by the + * relcache lookups) is safe. The OIDs are marked in shared + * memory only after the backend confirms success, in + * handle_query_context(); resolving them there would issue + * do_query into the in-flight statement/COMMIT response and hang + * the session. + */ + if (pool_config->disable_load_balance_on_write == DLBOW_DML_ADAPTIVE_GLOBAL) + { + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); + MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); + int *oids; + int num_oids; + int i; + + /* + * Outside an explicit transaction each statement stands + * alone: discard any OIDs left over from a previous (e.g. + * failed) autocommit statement so they are not marked by this + * one. Inside a transaction we accumulate until COMMIT. + */ + if (!session_context->is_in_transaction) + { + if (session_context->transaction_temp_write_oid_list != NIL) + list_free(session_context->transaction_temp_write_oid_list); + session_context->transaction_temp_write_oid_list = NIL; + session_context->transaction_temp_write_dboid = 0; + } + + num_oids = pool_extract_table_oids(node, &oids); + for (i = 0; i < num_oids; i++) + { + if (oids[i] > 0) + session_context->transaction_temp_write_oid_list = + list_append_unique_int(session_context->transaction_temp_write_oid_list, oids[i]); + } + + if (session_context->transaction_temp_write_oid_list != NIL && + session_context->transaction_temp_write_dboid <= 0) + session_context->transaction_temp_write_dboid = + pool_track_table_mutation_get_database_oid(); + + MemoryContextSwitchTo(old_context); + } + } + + } +} + +/* + * Decide the backend node for a load-balanceable SELECT when + * disable_load_balance_on_write = dml_adaptive_global. If the child is in its + * cold start window, the database OID cannot be resolved, or any table used by + * the SELECT was recently written (tracked in shared memory), the query is + * routed to the primary to avoid a stale read. Otherwise the usual load + * balancing logic (statement level load balancing and replication delay + * handling) is applied. Factored out of where_to_send_main_replica() to keep + * that function readable. + */ +static void +where_to_send_dml_adaptive_global(POOL_QUERY_CONTEXT *query_context, + char *query, Node *node, POOL_DEST dest) +{ + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); + POOL_QUERY_CONTEXT *qctx = session_context->query_context; + bool force_primary = false; + int lb_node; + + if (pool_track_table_mutation_in_cold_start()) + { + ereport(DEBUG1, + (errmsg("could not load balance because of track table mutation cold start"), + errdetail("destination = PRIMARY for query= \"%s\"", query))); + force_primary = true; + } + else + { + SelectContext ctx; + int dboid; + int num_oids; + int i; + + memset(&ctx, 0, sizeof(ctx)); + num_oids = pool_extract_table_oids_from_select_stmt(node, &ctx); + if (num_oids > 0) + { + dboid = pool_track_table_mutation_get_database_oid(); + + if (dboid <= 0) + { + ereport(DEBUG1, + (errmsg("could not load balance because database oid was unavailable"), + errdetail("destination = PRIMARY for query= \"%s\"", query))); + force_primary = true; + } + else + { + for (i = 0; i < num_oids; i++) + { + if (pool_track_table_mutation_table_is_stale(ctx.table_oids[i], dboid)) + { + ereport(DEBUG1, + (errmsg("could not load balance because table \"%s\" was recently written", ctx.table_names[i]), + errdetail("destination = PRIMARY for query= \"%s\"", query))); + force_primary = true; + break; + } + } + } + } + } + + if (force_primary) + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + return; + } + + if (pool_config->statement_level_load_balance) + session_context->load_balance_node_id = select_load_balancing_node(); + + /* + * If replication delay is too much, and prefer_lower_delay_standby is + * true then elect the lowest-delayed node, otherwise send to primary. + */ + lb_node = session_context->load_balance_node_id; + if (STREAM && check_replication_delay(lb_node)) + { + ereport(DEBUG1, + (errmsg("could not load balance because of too much replication delay"), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + if (pool_config->prefer_lower_delay_standby) + { + lb_node = select_load_balancing_node(); + session_context->load_balance_node_id = lb_node; + qctx->load_balance_node_id = lb_node; + pool_set_node_to_be_sent(query_context, lb_node); + } + else + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + } + else + { + qctx->load_balance_node_id = session_context->load_balance_node_id; + pool_set_node_to_be_sent(query_context, qctx->load_balance_node_id); + } +} + +/* + * Decide the backend node to be sent in streaming replication mode, logical + * replication mode. Called by pool_where_to_send. + */ +static void +where_to_send_main_replica(POOL_QUERY_CONTEXT *query_context, char *query, Node *node) +{ + POOL_DEST dest; + POOL_SESSION_CONTEXT *session_context; + POOL_CONNECTION_POOL *backend; + + /* + * From syntactically analysis decide the statement to be sent to the + * primary, the standby or either or both. + */ + dest = send_to_where(node); + + session_context = pool_get_session_context(false); + backend = session_context->backend; + + /* + * Collect/discard information for disable_load_balance_on_write = + * dml_adaptive case. + */ + dml_adaptive(node, query); + + ereport(DEBUG1, + (errmsg("decide where to send the query"), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + /* Should be sent to primary only? */ + if (dest == POOL_PRIMARY) + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + + /* + * Resolve table and database OIDs now to populate relcache. This + * avoids potential hangs in CommandComplete where we shouldn't be + * running new queries against the backend. + */ + if (pool_config->disable_load_balance_on_write == + DLBOW_DML_ADAPTIVE_GLOBAL) + { + int *oids; + + pool_extract_table_oids(node, &oids); + pool_track_table_mutation_get_database_oid(); + } + } + /* Should be sent to both primary and standby? */ + else if (dest == POOL_BOTH) + { + if (is_tx_started_by_multi_statement_query()) + { + /* + * If we are in an explicit transaction and the transaction was + * started by a multi statement query, we should send query to + * primary node only (which was supposed to be sent to all nodes) + * until the transaction gets committed or aborted. + */ + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + else + { + pool_setall_node_to_be_sent(query_context); + } + } + else if (pool_is_writing_transaction() && + pool_config->disable_load_balance_on_write == DLBOW_ALWAYS) + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + + /* + * Ok, we might be able to load balance the SELECT query. + */ + else + { + if (pool_config->load_balance_mode && + is_select_query(node, query) && + MAJOR(backend) == PROTO_MAJOR_V3) + { + /* + * If (we are outside of an explicit transaction) OR (the + * transaction has not issued a write query yet, AND transaction + * isolation level is not SERIALIZABLE) we might be able to load + * balance. + */ + ereport(DEBUG1, + (errmsg("checking load balance preconditions. TSTATE:%c writing_transaction:%d failed_transaction:%d", + TSTATE(backend, PRIMARY_NODE_ID), + pool_is_writing_transaction(), + pool_is_failed_transaction()), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + if (TSTATE(backend, PRIMARY_NODE_ID) == 'I' || + (!pool_is_writing_transaction() && + !pool_is_failed_transaction() && + pool_get_transaction_isolation() != POOL_SERIALIZABLE)) + { + /* + * Load balance if possible + */ + + /* + * If system catalog is used in the SELECT, we prefer to send + * to the primary. Example: SELECT * FROM pg_class WHERE + * relname = 't1'; Because 't1' is a constant, it's hard to + * recognize as table name. Most use case such query is + * against system catalog, and the table name can be a + * temporary table, it's best to query against primary system + * catalog. Please note that this test must be done *before* + * test using pool_has_temp_table. + */ + if (pool_has_system_catalog(node)) + { + ereport(DEBUG1, + (errmsg("could not load balance because systems catalogs are used"), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + + /* + * If temporary table is used in the SELECT, we prefer to send + * to the primary. + */ + else if (pool_config->check_temp_table && pool_has_temp_table(node)) + { + ereport(DEBUG1, + (errmsg("could not load balance because temporary tables are used"), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + + /* + * If unlogged table is used in the SELECT, we prefer to send + * to the primary. + */ + else if (pool_config->check_unlogged_table && pool_has_unlogged_table(node)) + { + ereport(DEBUG1, + (errmsg("could not load balance because unlogged tables are used"), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + + /* + * When query match the query patterns in + * primary_routing_query_pattern_list, we send only to main + * node. + */ + else if (pattern_compare(query, WRITELIST, "primary_routing_query_pattern_list") == 1) + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + + /* + * If a writing function call is used, we prefer to send to + * the primary. + */ + else if (pool_has_function_call(node)) + { + ereport(DEBUG1, + (errmsg("could not load balance because writing functions are used"), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + else if (is_select_object_in_temp_write_list(node, query)) + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + + /* + * Check track table mutation for recently written tables. If + * in cold start or any table was recently written, route to + * primary to avoid stale reads. + */ + else if (pool_config->disable_load_balance_on_write == + DLBOW_DML_ADAPTIVE_GLOBAL) + { + where_to_send_dml_adaptive_global(query_context, query, node, dest); + } + else + { + if (pool_config->statement_level_load_balance) + { + session_context->load_balance_node_id = select_load_balancing_node(); + } + + /* + * As streaming replication delay is too much, if + * prefer_lower_delay_standby is true then elect new load + * balance node which is lowest delayed, false then send + * to the primary. + */ + if (check_replication_delay(session_context->load_balance_node_id)) + { + ereport(DEBUG1, + (errmsg("could not load balance because of too much replication delay"), + errdetail("destination = %d for query= \"%s\"", dest, query))); + + /* + * If prefer_lower_delay_standby is on, choose lower + * delay standby. + */ + if (pool_config->prefer_lower_delay_standby) + { + int new_load_balancing_node = select_load_balancing_node(); + + session_context->load_balance_node_id = new_load_balancing_node; + session_context->query_context->load_balance_node_id = session_context->load_balance_node_id; + pool_set_node_to_be_sent(query_context, session_context->query_context->load_balance_node_id); + } + else /* delay is too much. prefer to send to + * primary */ + { + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + } + + /* + * Not streaming replication mode, or delay_threshold is 0 + * or replication delay is small enough. + */ + else + { + session_context->query_context->load_balance_node_id = session_context->load_balance_node_id; + pool_set_node_to_be_sent(query_context, + session_context->query_context->load_balance_node_id); + } + } + } + else + { + /* Send to the primary only */ + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + } + else + { + /* Send to the primary only */ + pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); + } + } +} + +/* + * Decide the backend node to be sent in replication mode and snapshot + * isolation mode. + * Called by pool_where_to_send. + */ +static void +where_to_send_native_replication(POOL_QUERY_CONTEXT *query_context, char *query, Node *node) +{ + POOL_SESSION_CONTEXT *session_context; + POOL_CONNECTION_POOL *backend; + + session_context = pool_get_session_context(false); + backend = session_context->backend; + + /* + * Check to see if we can load balance the SELECT (or any read only query + * from syntactical point of view). + */ + elog(DEBUG1, "Maybe: load balance mode: %d is_select_query: %d", + pool_config->load_balance_mode, is_select_query(node, query)); + + if (pool_config->load_balance_mode && + is_select_query(node, query) && + MAJOR(backend) == PROTO_MAJOR_V3) + { + /* + * In snapshot isolation mode, we always load balance if current + * transaction is read only unless load balance mode is off. + */ + if (pool_config->backend_clustering_mode == CM_SNAPSHOT_ISOLATION && + pool_config->load_balance_mode) + { + if (TSTATE(backend, MAIN_NODE_ID) == 'T') + { + /* + * We are in an explicit transaction. If the transaction is + * read only, we can load balance. + */ + if (session_context->transaction_read_only) + { + /* Ok, we can load balance. We are done! */ + set_load_balance_info(query_context); + set_virtual_main_node(query_context); + return; + } + } + else if (TSTATE(backend, MAIN_NODE_ID) == 'I') + { + /* + * We are out side transaction. If default transaction is read + * only, we can load balance. + */ + static char *si_query = "SELECT current_setting('transaction_read_only')"; + POOL_SELECT_RESULT *res; + bool load_balance = false; + + do_query(CONNECTION(backend, MAIN_NODE_ID), si_query, &res, MAJOR(backend)); + if (res) + { + if (res->data[0] && !strcmp(res->data[0], "on")) + { + load_balance = true; + } + free_select_result(res); + } + + per_node_statement_log(backend, MAIN_NODE_ID, si_query); + + if (load_balance) + { + /* Ok, we can load balance. We are done! */ + set_load_balance_info(query_context); + set_virtual_main_node(query_context); + return; + } + } + } + + /* + * If a writing function call is used or replicate_select is true, we + * have to send to all nodes since the function may modify database. + */ + elog(DEBUG1, "Maybe sent to all node: pool_has_function_call: %d pool_config->replicate_select: %d", + pool_has_function_call(node), pool_config->replicate_select); + if (pool_has_function_call(node) || pool_config->replicate_select) + { + pool_setall_node_to_be_sent(query_context); + } + + /* + * If (we are outside of an explicit transaction) OR (the transaction + * has not issued a write query yet, AND transaction isolation level + * is not SERIALIZABLE) we might be able to load balance. + */ + else if (TSTATE(backend, MAIN_NODE_ID) == 'I' || + (!pool_is_writing_transaction() && + !pool_is_failed_transaction() && + pool_get_transaction_isolation() != POOL_SERIALIZABLE)) + { + elog(DEBUG1, "load balance TSTATE: %c pool_is_writing_transaction: %d pool_is_failed_transaction: %d", + TSTATE(backend, MAIN_NODE_ID), + pool_is_writing_transaction(), + pool_is_failed_transaction()); + set_load_balance_info(query_context); + } + else + { + /* only send to main node */ + elog(DEBUG1, "unable to load balance"); + pool_set_node_to_be_sent(query_context, REAL_MAIN_NODE_ID); + } + } + else + { + if (is_select_query(node, query) && !pool_config->replicate_select && + !pool_has_function_call(node)) + { + /* only send to main node */ + pool_set_node_to_be_sent(query_context, REAL_MAIN_NODE_ID); + } + else + { + /* send to all nodes */ + pool_setall_node_to_be_sent(query_context); + } + } +} + +/* + * Wait for failover/failback to finish. + * Return values: + * 0: no failover/failback occurred. + * -1: failover/failback occurred and finished within certain period. + * -2: failover/failback occurred and timed out. + */ +int +wait_for_failover_to_finish(void) +{ +#define MAX_FAILOVER_WAIT 30 /* waiting for failover finish timeout in + * seconds */ + + volatile POOL_REQUEST_INFO *my_req; + int ret = 0; + int i; + + /* + * Wait for failover to finish + */ + for (i = 0; i < MAX_FAILOVER_WAIT; i++) + { + my_req = Req_info; + if (my_req->switching == 0) + return ret; + ret = -1; /* failover/failback finished */ + sleep(1); + } + return -2; /* timed out */ +} diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c index d6514c632..0bab75ea6 100644 --- a/src/context/pool_session_context.c +++ b/src/context/pool_session_context.c @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -27,15 +27,20 @@ #include "utils/memutils.h" #include "utils/elog.h" #include "pool_config.h" -#include "context/pool_session_context.h" #include "protocol/pool_proto_modules.h" +#include "protocol/pool_process_query.h" +#include "protocol/pool_connection_pool.h" +#include "protocol/pool_pg_utils.h" +#include "context/pool_session_context.h" static POOL_SESSION_CONTEXT session_context_d; -static POOL_SESSION_CONTEXT * session_context = NULL; +static POOL_SESSION_CONTEXT *session_context = NULL; static void GetTranIsolationErrorCb(void *arg); static void init_sent_message_list(void); -static POOL_PENDING_MESSAGE * copy_pending_message(POOL_PENDING_MESSAGE * messag); -static void dump_sent_message(char *caller, POOL_SENT_MESSAGE * m); +static POOL_PENDING_MESSAGE *copy_pending_message(POOL_PENDING_MESSAGE *message); +static void dump_sent_message(char *caller, POOL_SENT_MESSAGE *m); +static void dml_adaptive_init(void); +static void dml_adaptive_destroy(void); #ifdef PENDING_MESSAGE_DEBUG static int Elevel = LOG; @@ -47,7 +52,7 @@ static int Elevel = DEBUG2; * Initialize per session context */ void -pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) +pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { session_context = &session_context_d; ProcessInfo *process_info; @@ -71,7 +76,7 @@ pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * bac session_context->query_context = NULL; /* Initialize local session id */ - pool_incremnet_local_session_id(); + pool_increment_local_session_id(); /* Create memory context */ /* TODO re-think about the parent for this context ?? */ @@ -91,13 +96,13 @@ pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * bac (errmsg("failed to get process info for current process"))); /* Choose load balancing node if necessary */ - if (pool_config->load_balance_mode) + if (!RAW_MODE && pool_config->load_balance_mode) { node_id = select_load_balancing_node(); } else { - node_id = SL_MODE ? PRIMARY_NODE_ID : MASTER_NODE_ID; + node_id = SL_MODE ? PRIMARY_NODE_ID : MAIN_NODE_ID; } session_context->load_balance_node_id = node_id; @@ -120,6 +125,7 @@ pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * bac /* We don't have a write query in this transaction yet */ pool_unset_writing_transaction(); + pool_unset_really_writing_transaction(); /* Error doesn't occur in this transaction yet */ pool_unset_failed_transaction(); @@ -133,11 +139,11 @@ pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * bac /* Backends have not ignored messages yet */ pool_unset_ignore_till_sync(); - /* Initialize where to send map for PREPARE statements */ -#ifdef NOT_USED - memset(&session_context->prep_where, 0, sizeof(session_context->prep_where)); - session_context->prep_where.nelem = POOL_MAX_PREPARED_STATEMENTS; -#endif /* NOT_USED */ + /* Unset suspend reading from frontend flag */ + pool_unset_suspend_reading_from_frontend(); + + /* Unset suspend reading from frontend (copy in) flag */ + pool_unset_suspend_reading_from_frontend_copy_in(); /* * Reset flag to indicate difference in number of affected tuples in @@ -157,10 +163,22 @@ pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * bac /* Initialize previous pending message */ pool_pending_message_reset_previous_message(); -#ifdef NOT_USED - /* Initialize preferred master node id */ - pool_reset_preferred_master_node_id(); -#endif + /* Initialize temp tables */ + pool_temp_tables_init(); + + /* Snapshot isolation state */ + session_context->si_state = SI_NO_SNAPSHOT; + + /* Transaction read only */ + session_context->transaction_read_only = false; + + dml_adaptive_init(); + + unset_tx_started_by_multi_statement_query(); + + unset_query_cache_disabled(); + + unset_query_cache_disabled_tx(); } /* @@ -182,6 +200,8 @@ pool_session_context_destroy(void) if (session_context->query_context) pool_query_context_destroy(session_context->query_context); MemoryContextDelete(session_context->memory_context); + + dml_adaptive_destroy(); } /* XXX For now, just zap memory */ memset(&session_context_d, 0, sizeof(session_context_d)); @@ -246,7 +266,7 @@ pool_unset_query_in_progress(void) s->in_progress = false; - /* Restore where_to_send map if neccessary */ + /* Restore where_to_send map if necessary */ if (s->need_to_restore_where_to_send) { memcpy(s->query_context->where_to_send, s->where_to_send_save, sizeof(s->where_to_send_save)); @@ -418,7 +438,7 @@ pool_remove_sent_messages(char kind) * Destroy sent message */ void -pool_sent_message_destroy(POOL_SENT_MESSAGE * message) +pool_sent_message_destroy(POOL_SENT_MESSAGE *message) { bool in_progress; POOL_QUERY_CONTEXT *qc = NULL; @@ -481,14 +501,64 @@ pool_clear_sent_message_list(void) } } +/* + * Zap query context info in sent messages to indicate that the query context + * has been already removed. + */ +void +pool_zap_query_context_in_sent_messages(POOL_QUERY_CONTEXT *query_context) +{ + int i; + POOL_SENT_MESSAGE_LIST *msglist; + + msglist = &pool_get_session_context(false)->message_list; + + for (i = 0; i < msglist->size; i++) + { + elog(DEBUG5, "checking zapping sent message: %p query_context: %p", + &msglist->sent_messages[i], msglist->sent_messages[i]->query_context); + if (msglist->sent_messages[i]->query_context == query_context) + { + msglist->sent_messages[i]->query_context = NULL; + elog(DEBUG5, "Zap sent message: %p", &msglist->sent_messages[i]); + } + } +} + static void -dump_sent_message(char *caller, POOL_SENT_MESSAGE * m) +dump_sent_message(char *caller, POOL_SENT_MESSAGE *m) { ereport(DEBUG5, (errmsg("called by %s: sent message: address: %p kind: %c name: =%s= state:%d", caller, m, m->kind, m->name, m->state))); } +static void +dml_adaptive_init(void) +{ + if (DLBOW_IS_DML_ADAPTIVE(pool_config->disable_load_balance_on_write)) + { + session_context->is_in_transaction = false; + session_context->transaction_temp_write_list = NIL; + session_context->transaction_temp_write_oid_list = NIL; + session_context->transaction_temp_write_dboid = 0; + } +} + +static void +dml_adaptive_destroy(void) +{ + if (DLBOW_IS_DML_ADAPTIVE( + pool_config->disable_load_balance_on_write) && + session_context) + { + if (session_context->transaction_temp_write_list != NIL) + list_free_deep(session_context->transaction_temp_write_list); + if (session_context->transaction_temp_write_oid_list != NIL) + list_free(session_context->transaction_temp_write_oid_list); + } +} + /* * Create a sent message. * kind: one of 'P':Parse, 'B':Bind or 'Q':Query(PREPARE) @@ -500,7 +570,7 @@ dump_sent_message(char *caller, POOL_SENT_MESSAGE * m) POOL_SENT_MESSAGE * pool_create_sent_message(char kind, int len, char *contents, int num_tsparams, const char *name, - POOL_QUERY_CONTEXT * query_context) + POOL_QUERY_CONTEXT *query_context) { POOL_SENT_MESSAGE *msg; @@ -529,7 +599,7 @@ pool_create_sent_message(char kind, int len, char *contents, * Add a sent message to sent message list */ void -pool_add_sent_message(POOL_SENT_MESSAGE * message) +pool_add_sent_message(POOL_SENT_MESSAGE *message) { POOL_SENT_MESSAGE *old_msg; POOL_SENT_MESSAGE_LIST *msglist; @@ -594,7 +664,7 @@ pool_add_sent_message(POOL_SENT_MESSAGE * message) } /* - * Get a sent message + * Find a sent message by kind and name. */ POOL_SENT_MESSAGE * pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state) @@ -618,11 +688,34 @@ pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state return NULL; } +/* + * Find a sent message by query context. + */ +POOL_SENT_MESSAGE * +pool_get_sent_message_by_query_context(POOL_QUERY_CONTEXT *query_context) +{ + int i; + POOL_SENT_MESSAGE_LIST *msglist; + + msglist = &pool_get_session_context(false)->message_list; + + if (query_context == NULL) + return NULL; + + for (i = 0; i < msglist->size; i++) + { + if (msglist->sent_messages[i]->query_context == query_context) + return msglist->sent_messages[i]; + } + + return NULL; +} + /* * Set message state to POOL_SENT_MESSAGE_STATE to POOL_SENT_MESSAGE_CLOSED. */ void -pool_set_sent_message_state(POOL_SENT_MESSAGE * message) +pool_set_sent_message_state(POOL_SENT_MESSAGE *message) { ereport(DEBUG5, (errmsg("pool_set_sent_message_state: name:%s kind:%c previous state: %d", @@ -648,6 +741,12 @@ pool_unset_writing_transaction(void) } } +void +pool_unset_really_writing_transaction(void) +{ + pool_get_session_context(false)->really_writing_transaction = false; +} + /* * We have a write query in this transaction. */ @@ -655,10 +754,13 @@ void pool_set_writing_transaction(void) { /* - * If disable_transaction_on_write is 'off', then never turn on writing - * transaction flag. + * If disable_load_balance_on_write is 'off' or 'dml_adaptive' or + * 'dml_adaptive_global', then never turn on writing transaction flag. */ - if (pool_config->disable_load_balance_on_write != DLBOW_OFF) + if (pool_config->disable_load_balance_on_write != + DLBOW_OFF && + !DLBOW_IS_DML_ADAPTIVE( + pool_config->disable_load_balance_on_write)) { pool_get_session_context(false)->writing_transaction = true; ereport(DEBUG5, @@ -666,6 +768,12 @@ pool_set_writing_transaction(void) } } +void +pool_set_really_writing_transaction(void) +{ + pool_get_session_context(false)->really_writing_transaction = true; +} + /* * Do we have a write query in this transaction? */ @@ -675,6 +783,15 @@ pool_is_writing_transaction(void) return pool_get_session_context(false)->writing_transaction; } +/* + * Do we really have a write query in this transaction? + */ +bool +pool_is_really_writing_transaction(void) +{ + return pool_get_session_context(false)->really_writing_transaction; +} + /* * Error doesn't occur in this transaction yet. */ @@ -761,7 +878,7 @@ pool_get_transaction_isolation(void) /* No cached data is available. Ask backend. */ - do_query(MASTER(session_context->backend), + do_query(MAIN(session_context->backend), "SELECT current_setting('transaction_isolation')", &res, MAJOR(session_context->backend)); error_context_stack = callback.previous; @@ -860,81 +977,7 @@ pool_copy_prep_where(bool *src, bool *dest) { memcpy(dest, src, sizeof(bool) * MAX_NUM_BACKENDS); } -#ifdef NOT_USED -/* - * Add to send map a PREPARED statement - */ -void -pool_add_prep_where(char *name, bool *map) -{ - int i; - - if (!session_context) - { - ereport(ERROR, - (errmsg("pool_add_prep_where: session context is not initialized"))); - return; - } - - for (i = 0; i < POOL_MAX_PREPARED_STATEMENTS; i++) - { - if (*session_context->prep_where.name[i] == '\0') - { - strncpy(session_context->prep_where.name[i], name, POOL_MAX_PREPARED_NAME); - pool_copy_prep_where(map, session_context->prep_where.where_to_send[i]); - return; - } - } - ereport(ERROR, - (errmsg("pool_add_prep_where: no empty slot found"))); -} - -/* - * Search send map by PREPARED statement name - */ -bool * -pool_get_prep_where(char *name) -{ - int i; - - if (!session_context) - ereport(ERROR, - (errmsg("pool_get_prep_where: session context is not initialized"))); - - - for (i = 0; i < POOL_MAX_PREPARED_STATEMENTS; i++) - { - if (!strcmp(session_context->prep_where.name[i], name)) - { - return session_context->prep_where.where_to_send[i]; - } - } - return NULL; -} -/* - * Remove PREPARED statement by name - */ -void -pool_delete_prep_where(char *name) -{ - int i; - - if (!session_context) - ereport(ERROR, - (errmsg("pool_delete_prep_where: session context is not initialized"))); - - for (i = 0; i < POOL_MAX_PREPARED_STATEMENTS; i++) - { - if (!strcmp(session_context->prep_where.name[i], name)) - { - memset(&session_context->prep_where.where_to_send[i], 0, sizeof(bool) * MAX_NUM_BACKENDS); - *session_context->prep_where.name[i] = '\0'; - return; - } - } -} -#endif /* NOT_USED */ /* * Initialize sent message list */ @@ -959,7 +1002,7 @@ init_sent_message_list(void) * is used. Returns true if it is not used. */ bool -can_query_context_destroy(POOL_QUERY_CONTEXT * qc) +can_query_context_destroy(POOL_QUERY_CONTEXT *qc) { int i; int count = 0; @@ -993,7 +1036,7 @@ can_query_context_destroy(POOL_QUERY_CONTEXT * qc) { count++; } - next = lnext(cell); + next = lnext(session_context->pending_messages, cell); } if (count >= 1) @@ -1031,7 +1074,7 @@ pool_pending_messages_destroy(void) if (!session_context) ereport(ERROR, - (errmsg("pool_pending_message_destory: session context is not initialized"))); + (errmsg("pool_pending_message_destroy: session context is not initialized"))); foreach(cell, session_context->pending_messages) { @@ -1085,7 +1128,7 @@ pool_pending_message_create(char kind, int len, char *contents) default: ereport(ERROR, - (errmsg("pool_pending_message_create: unknow kind: %c", kind))); + (errmsg("pool_pending_message_create: unknown kind: %c", kind))); break; } @@ -1103,7 +1146,8 @@ pool_pending_message_create(char kind, int len, char *contents) msg->portal[0] = '\0'; msg->is_rows_returned = false; msg->not_forward_to_frontend = false; - msg->node_ids[0] = msg->node_ids[1] = -1; + memset(msg->node_ids, false, sizeof(msg->node_ids)); + msg->flush_pending = false; MemoryContextSwitchTo(old_context); @@ -1115,24 +1159,9 @@ pool_pending_message_create(char kind, int len, char *contents) * message was sent. */ void -pool_pending_message_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context) +pool_pending_message_dest_set(POOL_PENDING_MESSAGE *message, POOL_QUERY_CONTEXT *query_context) { - int i; - int j = 0; - - for (i = 0; i < MAX_NUM_BACKENDS; i++) - { - if (query_context->where_to_send[i]) - { - if (j > 1) - { - ereport(ERROR, - (errmsg("pool_pending_messages_dest_set: node ids exceeds 2"))); - return; - } - message->node_ids[j++] = i; - } - } + memcpy(message->node_ids, query_context->where_to_send, sizeof(message->node_ids)); message->query_context = query_context; @@ -1147,7 +1176,7 @@ pool_pending_message_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * which indicates which backend nodes the message was sent. */ void -pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context) +pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE *message, POOL_QUERY_CONTEXT *query_context) { int i; @@ -1160,11 +1189,11 @@ pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE * message, POOL /* Rewrite where_to_send map */ memset(query_context->where_to_send, 0, sizeof(query_context->where_to_send)); - for (i = 0; i < 2; i++) + for (i = 0; i < MAX_NUM_BACKENDS; i++) { - if (message->node_ids[i] != -1) + if (message->node_ids[i]) { - query_context->where_to_send[message->node_ids[i]] = 1; + query_context->where_to_send[i] = 1; } } } @@ -1173,18 +1202,17 @@ pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE * message, POOL * Set query field of message. */ void -pool_pending_message_query_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context) +pool_pending_message_query_set(POOL_PENDING_MESSAGE *message, POOL_QUERY_CONTEXT *query_context) { StrNCpy(message->query, query_context->original_query, sizeof(message->query)); } /* - * Add one message to the tail of the list + * Add one message to the tail of the list. */ void -pool_pending_message_add(POOL_PENDING_MESSAGE * message) +pool_pending_message_add(POOL_PENDING_MESSAGE *message) { - POOL_PENDING_MESSAGE *msg; MemoryContext old_context; if (!session_context) @@ -1236,8 +1264,7 @@ pool_pending_message_add(POOL_PENDING_MESSAGE * message) (errmsg("pool_pending_message_add: message type: sync"))); old_context = MemoryContextSwitchTo(session_context->memory_context); - msg = copy_pending_message(message); - session_context->pending_messages = lappend(session_context->pending_messages, msg); + session_context->pending_messages = lappend(session_context->pending_messages, message); MemoryContextSwitchTo(old_context); } @@ -1313,7 +1340,7 @@ pool_pending_message_pull_out(void) pool_pending_message_free_pending_message(m); session_context->pending_messages = - list_delete_cell(session_context->pending_messages, cell, NULL); + list_delete_cell(session_context->pending_messages, cell); MemoryContextSwitchTo(old_context); return message; @@ -1343,7 +1370,7 @@ pool_pending_message_get(POOL_MESSAGE_TYPE type) { POOL_PENDING_MESSAGE *m = (POOL_PENDING_MESSAGE *) lfirst(cell); - next = lnext(cell); + next = lnext(session_context->pending_messages, cell); if (m->type == type) { @@ -1361,7 +1388,7 @@ pool_pending_message_get(POOL_MESSAGE_TYPE type) * close message. */ char -pool_get_close_message_spec(POOL_PENDING_MESSAGE * msg) +pool_get_close_message_spec(POOL_PENDING_MESSAGE *msg) { return *msg->contents; } @@ -1371,7 +1398,7 @@ pool_get_close_message_spec(POOL_PENDING_MESSAGE * msg) * The returned pointer is within "msg". */ char * -pool_get_close_message_name(POOL_PENDING_MESSAGE * msg) +pool_get_close_message_name(POOL_PENDING_MESSAGE *msg) { return (msg->contents) + 1; } @@ -1380,7 +1407,8 @@ pool_get_close_message_name(POOL_PENDING_MESSAGE * msg) * Perform deep copy of POOL_PENDING_MESSAGE object in the current memory * context except the query context. */ -static POOL_PENDING_MESSAGE * copy_pending_message(POOL_PENDING_MESSAGE * message) +static POOL_PENDING_MESSAGE * +copy_pending_message(POOL_PENDING_MESSAGE *message) { POOL_PENDING_MESSAGE *msg; @@ -1397,7 +1425,7 @@ static POOL_PENDING_MESSAGE * copy_pending_message(POOL_PENDING_MESSAGE * messag * context except the query context. */ void -pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE * message) +pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE *message) { if (message == NULL) return; @@ -1427,7 +1455,7 @@ pool_pending_message_reset_previous_message(void) * Set previous message. */ void -pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE * message) +pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE *message) { if (!session_context) { @@ -1475,7 +1503,7 @@ const char * pool_pending_message_type_to_string(POOL_MESSAGE_TYPE type) { static const char *pending_msg_string[] = {"Parse", "Bind", "Execute", - "Descripbe", "Close", "Sync"}; + "Describe", "Close", "Sync"}; if (type < 0 || type > POOL_SYNC) return "unknown type"; @@ -1528,7 +1556,7 @@ pool_check_pending_message_and_reply(POOL_MESSAGE_TYPE type, char kind) * pool_pending_message_free_pending_message. */ POOL_PENDING_MESSAGE * -pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT * qc) +pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT *qc) { List *msgs; POOL_PENDING_MESSAGE *msg; @@ -1580,15 +1608,21 @@ pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT * qc) * the pending message is one of primary or standby node. */ int -pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE * msg) +pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE *msg) { int backend_id = -1; + int i; - if (msg->node_ids[0] != -1) - backend_id = msg->node_ids[0]; - else if (msg->node_ids[1] != -1) - backend_id = msg->node_ids[1]; - else + for (i = 0; i < MAX_NUM_BACKENDS; i++) + { + if (msg->node_ids[i]) + { + backend_id = i; + break; + } + } + + if (backend_id == -1) ereport(ERROR, (errmsg("pool_pending_message_get_target_backend_id: no target backend id found"))); @@ -1603,7 +1637,8 @@ pool_pending_message_get_message_num_by_backend_id(int backend_id) { ListCell *cell; ListCell *next; - int cnt = 0; + int cnt = 0; + int i; if (!session_context) { @@ -1616,14 +1651,39 @@ pool_pending_message_get_message_num_by_backend_id(int backend_id) { POOL_PENDING_MESSAGE *msg = (POOL_PENDING_MESSAGE *) lfirst(cell); - if (msg->node_ids[0] == backend_id || msg->node_ids[1] == backend_id) - cnt++; + for (i = 0; i < MAX_NUM_BACKENDS; i++) + { + if (msg->node_ids[i] && i == backend_id) + { + cnt++; + break; + } + } - next = lnext(cell); + next = lnext(session_context->pending_messages, cell); } return cnt; } +/* + * Set flush request flag + */ +void +pool_pending_message_set_flush_request(void) +{ + ListCell *msg_item; + + foreach(msg_item, session_context->pending_messages) + { + POOL_PENDING_MESSAGE *msg = (POOL_PENDING_MESSAGE *) lfirst(msg_item); + + msg->flush_pending = true; + ereport(DEBUG5, + (errmsg("pool_pending_message_set_flush_request: msg: %s", + pool_pending_message_type_to_string(msg->type)))); + } +} + /* * Dump whole pending message list */ @@ -1640,6 +1700,9 @@ dump_pending_message(void) return; } + if (!message_level_is_interesting(DEBUG5)) + return; + ereport(DEBUG5, (errmsg("start dumping pending message list"))); @@ -1652,7 +1715,7 @@ dump_pending_message(void) message->type, message->contents_len, message->query, message->statement, message->portal, message->node_ids[0], message->node_ids[1]))); - next = lnext(cell); + next = lnext(session_context->pending_messages, cell); } ereport(DEBUG5, @@ -1709,34 +1772,448 @@ pool_get_minor_version(void) return 0; } -#ifdef NOT_USED /* - * Set preferred "master" node id. - * Only used for SimpleForwardToFrontend. + * Is suspend_reading_from_frontend flag set? + */ +bool +pool_is_suspend_reading_from_frontend(void) +{ + return session_context->suspend_reading_from_frontend; +} + +/* + * Set suspend_reading_from_frontend flag. */ void -pool_set_preferred_master_node_id(int node_id) +pool_set_suspend_reading_from_frontend(void) { - session_context->preferred_master_node_id = node_id; + session_context->suspend_reading_from_frontend = true; } /* - * Return preferred "master" node id. - * Only used for SimpleForwardToFrontend. + * Unset suspend_reading_from_frontend flag. */ -int -pool_get_preferred_master_node_id(void) +void +pool_unset_suspend_reading_from_frontend(void) { - return session_context->preferred_master_node_id; + session_context->suspend_reading_from_frontend = false; } /* - * Reset preferred "master" node id. - * Only used for SimpleForwardToFrontend. + * Is suspend_reading_from_frontend_copy_in flag set? + */ +bool +pool_is_suspend_reading_from_frontend_copy_in(void) +{ + return session_context->suspend_reading_from_frontend_copy_in; +} + +/* + * Set suspend_reading_from_frontend_copy_in flag. */ void -pool_reset_preferred_master_node_id(void) +pool_set_suspend_reading_from_frontend_copy_in(void) { - session_context->preferred_master_node_id = -1; + session_context->suspend_reading_from_frontend_copy_in = true; } + +/* + * Unset suspend_reading_from_frontend_copy_in flag. + */ +void +pool_unset_suspend_reading_from_frontend_copy_in(void) +{ + session_context->suspend_reading_from_frontend_copy_in = false; +} + +/*----------------------------------------------------------------------- + * Temporary table list management modules. + *----------------------------------------------------------------------- + */ + +/* + * Initialize temp table list + */ +void +pool_temp_tables_init(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_init: session context is not initialized"))); + + session_context->temp_tables = NIL; +} + +/* + * Destroy temp table list + */ +void +pool_temp_tables_destroy(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_destroy: session context is not initialized"))); + + list_free(session_context->temp_tables); +} + +/* + * Add a temp table to the tail of the list. + * If the table already exists, just replace state. + */ +void +pool_temp_tables_add(char *tablename, POOL_TEMP_TABLE_STATE state) +{ + MemoryContext old_context; + POOL_TEMP_TABLE *table; + + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_add: session context is not initialized"))); + + old_context = MemoryContextSwitchTo(session_context->memory_context); + + table = pool_temp_tables_find(tablename); + if (table) + { + /* Table already exists. Just replace state. */ + table->state = state; + } + else + { + table = palloc(sizeof(POOL_TEMP_TABLE)); + StrNCpy(table->tablename, tablename, sizeof(table->tablename)); + table->state = state; + session_context->temp_tables = lappend(session_context->temp_tables, table); + } + + MemoryContextSwitchTo(old_context); +} + +/* + * Returns pointer to the table cell if specified tablename is in the temp table list. + */ + +POOL_TEMP_TABLE * +pool_temp_tables_find(char *tablename) +{ + ListCell *cell; + + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_find: session context is not initialized"))); + + foreach(cell, session_context->temp_tables) + { + POOL_TEMP_TABLE *table = (POOL_TEMP_TABLE *) lfirst(cell); + + if (strcmp(tablename, table->tablename) == 0) + return table; + } + return NULL; +} + +/* + * If requested state or table state is TEMP_TABLE_DROP_COMMITTED, removes the + * temp table entry from the list. Otherwise just set the requested state to + * the table state. + */ +void +pool_temp_tables_delete(char *tablename, POOL_TEMP_TABLE_STATE state) +{ + POOL_TEMP_TABLE *table; + MemoryContext old_context; + + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_delete: session context is not initialized"))); + + ereport(LOG, + (errmsg("pool_temp_tables_delete: table: %s state: %d", tablename, state))); + + old_context = MemoryContextSwitchTo(session_context->memory_context); + + table = pool_temp_tables_find(tablename); + + if (table) + { + if (table->state == TEMP_TABLE_DROP_COMMITTED) + { + ereport(DEBUG1, + (errmsg("pool_temp_tables_delete: remove %s. previous state: %d requested state: %d", + table->tablename, table->state, state))); + + session_context->temp_tables = list_delete_ptr(session_context->temp_tables, table); + } + else + { + ereport(DEBUG1, + (errmsg("pool_temp_tables_delete: set state %s. previous state: %d requested state: %d", + table->tablename, table->state, state))); + table->state = state; + } + } + + MemoryContextSwitchTo(old_context); +} + +/* + * Commits creating entries. Also remove dropping entries. This is supposed to + * be called when an explicit transaction commits. + */ +void +pool_temp_tables_commit_pending(void) +{ + ListCell *cell; + MemoryContext old_context; + + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_commit_pending: session context is not initialized"))); + + old_context = MemoryContextSwitchTo(session_context->memory_context); + + pool_temp_tables_dump(); + +Retry: + foreach(cell, session_context->temp_tables) + { + POOL_TEMP_TABLE *table = (POOL_TEMP_TABLE *) lfirst(cell); + + if (table->state == TEMP_TABLE_CREATING) + { + ereport(DEBUG1, + (errmsg("pool_temp_tables_commit_pending: commit: %s", table->tablename))); + + table->state = TEMP_TABLE_CREATE_COMMITTED; + } + else if (table->state == TEMP_TABLE_DROPPING) + { + ereport(DEBUG1, + (errmsg("pool_temp_tables_commit_pending: remove: %s", table->tablename))); + session_context->temp_tables = list_delete_cell(session_context->temp_tables, cell); + pool_temp_tables_dump(); + goto Retry; + } + } + + MemoryContextSwitchTo(old_context); +} + +/* + * Removes all ongoing creating or dropping entries. This is supposed to be + * called when an explicit transaction aborts. + */ +void +pool_temp_tables_remove_pending(void) +{ + ListCell *cell; + MemoryContext old_context; + + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_remove_pending: session context is not initialized"))); + + old_context = MemoryContextSwitchTo(session_context->memory_context); + + pool_temp_tables_dump(); + +Retry: + foreach(cell, session_context->temp_tables) + { + POOL_TEMP_TABLE *table = (POOL_TEMP_TABLE *) lfirst(cell); + + if (table->state == TEMP_TABLE_CREATING || table->state == TEMP_TABLE_DROPPING) + { + ereport(DEBUG1, + (errmsg("pool_temp_tables_remove_pending: remove: %s", table->tablename))); + + session_context->temp_tables = list_delete_cell(session_context->temp_tables, cell); + pool_temp_tables_dump(); + goto Retry; + } + } + + MemoryContextSwitchTo(old_context); +} + +void +pool_temp_tables_dump(void) +{ +#ifdef TEMP_TABLES_DEBUG + ListCell *cell; + + if (!session_context) + ereport(ERROR, + (errmsg("pool_temp_tables_dump: session context is not initialized"))); + + foreach(cell, session_context->temp_tables) + { + POOL_TEMP_TABLE *table = (POOL_TEMP_TABLE *) lfirst(cell); + + ereport(DEBUG1, + (errmsg("pool_temp_tables_dump: table %s state: %d", + table->tablename, table->state))); + } #endif + +} + +/* + * Return true if an explicit transaction has been started by a + * multi-statement-query + */ +bool +is_tx_started_by_multi_statement_query(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("is_tx_started_by_multi_statement_query: session context is not initialized"))); + + return session_context->is_tx_started_by_multi_statement; +} + +/* + * Remember that an explicit transaction has been started by a + * multi-statement-query + */ +void +set_tx_started_by_multi_statement_query(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("set_tx_started_by_multi_statement_query: session context is not initialized"))); + + session_context->is_tx_started_by_multi_statement = true; +} + +/* + * Forget that an explicit transaction has been started by a + * multi-statement-query + */ +void +unset_tx_started_by_multi_statement_query(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("unset_tx_started_by_multi_statement_query: session context is not initialized"))); + + session_context->is_tx_started_by_multi_statement = false; +} + +/* + * Set query_cache_disabled + */ +void +set_query_cache_disabled(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("set_query_cache_disabled: session context is not initialized"))); + + session_context->query_cache_disabled = true; +} + +/* + * Unset query_cache_disabled + */ +void +unset_query_cache_disabled(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("unset_query_cache_disabled: session context is not initialized"))); + + session_context->query_cache_disabled = false; +} + +/* + * Get query_cache_disabled + */ +bool +query_cache_disabled(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("query_cache_disabled: session context is not initialized"))); + + return session_context->query_cache_disabled || + session_context->query_cache_disabled_tx; +} + +/* + * Set query_cache_disabled in transaction + */ +void +set_query_cache_disabled_tx(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("set_query_cache_disabled_tx: session context is not initialized"))); + + session_context->query_cache_disabled_tx = true; +} + +/* + * Unset query_cache_disabled in transaction + */ +void +unset_query_cache_disabled_tx(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("unset_query_cache_disabled_tx: session context is not initialized"))); + + session_context->query_cache_disabled_tx = false; +} + +/* + * Get query_cache_disabled in transaction + */ +bool +query_cache_disabled_tx(void) +{ + if (!session_context) + ereport(ERROR, + (errmsg("query_cache_disabled_tx: session context is not initialized"))); + + return session_context->query_cache_disabled_tx; +} + +/* + * clear sync map + */ +void +clear_sync_map(POOL_SESSION_CONTEXT *session_context) +{ + memset(session_context->sync_map, 0, sizeof(session_context->sync_map)); +} + +/* + * get sync map + */ +bool +get_sync_map(POOL_SESSION_CONTEXT *session_context, int node_id) +{ + return session_context->sync_map[node_id]; +} + +/* + * set sync map + */ +void +set_sync_map(POOL_SESSION_CONTEXT *session_context, int node_id) +{ + elog(DEBUG5, "set sync map %d", node_id); + session_context->sync_map[node_id] = true; +} + +/* + * unset sync map + */ +void +unset_sync_map(POOL_SESSION_CONTEXT *session_context, int node_id) +{ + elog(DEBUG5, "unset sync map %d", node_id); + session_context->sync_map[node_id] = false; +} diff --git a/src/include/Makefile.am b/src/include/Makefile.am index c2e47e41c..a1fd2c0fb 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -5,4 +5,4 @@ DEFS = @DEFS@ \ EXTRA_DIST = auth \ context query_cache\ - parser pool.h pcp pool_type.h pool_config.h protocol rewrite version.h utils watchdog config.h config.h.in pool_config_variables.h pgproto + parser pool.h pcp pool_type.h pool_config.h protocol rewrite version.h utils watchdog config.h config.h.in pool_config_variables.h pgproto main diff --git a/src/include/Makefile.in b/src/include/Makefile.in deleted file mode 100644 index e2e1b646c..000000000 --- a/src/include/Makefile.in +++ /dev/null @@ -1,540 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/include -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(srcdir)/config.h.in $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ \ - -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" - -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -# suggested by libtoolize -ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = auth \ - context query_cache\ - parser pool.h pcp pool_type.h pool_config.h protocol rewrite version.h utils watchdog config.h config.h.in pool_config_variables.h pgproto - -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps src/include/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps src/include/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @if test ! -f $@; then rm -f stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status src/include/config.h -$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile config.h -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-hdr distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: all install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool cscopelist-am ctags ctags-am distclean \ - distclean-generic distclean-hdr distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/include/auth/md5.h b/src/include/auth/md5.h index 6ea08ad8f..808715217 100644 --- a/src/include/auth/md5.h +++ b/src/include/auth/md5.h @@ -3,7 +3,7 @@ * md5.h * Interface to md5.c * - * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * $Header$ @@ -26,4 +26,6 @@ extern int pool_md5_hash(const void *buff, size_t len, char *hexsum); extern int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); extern void bytesToHex(char *b, int len, char *s); +extern bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); + #endif diff --git a/src/include/auth/pool_auth.h b/src/include/auth/pool_auth.h new file mode 100644 index 000000000..a5ee9a183 --- /dev/null +++ b/src/include/auth/pool_auth.h @@ -0,0 +1,33 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + + +#ifndef pool_auth_h +#define pool_auth_h + +extern void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password); +extern int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); +extern void authenticate_frontend(POOL_CONNECTION *frontend); + +extern void pool_random_salt(char *md5Salt); +extern void pool_random(void *buf, size_t len); + +#endif /* pool_auth_h */ diff --git a/src/include/auth/pool_hba.h b/src/include/auth/pool_hba.h index 77cad9d7f..e92404fd9 100644 --- a/src/include/auth/pool_hba.h +++ b/src/include/auth/pool_hba.h @@ -29,6 +29,11 @@ #include "parser/pg_list.h" #include "pool.h" +#ifdef USE_LDAP +#define LDAP_DEPRECATED 1 +#include +#endif + /* UserAuth type used for HBA which indicates the authentication method */ typedef enum UserAuth { @@ -46,6 +51,9 @@ typedef enum UserAuth #ifdef USE_PAM ,uaPAM #endif /* USE_PAM */ +#ifdef USE_LDAP + ,uaLDAP +#endif /* USE_LDAP */ } UserAuth; @@ -79,9 +87,25 @@ struct HbaLine UserAuth auth_method; char *pamservice; bool pam_use_hostname; + + bool ldaptls; + char *ldapscheme; + char *ldapserver; + int ldapport; + char *ldapbinddn; + char *ldapbindpasswd; + char *ldapsearchattribute; + char *ldapsearchfilter; + char *ldapbasedn; + int ldapscope; + char *ldapprefix; + char *ldapsuffix; + /* Additional LDAPl option with pgpool */ + bool backend_use_passwd; /* If true, pgpool use same password to + * auth backend */ }; extern bool load_hba(char *hbapath); -extern void ClientAuthentication(POOL_CONNECTION * frontend); +extern void ClientAuthentication(POOL_CONNECTION *frontend); #endif /* POOL_HBA_H */ diff --git a/src/include/auth/pool_passwd.h b/src/include/auth/pool_passwd.h index bbcaaa810..17b07b456 100644 --- a/src/include/auth/pool_passwd.h +++ b/src/include/auth/pool_passwd.h @@ -29,7 +29,8 @@ #define POOL_PASSWD_FILENAME "pool_passwd" #define POOL_PASSWD_LEN 35 -#define MAX_POOL_PASSWD_LEN 132 /* In case of TEXT prefix(4byte) and plain text password(128byte)*/ +#define MAX_POOL_PASSWD_LEN 132 /* In case of TEXT prefix(4byte) and plain + * text password(128byte) */ #define MAX_USER_NAME_LEN 128 #define MAX_PGPASS_LEN 128 @@ -47,7 +48,7 @@ typedef enum * pgpool-II child main process */ POOL_PASSWD_RW, /* open pool_passwd in read/write mode. used * by pg_md5 command */ -} POOL_PASSWD_MODE; +} POOL_PASSWD_MODE; typedef enum PasswordType { @@ -64,16 +65,16 @@ typedef struct UserPassword char *userName; char *password; PasswordType passwordType; -} UserPassword; +} UserPassword; typedef struct PasswordMapping { UserPassword pgpoolUser; UserPassword backendUser; bool mappedUser; -} PasswordMapping; +} PasswordMapping; -extern PasswordMapping * pool_get_user_credentials(char *username); +extern PasswordMapping *pool_get_user_credentials(char *username); extern PasswordType get_password_type(const char *shadow_pass); extern void pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode); extern int pool_create_passwdent(char *username, char *passwd); @@ -84,5 +85,6 @@ extern void pool_reopen_passwd_file(void); extern char *get_decrypted_password(const char *shadow_pass); extern char *read_pool_key(char *key_file_path); extern char *get_pgpool_config_user_password(char *username, char *password_in_config); -extern void delete_passwordMapping(PasswordMapping * pwdMapping); +extern void delete_passwordMapping(PasswordMapping *pwdMapping); +extern int check_password_type_is_not_md5(char *username, char *password_in_config); #endif /* POOL_PASSWD_H */ diff --git a/src/include/auth/scram-common.h b/src/include/auth/scram-common.h index 9852f48e6..56ca862c0 100644 --- a/src/include/auth/scram-common.h +++ b/src/include/auth/scram-common.h @@ -82,12 +82,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/auth/scram.h b/src/include/auth/scram.h index 883ab1442..2eaf0c06c 100644 --- a/src/include/auth/scram.h +++ b/src/include/auth/scram.h @@ -48,17 +48,17 @@ /* Routines dedicated to authentication */ extern void *pg_be_scram_init(const char *username, const char *shadow_pass); -extern int pg_be_scram_exchange(void *opaq, char *input, int inputlen, - char **output, int *outputlen, char **logdetail); +extern int pg_be_scram_exchange(void *opaq, 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 scram_verify_plain_password(const char *username, - const char *password, const char *verifier); + const char *password, const char *verifier); extern void *pg_fe_scram_init(const char *username, const char *password); extern void pg_fe_scram_exchange(void *opaq, char *input, int inputlen, - char **output, int *outputlen, - bool *done, bool *success); + char **output, int *outputlen, + bool *done, bool *success); extern void pg_fe_scram_free(void *opaq); extern char *pg_fe_scram_build_verifier(const char *password); diff --git a/src/include/config.h.in b/src/include/config.h.in deleted file mode 100644 index 0f539e0f1..000000000 --- a/src/include/config.h.in +++ /dev/null @@ -1,353 +0,0 @@ -/* src/include/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to the type of arg 1 of 'accept' */ -#undef ACCEPT_TYPE_ARG1 - -/* Define to the type of arg 2 of 'accept' */ -#undef ACCEPT_TYPE_ARG2 - -/* Define to the type of arg 3 of 'accept' */ -#undef ACCEPT_TYPE_ARG3 - -/* Define to the return type of 'accept' */ -#undef ACCEPT_TYPE_RETURN - -/* float4 values are passed by value if 'true', by reference if 'false' */ -#undef FLOAT4PASSBYVAL - -/* float8, int8, and related values are passed by value if 'true', by - reference if 'false' */ -#undef FLOAT8PASSBYVAL - -/* Define to 1 if you have the `asprintf' function. */ -#undef HAVE_ASPRINTF - -/* Define to 1 if you have the header file. */ -#undef HAVE_CRYPT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -#undef HAVE_DOPRNT - -/* Define to 1 if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have the `gai_strerror' function. */ -#undef HAVE_GAI_STRERROR - -/* Define to 1 if you have the header file. */ -#undef HAVE_GETOPT_H - -/* Define to 1 if you have the `hstrerror' function. */ -#undef HAVE_HSTRERROR - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `BSD' library (-lBSD). */ -#undef HAVE_LIBBSD - -/* Define to 1 if you have the `crypt' library (-lcrypt). */ -#undef HAVE_LIBCRYPT - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -#undef HAVE_LIBCRYPTO - -/* Define to 1 if you have the `gen' library (-lgen). */ -#undef HAVE_LIBGEN - -/* Define to 1 if you have the `IPC' library (-lIPC). */ -#undef HAVE_LIBIPC - -/* Define to 1 if you have the `lc' library (-llc). */ -#undef HAVE_LIBLC - -/* Define to 1 if you have the `m' library (-lm). */ -#undef HAVE_LIBM - -/* Define to 1 if you have the `memcached' library (-lmemcached). */ -#undef HAVE_LIBMEMCACHED - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBMEMCACHED_MEMCACHED_H - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - -/* Define to 1 if you have the `pam' library (-lpam). */ -#undef HAVE_LIBPAM - -/* Define to 1 if you have the `pq' library (-lpq). */ -#undef HAVE_LIBPQ - -/* Define to 1 if you have the `PW' library (-lPW). */ -#undef HAVE_LIBPW - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -#undef HAVE_LIBRESOLV - -/* Define to 1 if you have the `socket' library (-lsocket). */ -#undef HAVE_LIBSOCKET - -/* Define to 1 if you have the `ssl' library (-lssl). */ -#undef HAVE_LIBSSL - -/* Define to 1 if constants of type 'long long int' should have the suffix LL. - */ -#undef HAVE_LL_CONSTANTS - -/* Define to 1 if `long int' works and is 64 bits. */ -#undef HAVE_LONG_INT_64 - -/* Define to 1 if `long long int' works and is 64 bits. */ -#undef HAVE_LONG_LONG_INT_64 - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETDB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_IN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_TCP_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_SSL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_PAM_PAM_APPL_H - -/* Define to 1 if you have the `PQprepare' function. */ -#undef HAVE_PQPREPARE - -/* Define to 1 if you have the `pstat' function. */ -#undef HAVE_PSTAT - -/* Define to 1 if you have the header file. */ -#undef HAVE_SECURITY_PAM_APPL_H - -/* Define to 1 if you have the `select' function. */ -#undef HAVE_SELECT - -/* Define to 1 if you have the `setproctitle' function. */ -#undef HAVE_SETPROCTITLE - -/* Define to 1 if you have the `setsid' function. */ -#undef HAVE_SETSID - -/* Define to 1 if you have the `sigprocmask' function. */ -#undef HAVE_SIGPROCMASK - -/* Define to 1 if you have the `snprintf' function. */ -#undef HAVE_SNPRINTF - -/* Define to 1 if you have the `socket' function. */ -#undef HAVE_SOCKET - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `strdup' function. */ -#undef HAVE_STRDUP - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - -/* Define to 1 if you have the `strftime' function. */ -#undef HAVE_STRFTIME - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strlcat,' function. */ -#undef HAVE_STRLCAT_ - -/* Define to 1 if you have the `strlcpy' function. */ -#undef HAVE_STRLCPY - -/* Define to 1 if you have the `strtok' function. */ -#undef HAVE_STRTOK - -/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ -#undef HAVE_STRUCT_SOCKADDR_SA_LEN - -/* Define to 1 if the system has the type `struct sockaddr_storage'. */ -#undef HAVE_STRUCT_SOCKADDR_STORAGE - -/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ -#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY - -/* Define to 1 if `ss_len' is a member of `struct sockaddr_storage'. */ -#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN - -/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ -#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY - -/* Define to 1 if `__ss_len' is a member of `struct sockaddr_storage'. */ -#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PSTAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SEM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SHM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UN_H - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#undef HAVE_SYS_WAIT_H - -/* checking termios */ -#undef HAVE_TERMIOS_H - -/* Define to 1 if the system has the type `union semun'. */ -#undef HAVE_UNION_SEMUN - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `vasprintf' function. */ -#undef HAVE_VASPRINTF - -/* Define to 1 if you have the `vprintf' function. */ -#undef HAVE_VPRINTF - -/* Define to 1 if you have the `vsnprintf' function. */ -#undef HAVE_VSNPRINTF - -/* Define to 1 if you have the `vsyslog' function. */ -#undef HAVE_VSYSLOG - -/* Define to 1 if you have the `wait3' system call. Deprecated, you should no - longer depend upon `wait3'. */ -#undef HAVE_WAIT3 - -/* Define to the appropriate snprintf format for 64-bit ints, if any. */ -#undef INT64_FORMAT - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define as the return type of signal handlers (`int' or `void'). */ -#undef RETSIGTYPE - -/* The size of `size_t', as computed by sizeof. */ -#undef SIZEOF_SIZE_T - -/* The size of `unsigned long', as computed by sizeof. */ -#undef SIZEOF_UNSIGNED_LONG - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to 1 if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Define to the appropriate snprintf format for unsigned 64-bit ints, if any. - */ -#undef UINT64_FORMAT - -/* Define to 1 to build with assertion checks. (--enable-cassert) */ -#undef USE_ASSERT_CHECKING - -/* Define to 1 if you want float4 values to be passed by value. - (--enable-float4-byval) */ -#undef USE_FLOAT4_BYVAL - -/* Define to 1 if you want float8, int8, etc values to be passed by value. - (--enable-float8-byval) */ -#undef USE_FLOAT8_BYVAL - -/* Define to 1 to build with memcached support */ -#undef USE_MEMCACHED - -/* Define to 1 to build with PAM support. (--with-pam) */ -#undef USE_PAM - -/* Use replacement snprintf() functions. */ -#undef USE_REPL_SNPRINTF - -/* Define to 1 if you want to use row lock against the sequence table for - insert_lock. (--enable-sequence-lock) */ -#undef USE_SEQUENCE_LOCK - -/* Define to 1 to build with SSL support. (--with-openssl) */ -#undef USE_SSL - -/* Define to 1 if you want to use table lock against the target table for - insert_lock. (--enable-table-lock) */ -#undef USE_TABLE_LOCK - -/* Version number of package */ -#undef VERSION - -/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a - `char[]'. */ -#undef YYTEXT_POINTER - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `int' if does not define. */ -#undef pid_t diff --git a/src/include/context/pool_process_context.h b/src/include/context/pool_process_context.h index d57bb0511..194b6220a 100644 --- a/src/include/context/pool_process_context.h +++ b/src/include/context/pool_process_context.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2015 PgPool Global Development Group + * Copyright (c) 2003-2021 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -25,7 +25,11 @@ #ifndef POOL_PROCESS_CONTEXT_H #define POOL_PROCESS_CONTEXT_H -#include "pool.h" + +/* #include "pool.h" */ +#include "pcp/libpcp_ext.h" +#include "utils/pool_signal.h" + /* * Child process context: @@ -53,22 +57,22 @@ typedef struct unsigned int last_alarm_second; unsigned int undo_alarm_second; -} POOL_PROCESS_CONTEXT; +} POOL_PROCESS_CONTEXT; extern void pool_init_process_context(void); -extern POOL_PROCESS_CONTEXT * pool_get_process_context(void); -extern ProcessInfo * pool_get_my_process_info(void); -extern void pool_incremnet_local_session_id(void); -extern int pool_coninfo_size(void); +extern POOL_PROCESS_CONTEXT *pool_get_process_context(void); +extern ProcessInfo *pool_get_my_process_info(void); +extern void pool_increment_local_session_id(void); +extern size_t pool_coninfo_size(void); extern int pool_coninfo_num(void); -extern ConnectionInfo * pool_coninfo(int child, int connection_pool, int backend); -extern ConnectionInfo * pool_coninfo_pid(int pid, int connection_pool, int backend); +extern ConnectionInfo *pool_coninfo(int child, int connection_pool, int backend); +extern ConnectionInfo *pool_coninfo_pid(int pid, int connection_pool, int backend); extern void pool_coninfo_set_frontend_connected(int proc_id, int pool_index); extern void pool_coninfo_unset_frontend_connected(int proc_id, int pool_index); -extern ConnectionInfo * pool_coninfo_backend_pid(int backend_pid, int *backend_node_id); -extern void pool_set_connection_will_be_terminated(ConnectionInfo * connInfo); -extern void pool_unset_connection_will_be_terminated(ConnectionInfo * connInfo); +extern ConnectionInfo *pool_coninfo_backend_pid(int backend_pid, int *backend_node_id); +extern void pool_set_connection_will_be_terminated(ConnectionInfo *connInfo); +extern void pool_unset_connection_will_be_terminated(ConnectionInfo *connInfo); extern void pool_alarm(pool_sighandler_t handler, unsigned int second); extern void pool_undo_alarm(void); diff --git a/src/include/context/pool_query_context.h b/src/include/context/pool_query_context.h index 55e8b873a..66e0395e4 100644 --- a/src/include/context/pool_query_context.h +++ b/src/include/context/pool_query_context.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2017 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -44,7 +44,7 @@ typedef enum POOL_PARSE_COMPLETE, POOL_BIND_COMPLETE, POOL_EXECUTE_COMPLETE -} POOL_QUERY_STATE; +} POOL_QUERY_STATE; /* * Query context: @@ -62,7 +62,8 @@ typedef struct Node *rewritten_parse_tree; /* rewritten raw parser output if any */ bool where_to_send[MAX_NUM_BACKENDS]; /* DB node map to send * query */ - int virtual_master_node_id; /* the 1st DB node to send query */ + int load_balance_node_id; /* load balance node id per statement */ + int virtual_main_node_id; /* the 1st DB node to send query */ POOL_QUERY_STATE query_state[MAX_NUM_BACKENDS]; /* for extended query * protocol */ bool is_cache_safe; /* true if SELECT is safe to cache */ @@ -89,34 +90,41 @@ typedef struct * extended query, do not commit cache if * this flag is true. */ + bool atEnd; /* if true all rows have been already fetched + * from the portal */ + + bool partial_fetch; /* if true some rows have been fetched by an + * execute with non 0 row option */ + + bool sync_msg; /* true if this is a special query context for + * sync message */ MemoryContext memory_context; /* memory context for query context */ -} POOL_QUERY_CONTEXT; +} POOL_QUERY_CONTEXT; -extern POOL_QUERY_CONTEXT * pool_init_query_context(void); -extern void pool_query_context_destroy(POOL_QUERY_CONTEXT * query_context); -extern POOL_QUERY_CONTEXT * pool_query_context_shallow_copy(POOL_QUERY_CONTEXT * query_context); -extern void pool_start_query(POOL_QUERY_CONTEXT * query_context, char *query, int len, Node *node); -extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); -extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); -extern bool pool_is_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); -extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); -extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); -extern void pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT * query_context); -extern void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT * query_context); -extern bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT * query_context); -extern void pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node); -extern POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, int send_type, int node_id); -extern POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, char *kind, int len, char *contents, int send_type, int node_id, bool nowait); +extern POOL_QUERY_CONTEXT *pool_init_query_context(void); +extern void pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context); +extern POOL_QUERY_CONTEXT *pool_query_context_shallow_copy(POOL_QUERY_CONTEXT *query_context); +extern void pool_start_query(POOL_QUERY_CONTEXT *query_context, char *query, int len, Node *node); +extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); +extern bool pool_is_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); +extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); +extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); +extern void pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT *query_context); +extern void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context); +extern bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT *query_context); +extern void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *node); +extern POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, int send_type, int node_id); +extern POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *kind, int len, char *contents, int send_type, int node_id, bool nowait); extern Node *pool_get_parse_tree(void); extern char *pool_get_query_string(void); extern bool is_set_transaction_serializable(Node *node); extern bool is_start_transaction_query(Node *node); extern bool is_read_write(TransactionStmt *node); extern bool is_serializable(TransactionStmt *node); -extern bool pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT * query_context); +extern bool pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT *query_context); extern bool is_savepoint_query(Node *node); extern bool is_2pc_transaction_query(Node *node); -extern void pool_set_query_state(POOL_QUERY_CONTEXT * query_context, POOL_QUERY_STATE state); +extern void pool_set_query_state(POOL_QUERY_CONTEXT *query_context, POOL_QUERY_STATE state); extern int statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2); extern bool pool_is_cache_safe(void); extern void pool_set_cache_safe(void); @@ -125,5 +133,9 @@ extern bool pool_is_cache_exceeded(void); extern void pool_set_cache_exceeded(void); extern void pool_unset_cache_exceeded(void); extern bool pool_is_transaction_read_only(Node *node); -extern void pool_force_query_node_to_backend(POOL_QUERY_CONTEXT * query_context, int backend_id); +extern void pool_force_query_node_to_backend(POOL_QUERY_CONTEXT *query_context, int backend_id); +extern void check_object_relationship_list(char *name, bool is_func_name); +extern int wait_for_failover_to_finish(void); +extern void set_virtual_main_node(POOL_QUERY_CONTEXT *query_context); + #endif /* POOL_QUERY_CONTEXT_H */ diff --git a/src/include/context/pool_session_context.h b/src/include/context/pool_session_context.h index 7eb48186c..cf7a1fbe8 100644 --- a/src/include/context/pool_session_context.h +++ b/src/include/context/pool_session_context.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -41,9 +41,9 @@ typedef enum POOL_UNKNOWN, /* Unknown. Need to ask backend */ POOL_READ_UNCOMMITTED, /* Read uncommitted */ POOL_READ_COMMITTED, /* Read committed */ - POOL_REPEATABLE_READ, /* Rpeatable read */ + POOL_REPEATABLE_READ, /* Repeatable read */ POOL_SERIALIZABLE /* Serializable */ -} POOL_TRANSACTION_ISOLATION; +} POOL_TRANSACTION_ISOLATION; /* * Return values for pool_use_sync_map @@ -60,10 +60,10 @@ typedef enum */ typedef enum { - POOL_SENT_MESSAGE_CREATED, /* initial state of sent meesage */ - POOL_SENT_MESSAGE_CLOSED /* sent meesage closed but close complete + POOL_SENT_MESSAGE_CREATED, /* initial state of sent message */ + POOL_SENT_MESSAGE_CLOSED /* sent message closed but close complete * message has not arrived yet */ -} POOL_SENT_MESSAGE_STATE; +} POOL_SENT_MESSAGE_STATE; /* * Message content of extended query @@ -90,7 +90,7 @@ typedef struct int param_offset; /* Offset from contents where actual bind * parameters are stored. This is meaningful * only when is_cache_safe is true. */ -} POOL_SENT_MESSAGE; +} POOL_SENT_MESSAGE; /* * List of POOL_SENT_MESSAGE (XXX this should have been implemented using a @@ -101,7 +101,7 @@ typedef struct int capacity; /* capacity of list */ int size; /* number of elements */ POOL_SENT_MESSAGE **sent_messages; -} POOL_SENT_MESSAGE_LIST; +} POOL_SENT_MESSAGE_LIST; /* * Received message queue used in extended query/streaming replication mode. @@ -123,7 +123,7 @@ typedef enum POOL_DESCRIBE, POOL_CLOSE, POOL_SYNC -} POOL_MESSAGE_TYPE; +} POOL_MESSAGE_TYPE; typedef struct { @@ -132,7 +132,7 @@ typedef struct * kind */ int contents_len; /* message packet length */ char query[QUERY_STRING_BUFFER_LEN]; /* copy of original query */ - char statement[MAX_IDENTIFIER_LEN]; /* prepared statment name if + char statement[MAX_IDENTIFIER_LEN]; /* prepared statement name if * any */ char portal[MAX_IDENTIFIER_LEN]; /* portal name if any */ bool is_rows_returned; /* true if the message could produce row @@ -140,13 +140,43 @@ typedef struct bool not_forward_to_frontend; /* Do not forward response from * backend to frontend. This is * used by parse_before_bind() */ - int node_ids[2]; /* backend node ids this message was sent to. - * -1 means no message was sent. */ + bool node_ids[MAX_NUM_BACKENDS]; /* backend node map which this + * message was sent to */ POOL_QUERY_CONTEXT *query_context; /* query context */ -} POOL_PENDING_MESSAGE; -/* Return true if node_id is one of node_ids */ -#define IS_SENT_NODE_ID(msg, node_id) (msg->node_ids[0] == node_id || msg->node_ids[1] == node_id) + /* + * If "flush" message arrives, this flag is set to true until all buffered + * message for frontend are sent out. + */ + bool flush_pending; + + bool is_tx_started_by_multi_statement; /* true if an explicit + * transaction has been + * started by multi + * statement query */ +} POOL_PENDING_MESSAGE; + +typedef enum +{ + TEMP_TABLE_CREATING = 1, /* temp table creating, not committed yet. */ + TEMP_TABLE_DROPPING, /* temp table dropping, not committed yet. */ + TEMP_TABLE_CREATE_COMMITTED, /* temp table created and committed. */ + TEMP_TABLE_DROP_COMMITTED, /* temp table dropped and committed. */ +} POOL_TEMP_TABLE_STATE; + +typedef struct +{ + char tablename[MAX_IDENTIFIER_LEN]; /* temporary table name */ + POOL_TEMP_TABLE_STATE state; /* see above */ +} POOL_TEMP_TABLE; + + +typedef enum +{ + SI_NO_SNAPSHOT, + SI_SNAPSHOT_PREPARED +} SI_STATE; + /* * Per session context: @@ -179,9 +209,23 @@ typedef struct /* If true, the command in progress has finished successfully. */ bool command_success; - /* If true, write query has been appeared in this transaction */ + /* + * If true, write query has been appeared in this transaction. Note that + * the flag may not be turned off even if a transaction is started or + * committed if disable_load_balance_on_write is other than "transaction". + * Also if disable_load_balance_on_write is "dml_adaptive", the flag is + * never be turned on. + */ bool writing_transaction; + /* + * Unlike "writing_transaction", this flag is turned on whenever writing + * query is issued in an explicit transaction, and is turned off when the + * transaction is closed. Of course turned off when new transaction + * starts. This flag is referenced by query cache. + */ + bool really_writing_transaction; + /* If true, error occurred in this transaction */ bool failed_transaction; @@ -240,14 +284,14 @@ typedef struct * transaction */ /* - * Parse/Bind/Decribe/Execute/Close message queue. + * Parse/Bind/Describe/Execute/Close message queue. */ List *pending_messages; /* * The last pending message. Reset at Ready for query. Note that this is * a shallow copy of pending message. Once the are is reset, - * previos_message_exists is set to false. + * previous_message_exists is set to false. */ bool previous_message_exists; POOL_PENDING_MESSAGE previous_message; @@ -256,15 +300,97 @@ typedef struct int major; /* Protocol minor version number */ int minor; + + /* + * Do not read messages from frontend. Used in extended protocol + + * streaming replication. If sync message is received from frontend, this + * flag prevent from reading any message from frontend until read for + * query message arrives from backend. + */ + bool suspend_reading_from_frontend; + + /* + * Do not read messages from frontend until COP-IN response ('G') received + * from backend. Used in extended protocol + streaming replication. This + * flag is set when execute COPY FROM STDIN. + */ + bool suspend_reading_from_frontend_copy_in; + + /* + * Temp tables list + */ + List *temp_tables; + + bool is_in_transaction; + + /* + * Current transaction temp write list + */ + List *transaction_temp_write_list; + + /* + * For disable_load_balance_on_write = dml_adaptive_global: the table OIDs + * written in the current explicit transaction, plus the database OID they + * belong to. Both are resolved at DML routing time (when the backend + * connection is idle and do_query is safe) and consumed on COMMIT by + * handle_query_context() to mark the tables as written in shared memory. + * Resolving here -- rather than at COMMIT -- avoids issuing do_query + * while the COMMIT response is still in flight, which would desync the + * protocol and hang the session. + */ + List *transaction_temp_write_oid_list; + int transaction_temp_write_dboid; + #ifdef NOT_USED - /* Preferred "master" node id. Only used for SimpleForwardToFrontend. */ - int preferred_master_node_id; + /* Preferred "main" node id. Only used for SimpleForwardToFrontend. */ + int preferred_main_node_id; #endif -} POOL_SESSION_CONTEXT; -extern void pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); + /* + * Whether snapshot is acquired in this transaction. Only used by Snapshot + * Isolation mode. + */ + SI_STATE si_state; + /* Whether transaction is read only. Only used by Snapshot Isolation mode. */ + SI_STATE transaction_read_only; + + /* + * If true, the current message from backend must be flushed to frontend. + * Set by read_kind_from_backend and reset by SimpleForwardToFrontend. + */ + bool flush_pending; + + bool is_tx_started_by_multi_statement; /* True if an explicit + * transaction has been + * started by a + * multi-statement-query */ + + /* + * True if query cache feature disabled until session ends. This is set + * when SET ROLE/SET SESSION AUTHORIZATION executed. + */ + bool query_cache_disabled; + + /* + * True if query cache feature disabled until current transaction ends. + * This is set when REVOKE executed in a transaction. + */ + bool query_cache_disabled_tx; + + /* + * A map to send sync message. Each entry represents backend node. + */ + bool sync_map[MAX_NUM_BACKENDS]; + + /* + * Backend node id map do_query sent to, without sending a sync message. + */ + bool pending_sync_map[MAX_NUM_BACKENDS]; +} POOL_SESSION_CONTEXT; + +extern void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); extern void pool_session_context_destroy(void); -extern POOL_SESSION_CONTEXT * pool_get_session_context(bool noerror); +extern POOL_SESSION_CONTEXT *pool_get_session_context(bool noerror); extern int pool_get_local_session_id(void); extern bool pool_is_query_in_progress(void); extern void pool_set_query_in_progress(void); @@ -278,19 +404,24 @@ extern void pool_unset_doing_extended_query_message(void); extern bool pool_is_ignore_till_sync(void); extern void pool_set_ignore_till_sync(void); extern void pool_unset_ignore_till_sync(void); -extern POOL_SENT_MESSAGE * pool_create_sent_message(char kind, int len, char *contents, - int num_tsparams, const char *name, - POOL_QUERY_CONTEXT * query_context); -extern void pool_add_sent_message(POOL_SENT_MESSAGE * message); +extern POOL_SENT_MESSAGE *pool_create_sent_message(char kind, int len, char *contents, + int num_tsparams, const char *name, + POOL_QUERY_CONTEXT *query_context); +extern void pool_add_sent_message(POOL_SENT_MESSAGE *message); extern bool pool_remove_sent_message(char kind, const char *name); extern void pool_remove_sent_messages(char kind); extern void pool_clear_sent_message_list(void); -extern void pool_sent_message_destroy(POOL_SENT_MESSAGE * message); -extern POOL_SENT_MESSAGE * pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state); -extern void pool_set_sent_message_state(POOL_SENT_MESSAGE * message); +extern void pool_sent_message_destroy(POOL_SENT_MESSAGE *message); +extern POOL_SENT_MESSAGE *pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state); +extern void pool_set_sent_message_state(POOL_SENT_MESSAGE *message); +extern void pool_zap_query_context_in_sent_messages(POOL_QUERY_CONTEXT *query_context); +extern POOL_SENT_MESSAGE *pool_get_sent_message_by_query_context(POOL_QUERY_CONTEXT *query_context); extern void pool_unset_writing_transaction(void); +extern void pool_unset_really_writing_transaction(void); extern void pool_set_writing_transaction(void); +extern void pool_set_really_writing_transaction(void); extern bool pool_is_writing_transaction(void); +extern bool pool_is_really_writing_transaction(void); extern void pool_unset_failed_transaction(void); extern void pool_set_failed_transaction(void); extern bool pool_is_failed_transaction(void); @@ -301,42 +432,65 @@ extern void pool_unset_command_success(void); extern void pool_set_command_success(void); extern bool pool_is_command_success(void); extern void pool_copy_prep_where(bool *src, bool *dest); -extern bool can_query_context_destroy(POOL_QUERY_CONTEXT * qc); +extern bool can_query_context_destroy(POOL_QUERY_CONTEXT *qc); extern void pool_pending_messages_init(void); extern void pool_pending_messages_destroy(void); -extern POOL_PENDING_MESSAGE * pool_pending_message_create(char kind, int len, char *contents); -extern void pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE * message); -extern void pool_pending_message_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); -extern void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); -extern void pool_pending_message_query_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); -extern void pool_pending_message_add(POOL_PENDING_MESSAGE * message); -extern POOL_PENDING_MESSAGE * pool_pending_message_head_message(void); -extern POOL_PENDING_MESSAGE * pool_pending_message_pull_out(void); -extern POOL_PENDING_MESSAGE * pool_pending_message_get(POOL_MESSAGE_TYPE type); -extern char pool_get_close_message_spec(POOL_PENDING_MESSAGE * msg); -extern char *pool_get_close_message_name(POOL_PENDING_MESSAGE * msg); +extern POOL_PENDING_MESSAGE *pool_pending_message_create(char kind, int len, char *contents); +extern void pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE *message); +extern void pool_pending_message_dest_set(POOL_PENDING_MESSAGE *message, POOL_QUERY_CONTEXT *query_context); +extern void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE *message, POOL_QUERY_CONTEXT *query_context); +extern void pool_pending_message_query_set(POOL_PENDING_MESSAGE *message, POOL_QUERY_CONTEXT *query_context); +extern void pool_pending_message_add(POOL_PENDING_MESSAGE *message); +extern POOL_PENDING_MESSAGE *pool_pending_message_head_message(void); +extern POOL_PENDING_MESSAGE *pool_pending_message_pull_out(void); +extern POOL_PENDING_MESSAGE *pool_pending_message_get(POOL_MESSAGE_TYPE type); +extern char pool_get_close_message_spec(POOL_PENDING_MESSAGE *msg); +extern char *pool_get_close_message_name(POOL_PENDING_MESSAGE *msg); extern void pool_pending_message_reset_previous_message(void); -extern void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE * message); -extern POOL_PENDING_MESSAGE * pool_pending_message_get_previous_message(void); +extern void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE *message); +extern POOL_PENDING_MESSAGE *pool_pending_message_get_previous_message(void); extern bool pool_pending_message_exists(void); extern const char *pool_pending_message_type_to_string(POOL_MESSAGE_TYPE type); extern void pool_check_pending_message_and_reply(POOL_MESSAGE_TYPE type, char kind); -extern POOL_PENDING_MESSAGE * pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT * qc); -extern int pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE * msg); +extern POOL_PENDING_MESSAGE *pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT *qc); +extern int pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE *msg); extern int pool_pending_message_get_message_num_by_backend_id(int backend_id); +extern void pool_pending_message_set_flush_request(void); extern void dump_pending_message(void); extern void pool_set_major_version(int major); extern void pool_set_minor_version(int minor); extern int pool_get_minor_version(void); -#ifdef NOT_USED -extern void pool_set_preferred_master_node_id(int node_id); -extern int pool_get_preferred_master_node_id(void); -extern void pool_reset_preferred_master_node_id(void); -#endif +extern bool pool_is_suspend_reading_from_frontend(void); +extern void pool_set_suspend_reading_from_frontend(void); +extern void pool_unset_suspend_reading_from_frontend(void); + +extern bool pool_is_suspend_reading_from_frontend_copy_in(void); +extern void pool_set_suspend_reading_from_frontend_copy_in(void); +extern void pool_unset_suspend_reading_from_frontend_copy_in(void); + +extern void pool_temp_tables_init(void); +extern void pool_temp_tables_destroy(void); +extern void pool_temp_tables_add(char *tablename, POOL_TEMP_TABLE_STATE state); +extern POOL_TEMP_TABLE *pool_temp_tables_find(char *tablename); +extern void pool_temp_tables_delete(char *tablename, POOL_TEMP_TABLE_STATE state); +extern void pool_temp_tables_commit_pending(void); +extern void pool_temp_tables_remove_pending(void); +extern void pool_temp_tables_dump(void); + +extern bool is_tx_started_by_multi_statement_query(void); +extern void set_tx_started_by_multi_statement_query(void); +extern void unset_tx_started_by_multi_statement_query(void); + +extern void set_query_cache_disabled(void); +extern void unset_query_cache_disabled(void); +extern bool query_cache_disabled(void); +extern void set_query_cache_disabled_tx(void); +extern void unset_query_cache_disabled_tx(void); +extern bool query_cache_disabled_tx(void); + +extern void clear_sync_map(POOL_SESSION_CONTEXT *session_context); +extern bool get_sync_map(POOL_SESSION_CONTEXT *session_context, int node_id); +extern void set_sync_map(POOL_SESSION_CONTEXT *session_context, int node_id); +extern void unset_sync_map(POOL_SESSION_CONTEXT *session_context, int node_id); -#ifdef NOT_USED -extern void pool_add_prep_where(char *name, bool *map); -extern bool *pool_get_prep_where(char *name); -extern void pool_delete_prep_where(char *name); -#endif /* NOT_USED */ #endif /* POOL_SESSION_CONTEXT_H */ diff --git a/src/include/main/health_check.h b/src/include/main/health_check.h new file mode 100644 index 000000000..f8369aa1e --- /dev/null +++ b/src/include/main/health_check.h @@ -0,0 +1,60 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2025 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + + +#ifndef health_check_h +#define health_check_h + +/* + * Health check statistics per node +*/ +typedef struct +{ + uint64 total_count; /* total count of health check */ + uint64 success_count; /* total count of successful health check */ + uint64 fail_count; /* total count of failed health check */ + uint64 skip_count; /* total count of skipped health check */ + uint64 retry_count; /* total count of health check retries */ + uint32 max_retry_count; /* max retry count in a health check + * session */ + uint64 total_health_check_duration; /* sum of health check + * duration */ + int32 max_health_check_duration; /* maximum duration spent for a + * health check session in milli + * seconds */ + int32 min_health_check_duration; /* minimum duration spent for a + * health check session in milli + * seconds */ + time_t last_health_check; /* last health check timestamp */ + time_t last_successful_health_check; /* last successful health + * check timestamp */ + time_t last_skip_health_check; /* last skipped health check timestamp */ + time_t last_failed_health_check; /* last failed health check + * timestamp */ +} POOL_HEALTH_CHECK_STATISTICS; + +extern volatile POOL_HEALTH_CHECK_STATISTICS *health_check_stats; /* health check stats + * area in shared memory */ + +extern void do_health_check_child(void *params); +extern size_t health_check_stats_shared_memory_size(void); +extern void health_check_stats_init(POOL_HEALTH_CHECK_STATISTICS *addr); + +#endif /* health_check_h */ diff --git a/src/include/main/pgpool_logger.h b/src/include/main/pgpool_logger.h new file mode 100644 index 000000000..82adbd2e1 --- /dev/null +++ b/src/include/main/pgpool_logger.h @@ -0,0 +1,96 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pgpool_logger.h.: master definition header file + * + */ +/*------------------------------------------------------------------------- + * From: PostgreSQL + * src/include/postmaster/syslogger.h + * Exports from postmaster/syslogger.c. + * + * Copyright (c) 2004-2020, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef _SYSLOGGER_H +#define _SYSLOGGER_H + +#include /* for PIPE_BUF */ + + +/* + * Primitive protocol structure for writing to syslogger pipe(s). The idea + * here is to divide long messages into chunks that are not more than + * PIPE_BUF bytes long, which according to POSIX spec must be written into + * the pipe atomically. The pipe reader then uses the protocol headers to + * reassemble the parts of a message into a single string. The reader can + * also cope with non-protocol data coming down the pipe, though we cannot + * guarantee long strings won't get split apart. + * + * We use non-nul bytes in is_last to make the protocol a tiny bit + * more robust against finding a false double nul byte prologue. But + * we still might find it in the len and/or pid bytes unless we're careful. + */ + +#ifdef PIPE_BUF +/* Are there any systems with PIPE_BUF > 64K? Unlikely, but ... */ +#if PIPE_BUF > 65536 +#define PIPE_CHUNK_SIZE 65536 +#else +#define PIPE_CHUNK_SIZE ((int) PIPE_BUF) +#endif +#else /* not defined */ +/* POSIX says the value of PIPE_BUF must be at least 512, so use that */ +#define PIPE_CHUNK_SIZE 512 +#endif + +typedef struct +{ + char nuls[2]; /* always \0\0 */ + uint16 len; /* size of this chunk (counts data only) */ + int32 pid; /* writer's pid */ + char is_last; /* last chunk of message? 't' or 'f' ('T' or + * 'F' for CSV case) */ + char data[]; /* data payload starts here */ +} PipeProtoHeader; + +typedef union +{ + PipeProtoHeader proto; + char filler[PIPE_CHUNK_SIZE]; +} PipeProtoChunk; + +#define PIPE_HEADER_SIZE offsetof(PipeProtoHeader, data) +#define PIPE_MAX_PAYLOAD ((int) (PIPE_CHUNK_SIZE - PIPE_HEADER_SIZE)) + + +extern int syslogPipe[2]; +extern bool redirection_done; + + +extern int SysLogger_Start(void); + +extern void write_syslogger_file(const char *buffer, int count, int dest); + + +extern bool CheckLogrotateSignal(void); +extern void RemoveLogrotateSignalFiles(void); + + +#endif /* _SYSLOGGER_H */ diff --git a/src/include/main/pool_internal_comms.h b/src/include/main/pool_internal_comms.h new file mode 100644 index 000000000..b20b85d6f --- /dev/null +++ b/src/include/main/pool_internal_comms.h @@ -0,0 +1,45 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + + +#ifndef pool_internal_comms_h +#define pool_internal_comms_h + +extern bool terminate_pgpool(char mode, bool error); +extern void notice_backend_error(int node_id, unsigned char flags); +extern bool degenerate_backend_set(int *node_id_set, int count, + unsigned char flags); +extern bool degenerate_backend_set_ex(int *node_id_set, int count, + unsigned char flags, bool error, bool test_only); +extern bool promote_backend(int node_id, unsigned char flags); +extern bool send_failback_request(int node_id, bool throw_error, + unsigned char flags); + +extern void degenerate_all_quarantine_nodes(void); +extern bool close_idle_connections(void); + +/* defined in pgpool_main.c */ +extern void register_watchdog_quorum_change_interrupt(void); +extern void register_watchdog_state_change_interrupt(void); +extern void register_backend_state_sync_req_interrupt(void); +extern void register_inform_quarantine_nodes_req(void); +extern bool register_node_operation_request(POOL_REQUEST_KIND kind, + int *node_id_set, int count, unsigned char flags); +#endif /* pool_internal_comms_h */ diff --git a/src/include/parser/explain.h b/src/include/parser/explain.h index 1a44ae216..b2255b01e 100644 --- a/src/include/parser/explain.h +++ b/src/include/parser/explain.h @@ -19,7 +19,7 @@ typedef enum ExplainFormat EXPLAIN_FORMAT_XML, EXPLAIN_FORMAT_JSON, EXPLAIN_FORMAT_YAML -} ExplainFormat; +} ExplainFormat; typedef struct ExplainState { @@ -41,12 +41,12 @@ typedef struct ExplainState List *rtable_names; /* alias names for RTEs */ List *deparse_cxt; /* context list for deparsing expressions */ Bitmapset *printed_subplans; /* ids of SubPlans we've printed */ -} ExplainState; +} ExplainState; /* Hook for plugins to get control in ExplainOneQuery() */ typedef void (*ExplainOneQuery_hook_type) (Query *query, IntoClause *into, - ExplainState *es, + ExplainState * es, const char *queryString, ParamListInfo params); extern PGDLLIMPORT ExplainOneQuery_hook_type ExplainOneQuery_hook; @@ -57,42 +57,42 @@ extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook; extern void ExplainQuery(ExplainStmt *stmt, const char *queryString, - ParamListInfo params, DestReceiver *dest); + ParamListInfo params, DestReceiver * dest); -extern ExplainState *NewExplainState(void); +extern ExplainState * NewExplainState(void); extern TupleDesc ExplainResultDesc(ExplainStmt *stmt); extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into, - ExplainState *es, - const char *queryString, ParamListInfo params); + ExplainState * es, + const char *queryString, ParamListInfo params); -extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, - ExplainState *es, const char *queryString, - ParamListInfo params, const instr_time *planduration); +extern void ExplainOnePlan(PlannedStmt * plannedstmt, IntoClause *into, + ExplainState * es, const char *queryString, + ParamListInfo params, const instr_time * planduration); -extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc); -extern void ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc); +extern void ExplainPrintPlan(ExplainState * es, QueryDesc * queryDesc); +extern void ExplainPrintTriggers(ExplainState * es, QueryDesc * queryDesc); -extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc); +extern void ExplainQueryText(ExplainState * es, QueryDesc * queryDesc); -extern void ExplainBeginOutput(ExplainState *es); -extern void ExplainEndOutput(ExplainState *es); -extern void ExplainSeparatePlans(ExplainState *es); +extern void ExplainBeginOutput(ExplainState * es); +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, int value, - ExplainState *es); + ExplainState * es); extern void ExplainPropertyLong(const char *qlabel, long value, - ExplainState *es); + ExplainState * es); extern void ExplainPropertyFloat(const char *qlabel, double value, int ndigits, - ExplainState *es); + ExplainState * es); extern void ExplainPropertyBool(const char *qlabel, bool value, - ExplainState *es); + ExplainState * es); #endif /* EXPLAIN_H */ diff --git a/src/include/parser/extensible.h b/src/include/parser/extensible.h index b11b0a58e..03089137e 100644 --- a/src/include/parser/extensible.h +++ b/src/include/parser/extensible.h @@ -27,7 +27,7 @@ typedef struct ExtensibleNode { NodeTag type; const char *extnodename; /* identifier of ExtensibleNodeMethods */ -} ExtensibleNode; +} ExtensibleNode; /* * node_size is the size of an extensible node of this type in bytes. @@ -62,11 +62,11 @@ typedef struct ExtensibleNodeMethods void (*nodeOut) (struct StringInfoData *str, const struct ExtensibleNode *node); void (*nodeRead) (struct ExtensibleNode *node); -} ExtensibleNodeMethods; +} ExtensibleNodeMethods; -extern void RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *method); +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 diff --git a/src/include/parser/gramparse.h b/src/include/parser/gramparse.h index 5544d7f18..c375cb860 100644 --- a/src/include/parser/gramparse.h +++ b/src/include/parser/gramparse.h @@ -8,8 +8,8 @@ * Definitions that are needed outside the core parser should be in parser.h. * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/gramparse.h @@ -24,6 +24,7 @@ #include "scanner.h" #define AMTYPE_INDEX 'i' /* index access method */ +#define AMTYPE_TABLE 't' /* table access method */ /* * NB: include gram.h only AFTER including scanner.h, because scanner.h @@ -68,11 +69,17 @@ 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); +extern int minimal_base_yylex(YYSTYPE *lvalp, YYLTYPE * llocp, + core_yyscan_t yyscanner); /* from gram.y */ extern void parser_init(base_yy_extra_type *yyext); extern int base_yyparse(core_yyscan_t yyscanner); +/* from gram_minimal.y */ +extern void minimal_parser_init(base_yy_extra_type *yyext); +extern int minimal_base_yyparse(core_yyscan_t yyscanner); + #endif /* GRAMPARSE_H */ diff --git a/src/include/parser/keywords.h b/src/include/parser/keywords.h index e2f44d08e..a56380499 100644 --- a/src/include/parser/keywords.h +++ b/src/include/parser/keywords.h @@ -1,39 +1,30 @@ /*------------------------------------------------------------------------- * * keywords.h - * lexical token lookup for key words in PostgreSQL + * PostgreSQL's list of SQL keywords * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * src/include/parser/keywords.h + * src/include/common/keywords.h * *------------------------------------------------------------------------- */ #ifndef KEYWORDS_H #define KEYWORDS_H +#include "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; - -extern PGDLLIMPORT const ScanKeyword ScanKeywords[]; -extern PGDLLIMPORT const int NumScanKeywords; - -extern const ScanKeyword *ScanKeywordLookup(const char *text, - const ScanKeyword *keywords, - int num_keywords); +extern PGDLLIMPORT const ScanKeywordList ScanKeywords; +extern PGDLLIMPORT const uint8 ScanKeywordCategories[]; +extern PGDLLIMPORT const bool ScanKeywordBareLabel[]; #endif /* KEYWORDS_H */ diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 8e07e973e..098738447 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -2,13 +2,13 @@ * * 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) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -20,451 +20,504 @@ /* there is deliberately not an #ifndef KWLIST_H here */ /* - * List of keyword (name, token-value, category) entries. + * List of keyword (name, token-value, category, bare-label-status) 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 */ -PG_KEYWORD("abort", ABORT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("absolute", ABSOLUTE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("access", ACCESS, UNRESERVED_KEYWORD) -PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD) -PG_KEYWORD("add", ADD_P, UNRESERVED_KEYWORD) -PG_KEYWORD("admin", ADMIN, UNRESERVED_KEYWORD) -PG_KEYWORD("after", AFTER, UNRESERVED_KEYWORD) -PG_KEYWORD("aggregate", AGGREGATE, UNRESERVED_KEYWORD) -PG_KEYWORD("all", ALL, RESERVED_KEYWORD) -PG_KEYWORD("also", ALSO, UNRESERVED_KEYWORD) -PG_KEYWORD("alter", ALTER, UNRESERVED_KEYWORD) -PG_KEYWORD("always", ALWAYS, UNRESERVED_KEYWORD) -PG_KEYWORD("analyse", ANALYSE, RESERVED_KEYWORD) /* British spelling */ -PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD) -PG_KEYWORD("and", AND, RESERVED_KEYWORD) -PG_KEYWORD("any", ANY, RESERVED_KEYWORD) -PG_KEYWORD("array", ARRAY, RESERVED_KEYWORD) -PG_KEYWORD("as", AS, RESERVED_KEYWORD) -PG_KEYWORD("asc", ASC, RESERVED_KEYWORD) -PG_KEYWORD("assertion", ASSERTION, UNRESERVED_KEYWORD) -PG_KEYWORD("assignment", ASSIGNMENT, UNRESERVED_KEYWORD) -PG_KEYWORD("asymmetric", ASYMMETRIC, RESERVED_KEYWORD) -PG_KEYWORD("at", AT, UNRESERVED_KEYWORD) -PG_KEYWORD("attach", ATTACH, UNRESERVED_KEYWORD) -PG_KEYWORD("attribute", ATTRIBUTE, UNRESERVED_KEYWORD) -PG_KEYWORD("authorization", AUTHORIZATION, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("backward", BACKWARD, UNRESERVED_KEYWORD) -PG_KEYWORD("before", BEFORE, UNRESERVED_KEYWORD) -PG_KEYWORD("begin", BEGIN_P, UNRESERVED_KEYWORD) -PG_KEYWORD("between", BETWEEN, COL_NAME_KEYWORD) -PG_KEYWORD("bigint", BIGINT, COL_NAME_KEYWORD) -PG_KEYWORD("binary", BINARY, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("bit", BIT, COL_NAME_KEYWORD) -PG_KEYWORD("boolean", BOOLEAN_P, COL_NAME_KEYWORD) -PG_KEYWORD("both", BOTH, RESERVED_KEYWORD) -PG_KEYWORD("by", BY, UNRESERVED_KEYWORD) -PG_KEYWORD("cache", CACHE, UNRESERVED_KEYWORD) -PG_KEYWORD("call", CALL, UNRESERVED_KEYWORD) -PG_KEYWORD("called", CALLED, UNRESERVED_KEYWORD) -PG_KEYWORD("cascade", CASCADE, UNRESERVED_KEYWORD) -PG_KEYWORD("cascaded", CASCADED, UNRESERVED_KEYWORD) -PG_KEYWORD("case", CASE, RESERVED_KEYWORD) -PG_KEYWORD("cast", CAST, RESERVED_KEYWORD) -PG_KEYWORD("catalog", CATALOG_P, UNRESERVED_KEYWORD) -PG_KEYWORD("chain", CHAIN, UNRESERVED_KEYWORD) -PG_KEYWORD("char", CHAR_P, COL_NAME_KEYWORD) -PG_KEYWORD("character", CHARACTER, COL_NAME_KEYWORD) -PG_KEYWORD("characteristics", CHARACTERISTICS, UNRESERVED_KEYWORD) -PG_KEYWORD("check", CHECK, RESERVED_KEYWORD) -PG_KEYWORD("checkpoint", CHECKPOINT, UNRESERVED_KEYWORD) -PG_KEYWORD("class", CLASS, UNRESERVED_KEYWORD) -PG_KEYWORD("close", CLOSE, UNRESERVED_KEYWORD) -PG_KEYWORD("cluster", CLUSTER, UNRESERVED_KEYWORD) -PG_KEYWORD("coalesce", COALESCE, COL_NAME_KEYWORD) -PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD) -PG_KEYWORD("collation", COLLATION, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD) -PG_KEYWORD("columns", COLUMNS, UNRESERVED_KEYWORD) -PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD) -PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD) -PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD) -PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD) -PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD) -PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD) -PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD) -PG_KEYWORD("constraint", CONSTRAINT, RESERVED_KEYWORD) -PG_KEYWORD("constraints", CONSTRAINTS, UNRESERVED_KEYWORD) -PG_KEYWORD("content", CONTENT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("continue", CONTINUE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("conversion", CONVERSION_P, UNRESERVED_KEYWORD) -PG_KEYWORD("copy", COPY, UNRESERVED_KEYWORD) -PG_KEYWORD("cost", COST, UNRESERVED_KEYWORD) -PG_KEYWORD("create", CREATE, RESERVED_KEYWORD) -PG_KEYWORD("cross", CROSS, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("csv", CSV, UNRESERVED_KEYWORD) -PG_KEYWORD("cube", CUBE, UNRESERVED_KEYWORD) -PG_KEYWORD("current", CURRENT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("current_catalog", CURRENT_CATALOG, RESERVED_KEYWORD) -PG_KEYWORD("current_date", CURRENT_DATE, RESERVED_KEYWORD) -PG_KEYWORD("current_role", CURRENT_ROLE, RESERVED_KEYWORD) -PG_KEYWORD("current_schema", CURRENT_SCHEMA, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("current_time", CURRENT_TIME, RESERVED_KEYWORD) -PG_KEYWORD("current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD) -PG_KEYWORD("current_user", CURRENT_USER, RESERVED_KEYWORD) -PG_KEYWORD("cursor", CURSOR, UNRESERVED_KEYWORD) -PG_KEYWORD("cycle", CYCLE, UNRESERVED_KEYWORD) -PG_KEYWORD("data", DATA_P, UNRESERVED_KEYWORD) -PG_KEYWORD("database", DATABASE, UNRESERVED_KEYWORD) -PG_KEYWORD("day", DAY_P, UNRESERVED_KEYWORD) -PG_KEYWORD("deallocate", DEALLOCATE, UNRESERVED_KEYWORD) -PG_KEYWORD("dec", DEC, COL_NAME_KEYWORD) -PG_KEYWORD("decimal", DECIMAL_P, COL_NAME_KEYWORD) -PG_KEYWORD("declare", DECLARE, UNRESERVED_KEYWORD) -PG_KEYWORD("default", DEFAULT, RESERVED_KEYWORD) -PG_KEYWORD("defaults", DEFAULTS, UNRESERVED_KEYWORD) -PG_KEYWORD("deferrable", DEFERRABLE, RESERVED_KEYWORD) -PG_KEYWORD("deferred", DEFERRED, UNRESERVED_KEYWORD) -PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD) -PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD) -PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD) -PG_KEYWORD("depends", DEPENDS, UNRESERVED_KEYWORD) -PG_KEYWORD("desc", DESC, RESERVED_KEYWORD) -PG_KEYWORD("detach", DETACH, UNRESERVED_KEYWORD) -PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD) -PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD) -PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD) -PG_KEYWORD("do", DO, RESERVED_KEYWORD) -PG_KEYWORD("document", DOCUMENT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD) -PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD) -PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD) -PG_KEYWORD("else", ELSE, RESERVED_KEYWORD) -PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("encoding", ENCODING, UNRESERVED_KEYWORD) -PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD) -PG_KEYWORD("end", END_P, RESERVED_KEYWORD) -PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD) -PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD) -PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD) -PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD) -PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD) -PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD) -PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD) -PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD) -PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD) -PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD) -PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD) -PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD) -PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD) -PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD) -PG_KEYWORD("family", FAMILY, UNRESERVED_KEYWORD) -PG_KEYWORD("fetch", FETCH, RESERVED_KEYWORD) -PG_KEYWORD("filter", FILTER, UNRESERVED_KEYWORD) -PG_KEYWORD("first", FIRST_P, UNRESERVED_KEYWORD) -PG_KEYWORD("float", FLOAT_P, COL_NAME_KEYWORD) -PG_KEYWORD("following", FOLLOWING, UNRESERVED_KEYWORD) -PG_KEYWORD("for", FOR, RESERVED_KEYWORD) -PG_KEYWORD("force", FORCE, UNRESERVED_KEYWORD) -PG_KEYWORD("foreign", FOREIGN, RESERVED_KEYWORD) -PG_KEYWORD("forward", FORWARD, UNRESERVED_KEYWORD) -PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("from", FROM, RESERVED_KEYWORD) -PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD) -PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD) -PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD) -PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD) -PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD) -PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD) -PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD) -PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD) -PG_KEYWORD("grouping", GROUPING, COL_NAME_KEYWORD) -PG_KEYWORD("groups", GROUPS, UNRESERVED_KEYWORD) -PG_KEYWORD("handler", HANDLER, UNRESERVED_KEYWORD) -PG_KEYWORD("having", HAVING, RESERVED_KEYWORD) -PG_KEYWORD("header", HEADER_P, UNRESERVED_KEYWORD) -PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD) -PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD) -PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD) -PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD) -PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD) -PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD) -PG_KEYWORD("implicit", IMPLICIT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("import", IMPORT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("in", IN_P, RESERVED_KEYWORD) -PG_KEYWORD("include", INCLUDE, UNRESERVED_KEYWORD) -PG_KEYWORD("including", INCLUDING, UNRESERVED_KEYWORD) -PG_KEYWORD("increment", INCREMENT, UNRESERVED_KEYWORD) -PG_KEYWORD("index", INDEX, UNRESERVED_KEYWORD) -PG_KEYWORD("indexes", INDEXES, UNRESERVED_KEYWORD) -PG_KEYWORD("inherit", INHERIT, UNRESERVED_KEYWORD) -PG_KEYWORD("inherits", INHERITS, UNRESERVED_KEYWORD) -PG_KEYWORD("initially", INITIALLY, RESERVED_KEYWORD) -PG_KEYWORD("inline", INLINE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("inner", INNER_P, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("inout", INOUT, COL_NAME_KEYWORD) -PG_KEYWORD("input", INPUT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("insensitive", INSENSITIVE, UNRESERVED_KEYWORD) -PG_KEYWORD("insert", INSERT, UNRESERVED_KEYWORD) -PG_KEYWORD("instead", INSTEAD, UNRESERVED_KEYWORD) -PG_KEYWORD("int", INT_P, COL_NAME_KEYWORD) -PG_KEYWORD("integer", INTEGER, COL_NAME_KEYWORD) -PG_KEYWORD("intersect", INTERSECT, RESERVED_KEYWORD) -PG_KEYWORD("interval", INTERVAL, COL_NAME_KEYWORD) -PG_KEYWORD("into", INTO, RESERVED_KEYWORD) -PG_KEYWORD("invoker", INVOKER, UNRESERVED_KEYWORD) -PG_KEYWORD("is", IS, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD) -PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD) -PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD) -PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD) -PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("last", LAST_P, UNRESERVED_KEYWORD) -PG_KEYWORD("lateral", LATERAL_P, RESERVED_KEYWORD) -PG_KEYWORD("leading", LEADING, RESERVED_KEYWORD) -PG_KEYWORD("leakproof", LEAKPROOF, UNRESERVED_KEYWORD) -PG_KEYWORD("least", LEAST, COL_NAME_KEYWORD) -PG_KEYWORD("left", LEFT, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("level", LEVEL, UNRESERVED_KEYWORD) -PG_KEYWORD("like", LIKE, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("limit", LIMIT, RESERVED_KEYWORD) -PG_KEYWORD("listen", LISTEN, UNRESERVED_KEYWORD) -PG_KEYWORD("load", LOAD, UNRESERVED_KEYWORD) -PG_KEYWORD("local", LOCAL, UNRESERVED_KEYWORD) -PG_KEYWORD("localtime", LOCALTIME, RESERVED_KEYWORD) -PG_KEYWORD("localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD) -PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD) -PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD) -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("materialized", MATERIALIZED, UNRESERVED_KEYWORD) -PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD) -PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD) -PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD) -PG_KEYWORD("mode", MODE, UNRESERVED_KEYWORD) -PG_KEYWORD("month", MONTH_P, UNRESERVED_KEYWORD) -PG_KEYWORD("move", MOVE, UNRESERVED_KEYWORD) -PG_KEYWORD("name", NAME_P, UNRESERVED_KEYWORD) -PG_KEYWORD("names", NAMES, UNRESERVED_KEYWORD) -PG_KEYWORD("national", NATIONAL, COL_NAME_KEYWORD) -PG_KEYWORD("natural", NATURAL, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("nchar", NCHAR, COL_NAME_KEYWORD) -PG_KEYWORD("new", NEW, UNRESERVED_KEYWORD) -PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD) -PG_KEYWORD("no", NO, UNRESERVED_KEYWORD) -PG_KEYWORD("none", NONE, COL_NAME_KEYWORD) -PG_KEYWORD("not", NOT, RESERVED_KEYWORD) -PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD) -PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD) -PG_KEYWORD("notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("nowait", NOWAIT, UNRESERVED_KEYWORD) -PG_KEYWORD("null", NULL_P, RESERVED_KEYWORD) -PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD) -PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD) -PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD) -PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("of", OF, UNRESERVED_KEYWORD) -PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD) -PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD) -PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD) -PG_KEYWORD("old", OLD, UNRESERVED_KEYWORD) -PG_KEYWORD("on", ON, RESERVED_KEYWORD) -PG_KEYWORD("only", ONLY, RESERVED_KEYWORD) -PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD) -PG_KEYWORD("option", OPTION, UNRESERVED_KEYWORD) -PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD) -PG_KEYWORD("or", OR, RESERVED_KEYWORD) -PG_KEYWORD("order", ORDER, RESERVED_KEYWORD) -PG_KEYWORD("ordinality", ORDINALITY, UNRESERVED_KEYWORD) -PG_KEYWORD("others", OTHERS, UNRESERVED_KEYWORD) -PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD) -PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD) -PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD) -PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD) -PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD) -PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD) -PG_KEYWORD("parallel", PARALLEL, UNRESERVED_KEYWORD) -PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD) -PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD) -PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD) -PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD) -PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD) -PG_KEYWORD("pgpool", PGPOOL, UNRESERVED_KEYWORD) -PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD) -PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD) -PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD) -PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD) -PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD) -PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD) -PG_KEYWORD("prepare", PREPARE, UNRESERVED_KEYWORD) -PG_KEYWORD("prepared", PREPARED, UNRESERVED_KEYWORD) -PG_KEYWORD("preserve", PRESERVE, UNRESERVED_KEYWORD) -PG_KEYWORD("primary", PRIMARY, RESERVED_KEYWORD) -PG_KEYWORD("prior", PRIOR, UNRESERVED_KEYWORD) -PG_KEYWORD("privileges", PRIVILEGES, UNRESERVED_KEYWORD) -PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD) -PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD) -PG_KEYWORD("procedures", PROCEDURES, UNRESERVED_KEYWORD) -PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD) -PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD) -PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD) -PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD) -PG_KEYWORD("read", READ, UNRESERVED_KEYWORD) -PG_KEYWORD("real", REAL, COL_NAME_KEYWORD) -PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD) -PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD) -PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD) -PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD) -PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD) -PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD) -PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD) -PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD) -PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD) -PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD) -PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD) -PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD) -PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD) -PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD) -PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD) -PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD) -PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD) -PG_KEYWORD("returns", RETURNS, UNRESERVED_KEYWORD) -PG_KEYWORD("revoke", REVOKE, UNRESERVED_KEYWORD) -PG_KEYWORD("right", RIGHT, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("role", ROLE, UNRESERVED_KEYWORD) -PG_KEYWORD("rollback", ROLLBACK, UNRESERVED_KEYWORD) -PG_KEYWORD("rollup", ROLLUP, UNRESERVED_KEYWORD) -PG_KEYWORD("routine", ROUTINE, UNRESERVED_KEYWORD) -PG_KEYWORD("routines", ROUTINES, UNRESERVED_KEYWORD) -PG_KEYWORD("row", ROW, COL_NAME_KEYWORD) -PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD) -PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD) -PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD) -PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD) -PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD) -PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD) -PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD) -PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD) -PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD) -PG_KEYWORD("select", SELECT, RESERVED_KEYWORD) -PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD) -PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD) -PG_KEYWORD("serializable", SERIALIZABLE, UNRESERVED_KEYWORD) -PG_KEYWORD("server", SERVER, UNRESERVED_KEYWORD) -PG_KEYWORD("session", SESSION, UNRESERVED_KEYWORD) -PG_KEYWORD("session_user", SESSION_USER, RESERVED_KEYWORD) -PG_KEYWORD("set", SET, UNRESERVED_KEYWORD) -PG_KEYWORD("setof", SETOF, COL_NAME_KEYWORD) -PG_KEYWORD("sets", SETS, UNRESERVED_KEYWORD) -PG_KEYWORD("share", SHARE, UNRESERVED_KEYWORD) -PG_KEYWORD("show", SHOW, UNRESERVED_KEYWORD) -PG_KEYWORD("similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("simple", SIMPLE, UNRESERVED_KEYWORD) -PG_KEYWORD("skip", SKIP, UNRESERVED_KEYWORD) -PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD) -PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD) -PG_KEYWORD("some", SOME, RESERVED_KEYWORD) -PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD) -PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD) -PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("start", START, UNRESERVED_KEYWORD) -PG_KEYWORD("statement", STATEMENT, UNRESERVED_KEYWORD) -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("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("symmetric", SYMMETRIC, RESERVED_KEYWORD) -PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD) -PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD) -PG_KEYWORD("table", TABLE, RESERVED_KEYWORD) -PG_KEYWORD("tables", TABLES, UNRESERVED_KEYWORD) -PG_KEYWORD("tablesample", TABLESAMPLE, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("tablespace", TABLESPACE, UNRESERVED_KEYWORD) -PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD) -PG_KEYWORD("template", TEMPLATE, UNRESERVED_KEYWORD) -PG_KEYWORD("temporary", TEMPORARY, UNRESERVED_KEYWORD) -PG_KEYWORD("text", TEXT_P, UNRESERVED_KEYWORD) -PG_KEYWORD("then", THEN, RESERVED_KEYWORD) -PG_KEYWORD("ties", TIES, UNRESERVED_KEYWORD) -PG_KEYWORD("time", TIME, COL_NAME_KEYWORD) -PG_KEYWORD("timestamp", TIMESTAMP, COL_NAME_KEYWORD) -PG_KEYWORD("to", TO, RESERVED_KEYWORD) -PG_KEYWORD("trailing", TRAILING, RESERVED_KEYWORD) -PG_KEYWORD("transaction", TRANSACTION, UNRESERVED_KEYWORD) -PG_KEYWORD("transform", TRANSFORM, UNRESERVED_KEYWORD) -PG_KEYWORD("treat", TREAT, COL_NAME_KEYWORD) -PG_KEYWORD("trigger", TRIGGER, UNRESERVED_KEYWORD) -PG_KEYWORD("trim", TRIM, COL_NAME_KEYWORD) -PG_KEYWORD("true", TRUE_P, RESERVED_KEYWORD) -PG_KEYWORD("truncate", TRUNCATE, UNRESERVED_KEYWORD) -PG_KEYWORD("trusted", TRUSTED, UNRESERVED_KEYWORD) -PG_KEYWORD("type", TYPE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD) -PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD) -PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD) -PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD) -PG_KEYWORD("union", UNION, RESERVED_KEYWORD) -PG_KEYWORD("unique", UNIQUE, RESERVED_KEYWORD) -PG_KEYWORD("unknown", UNKNOWN, UNRESERVED_KEYWORD) -PG_KEYWORD("unlisten", UNLISTEN, UNRESERVED_KEYWORD) -PG_KEYWORD("unlogged", UNLOGGED, UNRESERVED_KEYWORD) -PG_KEYWORD("until", UNTIL, UNRESERVED_KEYWORD) -PG_KEYWORD("update", UPDATE, UNRESERVED_KEYWORD) -PG_KEYWORD("user", USER, RESERVED_KEYWORD) -PG_KEYWORD("using", USING, RESERVED_KEYWORD) -PG_KEYWORD("vacuum", VACUUM, UNRESERVED_KEYWORD) -PG_KEYWORD("valid", VALID, UNRESERVED_KEYWORD) -PG_KEYWORD("validate", VALIDATE, UNRESERVED_KEYWORD) -PG_KEYWORD("validator", VALIDATOR, UNRESERVED_KEYWORD) -PG_KEYWORD("value", VALUE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("values", VALUES, COL_NAME_KEYWORD) -PG_KEYWORD("varchar", VARCHAR, COL_NAME_KEYWORD) -PG_KEYWORD("variadic", VARIADIC, RESERVED_KEYWORD) -PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD) -PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD) -PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD) -PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD) -PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD) -PG_KEYWORD("when", WHEN, RESERVED_KEYWORD) -PG_KEYWORD("where", WHERE, RESERVED_KEYWORD) -PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD) -PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD) -PG_KEYWORD("with", WITH, RESERVED_KEYWORD) -PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD) -PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD) -PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD) -PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD) -PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD) -PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD) -PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD) -PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD) -PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD) -PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD) -PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD) -PG_KEYWORD("xmlnamespaces", XMLNAMESPACES, COL_NAME_KEYWORD) -PG_KEYWORD("xmlparse", XMLPARSE, COL_NAME_KEYWORD) -PG_KEYWORD("xmlpi", XMLPI, COL_NAME_KEYWORD) -PG_KEYWORD("xmlroot", XMLROOT, COL_NAME_KEYWORD) -PG_KEYWORD("xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD) -PG_KEYWORD("xmltable", XMLTABLE, COL_NAME_KEYWORD) -PG_KEYWORD("year", YEAR_P, UNRESERVED_KEYWORD) -PG_KEYWORD("yes", YES_P, UNRESERVED_KEYWORD) -PG_KEYWORD("zone", ZONE, UNRESERVED_KEYWORD) +/* name, value, category, is-bare-label */ +PG_KEYWORD("abort", ABORT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("absent", ABSENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("absolute", ABSOLUTE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("access", ACCESS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("add", ADD_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("admin", ADMIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("after", AFTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("aggregate", AGGREGATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("all", ALL, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("also", ALSO, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("alter", ALTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("always", ALWAYS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("analyse", ANALYSE, RESERVED_KEYWORD, BARE_LABEL) /* British spelling */ +PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("and", AND, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("any", ANY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("array", ARRAY, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("as", AS, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("asc", ASC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("asensitive", ASENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("assertion", ASSERTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("assignment", ASSIGNMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("asymmetric", ASYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("at", AT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("atomic", ATOMIC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("attach", ATTACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("attribute", ATTRIBUTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("authorization", AUTHORIZATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("backward", BACKWARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("before", BEFORE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("begin", BEGIN_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("between", BETWEEN, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("bigint", BIGINT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("binary", BINARY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("bit", BIT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("boolean", BOOLEAN_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("both", BOTH, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("breadth", BREADTH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("by", BY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cache", CACHE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("call", CALL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("called", CALLED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cascade", CASCADE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cascaded", CASCADED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("case", CASE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cast", CAST, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("catalog", CATALOG_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("chain", CHAIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("char", CHAR_P, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("character", CHARACTER, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("characteristics", CHARACTERISTICS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("check", CHECK, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("checkpoint", CHECKPOINT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("class", CLASS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("close", CLOSE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cluster", CLUSTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("coalesce", COALESCE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("collation", COLLATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("columns", COLUMNS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("compression", COMPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("conditional", CONDITIONAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("constraint", CONSTRAINT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("constraints", CONSTRAINTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("content", CONTENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("continue", CONTINUE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("conversion", CONVERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("copy", COPY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cost", COST, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("create", CREATE, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("cross", CROSS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("csv", CSV, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cube", CUBE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current", CURRENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_catalog", CURRENT_CATALOG, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_date", CURRENT_DATE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_role", CURRENT_ROLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_schema", CURRENT_SCHEMA, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_time", CURRENT_TIME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_user", CURRENT_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cursor", CURSOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cycle", CYCLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("data", DATA_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("database", DATABASE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("day", DAY_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("deallocate", DEALLOCATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("dec", DEC, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("decimal", DECIMAL_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("declare", DECLARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("default", DEFAULT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("defaults", DEFAULTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("deferrable", DEFERRABLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("deferred", DEFERRED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("depends", DEPENDS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("depth", DEPTH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("desc", DESC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("detach", DETACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("do", DO, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("document", DOCUMENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("else", ELSE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("empty", EMPTY_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("encoding", ENCODING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("end", END_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("enforced", ENFORCED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("error", ERROR_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("expression", EXPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("family", FAMILY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("fetch", FETCH, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("filter", FILTER, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("finalize", FINALIZE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("first", FIRST_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("float", FLOAT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("following", FOLLOWING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("for", FOR, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("force", FORCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("foreign", FOREIGN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("format", FORMAT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("forward", FORWARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("from", FROM, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("grouping", GROUPING, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("groups", GROUPS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("handler", HANDLER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("having", HAVING, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("header", HEADER_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("implicit", IMPLICIT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("import", IMPORT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("in", IN_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("include", INCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("including", INCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("increment", INCREMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("indent", INDENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("index", INDEX, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("indexes", INDEXES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inherit", INHERIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inherits", INHERITS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("initially", INITIALLY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inline", INLINE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inner", INNER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("inout", INOUT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("input", INPUT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("insensitive", INSENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("insert", INSERT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("instead", INSTEAD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("int", INT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("integer", INTEGER, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("intersect", INTERSECT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("interval", INTERVAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("into", INTO, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("invoker", INVOKER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("is", IS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json", JSON, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_array", JSON_ARRAY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_arrayagg", JSON_ARRAYAGG, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_exists", JSON_EXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_object", JSON_OBJECT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_query", JSON_QUERY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_scalar", JSON_SCALAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_serialize", JSON_SERIALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_table", JSON_TABLE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_value", JSON_VALUE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("keep", KEEP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("keys", KEYS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("last", LAST_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("lateral", LATERAL_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("leading", LEADING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("leakproof", LEAKPROOF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("least", LEAST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("left", LEFT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("level", LEVEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("like", LIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("limit", LIMIT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("listen", LISTEN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("load", LOAD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("local", LOCAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("localtime", LOCALTIME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("matched", MATCHED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("merge", MERGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("merge_action", MERGE_ACTION, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("mode", MODE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("month", MONTH_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("move", MOVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("name", NAME_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("names", NAMES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("national", NATIONAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("natural", NATURAL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nchar", NCHAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nested", NESTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("new", NEW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfc", NFC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfd", NFD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfkc", NFKC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfkd", NFKD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("no", NO, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("none", NONE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("normalize", NORMALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("normalized", NORMALIZED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("not", NOT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("nowait", NOWAIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("null", NULL_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("objects", OBJECTS_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("of", OF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("old", OLD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("omit", OMIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("on", ON, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("only", ONLY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("option", OPTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("or", OR, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("order", ORDER, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("ordinality", ORDINALITY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("others", OTHERS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parallel", PARALLEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parameter", PARAMETER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("path", PATH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("period", PERIOD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("pgpool", PGPOOL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("plan", PLAN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("prepare", PREPARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("prepared", PREPARED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("preserve", PRESERVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("primary", PRIMARY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("prior", PRIOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("privileges", PRIVILEGES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedures", PROCEDURES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("quotes", QUOTES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("read", READ, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("real", REAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("return", RETURN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("returns", RETURNS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("revoke", REVOKE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("right", RIGHT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("role", ROLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rollback", ROLLBACK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rollup", ROLLUP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("routine", ROUTINE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("routines", ROUTINES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("row", ROW, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("scalar", SCALAR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("select", SELECT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("serializable", SERIALIZABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("server", SERVER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("session", SESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("session_user", SESSION_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("set", SET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("setof", SETOF, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("sets", SETS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("share", SHARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("show", SHOW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("simple", SIMPLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("skip", SKIP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("some", SOME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("source", SOURCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("start", START, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("statement", STATEMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("statistics", STATISTICS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stdin", STDIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stored", STORED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("string", STRING_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("support", SUPPORT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("symmetric", SYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("system_user", SYSTEM_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("table", TABLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("tables", TABLES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("tablesample", TABLESAMPLE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("tablespace", TABLESPACE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("target", TARGET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("template", TEMPLATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("temporary", TEMPORARY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("text", TEXT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("then", THEN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ties", TIES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("time", TIME, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("timestamp", TIMESTAMP, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("to", TO, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("trailing", TRAILING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("transaction", TRANSACTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("transform", TRANSFORM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("treat", TREAT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("trigger", TRIGGER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("trim", TRIM, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("true", TRUE_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("truncate", TRUNCATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("trusted", TRUSTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("type", TYPE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("uescape", UESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unconditional", UNCONDITIONAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("union", UNION, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("unique", UNIQUE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unknown", UNKNOWN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unlisten", UNLISTEN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unlogged", UNLOGGED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("until", UNTIL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("update", UPDATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("user", USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("using", USING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("vacuum", VACUUM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("valid", VALID, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("validate", VALIDATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("validator", VALIDATOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("value", VALUE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("values", VALUES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("varchar", VARCHAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("variadic", VARIADIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("virtual", VIRTUAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("when", WHEN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("where", WHERE, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("with", WITH, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlnamespaces", XMLNAMESPACES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlparse", XMLPARSE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlpi", XMLPI, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlroot", XMLROOT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmltable", XMLTABLE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("year", YEAR_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("yes", YES_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("zone", ZONE, UNRESERVED_KEYWORD, BARE_LABEL) diff --git a/src/include/parser/kwlist_d.h b/src/include/parser/kwlist_d.h new file mode 100644 index 000000000..023a3432a --- /dev/null +++ b/src/include/parser/kwlist_d.h @@ -0,0 +1,1173 @@ +/*------------------------------------------------------------------------- + * + * kwlist_d.h + * List of keywords represented as a ScanKeywordList. + * + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/tools/gen_keywordlist.pl + * + *------------------------------------------------------------------------- + */ + +#ifndef KWLIST_D_H +#define KWLIST_D_H + +#include "kwlookup.h" + +static const char ScanKeywords_kw_string[] = + "abort\0" + "absent\0" + "absolute\0" + "access\0" + "action\0" + "add\0" + "admin\0" + "after\0" + "aggregate\0" + "all\0" + "also\0" + "alter\0" + "always\0" + "analyse\0" + "analyze\0" + "and\0" + "any\0" + "array\0" + "as\0" + "asc\0" + "asensitive\0" + "assertion\0" + "assignment\0" + "asymmetric\0" + "at\0" + "atomic\0" + "attach\0" + "attribute\0" + "authorization\0" + "backward\0" + "before\0" + "begin\0" + "between\0" + "bigint\0" + "binary\0" + "bit\0" + "boolean\0" + "both\0" + "breadth\0" + "by\0" + "cache\0" + "call\0" + "called\0" + "cascade\0" + "cascaded\0" + "case\0" + "cast\0" + "catalog\0" + "chain\0" + "char\0" + "character\0" + "characteristics\0" + "check\0" + "checkpoint\0" + "class\0" + "close\0" + "cluster\0" + "coalesce\0" + "collate\0" + "collation\0" + "column\0" + "columns\0" + "comment\0" + "comments\0" + "commit\0" + "committed\0" + "compression\0" + "concurrently\0" + "conditional\0" + "configuration\0" + "conflict\0" + "connection\0" + "constraint\0" + "constraints\0" + "content\0" + "continue\0" + "conversion\0" + "copy\0" + "cost\0" + "create\0" + "cross\0" + "csv\0" + "cube\0" + "current\0" + "current_catalog\0" + "current_date\0" + "current_role\0" + "current_schema\0" + "current_time\0" + "current_timestamp\0" + "current_user\0" + "cursor\0" + "cycle\0" + "data\0" + "database\0" + "day\0" + "deallocate\0" + "dec\0" + "decimal\0" + "declare\0" + "default\0" + "defaults\0" + "deferrable\0" + "deferred\0" + "definer\0" + "delete\0" + "delimiter\0" + "delimiters\0" + "depends\0" + "depth\0" + "desc\0" + "detach\0" + "dictionary\0" + "disable\0" + "discard\0" + "distinct\0" + "do\0" + "document\0" + "domain\0" + "double\0" + "drop\0" + "each\0" + "else\0" + "empty\0" + "enable\0" + "encoding\0" + "encrypted\0" + "end\0" + "enforced\0" + "enum\0" + "error\0" + "escape\0" + "event\0" + "except\0" + "exclude\0" + "excluding\0" + "exclusive\0" + "execute\0" + "exists\0" + "explain\0" + "expression\0" + "extension\0" + "external\0" + "extract\0" + "false\0" + "family\0" + "fetch\0" + "filter\0" + "finalize\0" + "first\0" + "float\0" + "following\0" + "for\0" + "force\0" + "foreign\0" + "format\0" + "forward\0" + "freeze\0" + "from\0" + "full\0" + "function\0" + "functions\0" + "generated\0" + "global\0" + "grant\0" + "granted\0" + "greatest\0" + "group\0" + "grouping\0" + "groups\0" + "handler\0" + "having\0" + "header\0" + "hold\0" + "hour\0" + "identity\0" + "if\0" + "ilike\0" + "immediate\0" + "immutable\0" + "implicit\0" + "import\0" + "in\0" + "include\0" + "including\0" + "increment\0" + "indent\0" + "index\0" + "indexes\0" + "inherit\0" + "inherits\0" + "initially\0" + "inline\0" + "inner\0" + "inout\0" + "input\0" + "insensitive\0" + "insert\0" + "instead\0" + "int\0" + "integer\0" + "intersect\0" + "interval\0" + "into\0" + "invoker\0" + "is\0" + "isnull\0" + "isolation\0" + "join\0" + "json\0" + "json_array\0" + "json_arrayagg\0" + "json_exists\0" + "json_object\0" + "json_objectagg\0" + "json_query\0" + "json_scalar\0" + "json_serialize\0" + "json_table\0" + "json_value\0" + "keep\0" + "key\0" + "keys\0" + "label\0" + "language\0" + "large\0" + "last\0" + "lateral\0" + "leading\0" + "leakproof\0" + "least\0" + "left\0" + "level\0" + "like\0" + "limit\0" + "listen\0" + "load\0" + "local\0" + "localtime\0" + "localtimestamp\0" + "location\0" + "lock\0" + "locked\0" + "logged\0" + "mapping\0" + "match\0" + "matched\0" + "materialized\0" + "maxvalue\0" + "merge\0" + "merge_action\0" + "method\0" + "minute\0" + "minvalue\0" + "mode\0" + "month\0" + "move\0" + "name\0" + "names\0" + "national\0" + "natural\0" + "nchar\0" + "nested\0" + "new\0" + "next\0" + "nfc\0" + "nfd\0" + "nfkc\0" + "nfkd\0" + "no\0" + "none\0" + "normalize\0" + "normalized\0" + "not\0" + "nothing\0" + "notify\0" + "notnull\0" + "nowait\0" + "null\0" + "nullif\0" + "nulls\0" + "numeric\0" + "object\0" + "objects\0" + "of\0" + "off\0" + "offset\0" + "oids\0" + "old\0" + "omit\0" + "on\0" + "only\0" + "operator\0" + "option\0" + "options\0" + "or\0" + "order\0" + "ordinality\0" + "others\0" + "out\0" + "outer\0" + "over\0" + "overlaps\0" + "overlay\0" + "overriding\0" + "owned\0" + "owner\0" + "parallel\0" + "parameter\0" + "parser\0" + "partial\0" + "partition\0" + "passing\0" + "password\0" + "path\0" + "period\0" + "pgpool\0" + "placing\0" + "plan\0" + "plans\0" + "policy\0" + "position\0" + "preceding\0" + "precision\0" + "prepare\0" + "prepared\0" + "preserve\0" + "primary\0" + "prior\0" + "privileges\0" + "procedural\0" + "procedure\0" + "procedures\0" + "program\0" + "publication\0" + "quote\0" + "quotes\0" + "range\0" + "read\0" + "real\0" + "reassign\0" + "recursive\0" + "ref\0" + "references\0" + "referencing\0" + "refresh\0" + "reindex\0" + "relative\0" + "release\0" + "rename\0" + "repeatable\0" + "replace\0" + "replica\0" + "reset\0" + "restart\0" + "restrict\0" + "return\0" + "returning\0" + "returns\0" + "revoke\0" + "right\0" + "role\0" + "rollback\0" + "rollup\0" + "routine\0" + "routines\0" + "row\0" + "rows\0" + "rule\0" + "savepoint\0" + "scalar\0" + "schema\0" + "schemas\0" + "scroll\0" + "search\0" + "second\0" + "security\0" + "select\0" + "sequence\0" + "sequences\0" + "serializable\0" + "server\0" + "session\0" + "session_user\0" + "set\0" + "setof\0" + "sets\0" + "share\0" + "show\0" + "similar\0" + "simple\0" + "skip\0" + "smallint\0" + "snapshot\0" + "some\0" + "source\0" + "sql\0" + "stable\0" + "standalone\0" + "start\0" + "statement\0" + "statistics\0" + "stdin\0" + "stdout\0" + "storage\0" + "stored\0" + "strict\0" + "string\0" + "strip\0" + "subscription\0" + "substring\0" + "support\0" + "symmetric\0" + "sysid\0" + "system\0" + "system_user\0" + "table\0" + "tables\0" + "tablesample\0" + "tablespace\0" + "target\0" + "temp\0" + "template\0" + "temporary\0" + "text\0" + "then\0" + "ties\0" + "time\0" + "timestamp\0" + "to\0" + "trailing\0" + "transaction\0" + "transform\0" + "treat\0" + "trigger\0" + "trim\0" + "true\0" + "truncate\0" + "trusted\0" + "type\0" + "types\0" + "uescape\0" + "unbounded\0" + "uncommitted\0" + "unconditional\0" + "unencrypted\0" + "union\0" + "unique\0" + "unknown\0" + "unlisten\0" + "unlogged\0" + "until\0" + "update\0" + "user\0" + "using\0" + "vacuum\0" + "valid\0" + "validate\0" + "validator\0" + "value\0" + "values\0" + "varchar\0" + "variadic\0" + "varying\0" + "verbose\0" + "version\0" + "view\0" + "views\0" + "virtual\0" + "volatile\0" + "when\0" + "where\0" + "whitespace\0" + "window\0" + "with\0" + "within\0" + "without\0" + "work\0" + "wrapper\0" + "write\0" + "xml\0" + "xmlattributes\0" + "xmlconcat\0" + "xmlelement\0" + "xmlexists\0" + "xmlforest\0" + "xmlnamespaces\0" + "xmlparse\0" + "xmlpi\0" + "xmlroot\0" + "xmlserialize\0" + "xmltable\0" + "year\0" + "yes\0" + "zone"; + +static const uint16 ScanKeywords_kw_offsets[] = { + 0, + 6, + 13, + 22, + 29, + 36, + 40, + 46, + 52, + 62, + 66, + 71, + 77, + 84, + 92, + 100, + 104, + 108, + 114, + 117, + 121, + 132, + 142, + 153, + 164, + 167, + 174, + 181, + 191, + 205, + 214, + 221, + 227, + 235, + 242, + 249, + 253, + 261, + 266, + 274, + 277, + 283, + 288, + 295, + 303, + 312, + 317, + 322, + 330, + 336, + 341, + 351, + 367, + 373, + 384, + 390, + 396, + 404, + 413, + 421, + 431, + 438, + 446, + 454, + 463, + 470, + 480, + 492, + 505, + 517, + 531, + 540, + 551, + 562, + 574, + 582, + 591, + 602, + 607, + 612, + 619, + 625, + 629, + 634, + 642, + 658, + 671, + 684, + 699, + 712, + 730, + 743, + 750, + 756, + 761, + 770, + 774, + 785, + 789, + 797, + 805, + 813, + 822, + 833, + 842, + 850, + 857, + 867, + 878, + 886, + 892, + 897, + 904, + 915, + 923, + 931, + 940, + 943, + 952, + 959, + 966, + 971, + 976, + 981, + 987, + 994, + 1003, + 1013, + 1017, + 1026, + 1031, + 1037, + 1044, + 1050, + 1057, + 1065, + 1075, + 1085, + 1093, + 1100, + 1108, + 1119, + 1129, + 1138, + 1146, + 1152, + 1159, + 1165, + 1172, + 1181, + 1187, + 1193, + 1203, + 1207, + 1213, + 1221, + 1228, + 1236, + 1243, + 1248, + 1253, + 1262, + 1272, + 1282, + 1289, + 1295, + 1303, + 1312, + 1318, + 1327, + 1334, + 1342, + 1349, + 1356, + 1361, + 1366, + 1375, + 1378, + 1384, + 1394, + 1404, + 1413, + 1420, + 1423, + 1431, + 1441, + 1451, + 1458, + 1464, + 1472, + 1480, + 1489, + 1499, + 1506, + 1512, + 1518, + 1524, + 1536, + 1543, + 1551, + 1555, + 1563, + 1573, + 1582, + 1587, + 1595, + 1598, + 1605, + 1615, + 1620, + 1625, + 1636, + 1650, + 1662, + 1674, + 1689, + 1700, + 1712, + 1727, + 1738, + 1749, + 1754, + 1758, + 1763, + 1769, + 1778, + 1784, + 1789, + 1797, + 1805, + 1815, + 1821, + 1826, + 1832, + 1837, + 1843, + 1850, + 1855, + 1861, + 1871, + 1886, + 1895, + 1900, + 1907, + 1914, + 1922, + 1928, + 1936, + 1949, + 1958, + 1964, + 1977, + 1984, + 1991, + 2000, + 2005, + 2011, + 2016, + 2021, + 2027, + 2036, + 2044, + 2050, + 2057, + 2061, + 2066, + 2070, + 2074, + 2079, + 2084, + 2087, + 2092, + 2102, + 2113, + 2117, + 2125, + 2132, + 2140, + 2147, + 2152, + 2159, + 2165, + 2173, + 2180, + 2188, + 2191, + 2195, + 2202, + 2207, + 2211, + 2216, + 2219, + 2224, + 2233, + 2240, + 2248, + 2251, + 2257, + 2268, + 2275, + 2279, + 2285, + 2290, + 2299, + 2307, + 2318, + 2324, + 2330, + 2339, + 2349, + 2356, + 2364, + 2374, + 2382, + 2391, + 2396, + 2403, + 2410, + 2418, + 2423, + 2429, + 2436, + 2445, + 2455, + 2465, + 2473, + 2482, + 2491, + 2499, + 2505, + 2516, + 2527, + 2537, + 2548, + 2556, + 2568, + 2574, + 2581, + 2587, + 2592, + 2597, + 2606, + 2616, + 2620, + 2631, + 2643, + 2651, + 2659, + 2668, + 2676, + 2683, + 2694, + 2702, + 2710, + 2716, + 2724, + 2733, + 2740, + 2750, + 2758, + 2765, + 2771, + 2776, + 2785, + 2792, + 2800, + 2809, + 2813, + 2818, + 2823, + 2833, + 2840, + 2847, + 2855, + 2862, + 2869, + 2876, + 2885, + 2892, + 2901, + 2911, + 2924, + 2931, + 2939, + 2952, + 2956, + 2962, + 2967, + 2973, + 2978, + 2986, + 2993, + 2998, + 3007, + 3016, + 3021, + 3028, + 3032, + 3039, + 3050, + 3056, + 3066, + 3077, + 3083, + 3090, + 3098, + 3105, + 3112, + 3119, + 3125, + 3138, + 3148, + 3156, + 3166, + 3172, + 3179, + 3191, + 3197, + 3204, + 3216, + 3227, + 3234, + 3239, + 3248, + 3258, + 3263, + 3268, + 3273, + 3278, + 3288, + 3291, + 3300, + 3312, + 3322, + 3328, + 3336, + 3341, + 3346, + 3355, + 3363, + 3368, + 3374, + 3382, + 3392, + 3404, + 3418, + 3430, + 3436, + 3443, + 3451, + 3460, + 3469, + 3475, + 3482, + 3487, + 3493, + 3500, + 3506, + 3515, + 3525, + 3531, + 3538, + 3546, + 3555, + 3563, + 3571, + 3579, + 3584, + 3590, + 3598, + 3607, + 3612, + 3618, + 3629, + 3636, + 3641, + 3648, + 3656, + 3661, + 3669, + 3675, + 3679, + 3693, + 3703, + 3714, + 3724, + 3734, + 3748, + 3757, + 3763, + 3771, + 3784, + 3793, + 3798, + 3802, +}; + +#define SCANKEYWORDS_NUM_KEYWORDS 495 + +static int +ScanKeywords_hash_func(const void *key, size_t keylen) +{ + static const int16 h[991] = { + 32767, -121, 32767, -21, 32767, 32767, 32767, -435, + 391, 32767, 32767, 487, 377, 213, 32767, 32767, + 32767, 32767, 32767, 20, 32767, 32767, 1, -114, + 458, 375, 88, 535, 32767, 32767, 319, 387, + -180, 0, 0, 32767, -473, 163, 105, 0, + 32767, 32767, 32767, 21, 173, -212, 32767, 371, + 65, 125, 32767, 455, 32767, 370, -342, 830, + 32767, 176, 1114, -78, -161, 32767, 239, -903, + 32767, -653, 32767, -412, 149, 32767, 1137, 32767, + -618, 32767, 919, -333, 237, 20, 32767, 380, + 195, 32767, 152, 135, 264, 115, 95, 0, + 32767, 876, -342, 32767, 32767, 374, 956, 108, + -41, 0, -760, 32767, 32767, 0, 32767, 422, + 328, 32767, 32767, 32767, 60, -183, 32767, -630, + 32767, 266, -353, 503, 32767, -111, 32767, 32767, + 480, 171, -264, 32767, 193, 482, 73, 194, + 32767, 288, 32767, 176, 370, 32767, 32767, 0, + 234, 32767, 62, 229, 32767, 32767, 32767, 0, + 32767, 32767, 32767, 32767, 466, 32767, 56, 32767, + -77, 407, 395, 86, 0, 32767, 201, 562, + 0, -460, 0, 32767, 32767, 32767, 290, 32767, + 35, 32767, 1, 32767, 396, 70, 0, 97, + 434, 420, 272, 178, 32767, 32767, 29, 346, + 0, 382, 32767, 32767, 423, -1086, 32767, 378, + 32767, 429, 32767, -210, 0, 32767, 32767, 369, + -652, 328, 64, 418, 1112, 32767, 32767, 0, + 0, 216, 32767, 32767, -339, -659, 32767, 289, + 419, 47, 32767, 767, -622, 0, -293, 0, + 32767, 32767, -257, 0, 0, 32767, 0, 32767, + 32767, 441, 32767, 0, -279, 0, 38, -433, + 32767, 470, 32767, 0, 32767, 245, -162, 32767, + 32767, -238, 32767, 0, 32767, 32767, 77, 32767, + 32767, 103, 32767, 32767, 181, 342, 32767, 150, + 440, 12, 32767, 244, 32767, 0, -149, 835, + 32767, 390, 423, 189, 32767, 32767, 32767, 32767, + 32767, 0, 0, -138, 32767, 255, 32767, 282, + 32767, -740, -639, 48, -126, 32767, 32767, 32767, + 32767, 32767, 32767, 647, 46, 369, 32767, 0, + 32767, 32767, -206, 32767, 32767, -130, 32767, 96, + 32767, 0, -27, 32767, 356, 32767, 32767, -311, + 314, 13, -158, 32767, 32767, 0, 486, 52, + 32767, 437, -3, 308, -314, -94, 32767, 32767, + 32767, 32767, 0, 32767, 765, 270, 32767, 205, + 32767, 32767, 240, -328, -50, 70, 57, -99, + 95, 32767, 32767, 464, 32767, 32767, 32767, 203, + 445, 32767, 391, 32767, 141, -210, 172, -125, + 0, 32767, 130, 32767, -66, 32767, 32767, 0, + 393, 32767, 32767, 185, 0, 32767, 258, 40, + -799, 32767, 23, 32767, 87, 32767, 119, 32767, + 32767, -227, 138, 32767, 32767, 32767, 206, 344, + 1, 71, 32767, 0, 421, 32767, 32767, 32767, + -625, 32767, 32767, 38, 491, 32767, 32767, -984, + 198, 0, 455, -16, 56, 0, -717, 411, + 200, 0, 32767, 0, 32767, 188, 82, 32767, + 32767, 0, 32767, -80, 80, 32767, -675, 32767, + 378, 26, 0, 32767, 32767, 57, 0, 32767, + 633, 32767, 0, 32767, 307, 32767, 132, 32767, + 320, 220, 32767, 0, 264, 32767, 499, -7, + 139, 271, 32767, 357, 532, 168, 32767, 258, + 32767, 17, 219, -178, 299, 32767, 32767, -27, + 382, 32767, 32767, 32767, 32767, 32767, 637, 32767, + 32767, 329, -364, 32767, -16, 355, -197, 127, + 340, -434, 224, -3, -186, 0, 176, 156, + 32767, 32767, 105, 32767, 435, 34, 32767, 32767, + 568, -176, 0, -471, 333, 32767, 0, -218, + 32767, 254, 283, 0, 326, 32767, 32767, 32767, + 0, 32767, 32767, 99, -142, 0, 318, 303, + 360, 267, 32767, 344, 0, 32767, 32767, 32767, + 547, 32767, 32767, 334, 0, -59, 446, -366, + -253, 32767, -165, 32767, 32767, 32767, 427, -152, + 15, 32767, 32767, 0, 51, 32767, 98, 599, + 169, 31, 0, -116, 0, 0, 32767, -402, + 32767, 32767, 263, 32767, 32767, -205, -94, 0, + 280, 260, 32767, 32767, 1124, 32767, -543, 0, + 0, 32767, 32767, 32767, 32767, 32767, 773, 7, + 930, 288, -620, 32767, 132, 32767, 0, 0, + 58, 32767, 373, 848, 228, 112, -4, 32767, + 32767, -152, 651, 32767, 32767, 1013, -685, 240, + 242, -117, 38, 110, 32767, 0, 32767, -48, + 32767, -113, 32767, 0, 92, 1228, 0, 760, + 32767, 0, 32767, 0, 457, -144, 774, 198, + 32767, 32767, 32767, 351, 329, 292, 32767, 32767, + 118, 32767, 32767, 331, 80, 117, 815, 32767, + 0, 32767, 370, 32767, 32767, 0, 32767, -419, + 32767, 32767, 32767, 0, 32767, 32767, 32767, 193, + 0, 32767, 0, 32767, 32767, 32767, 870, 0, + 32767, -52, 454, 0, 32767, 64, 0, 310, + 0, -338, 32767, 119, 32767, 32767, -366, 32767, + 0, 159, 32767, 362, 66, 32767, 32767, 32767, + 0, -122, -39, 425, 361, 32767, -160, 420, + 163, 210, 32767, 32767, 32767, 32767, -642, 0, + -287, 0, 32767, 0, 401, 0, 221, 32767, + 238, 0, 525, 0, 91, 32767, 325, 32767, + 32767, -651, 129, 463, 0, 0, 32767, 172, + 287, 32767, 32767, -122, 0, 32767, 32767, 798, + 492, 109, -52, 0, 0, 6, 32767, 32767, + 32767, 474, 32767, 87, 32767, 32767, 31, 32767, + 451, 7, 252, 69, 32767, 6, -276, 97, + 32767, 32767, 32767, 32767, 32767, 141, 524, 32767, + 83, -304, 32767, 32767, 32767, 941, 32767, 32767, + 32767, 32767, 107, 32767, 32767, 32767, 32767, 32767, + 32767, 535, -733, 493, 32767, 554, -257, 18, + 173, -370, 191, 528, 406, 0, 468, 292, + 32767, -142, 417, 179, -27, 322, 32767, 504, + 32767, 433, 153, 182, 394, 32767, 32767, 32767, + 0, 32767, 177, 118, 32767, 32767, 83, 194, + 18, -781, 0, 322, 0, 19, 344, 32767, + 156, 118, 0, 32767, 372, 32767, 32767, 0, + 32767, -452, 366, 1133, -126, 834, 32767, 32767, + 32767, 1193, 162, 32767, 0, 0, -328, 360, + 353, -489, 0, 32767, 32767, 32767, 32767, 32767, + -237, 290, 32767, -780, 32767, -78, 32767, 0, + 137, 0, 94, 0, 344, 32767, 671, -164, + 422, 32767, 405, 32767, 57, 0, 141, 32767, + 32767, -16, 32767, 32767, -55, 46, 221, 32767, + 247, 32767, 0, 10, 32767, 401, 613, 32767, + 0, -244, 250, 32767, 223, 32767, 274, 32767, + 32767, 0, 124, 32767, 291, 303, -299, 234, + 38, 32767, 0, 32767, 181, 0, 536, 32767, + 23, -195, -192, 0, 1087, 32767, 60, 32767, + 177, 32767, 0, -646, 622, -36, 752, 46, + 0, 32767, 32767, 1067, 0, 32767, -187, 192, + 0, 32767, 32767, 425, 0, 32767, 879, 32767, + 32767, -129, 0, 32767, 190, 175, 254 + }; + + const unsigned char *k = (const unsigned char *) key; + uint32 a = 0; + uint32 b = 1; + + while (keylen--) + { + unsigned char c = *k++ | 0x20; + + a = a * 257 + c; + b = b * 127 + c; + } + return h[a % 991] + h[b % 991]; +} + +const ScanKeywordList ScanKeywords = { + ScanKeywords_kw_string, + ScanKeywords_kw_offsets, + ScanKeywords_hash_func, + SCANKEYWORDS_NUM_KEYWORDS, + 17 +}; + +#endif /* KWLIST_D_H */ diff --git a/src/include/parser/kwlookup.h b/src/include/parser/kwlookup.h new file mode 100644 index 000000000..2fefe3563 --- /dev/null +++ b/src/include/parser/kwlookup.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * kwlookup.h + * Key word lookup for PostgreSQL + * + * + * Portions Copyright (c) 2003-2022, PgPool Global Development Group + * Portions Copyright (c) 1996-2022, 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 + +#include "pool_type.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/parser/makefuncs.h b/src/include/parser/makefuncs.h index b39c19e73..0441c8e5d 100644 --- a/src/include/parser/makefuncs.h +++ b/src/include/parser/makefuncs.h @@ -1,11 +1,11 @@ /*------------------------------------------------------------------------- * * makefuncs.h - * prototypes for the creator functions (for primitive nodes) + * prototypes for the creator functions of various nodes * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/makefuncs.h @@ -19,42 +19,42 @@ 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); +extern Var *makeVar(int varno, + AttrNumber varattno, + Oid vartype, + int32 vartypmod, + Oid varcollid, + Index varlevelsup); -extern Var *makeVarFromTargetEntry(Index varno, - TargetEntry *tle); +extern Var *makeVarFromTargetEntry(int varno, + TargetEntry *tle); extern Var *makeWholeRowVar(RangeTblEntry *rte, - Index varno, - Index varlevelsup, - bool allowScalar); + int 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); @@ -65,28 +65,46 @@ 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); +extern Constraint *makeNotNullConstraint(String *colname); extern TypeName *makeTypeName(char *typnam); 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 FuncCall *makeFuncCall(List *name, List *args, + CoercionForm funcformat, int location); +extern Node *makeStringConst(char *str, int location); 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); extern VacuumRelation *makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols); +extern JsonFormat *makeJsonFormat(JsonFormatType type, JsonEncoding encoding, + int location); +extern JsonValueExpr *makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr, + JsonFormat *format); +extern Node *makeJsonKeyValue(Node *key, Node *value); +extern Node *makeJsonIsPredicate(Node *expr, JsonFormat *format, + JsonValueType item_type, bool unique_keys, + int location); +extern JsonBehavior *makeJsonBehavior(JsonBehaviorType btype, Node *expr, + int location); +extern JsonTablePath *makeJsonTablePath(Const *pathvalue, char *pathname); +extern JsonTablePathSpec *makeJsonTablePathSpec(char *string, char *name, + int string_location, + int name_location); + #endif /* MAKEFUNC_H */ diff --git a/src/include/parser/miscnodes.h b/src/include/parser/miscnodes.h new file mode 100644 index 000000000..719cacff1 --- /dev/null +++ b/src/include/parser/miscnodes.h @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * miscnodes.h + * Definitions for hard-to-classify node types. + * + * Node types declared here are not part of parse trees, plan trees, + * or execution state trees. We only assign them NodeTag values because + * IsA() tests provide a convenient way to disambiguate what kind of + * structure is being passed through assorted APIs, such as function + * "context" pointers. + * + * + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/miscnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef MISCNODES_H +#define MISCNODES_H + +#include "nodes.h" + +/* + * ErrorSaveContext - + * function call context node for handling of "soft" errors + * + * A caller wishing to trap soft errors must initialize a struct like this + * with all fields zero/NULL except for the NodeTag. Optionally, set + * details_wanted = true if more than the bare knowledge that a soft error + * occurred is required. The struct is then passed to a SQL-callable function + * via the FunctionCallInfo.context field; or below the level of SQL calls, + * it could be passed to a subroutine directly. + * + * After calling code that might report an error this way, check + * error_occurred to see if an error happened. If so, and if details_wanted + * is true, error_data has been filled with error details (stored in the + * callee's memory context!). The ErrorData can be modified (e.g. downgraded + * to a WARNING) and reported with ThrowErrorData(). FreeErrorData() can be + * called to release error_data, although that step is typically not necessary + * if the called code was run in a short-lived context. + */ +typedef struct ErrorSaveContext +{ + NodeTag type; + bool error_occurred; /* set to true if we detect a soft error */ + bool details_wanted; /* does caller want more info than that? */ + ErrorData *error_data; /* details of error, if so */ +} ErrorSaveContext; + +#endif /* MISCNODES_H */ diff --git a/src/include/parser/nodes.h b/src/include/parser/nodes.h index 4df7e13c2..5412ef4c8 100644 --- a/src/include/parser/nodes.h +++ b/src/include/parser/nodes.h @@ -4,8 +4,8 @@ * Definitions for tagged nodes. * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/nodes.h @@ -16,6 +16,7 @@ #define NODES_H #include +#include "utils/palloc.h" /* * The first field of every node is NodeTag. Each node created (with makeNode) @@ -29,492 +30,108 @@ typedef enum NodeTag { T_Invalid = 0, - - /* - * TAGS FOR EXECUTOR NODES (execnodes.h) - */ - T_IndexInfo, - T_ExprContext, - T_ProjectionInfo, - T_JunkFilter, - T_OnConflictSetState, - T_ResultRelInfo, - T_EState, - T_TupleTableSlot, - - /* - * TAGS FOR PLAN NODES (plannodes.h) - */ - T_Plan, - T_Result, - T_ProjectSet, - T_ModifyTable, - T_Append, - T_MergeAppend, - T_RecursiveUnion, - T_BitmapAnd, - T_BitmapOr, - T_Scan, - T_SeqScan, - T_SampleScan, - T_IndexScan, - T_IndexOnlyScan, - T_BitmapIndexScan, - T_BitmapHeapScan, - T_TidScan, - T_SubqueryScan, - T_FunctionScan, - T_ValuesScan, - T_TableFuncScan, - T_CteScan, - T_NamedTuplestoreScan, - T_WorkTableScan, - T_ForeignScan, - T_CustomScan, - T_Join, - T_NestLoop, - T_MergeJoin, - T_HashJoin, - T_Material, - T_Sort, - T_Group, - T_Agg, - T_WindowAgg, - T_Unique, - T_Gather, - T_GatherMerge, - T_Hash, - T_SetOp, - T_LockRows, - T_Limit, - /* these aren't subclasses of Plan: */ - T_NestLoopParam, - T_PlanRowMark, - T_PartitionPruneInfo, - T_PartitionedRelPruneInfo, - T_PartitionPruneStepOp, - T_PartitionPruneStepCombine, - T_PlanInvalItem, - - /* - * TAGS FOR PLAN STATE NODES (execnodes.h) - * - * These should correspond one-to-one with Plan node types. - */ - T_PlanState, - T_ResultState, - T_ProjectSetState, - T_ModifyTableState, - T_AppendState, - T_MergeAppendState, - T_RecursiveUnionState, - T_BitmapAndState, - T_BitmapOrState, - T_ScanState, - T_SeqScanState, - T_SampleScanState, - T_IndexScanState, - T_IndexOnlyScanState, - T_BitmapIndexScanState, - T_BitmapHeapScanState, - T_TidScanState, - T_SubqueryScanState, - T_FunctionScanState, - T_TableFuncScanState, - T_ValuesScanState, - T_CteScanState, - T_NamedTuplestoreScanState, - T_WorkTableScanState, - T_ForeignScanState, - T_CustomScanState, - T_JoinState, - T_NestLoopState, - T_MergeJoinState, - T_HashJoinState, - T_MaterialState, - T_SortState, - T_GroupState, - T_AggState, - T_WindowAggState, - T_UniqueState, - T_GatherState, - T_GatherMergeState, - T_HashState, - T_SetOpState, - T_LockRowsState, - T_LimitState, - - /* - * TAGS FOR PRIMITIVE NODES (primnodes.h) - */ - T_Alias, - T_RangeVar, - T_TableFunc, - T_Expr, - T_Var, - T_Const, - T_Param, - T_Aggref, - T_GroupingFunc, - T_WindowFunc, - T_ArrayRef, - T_FuncExpr, - T_NamedArgExpr, - T_OpExpr, - T_DistinctExpr, - T_NullIfExpr, - T_ScalarArrayOpExpr, - T_BoolExpr, - T_SubLink, - T_SubPlan, - T_AlternativeSubPlan, - T_FieldSelect, - T_FieldStore, - T_RelabelType, - T_CoerceViaIO, - T_ArrayCoerceExpr, - T_ConvertRowtypeExpr, - T_CollateExpr, - T_CaseExpr, - T_CaseWhen, - T_CaseTestExpr, - T_ArrayExpr, - T_RowExpr, - T_RowCompareExpr, - T_CoalesceExpr, - T_MinMaxExpr, - T_SQLValueFunction, - T_XmlExpr, - T_NullTest, - T_BooleanTest, - T_CoerceToDomain, - T_CoerceToDomainValue, - T_SetToDefault, - T_CurrentOfExpr, - T_NextValueExpr, - T_InferenceElem, - T_TargetEntry, - T_RangeTblRef, - T_JoinExpr, - T_FromExpr, - T_OnConflictExpr, - T_IntoClause, - - /* - * TAGS FOR EXPRESSION STATE NODES (execnodes.h) - * - * ExprState represents the evaluation state for a whole expression tree. - * Most Expr-based plan nodes do not have a corresponding expression state - * node, they're fully handled within execExpr* - but sometimes the state - * needs to be shared with other parts of the executor, as for example - * with AggrefExprState, which nodeAgg.c has to modify. - */ - T_ExprState, - T_AggrefExprState, - T_WindowFuncExprState, - T_SetExprState, - T_SubPlanState, - T_AlternativeSubPlanState, - T_DomainConstraintState, - - /* - * TAGS FOR PLANNER NODES (relation.h) - */ - T_PlannerInfo, - T_PlannerGlobal, - T_RelOptInfo, - T_IndexOptInfo, - T_ForeignKeyOptInfo, - T_ParamPathInfo, - T_Path, - T_IndexPath, - T_BitmapHeapPath, - T_BitmapAndPath, - T_BitmapOrPath, - T_TidPath, - T_SubqueryScanPath, - T_ForeignPath, - T_CustomPath, - T_NestPath, - T_MergePath, - T_HashPath, - T_AppendPath, - T_MergeAppendPath, - T_ResultPath, - T_MaterialPath, - T_UniquePath, - T_GatherPath, - T_GatherMergePath, - T_ProjectionPath, - T_ProjectSetPath, - T_SortPath, - T_GroupPath, - T_UpperUniquePath, - T_AggPath, - T_GroupingSetsPath, - T_MinMaxAggPath, - T_WindowAggPath, - T_SetOpPath, - T_RecursiveUnionPath, - T_LockRowsPath, - T_ModifyTablePath, - T_LimitPath, - /* these aren't subclasses of Path: */ - T_EquivalenceClass, - T_EquivalenceMember, - T_PathKey, - T_PathTarget, - T_RestrictInfo, - T_PlaceHolderVar, - T_SpecialJoinInfo, - T_AppendRelInfo, - T_PlaceHolderInfo, - T_MinMaxAggInfo, - T_PlannerParamItem, - T_RollupData, - T_GroupingSetData, - T_StatisticExtInfo, - - /* - * TAGS FOR MEMORY NODES (memnodes.h) - */ - T_MemoryContext, - T_AllocSetContext, - T_SlabContext, - T_GenerationContext, - - /* - * TAGS FOR VALUE NODES (value.h) - */ - T_Value, - T_Integer, - T_Float, - T_String, - T_BitString, - T_Null, - - /* - * TAGS FOR LIST NODES (pg_list.h) - */ - T_List, - T_IntList, - T_OidList, - - /* - * TAGS FOR EXTENSIBLE NODES (extensible.h) - */ - T_ExtensibleNode, - - /* - * TAGS FOR STATEMENT NODES (mostly in parsenodes.h) - */ - T_RawStmt, - T_Query, - T_PlannedStmt, - T_InsertStmt, - T_DeleteStmt, - T_UpdateStmt, - T_SelectStmt, - T_AlterTableStmt, - T_AlterTableCmd, - T_AlterDomainStmt, - T_SetOperationStmt, - T_GrantStmt, - T_GrantRoleStmt, - T_AlterDefaultPrivilegesStmt, - T_ClosePortalStmt, - T_ClusterStmt, - T_CopyStmt, - T_CreateStmt, - T_DefineStmt, - T_DropStmt, - T_TruncateStmt, - T_CommentStmt, - T_FetchStmt, - T_IndexStmt, - T_CreateFunctionStmt, - T_AlterFunctionStmt, - T_DoStmt, - T_RenameStmt, - T_RuleStmt, - T_NotifyStmt, - T_ListenStmt, - T_UnlistenStmt, - T_TransactionStmt, - T_ViewStmt, - T_LoadStmt, - T_CreateDomainStmt, - T_CreatedbStmt, - T_DropdbStmt, - T_VacuumStmt, - T_ExplainStmt, - T_CreateTableAsStmt, - T_CreateSeqStmt, - T_AlterSeqStmt, - T_VariableSetStmt, - T_VariableShowStmt, - T_DiscardStmt, - T_CreateTrigStmt, - T_CreatePLangStmt, - T_CreateRoleStmt, - T_AlterRoleStmt, - T_DropRoleStmt, - T_LockStmt, - T_ConstraintsSetStmt, - T_ReindexStmt, - T_CheckPointStmt, - T_CreateSchemaStmt, - T_AlterDatabaseStmt, - T_AlterDatabaseSetStmt, - T_AlterRoleSetStmt, - T_CreateConversionStmt, - T_CreateCastStmt, - T_CreateOpClassStmt, - T_CreateOpFamilyStmt, - T_AlterOpFamilyStmt, - T_PrepareStmt, - T_ExecuteStmt, - T_DeallocateStmt, - T_DeclareCursorStmt, - T_CreateTableSpaceStmt, - T_DropTableSpaceStmt, - T_AlterObjectDependsStmt, - T_AlterObjectSchemaStmt, - T_AlterOwnerStmt, - T_AlterOperatorStmt, - T_DropOwnedStmt, - T_ReassignOwnedStmt, - T_CompositeTypeStmt, - T_CreateEnumStmt, - T_CreateRangeStmt, - T_AlterEnumStmt, - T_AlterTSDictionaryStmt, - T_AlterTSConfigurationStmt, - T_CreateFdwStmt, - T_AlterFdwStmt, - T_CreateForeignServerStmt, - T_AlterForeignServerStmt, - T_CreateUserMappingStmt, - T_AlterUserMappingStmt, - T_DropUserMappingStmt, - T_AlterTableSpaceOptionsStmt, - T_AlterTableMoveAllStmt, - T_SecLabelStmt, - T_CreateForeignTableStmt, - T_ImportForeignSchemaStmt, - T_CreateExtensionStmt, - T_AlterExtensionStmt, - T_AlterExtensionContentsStmt, - T_CreateEventTrigStmt, - T_AlterEventTrigStmt, - T_RefreshMatViewStmt, - T_ReplicaIdentityStmt, - T_AlterSystemStmt, - T_CreatePolicyStmt, - T_AlterPolicyStmt, - T_CreateTransformStmt, - T_CreateAmStmt, - T_CreatePublicationStmt, - T_AlterPublicationStmt, - T_CreateSubscriptionStmt, - T_AlterSubscriptionStmt, - T_DropSubscriptionStmt, - T_CreateStatsStmt, - T_AlterCollationStmt, - T_CallStmt, - - /* - * TAGS FOR PARSE TREE NODES (parsenodes.h) - */ - T_A_Expr, - T_ColumnRef, - T_ParamRef, - T_A_Const, - T_FuncCall, - T_A_Star, - T_A_Indices, - T_A_Indirection, - T_A_ArrayExpr, - T_ResTarget, - T_MultiAssignRef, - T_TypeCast, - T_CollateClause, - T_SortBy, - T_WindowDef, - T_RangeSubselect, - T_RangeFunction, - T_RangeTableSample, - T_RangeTableFunc, - T_RangeTableFuncCol, - T_TypeName, - T_ColumnDef, - T_IndexElem, - T_Constraint, - T_DefElem, - T_RangeTblEntry, - T_RangeTblFunction, - T_TableSampleClause, - T_WithCheckOption, - T_SortGroupClause, - T_GroupingSet, - T_WindowClause, - T_ObjectWithArgs, - T_AccessPriv, - T_CreateOpClassItem, - T_TableLikeClause, - T_FunctionParameter, - T_LockingClause, - T_RowMarkClause, - T_XmlSerialize, - T_WithClause, - T_InferClause, - T_OnConflictClause, - T_CommonTableExpr, - T_RoleSpec, - T_TriggerTransition, - T_PartitionElem, - T_PartitionSpec, - T_PartitionBoundSpec, - T_PartitionRangeDatum, - T_PartitionCmd, - T_VacuumRelation, - - /* - * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h) - */ - T_IdentifySystemCmd, - T_BaseBackupCmd, - T_CreateReplicationSlotCmd, - T_DropReplicationSlotCmd, - T_StartReplicationCmd, - T_TimeLineHistoryCmd, - T_SQLCmd, - - /* - * TAGS FOR RANDOM OTHER STUFF - * - * These are objects that aren't part of parse/plan/execute node tree - * structures, but we give them NodeTags anyway for identification - * purposes (usually because they are involved in APIs where we want to - * pass multiple object types through the same pointer). - */ - T_TriggerData, /* in commands/trigger.h */ - T_EventTriggerData, /* in commands/event_trigger.h */ - T_ReturnSetInfo, /* in nodes/execnodes.h */ - T_WindowObjectData, /* private in nodeWindowAgg.c */ - T_TIDBitmap, /* in nodes/tidbitmap.h */ - T_InlineCodeBlock, /* in nodes/parsenodes.h */ - T_FdwRoutine, /* in foreign/fdwapi.h */ - T_IndexAmRoutine, /* in access/amapi.h */ - TsmRoutine , /* in access/tsmapi.h */ - T_ForeignKeyCacheInfo, /* in utils/rel.h */ - T_CallContext, /* in nodes/parsenodes.h */ - /* pgpool Extention */ - T_PgpoolVariableSetStmt, - T_PgpoolVariableShowStmt - +#include "nodetags.h" + /* pgpool Extension */ + T_PgpoolVariableSetStmt, + T_PgpoolVariableShowStmt, + T_PgpoolQueryCacheStmt, } NodeTag; +/* + * pg_node_attr() - Used in node definitions to set extra information for + * gen_node_support.pl + * + * Attributes can be attached to a node as a whole (place the attribute + * specification on the first line after the struct's opening brace) + * or to a specific field (place it at the end of that field's line). The + * argument is a comma-separated list of attributes. Unrecognized attributes + * cause an error. + * + * Valid node attributes: + * + * - abstract: Abstract types are types that cannot be instantiated but that + * can be supertypes of other types. We track their fields, so that + * subtypes can use them, but we don't emit a node tag, so you can't + * instantiate them. + * + * - custom_copy_equal: Has custom implementations in copyfuncs.c and + * equalfuncs.c. + * + * - custom_read_write: Has custom implementations in outfuncs.c and + * readfuncs.c. + * + * - custom_query_jumble: Has custom implementation in queryjumblefuncs.c. + * Also available as a node field attribute. + * + * - no_copy: Does not support copyObject() at all. + * + * - no_equal: Does not support equal() at all. + * + * - no_copy_equal: Shorthand for both no_copy and no_equal. + * + * - no_query_jumble: Does not support JumbleQuery() at all. + * + * - no_read: Does not support nodeRead() at all. + * + * - nodetag_only: Does not support copyObject(), equal(), jumbleQuery() + * outNode() or nodeRead(). + * + * - special_read_write: Has special treatment in outNode() and nodeRead(). + * + * - nodetag_number(VALUE): assign the specified nodetag number instead of + * an auto-generated number. Typically this would only be used in stable + * branches, to give a newly-added node type a number without breaking ABI + * by changing the numbers of existing node types. + * + * Node types can be supertypes of other types whether or not they are marked + * abstract: if a node struct appears as the first field of another struct + * type, then it is the supertype of that type. The no_copy, no_equal, + * no_query_jumble and no_read node attributes are automatically inherited + * from the supertype. (Notice that nodetag_only does not inherit, so it's + * not quite equivalent to a combination of other attributes.) + * + * Valid node field attributes: + * + * - array_size(OTHERFIELD): This field is a dynamically allocated array with + * size indicated by the mentioned other field. The other field is either a + * scalar or a list, in which case the length of the list is used. + * + * - copy_as(VALUE): In copyObject(), replace the field's value with VALUE. + * + * - copy_as_scalar: In copyObject(), copy the field as a scalar value + * (e.g. a pointer) even if it is a node-type pointer. + * + * - equal_as_scalar: In equal(), compare the field as a scalar value + * even if it is a node-type pointer. + * + * - equal_ignore: Ignore the field for equality. + * + * - equal_ignore_if_zero: Ignore the field for equality if it is zero. + * (Otherwise, compare normally.) + * + * - custom_query_jumble: Has custom implementation in queryjumblefuncs.c + * for the field of a node. Also available as a node attribute. + * + * - query_jumble_ignore: Ignore the field for the query jumbling. Note + * that typmod and collation information are usually irrelevant for the + * query jumbling. + * + * - query_jumble_squash: Squash multiple values during query jumbling. + * + * - query_jumble_location: Mark the field as a location to track. This is + * only allowed for integer fields that include "location" in their name. + * + * - read_as(VALUE): In nodeRead(), replace the field's value with VALUE. + * + * - read_write_ignore: Ignore the field for read/write. This is only allowed + * if the node type is marked no_read or read_as() is also specified. + * + * - write_only_relids, write_only_nondefault_pathtarget, write_only_req_outer: + * Special handling for Path struct; see there. + * + */ +#define pg_node_attr(...) + /* * The first field of a node of any type is guaranteed to be the NodeTag. * Hence the type of any node can be gotten by casting it to Node. Declaring @@ -535,39 +152,18 @@ typedef struct Node * * !WARNING!: Avoid using newNode directly. You should be using the * macro makeNode. eg. to create a Query node, use makeNode(Query) - * - * Note: the size argument should always be a compile-time constant, so the - * apparent risk of multiple evaluation doesn't matter in practice. - */ -#ifdef __GNUC__ - -/* With GCC, we can use a compound statement within an expression */ -#define newNode(size, tag) \ -({ Node *_result; \ - AssertMacro((size) >= sizeof(Node)); /* need the tag, at least */ \ - _result = (Node *) palloc0fast(size); \ - _result->type = (tag); \ - _result; \ -}) -#else - -/* - * There is no way to dereference the palloc'ed pointer to assign the - * tag, and also return the pointer itself, so we need a holder variable. - * Fortunately, this macro isn't recursive so we just define - * a global variable for this purpose. */ -extern Node *newNodeMacroHolder; +static inline Node * +newNode(size_t size, NodeTag tag) +{ + Node *result; -#define newNode(size, tag) \ -( \ - AssertMacro((size) >= sizeof(Node)), /* need the tag, at least */ \ - newNodeMacroHolder = (Node *) palloc0fast(size), \ - newNodeMacroHolder->type = (tag), \ - newNodeMacroHolder \ -) -#endif /* __GNUC__ */ + Assert(size >= sizeof(Node)); /* need the tag, at least */ + result = (Node *) palloc0(size); + result->type = tag; + return result; +} #define makeNode(_type_) ((_type_ *) newNode(sizeof(_type_),T_##_type_)) #define NodeSetTag(nodeptr,t) (((Node*)(nodeptr))->type = (t)) @@ -608,16 +204,20 @@ 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 *nodeToStringWithLocations(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 DEBUG_NODE_TESTS_ENABLED +extern void *stringToNodeWithLocations(const char *str); +#endif extern struct Bitmapset *readBitmapset(void); extern uintptr_t readDatum(bool typbyval); extern bool *readBoolCols(int numCols); @@ -628,7 +228,7 @@ extern int16 *readAttrNumberCols(int numCols); /* * nodes/copyfuncs.c */ -extern void *copyObjectImpl(const void *obj); +extern void *copyObjectImpl(const void *from); /* cast result back to argument type, if supported by compiler */ #ifdef HAVE_TYPEOF @@ -644,15 +244,26 @@ extern bool equal(const void *a, const void *b); /* - * Typedefs for identifying qualifier selectivities and plan costs as such. - * These are just plain "double"s, but declaring a variable as Selectivity - * or Cost makes the intent more obvious. + * Typedef for parse location. This is just an int, but this way + * gen_node_support.pl knows which fields should get special treatment for + * location values. + * + * -1 is used for unknown. + */ +typedef int ParseLoc; + +/* + * Typedefs for identifying qualifier selectivities, plan costs, and row + * counts as such. These are just plain "double"s, but declaring a variable + * as Selectivity, Cost, or Cardinality makes the intent more obvious. * * These could have gone into plannodes.h or some such, but many files * depend on them... */ typedef double Selectivity; /* fraction of tuples a qualifier will pass */ typedef double Cost; /* execution cost (in page-access units) */ +typedef double Cardinality; /* (estimated) number of rows or other integer + * count */ /* @@ -667,10 +278,11 @@ typedef enum CmdType CMD_SELECT, /* select stmt */ CMD_UPDATE, /* update stmt */ CMD_INSERT, /* insert stmt */ - CMD_DELETE, + CMD_DELETE, /* delete stmt */ + CMD_MERGE, /* merge stmt */ CMD_UTILITY, /* cmds like create, destroy, copy, vacuum, * etc. */ - CMD_NOTHING /* dummy command for instead nothing rules + CMD_NOTHING, /* dummy command for instead nothing rules * with qual */ } CmdType; @@ -707,13 +319,15 @@ typedef enum JoinType */ JOIN_SEMI, /* 1 copy of each LHS row that has match(es) */ JOIN_ANTI, /* 1 copy of each LHS row that has no match */ + JOIN_RIGHT_SEMI, /* 1 copy of each RHS row that has match(es) */ + JOIN_RIGHT_ANTI, /* 1 copy of each RHS row that has no match */ /* * These codes are used internally in the planner, but are not supported * by the executor (nor, indeed, by most of the planner). */ JOIN_UNIQUE_OUTER, /* LHS path must be made unique */ - JOIN_UNIQUE_INNER /* RHS path must be made unique */ + JOIN_UNIQUE_INNER, /* RHS path must be made unique */ /* * We might need additional join types someday. @@ -722,10 +336,10 @@ typedef enum JoinType /* * OUTER joins are those for which pushed-down quals must behave differently - * from the join's own quals. This is in fact everything except INNER and - * SEMI joins. However, this macro must also exclude the JOIN_UNIQUE symbols - * since those are temporary proxies for what will eventually be an INNER - * join. + * from the join's own quals. This is in fact everything except INNER, SEMI + * and RIGHT_SEMI joins. However, this macro must also exclude the + * JOIN_UNIQUE symbols since those are temporary proxies for what will + * eventually be an INNER join. * * Note: semijoins are a hybrid case, but we choose to treat them as not * being outer joins. This is okay principally because the SQL syntax makes @@ -739,34 +353,35 @@ typedef enum JoinType ((1 << JOIN_LEFT) | \ (1 << JOIN_FULL) | \ (1 << JOIN_RIGHT) | \ - (1 << JOIN_ANTI))) != 0) + (1 << JOIN_ANTI) | \ + (1 << JOIN_RIGHT_ANTI))) != 0) /* * 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 { AGG_PLAIN, /* simple agg across all input rows */ AGG_SORTED, /* grouped agg, input must be sorted */ AGG_HASHED, /* grouped agg, use internal hashtable */ - AGG_MIXED /* grouped agg, hash and sort both used */ -} AggStrategy; + AGG_MIXED, /* grouped agg, hash and sort both used */ +} 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 @@ -776,7 +391,7 @@ typedef enum AggSplit /* Initial phase of partial aggregation, with serialization: */ AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE, /* Final phase of partial aggregation, with deserialization: */ - AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE + AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE, } AggSplit; /* Test whether an AggSplit value selects each primitive option: */ @@ -789,21 +404,21 @@ 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 { SETOPCMD_INTERSECT, SETOPCMD_INTERSECT_ALL, SETOPCMD_EXCEPT, - SETOPCMD_EXCEPT_ALL -} SetOpCmd; + SETOPCMD_EXCEPT_ALL, +} SetOpCmd; typedef enum SetOpStrategy { SETOP_SORTED, /* input must be sorted */ - SETOP_HASHED /* use internal hashtable */ -} SetOpStrategy; + SETOP_HASHED, /* use internal hashtable */ +} SetOpStrategy; /* * OnConflictAction - @@ -815,7 +430,19 @@ typedef enum OnConflictAction { ONCONFLICT_NONE, /* No "ON CONFLICT" clause */ ONCONFLICT_NOTHING, /* ON CONFLICT ... DO NOTHING */ - ONCONFLICT_UPDATE /* ON CONFLICT ... DO UPDATE */ + ONCONFLICT_UPDATE, /* ON CONFLICT ... DO UPDATE */ } OnConflictAction; +/* + * LimitOption - + * LIMIT option of query + * + * This is needed in both parsenodes.h and plannodes.h, so put it here... + */ +typedef enum LimitOption +{ + LIMIT_OPTION_COUNT, /* FETCH FIRST... ONLY */ + LIMIT_OPTION_WITH_TIES, /* FETCH FIRST... WITH TIES */ +} LimitOption; + #endif /* NODES_H */ diff --git a/src/include/parser/nodetags.h b/src/include/parser/nodetags.h new file mode 100644 index 000000000..312727639 --- /dev/null +++ b/src/include/parser/nodetags.h @@ -0,0 +1,496 @@ +/*------------------------------------------------------------------------- + * + * nodetags.h + * Generated node infrastructure code + * + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * NOTES + * ****************************** + * *** DO NOT EDIT THIS FILE! *** + * ****************************** + * + * It has been GENERATED by src/backend/nodes/gen_node_support.pl + * + *------------------------------------------------------------------------- + */ + T_List = 1, + T_Alias = 2, + T_RangeVar = 3, + T_TableFunc = 4, + T_IntoClause = 5, + T_Var = 6, + T_Const = 7, + T_Param = 8, + T_Aggref = 9, + T_GroupingFunc = 10, + T_WindowFunc = 11, + T_WindowFuncRunCondition = 12, + T_MergeSupportFunc = 13, + T_SubscriptingRef = 14, + T_FuncExpr = 15, + T_NamedArgExpr = 16, + T_OpExpr = 17, + T_DistinctExpr = 18, + T_NullIfExpr = 19, + T_ScalarArrayOpExpr = 20, + T_BoolExpr = 21, + T_SubLink = 22, + T_SubPlan = 23, + T_AlternativeSubPlan = 24, + T_FieldSelect = 25, + T_FieldStore = 26, + T_RelabelType = 27, + T_CoerceViaIO = 28, + T_ArrayCoerceExpr = 29, + T_ConvertRowtypeExpr = 30, + T_CollateExpr = 31, + T_CaseExpr = 32, + T_CaseWhen = 33, + T_CaseTestExpr = 34, + T_ArrayExpr = 35, + T_RowExpr = 36, + T_RowCompareExpr = 37, + T_CoalesceExpr = 38, + T_MinMaxExpr = 39, + T_SQLValueFunction = 40, + T_XmlExpr = 41, + T_JsonFormat = 42, + T_JsonReturning = 43, + T_JsonValueExpr = 44, + T_JsonConstructorExpr = 45, + T_JsonIsPredicate = 46, + T_JsonBehavior = 47, + T_JsonExpr = 48, + T_JsonTablePath = 49, + T_JsonTablePathScan = 50, + T_JsonTableSiblingJoin = 51, + T_NullTest = 52, + T_BooleanTest = 53, + T_MergeAction = 54, + T_CoerceToDomain = 55, + T_CoerceToDomainValue = 56, + T_SetToDefault = 57, + T_CurrentOfExpr = 58, + T_NextValueExpr = 59, + T_InferenceElem = 60, + T_ReturningExpr = 61, + T_TargetEntry = 62, + T_RangeTblRef = 63, + T_JoinExpr = 64, + T_FromExpr = 65, + T_OnConflictExpr = 66, + T_Query = 67, + T_TypeName = 68, + T_ColumnRef = 69, + T_ParamRef = 70, + T_A_Expr = 71, + T_A_Const = 72, + T_TypeCast = 73, + T_CollateClause = 74, + T_RoleSpec = 75, + T_FuncCall = 76, + T_A_Star = 77, + T_A_Indices = 78, + T_A_Indirection = 79, + T_A_ArrayExpr = 80, + T_ResTarget = 81, + T_MultiAssignRef = 82, + T_SortBy = 83, + T_WindowDef = 84, + T_RangeSubselect = 85, + T_RangeFunction = 86, + T_RangeTableFunc = 87, + T_RangeTableFuncCol = 88, + T_RangeTableSample = 89, + T_ColumnDef = 90, + T_TableLikeClause = 91, + T_IndexElem = 92, + T_DefElem = 93, + T_LockingClause = 94, + T_XmlSerialize = 95, + T_PartitionElem = 96, + T_PartitionSpec = 97, + T_PartitionBoundSpec = 98, + T_PartitionRangeDatum = 99, + T_PartitionCmd = 100, + T_RangeTblEntry = 101, + T_RTEPermissionInfo = 102, + T_RangeTblFunction = 103, + T_TableSampleClause = 104, + T_WithCheckOption = 105, + T_SortGroupClause = 106, + T_GroupingSet = 107, + T_WindowClause = 108, + T_RowMarkClause = 109, + T_WithClause = 110, + T_InferClause = 111, + T_OnConflictClause = 112, + T_CTESearchClause = 113, + T_CTECycleClause = 114, + T_CommonTableExpr = 115, + T_MergeWhenClause = 116, + T_ReturningOption = 117, + T_ReturningClause = 118, + T_TriggerTransition = 119, + T_JsonOutput = 120, + T_JsonArgument = 121, + T_JsonFuncExpr = 122, + T_JsonTablePathSpec = 123, + T_JsonTable = 124, + T_JsonTableColumn = 125, + T_JsonKeyValue = 126, + T_JsonParseExpr = 127, + T_JsonScalarExpr = 128, + T_JsonSerializeExpr = 129, + T_JsonObjectConstructor = 130, + T_JsonArrayConstructor = 131, + T_JsonArrayQueryConstructor = 132, + T_JsonAggConstructor = 133, + T_JsonObjectAgg = 134, + T_JsonArrayAgg = 135, + T_RawStmt = 136, + T_InsertStmt = 137, + T_DeleteStmt = 138, + T_UpdateStmt = 139, + T_MergeStmt = 140, + T_SelectStmt = 141, + T_SetOperationStmt = 142, + T_ReturnStmt = 143, + T_PLAssignStmt = 144, + T_CreateSchemaStmt = 145, + T_AlterTableStmt = 146, + T_AlterTableCmd = 147, + T_ATAlterConstraint = 148, + T_ReplicaIdentityStmt = 149, + T_AlterCollationStmt = 150, + T_AlterDomainStmt = 151, + T_GrantStmt = 152, + T_ObjectWithArgs = 153, + T_AccessPriv = 154, + T_GrantRoleStmt = 155, + T_AlterDefaultPrivilegesStmt = 156, + T_CopyStmt = 157, + T_VariableSetStmt = 158, + T_VariableShowStmt = 159, + T_CreateStmt = 160, + T_Constraint = 161, + T_CreateTableSpaceStmt = 162, + T_DropTableSpaceStmt = 163, + T_AlterTableSpaceOptionsStmt = 164, + T_AlterTableMoveAllStmt = 165, + T_CreateExtensionStmt = 166, + T_AlterExtensionStmt = 167, + T_AlterExtensionContentsStmt = 168, + T_CreateFdwStmt = 169, + T_AlterFdwStmt = 170, + T_CreateForeignServerStmt = 171, + T_AlterForeignServerStmt = 172, + T_CreateForeignTableStmt = 173, + T_CreateUserMappingStmt = 174, + T_AlterUserMappingStmt = 175, + T_DropUserMappingStmt = 176, + T_ImportForeignSchemaStmt = 177, + T_CreatePolicyStmt = 178, + T_AlterPolicyStmt = 179, + T_CreateAmStmt = 180, + T_CreateTrigStmt = 181, + T_CreateEventTrigStmt = 182, + T_AlterEventTrigStmt = 183, + T_CreatePLangStmt = 184, + T_CreateRoleStmt = 185, + T_AlterRoleStmt = 186, + T_AlterRoleSetStmt = 187, + T_DropRoleStmt = 188, + T_CreateSeqStmt = 189, + T_AlterSeqStmt = 190, + T_DefineStmt = 191, + T_CreateDomainStmt = 192, + T_CreateOpClassStmt = 193, + T_CreateOpClassItem = 194, + T_CreateOpFamilyStmt = 195, + T_AlterOpFamilyStmt = 196, + T_DropStmt = 197, + T_TruncateStmt = 198, + T_CommentStmt = 199, + T_SecLabelStmt = 200, + T_DeclareCursorStmt = 201, + T_ClosePortalStmt = 202, + T_FetchStmt = 203, + T_IndexStmt = 204, + T_CreateStatsStmt = 205, + T_StatsElem = 206, + T_AlterStatsStmt = 207, + T_CreateFunctionStmt = 208, + T_FunctionParameter = 209, + T_AlterFunctionStmt = 210, + T_DoStmt = 211, + T_InlineCodeBlock = 212, + T_CallStmt = 213, + T_CallContext = 214, + T_RenameStmt = 215, + T_AlterObjectDependsStmt = 216, + T_AlterObjectSchemaStmt = 217, + T_AlterOwnerStmt = 218, + T_AlterOperatorStmt = 219, + T_AlterTypeStmt = 220, + T_RuleStmt = 221, + T_NotifyStmt = 222, + T_ListenStmt = 223, + T_UnlistenStmt = 224, + T_TransactionStmt = 225, + T_CompositeTypeStmt = 226, + T_CreateEnumStmt = 227, + T_CreateRangeStmt = 228, + T_AlterEnumStmt = 229, + T_ViewStmt = 230, + T_LoadStmt = 231, + T_CreatedbStmt = 232, + T_AlterDatabaseStmt = 233, + T_AlterDatabaseRefreshCollStmt = 234, + T_AlterDatabaseSetStmt = 235, + T_DropdbStmt = 236, + T_AlterSystemStmt = 237, + T_ClusterStmt = 238, + T_VacuumStmt = 239, + T_VacuumRelation = 240, + T_ExplainStmt = 241, + T_CreateTableAsStmt = 242, + T_RefreshMatViewStmt = 243, + T_CheckPointStmt = 244, + T_DiscardStmt = 245, + T_LockStmt = 246, + T_ConstraintsSetStmt = 247, + T_ReindexStmt = 248, + T_CreateConversionStmt = 249, + T_CreateCastStmt = 250, + T_CreateTransformStmt = 251, + T_PrepareStmt = 252, + T_ExecuteStmt = 253, + T_DeallocateStmt = 254, + T_DropOwnedStmt = 255, + T_ReassignOwnedStmt = 256, + T_AlterTSDictionaryStmt = 257, + T_AlterTSConfigurationStmt = 258, + T_PublicationTable = 259, + T_PublicationObjSpec = 260, + T_CreatePublicationStmt = 261, + T_AlterPublicationStmt = 262, + T_CreateSubscriptionStmt = 263, + T_AlterSubscriptionStmt = 264, + T_DropSubscriptionStmt = 265, + T_PlannerGlobal = 266, + T_PlannerInfo = 267, + T_RelOptInfo = 268, + T_IndexOptInfo = 269, + T_ForeignKeyOptInfo = 270, + T_StatisticExtInfo = 271, + T_JoinDomain = 272, + T_EquivalenceClass = 273, + T_EquivalenceMember = 274, + T_PathKey = 275, + T_GroupByOrdering = 276, + T_PathTarget = 277, + T_ParamPathInfo = 278, + T_Path = 279, + T_IndexPath = 280, + T_IndexClause = 281, + T_BitmapHeapPath = 282, + T_BitmapAndPath = 283, + T_BitmapOrPath = 284, + T_TidPath = 285, + T_TidRangePath = 286, + T_SubqueryScanPath = 287, + T_ForeignPath = 288, + T_CustomPath = 289, + T_AppendPath = 290, + T_MergeAppendPath = 291, + T_GroupResultPath = 292, + T_MaterialPath = 293, + T_MemoizePath = 294, + T_UniquePath = 295, + T_GatherPath = 296, + T_GatherMergePath = 297, + T_NestPath = 298, + T_MergePath = 299, + T_HashPath = 300, + T_ProjectionPath = 301, + T_ProjectSetPath = 302, + T_SortPath = 303, + T_IncrementalSortPath = 304, + T_GroupPath = 305, + T_UpperUniquePath = 306, + T_AggPath = 307, + T_GroupingSetData = 308, + T_RollupData = 309, + T_GroupingSetsPath = 310, + T_MinMaxAggPath = 311, + T_WindowAggPath = 312, + T_SetOpPath = 313, + T_RecursiveUnionPath = 314, + T_LockRowsPath = 315, + T_ModifyTablePath = 316, + T_LimitPath = 317, + T_RestrictInfo = 318, + T_PlaceHolderVar = 319, + T_SpecialJoinInfo = 320, + T_OuterJoinClauseInfo = 321, + T_AppendRelInfo = 322, + T_RowIdentityVarInfo = 323, + T_PlaceHolderInfo = 324, + T_MinMaxAggInfo = 325, + T_PlannerParamItem = 326, + T_AggInfo = 327, + T_AggTransInfo = 328, + T_UniqueRelInfo = 329, + T_PlannedStmt = 330, + T_Result = 331, + T_ProjectSet = 332, + T_ModifyTable = 333, + T_Append = 334, + T_MergeAppend = 335, + T_RecursiveUnion = 336, + T_BitmapAnd = 337, + T_BitmapOr = 338, + T_SeqScan = 339, + T_SampleScan = 340, + T_IndexScan = 341, + T_IndexOnlyScan = 342, + T_BitmapIndexScan = 343, + T_BitmapHeapScan = 344, + T_TidScan = 345, + T_TidRangeScan = 346, + T_SubqueryScan = 347, + T_FunctionScan = 348, + T_ValuesScan = 349, + T_TableFuncScan = 350, + T_CteScan = 351, + T_NamedTuplestoreScan = 352, + T_WorkTableScan = 353, + T_ForeignScan = 354, + T_CustomScan = 355, + T_NestLoop = 356, + T_NestLoopParam = 357, + T_MergeJoin = 358, + T_HashJoin = 359, + T_Material = 360, + T_Memoize = 361, + T_Sort = 362, + T_IncrementalSort = 363, + T_Group = 364, + T_Agg = 365, + T_WindowAgg = 366, + T_Unique = 367, + T_Gather = 368, + T_GatherMerge = 369, + T_Hash = 370, + T_SetOp = 371, + T_LockRows = 372, + T_Limit = 373, + T_PlanRowMark = 374, + T_PartitionPruneInfo = 375, + T_PartitionedRelPruneInfo = 376, + T_PartitionPruneStepOp = 377, + T_PartitionPruneStepCombine = 378, + T_PlanInvalItem = 379, + T_ExprState = 380, + T_IndexInfo = 381, + T_ExprContext = 382, + T_ReturnSetInfo = 383, + T_ProjectionInfo = 384, + T_JunkFilter = 385, + T_OnConflictSetState = 386, + T_MergeActionState = 387, + T_ResultRelInfo = 388, + T_EState = 389, + T_WindowFuncExprState = 390, + T_SetExprState = 391, + T_SubPlanState = 392, + T_DomainConstraintState = 393, + T_ResultState = 394, + T_ProjectSetState = 395, + T_ModifyTableState = 396, + T_AppendState = 397, + T_MergeAppendState = 398, + T_RecursiveUnionState = 399, + T_BitmapAndState = 400, + T_BitmapOrState = 401, + T_ScanState = 402, + T_SeqScanState = 403, + T_SampleScanState = 404, + T_IndexScanState = 405, + T_IndexOnlyScanState = 406, + T_BitmapIndexScanState = 407, + T_BitmapHeapScanState = 408, + T_TidScanState = 409, + T_TidRangeScanState = 410, + T_SubqueryScanState = 411, + T_FunctionScanState = 412, + T_ValuesScanState = 413, + T_TableFuncScanState = 414, + T_CteScanState = 415, + T_NamedTuplestoreScanState = 416, + T_WorkTableScanState = 417, + T_ForeignScanState = 418, + T_CustomScanState = 419, + T_JoinState = 420, + T_NestLoopState = 421, + T_MergeJoinState = 422, + T_HashJoinState = 423, + T_MaterialState = 424, + T_MemoizeState = 425, + T_SortState = 426, + T_IncrementalSortState = 427, + T_GroupState = 428, + T_AggState = 429, + T_WindowAggState = 430, + T_UniqueState = 431, + T_GatherState = 432, + T_GatherMergeState = 433, + T_HashState = 434, + T_SetOpState = 435, + T_LockRowsState = 436, + T_LimitState = 437, + T_IndexAmRoutine = 438, + T_TableAmRoutine = 439, + T_TsmRoutine = 440, + T_EventTriggerData = 441, + T_TriggerData = 442, + T_TupleTableSlot = 443, + T_FdwRoutine = 444, + T_Bitmapset = 445, + T_ExtensibleNode = 446, + T_ErrorSaveContext = 447, + T_IdentifySystemCmd = 448, + T_BaseBackupCmd = 449, + T_CreateReplicationSlotCmd = 450, + T_DropReplicationSlotCmd = 451, + T_AlterReplicationSlotCmd = 452, + T_StartReplicationCmd = 453, + T_ReadReplicationSlotCmd = 454, + T_TimeLineHistoryCmd = 455, + T_UploadManifestCmd = 456, + T_SupportRequestSimplify = 457, + T_SupportRequestSelectivity = 458, + T_SupportRequestCost = 459, + T_SupportRequestRows = 460, + T_SupportRequestIndexCondition = 461, + T_SupportRequestWFuncMonotonic = 462, + T_SupportRequestOptimizeWindowClause = 463, + T_SupportRequestModifyInPlace = 464, + T_Integer = 465, + T_Float = 466, + T_Boolean = 467, + T_String = 468, + T_BitString = 469, + T_ForeignKeyCacheInfo = 470, + T_IntList = 471, + T_OidList = 472, + T_XidList = 473, + T_AllocSetContext = 474, + T_GenerationContext = 475, + T_SlabContext = 476, + T_BumpContext = 477, + T_TIDBitmap = 478, + T_WindowObjectData = 479, diff --git a/src/include/parser/parsenodes.h b/src/include/parser/parsenodes.h index 438b76a6b..7608230b9 100644 --- a/src/include/parser/parsenodes.h +++ b/src/include/parser/parsenodes.h @@ -12,8 +12,8 @@ * identifying statement boundaries in multi-statement source strings. * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/parsenodes.h @@ -28,13 +28,6 @@ #include "primnodes.h" #include "value.h" -typedef enum OverridingKind -{ - OVERRIDING_NOT_SET = 0, - OVERRIDING_USER_VALUE, - OVERRIDING_SYSTEM_VALUE -} OverridingKind; - /* Possible sources of a Query */ typedef enum QuerySource { @@ -42,7 +35,7 @@ typedef enum QuerySource 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 */ + QSRC_NON_INSTEAD_RULE, /* added by non-INSTEAD rule */ } QuerySource; /* Sort ordering options for ORDER BY and CREATE INDEX */ @@ -51,24 +44,32 @@ typedef enum SortByDir SORTBY_DEFAULT, SORTBY_ASC, SORTBY_DESC, - SORTBY_USING /* not allowed in CREATE INDEX ... */ + SORTBY_USING, /* not allowed in CREATE INDEX ... */ } SortByDir; typedef enum SortByNulls { SORTBY_NULLS_DEFAULT, SORTBY_NULLS_FIRST, - SORTBY_NULLS_LAST + SORTBY_NULLS_LAST, } SortByNulls; +/* Options for [ ALL | DISTINCT ] */ +typedef enum SetQuantifier +{ + SET_QUANTIFIER_DEFAULT, + SET_QUANTIFIER_ALL, + SET_QUANTIFIER_DISTINCT, +} SetQuantifier; + /* * Grantable rights are encoded so that we can OR them together in a bitmask. - * The present representation of AclItem limits us to 16 distinct rights, - * even though AclMode is defined as uint32. See utils/acl.h. + * The present representation of AclItem limits us to 32 distinct rights, + * even though AclMode is defined as uint64. See utils/acl.h. * * Caution: changing these codes breaks stored ACLs, hence forces initdb. */ -typedef uint32 AclMode; /* a bitmask of privilege bits */ +typedef uint64 AclMode; /* a bitmask of privilege bits */ #define ACL_INSERT (1<<0) /* for relations */ #define ACL_SELECT (1<<1) @@ -78,16 +79,25 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */ #define ACL_REFERENCES (1<<5) #define ACL_TRIGGER (1<<6) #define ACL_EXECUTE (1<<7) /* for functions */ -#define ACL_USAGE (1<<8) /* for languages, namespaces, FDWs, and - * servers */ +#define ACL_USAGE (1<<8) /* for various object types */ #define ACL_CREATE (1<<9) /* for namespaces and databases */ #define ACL_CREATE_TEMP (1<<10) /* for databases */ #define ACL_CONNECT (1<<11) /* for databases */ -#define N_ACL_RIGHTS 12 /* 1 plus the last 1< 0 + */ + List *rteperminfos pg_node_attr(query_jumble_ignore); + FromExpr *jointree; /* table join tree (FROM and WHERE clauses); + * also USING clause for MERGE */ + + List *mergeActionList; /* list of actions for MERGE (only) */ + + /* + * rtable index of target relation for MERGE to pull data. Initially, this + * is the same as resultRelation, but after query rewriting, if the target + * relation is a trigger-updatable view, this is the index of the expanded + * view subquery, whereas resultRelation is the index of the target view. + */ + int mergeTargetRelation pg_node_attr(query_jumble_ignore); + + /* join condition between source and target for MERGE */ + Node *mergeJoinCondition; List *targetList; /* target list (of TargetEntry) */ - OverridingKind override; /* OVERRIDING clause */ + /* OVERRIDING clause */ + OverridingKind override pg_node_attr(query_jumble_ignore); OnConflictExpr *onConflict; /* ON CONFLICT DO [NOTHING | UPDATE] */ + /* + * The following three fields describe the contents of the RETURNING list + * for INSERT/UPDATE/DELETE/MERGE. returningOldAlias and returningNewAlias + * are the alias names for OLD and NEW, which may be user-supplied values, + * the defaults "old" and "new", or NULL (if the default "old"/"new" is + * already in use as the alias for some other relation). + */ + char *returningOldAlias pg_node_attr(query_jumble_ignore); + char *returningNewAlias pg_node_attr(query_jumble_ignore); List *returningList; /* return-values list (of TargetEntry) */ List *groupClause; /* a list of SortGroupClause's */ + bool groupDistinct; /* is the group by clause distinct? */ List *groupingSets; /* a list of GroupingSet's if present */ @@ -158,18 +233,21 @@ typedef struct Query Node *limitOffset; /* # of result tuples to skip (int8 expr) */ Node *limitCount; /* # of result tuples to return (int8 expr) */ + LimitOption limitOption; /* limit type */ List *rowMarks; /* a list of RowMarkClause's */ Node *setOperations; /* set-operation tree if this is top level of * a UNION/INTERSECT/EXCEPT query */ - List *constraintDeps; /* a list of pg_constraint OIDs that the query - * depends on to be semantically valid */ + /* + * A list of pg_constraint OIDs that the query depends on to be + * semantically valid + */ + List *constraintDeps pg_node_attr(query_jumble_ignore); - List *withCheckOptions; /* a list of WithCheckOption's, which are - * only added during rewrite and therefore - * are not written out as part of Query. */ + /* a list of WithCheckOption's (added during rewrite) */ + List *withCheckOptions pg_node_attr(query_jumble_ignore); /* * The following two fields identify the portion of the source text string @@ -177,8 +255,10 @@ typedef struct Query * Queries, not in sub-queries. When not set, they might both be zero, or * both be -1 meaning "unknown". */ - int stmt_location; /* start location, or -1 if unknown */ - int stmt_len; /* length in bytes; 0 means "rest of string" */ + /* start location, or -1 if unknown */ + ParseLoc stmt_location; + /* length in bytes; 0 means "rest of string" */ + ParseLoc stmt_len pg_node_attr(query_jumble_ignore); } Query; @@ -206,25 +286,25 @@ typedef struct Query typedef struct TypeName { NodeTag type; - List *names; /* qualified name (list of Value strings) */ + List *names; /* qualified name (list of String nodes) */ Oid typeOid; /* type identified by OID */ bool setof; /* is a set? */ bool pct_type; /* %TYPE specified? */ List *typmods; /* type modifier expression(s) */ int32 typemod; /* prespecified type modifier */ List *arrayBounds; /* array bounds */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } TypeName; /* * ColumnRef - specifies a reference to a column, or possibly a whole tuple * - * The "fields" list must be nonempty. It can contain string Value nodes + * The "fields" list must be nonempty. It can contain String nodes * (representing names) and A_Star nodes (representing occurrence of a '*'). * 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. @@ -232,8 +312,8 @@ typedef struct TypeName typedef struct ColumnRef { NodeTag type; - List *fields; /* field names (Value strings) or A_Star */ - int location; /* token location, or -1 if unknown */ + List *fields; /* field names (String nodes) or A_Star */ + ParseLoc location; /* token location, or -1 if unknown */ } ColumnRef; /* @@ -243,7 +323,7 @@ typedef struct ParamRef { NodeTag type; int number; /* the number of the parameter */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } ParamRef; /* @@ -257,7 +337,6 @@ typedef enum A_Expr_Kind AEXPR_DISTINCT, /* IS DISTINCT FROM - name must be "=" */ AEXPR_NOT_DISTINCT, /* IS NOT DISTINCT FROM - name must be "=" */ AEXPR_NULLIF, /* NULLIF - name must be "=" */ - AEXPR_OF, /* IS [NOT] OF - name must be "=" or "<>" */ AEXPR_IN, /* [NOT] IN - name must be "=" or "<>" */ AEXPR_LIKE, /* [NOT] LIKE - name must be "~~" or "!~~" */ AEXPR_ILIKE, /* [NOT] ILIKE - name must be "~~*" or "!~~*" */ @@ -266,27 +345,52 @@ typedef enum A_Expr_Kind AEXPR_NOT_BETWEEN, /* name must be "NOT BETWEEN" */ AEXPR_BETWEEN_SYM, /* name must be "BETWEEN SYMMETRIC" */ AEXPR_NOT_BETWEEN_SYM, /* name must be "NOT BETWEEN SYMMETRIC" */ - AEXPR_PAREN /* nameless dummy node for parentheses */ } A_Expr_Kind; typedef struct A_Expr { + pg_node_attr(custom_read_write) + NodeTag type; A_Expr_Kind kind; /* see above */ List *name; /* possibly-qualified name of operator */ Node *lexpr; /* left argument, or NULL if none */ Node *rexpr; /* right argument, or NULL if none */ - int location; /* token location, or -1 if unknown */ + + /* + * If rexpr is a list of some kind, we separately track its starting and + * ending location; it's not the same as the starting and ending location + * of the token itself. + */ + ParseLoc rexpr_list_start; + ParseLoc rexpr_list_end; + ParseLoc location; /* token location, or -1 if unknown */ } A_Expr; /* * A_Const - a literal constant + * + * Value nodes are inline for performance. You can treat 'val' as a node, + * as in IsA(&val, Integer). 'val' is not valid if isnull is true. */ +union ValUnion +{ + Node node; + Integer ival; + Float fval; + Boolean boolval; + String sval; + BitString bsval; +}; + typedef struct A_Const { + pg_node_attr(custom_copy_equal, custom_read_write, custom_query_jumble) + NodeTag type; - Value val; /* value (includes type info, see value.h) */ - int location; /* token location, or -1 if unknown */ + union ValUnion val; + bool isnull; /* SQL NULL constant */ + ParseLoc location; /* token location, or -1 if unknown */ } A_Const; /* @@ -297,7 +401,7 @@ typedef struct TypeCast NodeTag type; Node *arg; /* the expression being casted */ TypeName *typeName; /* the target type */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } TypeCast; /* @@ -308,7 +412,7 @@ typedef struct CollateClause NodeTag type; Node *arg; /* input expression */ List *collname; /* possibly-qualified collation name */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } CollateClause; /* @@ -317,9 +421,10 @@ typedef struct CollateClause typedef enum RoleSpecType { ROLESPEC_CSTRING, /* role name is stored as a C string */ + ROLESPEC_CURRENT_ROLE, /* role spec is CURRENT_ROLE */ ROLESPEC_CURRENT_USER, /* role spec is CURRENT_USER */ ROLESPEC_SESSION_USER, /* role spec is SESSION_USER */ - ROLESPEC_PUBLIC /* role name is "public" */ + ROLESPEC_PUBLIC, /* role name is "public" */ } RoleSpecType; typedef struct RoleSpec @@ -327,7 +432,7 @@ typedef struct RoleSpec NodeTag type; RoleSpecType roletype; /* Type of this rolespec */ char *rolename; /* filled only for ROLESPEC_CSTRING */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } RoleSpec; /* @@ -351,12 +456,13 @@ typedef struct FuncCall List *args; /* the arguments (list of exprs) */ List *agg_order; /* ORDER BY (list of SortBy) */ Node *agg_filter; /* FILTER clause, if any */ + struct WindowDef *over; /* OVER clause, if any */ bool agg_within_group; /* ORDER BY appeared in WITHIN GROUP */ bool agg_star; /* argument was really '*' */ bool agg_distinct; /* arguments were labeled DISTINCT */ bool func_variadic; /* last argument was labeled VARIADIC */ - struct WindowDef *over; /* OVER clause, if any */ - int location; /* token location, or -1 if unknown */ + CoercionForm funcformat; /* how to display this node */ + ParseLoc location; /* token location, or -1 if unknown */ } FuncCall; /* @@ -388,7 +494,7 @@ typedef struct A_Indices * A_Indirection - select a field and/or array element from an expression * * The indirection list can contain A_Indices nodes (representing - * subscripting), string Value nodes (representing field selection --- the + * subscripting), String nodes (representing field selection --- the * string value is the name of the field to select), and A_Star nodes * (representing selection of all fields of a composite type). * For example, a complex selection operation like @@ -413,7 +519,9 @@ typedef struct A_ArrayExpr { NodeTag type; List *elements; /* array element expressions */ - int location; /* token location, or -1 if unknown */ + ParseLoc list_start; /* start of the element list */ + ParseLoc list_end; /* end of the elements list */ + ParseLoc location; /* token location, or -1 if unknown */ } A_ArrayExpr; /* @@ -440,7 +548,7 @@ typedef struct ResTarget char *name; /* column name or NULL */ List *indirection; /* subscripts, field names, and '*', or NIL */ Node *val; /* the value expression to compute or assign */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } ResTarget; /* @@ -470,7 +578,7 @@ typedef struct SortBy SortByDir sortby_dir; /* ASC/DESC/USING/default */ SortByNulls sortby_nulls; /* NULLS FIRST/LAST */ List *useOp; /* name of op to use, if SORTBY_USING */ - int location; /* operator location, or -1 if none/unknown */ + ParseLoc location; /* operator location, or -1 if none/unknown */ } SortBy; /* @@ -491,7 +599,7 @@ typedef struct WindowDef int frameOptions; /* frame_clause options, see below */ Node *startOffset; /* expression for starting bound, if any */ Node *endOffset; /* expression for ending bound, if any */ - int location; /* parse location, or -1 if none/unknown */ + ParseLoc location; /* parse location, or -1 if none/unknown */ } WindowDef; /* @@ -571,6 +679,9 @@ typedef struct RangeFunction /* * RangeTableFunc - raw form of "table functions" such as XMLTABLE + * + * Note: JSON_TABLE is also a "table function", but it uses JsonTable node, + * not RangeTableFunc. */ typedef struct RangeTableFunc { @@ -581,7 +692,7 @@ typedef struct RangeTableFunc List *namespaces; /* list of namespaces as ResTarget */ List *columns; /* list of RangeTableFuncCol */ Alias *alias; /* table alias & optional column aliases */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } RangeTableFunc; /* @@ -599,7 +710,7 @@ typedef struct RangeTableFuncCol bool is_not_null; /* does it have NOT NULL? */ Node *colexpr; /* column filter expression */ Node *coldefexpr; /* column default value expression */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } RangeTableFuncCol; /* @@ -619,7 +730,7 @@ typedef struct RangeTableSample List *method; /* sampling method name (possibly qualified) */ List *args; /* argument(s) for sampling method */ Node *repeatable; /* REPEATABLE expression, or NULL if none */ - int location; /* method name location, or -1 if unknown */ + ParseLoc location; /* method name location, or -1 if unknown */ } RangeTableSample; /* @@ -645,22 +756,24 @@ typedef struct ColumnDef NodeTag type; char *colname; /* name of column */ TypeName *typeName; /* type of column */ - int inhcount; /* number of times column is inherited */ + char *compression; /* compression method for column */ + int16 inhcount; /* number of times column is inherited */ 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 */ + char *storage_name; /* attstorage setting name or NULL 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 */ + 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 */ List *fdwoptions; /* per-column FDW options */ - int location; /* parse location, or -1 if none/unknown */ + ParseLoc location; /* parse location, or -1 if none/unknown */ } ColumnDef; /* @@ -671,17 +784,20 @@ typedef struct TableLikeClause NodeTag type; RangeVar *relation; bits32 options; /* OR of TableLikeOption flags */ + Oid relationOid; /* If table has been looked up, its OID */ } TableLikeClause; 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_COMPRESSION = 1 << 1, + CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 2, + CREATE_TABLE_LIKE_DEFAULTS = 1 << 3, + CREATE_TABLE_LIKE_GENERATED = 1 << 4, + CREATE_TABLE_LIKE_IDENTITY = 1 << 5, + CREATE_TABLE_LIKE_INDEXES = 1 << 6, + CREATE_TABLE_LIKE_STATISTICS = 1 << 7, + CREATE_TABLE_LIKE_STORAGE = 1 << 8, CREATE_TABLE_LIKE_ALL = PG_INT32_MAX } TableLikeOption; @@ -700,6 +816,7 @@ typedef struct IndexElem char *indexcolname; /* name for index column; NULL = default */ List *collation; /* name of collation; NIL = default */ List *opclass; /* name of desired opclass; NIL = default */ + List *opclassopts; /* opclass-specific options, or NIL */ SortByDir ordering; /* ASC/DESC/default */ SortByNulls nulls_ordering; /* FIRST/LAST/default */ } IndexElem; @@ -719,7 +836,7 @@ typedef enum DefElemAction DEFELEM_UNSPEC, /* no action given */ DEFELEM_SET, DEFELEM_ADD, - DEFELEM_DROP + DEFELEM_DROP, } DefElemAction; typedef struct DefElem @@ -727,9 +844,10 @@ typedef struct DefElem NodeTag type; char *defnamespace; /* NULL if unqualified name */ char *defname; - Node *arg; /* a (Value *) or a (TypeName *) */ + Node *arg; /* typically Integer, Float, String, or + * TypeName */ DefElemAction defaction; /* unspecified action, or SET/ADD/DROP */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } DefElem; /* @@ -758,7 +876,8 @@ typedef struct XmlSerialize XmlOptionType xmloption; /* DOCUMENT or CONTENT */ Node *expr; TypeName *typeName; - int location; /* token location, or -1 if unknown */ + bool indent; /* [NO] INDENT */ + ParseLoc location; /* token location, or -1 if unknown */ } XmlSerialize; /* Partitioning related definitions */ @@ -776,9 +895,16 @@ typedef struct PartitionElem Node *expr; /* expression to partition on, or NULL */ List *collation; /* name of collation; NIL = default */ List *opclass; /* name of desired opclass; NIL = default */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } PartitionElem; +typedef enum PartitionStrategy +{ + PARTITION_STRATEGY_LIST = 'l', + PARTITION_STRATEGY_RANGE = 'r', + PARTITION_STRATEGY_HASH = 'h', +} PartitionStrategy; + /* * PartitionSpec - parse-time representation of a partition key specification * @@ -787,17 +913,11 @@ typedef struct PartitionElem typedef struct PartitionSpec { NodeTag type; - char *strategy; /* partitioning strategy ('hash', 'list' or - * 'range') */ + PartitionStrategy strategy; List *partParams; /* List of PartitionElems */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } PartitionSpec; -/* Internal codes for partitioning strategies */ -#define PARTITION_STRATEGY_HASH 'h' -#define PARTITION_STRATEGY_LIST 'l' -#define PARTITION_STRATEGY_RANGE 'r' - /* * PartitionBoundSpec - a partition bound specification * @@ -822,7 +942,7 @@ typedef struct PartitionBoundSpec List *lowerdatums; /* List of PartitionRangeDatums */ List *upperdatums; /* List of PartitionRangeDatums */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } PartitionBoundSpec; /* @@ -834,7 +954,7 @@ typedef enum PartitionRangeDatumKind { PARTITION_RANGE_DATUM_MINVALUE = -1, /* less than any other value */ PARTITION_RANGE_DATUM_VALUE = 0, /* a specific (bounded) value */ - PARTITION_RANGE_DATUM_MAXVALUE = 1 /* greater than any other value */ + PARTITION_RANGE_DATUM_MAXVALUE = 1, /* greater than any other value */ } PartitionRangeDatumKind; typedef struct PartitionRangeDatum @@ -845,7 +965,7 @@ typedef struct PartitionRangeDatum Node *value; /* Const (or A_Const in raw tree), if kind is * PARTITION_RANGE_DATUM_VALUE, else NULL */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } PartitionRangeDatum; /* @@ -856,6 +976,7 @@ typedef struct PartitionCmd NodeTag type; RangeVar *name; /* name of partition to attach/detach */ PartitionBoundSpec *bound; /* FOR VALUES, if attaching */ + bool concurrent; } PartitionCmd; /**************************************************************************** @@ -904,35 +1025,13 @@ typedef struct PartitionCmd * them from the joinaliasvars list, because that would affect the attnums * of Vars referencing the rest of the list.) * - * inh is true for relation references that should be expanded to include - * inheritance children, if the rel has any. This *must* be false for - * RTEs other than RTE_RELATION entries. - * * inFromCl marks those range variables that are listed in the FROM clause. * It's false for RTEs that are added to a query behind the scenes, such * as the NEW and OLD variables for a rule, or the subqueries of a UNION. - * This flag is not used anymore during parsing, since the parser now uses - * a separate "namespace" data structure to control visibility, but it is - * needed by ruleutils.c to determine whether RTEs should be shown in - * decompiled queries. - * - * requiredPerms and checkAsUser specify run-time access permissions - * checks to be performed at query startup. The user must have *all* - * of the permissions that are OR'd together in requiredPerms (zero - * indicates no permissions checking). If checkAsUser is not zero, - * then do the permissions checks using the access rights of that user, - * not the current effective user ID. (This allows rules to act as - * setuid gateways.) Permissions checks only apply to RELATION RTEs. - * - * For SELECT/INSERT/UPDATE permissions, if the user doesn't have - * table-wide permissions then it is sufficient to have the permissions - * on all columns identified in selectedCols (for SELECT) and/or - * insertedCols and/or updatedCols (INSERT with ON CONFLICT DO UPDATE may - * have all 3). selectedCols, insertedCols and updatedCols are bitmapsets, - * which cannot have negative integer members, so we subtract - * FirstLowInvalidHeapAttributeNumber from column numbers before storing - * them in these fields. A whole-row Var reference is represented by - * setting the bit for InvalidAttrNumber. + * This flag is not used during parsing (except in transformLockingClause, + * q.v.); the parser now uses a separate "namespace" data structure to + * control visibility. But it is needed by ruleutils.c to determine + * whether RTEs should be shown in decompiled queries. * * securityQuals is a list of security barrier quals (boolean expressions), * to be tested in the listed order before returning a row from the @@ -951,38 +1050,94 @@ 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 */ + RTE_GROUP, /* the grouping step */ } RTEKind; typedef struct RangeTblEntry { + pg_node_attr(custom_read_write) + NodeTag type; - RTEKind rtekind; /* see above */ + /* + * Fields valid in all RTEs: + * + * put alias + eref first to make dump more legible + */ + /* user-written alias clause, if any */ + Alias *alias pg_node_attr(query_jumble_ignore); /* - * XXX the fields applicable to only some rte kinds should be merged into - * a union. I didn't do this yet because the diffs would impact a lot of - * code that is being actively worked on. FIXME someday. + * Expanded reference names. This uses a custom query jumble function so + * that the table name is included in the computation, but not its list of + * columns. */ + Alias *eref pg_node_attr(custom_query_jumble); + + RTEKind rtekind; /* see above */ /* * Fields valid for a plain relation RTE (else zero): * + * inh is true for relation references that should be expanded to include + * inheritance children, if the rel has any. In the parser, this will + * only be true for RTE_RELATION entries. The planner also uses this + * field to mark RTE_SUBQUERY entries that contain UNION ALL queries that + * it has flattened into pulled-up subqueries (creating a structure much + * like the effects of inheritance). + * + * 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/MERGE 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. + * + * perminfoindex is 1-based index of the RTEPermissionInfo belonging to + * this RTE in the containing struct's list of same; 0 if permissions need + * not be checked for this RTE. + * + * As a special case, relid, relkind, rellockmode, and perminfoindex can + * also be set (nonzero) in an RTE_SUBQUERY RTE. This occurs when we + * convert an RTE_RELATION RTE naming a view into an RTE_SUBQUERY + * containing the view's query. We still need to perform run-time locking + * and permission checks on the view, even though it's not directly used + * in the query anymore, and the most expedient way to do that is to + * retain these fields from the old state of the RTE. + * * As a special case, RTE_NAMEDTUPLESTORE can also set relid to indicate * 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. */ - Oid relid; /* OID of the relation */ - char relkind; /* relation kind (see pg_class.relkind) */ - struct TableSampleClause *tablesample; /* sampling info, or NULL */ + /* OID of the relation */ + Oid relid pg_node_attr(query_jumble_ignore); + /* inheritance requested? */ + bool inh; + /* relation kind (see pg_class.relkind) */ + char relkind pg_node_attr(query_jumble_ignore); + /* lock level that query requires on the rel */ + int rellockmode pg_node_attr(query_jumble_ignore); + /* index of RTEPermissionInfo entry, or 0 */ + Index perminfoindex pg_node_attr(query_jumble_ignore); + /* sampling info, or NULL */ + struct TableSampleClause *tablesample; /* * Fields valid for a subquery RTE (else NULL): */ - Query *subquery; /* the sub-query */ - bool security_barrier; /* is from security_barrier view? */ + /* the sub-query */ + Query *subquery; + /* is from security_barrier view? */ + bool security_barrier pg_node_attr(query_jumble_ignore); /* * Fields valid for a join RTE (else NULL/zero): @@ -995,14 +1150,54 @@ typedef struct RangeTblEntry * be a Var of one of the join's input relations, or such a Var with an * implicit coercion to the join's output column type, or a COALESCE * expression containing the two input column Vars (possibly coerced). - * Within a Query loaded from a stored rule, it is also possible for + * Elements beyond the first joinmergedcols entries are always just Vars, + * and are never referenced from elsewhere in the query (that is, join + * alias Vars are generated only for merged columns). We keep these + * entries only because they're needed in expandRTE() and similar code. + * + * Vars appearing within joinaliasvars are marked with varnullingrels sets + * that describe the nulling effects of this join and lower ones. This is + * essential for FULL JOIN cases, because the COALESCE expression only + * describes the semantics correctly if its inputs have been nulled by the + * join. For other cases, it allows expandRTE() to generate a valid + * representation of the join's output without consulting additional + * parser state. + * + * Within a Query loaded from a stored rule, it is possible for non-merged * joinaliasvars items to be null pointers, which are placeholders for * (necessarily unreferenced) columns dropped since the rule was made. * Also, once planning begins, joinaliasvars items can be almost anything, * as a result of subquery-flattening substitutions. + * + * joinleftcols is an integer list of physical column numbers of the left + * join input rel that are included in the join; likewise joinrightcols + * for the right join input rel. (Which rels those are can be determined + * from the associated JoinExpr.) If the join is USING/NATURAL, then the + * first joinmergedcols entries in each list identify the merged columns. + * The merged columns come first in the join output, then remaining + * columns of the left input, then remaining columns of the right. + * + * Note that input columns could have been dropped after creation of a + * stored rule, if they are not referenced in the query (in particular, + * merged columns could not be dropped); this is not accounted for in + * joinleftcols/joinrightcols. + */ + JoinType jointype; + /* number of merged (JOIN USING) columns */ + int joinmergedcols pg_node_attr(query_jumble_ignore); + /* list of alias-var expansions */ + List *joinaliasvars pg_node_attr(query_jumble_ignore); + /* left-side input column numbers */ + List *joinleftcols pg_node_attr(query_jumble_ignore); + /* right-side input column numbers */ + List *joinrightcols pg_node_attr(query_jumble_ignore); + + /* + * join_using_alias is an alias clause attached directly to JOIN/USING. It + * is different from the alias field (below) in that it does not hide the + * range variables of the tables being joined. */ - JoinType jointype; /* type of join */ - List *joinaliasvars; /* list of alias-var expansions */ + Alias *join_using_alias pg_node_attr(query_jumble_ignore); /* * Fields valid for a function RTE (else NIL/zero): @@ -1012,8 +1207,10 @@ typedef struct RangeTblEntry * implicit, and must be accounted for "by hand" in places such as * expandRTE(). */ - List *functions; /* list of RangeTblFunction nodes */ - bool funcordinality; /* is this called WITH ORDINALITY? */ + /* list of RangeTblFunction nodes */ + List *functions; + /* is this called WITH ORDINALITY? */ + bool funcordinality; /* * Fields valid for a TableFunc RTE (else NULL): @@ -1023,17 +1220,21 @@ typedef struct RangeTblEntry /* * Fields valid for a values RTE (else NIL): */ - List *values_lists; /* list of expression lists */ + /* list of expression lists */ + List *values_lists; /* * Fields valid for a CTE RTE (else NULL/zero): */ - char *ctename; /* name of the WITH list item */ - Index ctelevelsup; /* number of query levels up */ - bool self_reference; /* is this a recursive self-reference? */ + /* name of the WITH list item */ + char *ctename; + /* number of query levels up */ + Index ctelevelsup; + /* is this a recursive self-reference? */ + bool self_reference pg_node_attr(query_jumble_ignore); /* - * 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 @@ -1041,38 +1242,92 @@ 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 * all three lists (as well as an empty-string entry in eref). Testing * for zero coltype is the standard way to detect a dropped column. */ - List *coltypes; /* OID list of column type OIDs */ - List *coltypmods; /* integer list of column typmods */ - List *colcollations; /* OID list of column collation OIDs */ + /* OID list of column type OIDs */ + List *coltypes pg_node_attr(query_jumble_ignore); + /* integer list of column typmods */ + List *coltypmods pg_node_attr(query_jumble_ignore); + /* OID list of column collation OIDs */ + List *colcollations pg_node_attr(query_jumble_ignore); /* * Fields valid for ENR RTEs (else NULL/zero): */ - char *enrname; /* name of ephemeral named relation */ - double enrtuples; /* estimated or actual from caller */ + /* name of ephemeral named relation */ + char *enrname; + /* estimated or actual from caller */ + Cardinality enrtuples pg_node_attr(query_jumble_ignore); + + /* + * Fields valid for a GROUP RTE (else NIL): + */ + /* list of grouping expressions */ + List *groupexprs pg_node_attr(query_jumble_ignore); /* * Fields valid in all RTEs: */ - Alias *alias; /* user-written alias clause, if any */ - Alias *eref; /* expanded reference names */ - bool lateral; /* subquery, function, or values is LATERAL? */ - bool inh; /* inheritance requested? */ - bool inFromCl; /* present in FROM clause? */ + /* was LATERAL specified? */ + bool lateral pg_node_attr(query_jumble_ignore); + /* present in FROM clause? */ + bool inFromCl pg_node_attr(query_jumble_ignore); + /* security barrier quals to apply, if any */ + List *securityQuals pg_node_attr(query_jumble_ignore); +} RangeTblEntry; + +/* + * RTEPermissionInfo + * Per-relation information for permission checking. Added to the Query + * node by the parser when adding the corresponding RTE to the query + * range table and subsequently editorialized on by the rewriter if + * needed after rule expansion. + * + * Only the relations directly mentioned in the query are checked for + * access permissions by the core executor, so only their RTEPermissionInfos + * are present in the Query. However, extensions may want to check inheritance + * children too, depending on the value of rte->inh, so it's copied in 'inh' + * for their perusal. + * + * requiredPerms and checkAsUser specify run-time access permissions checks + * to be performed at query startup. The user must have *all* of the + * permissions that are OR'd together in requiredPerms (never 0!). If + * checkAsUser is not zero, then do the permissions checks using the access + * rights of that user, not the current effective user ID. (This allows rules + * to act as setuid gateways.) + * + * For SELECT/INSERT/UPDATE permissions, if the user doesn't have table-wide + * permissions then it is sufficient to have the permissions on all columns + * identified in selectedCols (for SELECT) and/or insertedCols and/or + * updatedCols (INSERT with ON CONFLICT DO UPDATE may have all 3). + * selectedCols, insertedCols and updatedCols are bitmapsets, which cannot have + * negative integer members, so we subtract FirstLowInvalidHeapAttributeNumber + * from column numbers before storing 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. + */ +typedef struct RTEPermissionInfo +{ + NodeTag type; + + Oid relid; /* relation OID */ + bool inh; /* separately check inheritance children? */ AclMode requiredPerms; /* bitmask of required access permissions */ Oid checkAsUser; /* if valid, check access as this role */ Bitmapset *selectedCols; /* columns needing SELECT permission */ Bitmapset *insertedCols; /* columns needing INSERT permission */ Bitmapset *updatedCols; /* columns needing UPDATE permission */ - List *securityQuals; /* security barrier quals to apply, if any */ -} RangeTblEntry; +} RTEPermissionInfo; /* * RangeTblFunction - @@ -1089,20 +1344,29 @@ typedef struct RangeTblEntry * time. We do however remember how many columns we thought the type had * (including dropped columns!), so that we can successfully ignore any * columns added after the query was parsed. + * + * The query jumbling only needs to track the function expression. */ typedef struct RangeTblFunction { NodeTag type; Node *funcexpr; /* expression tree for func call */ - int funccolcount; /* number of columns it contributes to RTE */ + /* number of columns it contributes to RTE */ + int funccolcount pg_node_attr(query_jumble_ignore); /* These fields record the contents of a column definition list, if any: */ - List *funccolnames; /* column names (list of String) */ - List *funccoltypes; /* OID list of column type OIDs */ - List *funccoltypmods; /* integer list of column typmods */ - List *funccolcollations; /* OID list of column collation OIDs */ + /* column names (list of String) */ + List *funccolnames pg_node_attr(query_jumble_ignore); + /* OID list of column type OIDs */ + List *funccoltypes pg_node_attr(query_jumble_ignore); + /* integer list of column typmods */ + List *funccoltypmods pg_node_attr(query_jumble_ignore); + /* OID list of column collation OIDs */ + List *funccolcollations pg_node_attr(query_jumble_ignore); + /* This is set during planning for use by the executor: */ - Bitmapset *funcparams; /* PARAM_EXEC Param IDs affecting this func */ + /* PARAM_EXEC Param IDs affecting this func */ + Bitmapset *funcparams pg_node_attr(query_jumble_ignore); } RangeTblFunction; /* @@ -1129,7 +1393,9 @@ 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_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 */ } WCOKind; typedef struct WithCheckOption @@ -1206,8 +1472,10 @@ typedef struct SortGroupClause Index tleSortGroupRef; /* reference into targetlist */ Oid eqop; /* the equality operator ('=' op) */ Oid sortop; /* the ordering operator ('<' op), or 0 */ + bool reverse_sort; /* is sortop a "greater than" operator? */ bool nulls_first; /* do NULLs come before normal values? */ - bool hashable; /* can eqop be implemented by hashing? */ + /* can eqop be implemented by hashing? */ + bool hashable pg_node_attr(query_jumble_ignore); } SortGroupClause; /* @@ -1260,21 +1528,21 @@ typedef struct SortGroupClause * * SETS( SIMPLE(1,2), CUBE( SIMPLE(3), SIMPLE(4,5) ) ) */ -typedef enum +typedef enum GroupingSetKind { GROUPING_SET_EMPTY, GROUPING_SET_SIMPLE, GROUPING_SET_ROLLUP, GROUPING_SET_CUBE, - GROUPING_SET_SETS + GROUPING_SET_SETS, } GroupingSetKind; typedef struct GroupingSet { NodeTag type; - GroupingSetKind kind; + GroupingSetKind kind pg_node_attr(query_jumble_ignore); List *content; - int location; + ParseLoc location; } GroupingSet; /* @@ -1285,6 +1553,8 @@ typedef struct GroupingSet * if the clause originally came from WINDOW, and is NULL if it originally * was an OVER clause (but note that we collapse out duplicate OVERs). * partitionClause and orderClause are lists of SortGroupClause structs. + * partitionClause is sanitized by the query planner to remove any columns or + * expressions belonging to redundant PathKeys. * If we have RANGE with offset PRECEDING/FOLLOWING, the semantics of that are * specified by startInRangeFunc/inRangeColl/inRangeAsc/inRangeNullsFirst * for the start offset, or endInRangeFunc/inRange* for the end offset. @@ -1293,24 +1563,36 @@ typedef struct GroupingSet * When refname isn't null, the partitionClause is always copied from there; * the orderClause might or might not be copied (see copiedOrder); the framing * options are never copied, per spec. + * + * The information relevant for the query jumbling is the partition clause + * type and its bounds. */ typedef struct WindowClause { NodeTag type; - char *name; /* window name (NULL in an OVER clause) */ - char *refname; /* referenced window name, if any */ + /* window name (NULL in an OVER clause) */ + char *name pg_node_attr(query_jumble_ignore); + /* referenced window name, if any */ + char *refname pg_node_attr(query_jumble_ignore); List *partitionClause; /* PARTITION BY list */ - List *orderClause; /* ORDER BY list */ + /* ORDER BY list */ + List *orderClause; int frameOptions; /* frame_clause options, see WindowDef */ Node *startOffset; /* expression for starting bound, if any */ Node *endOffset; /* expression for ending bound, if any */ - Oid startInRangeFunc; /* in_range function for startOffset */ - Oid endInRangeFunc; /* in_range function for endOffset */ - Oid inRangeColl; /* collation for in_range tests */ - bool inRangeAsc; /* use ASC sort order for in_range tests? */ - bool inRangeNullsFirst; /* nulls sort first for in_range tests? */ + /* in_range function for startOffset */ + Oid startInRangeFunc pg_node_attr(query_jumble_ignore); + /* in_range function for endOffset */ + Oid endInRangeFunc pg_node_attr(query_jumble_ignore); + /* collation for in_range tests */ + Oid inRangeColl pg_node_attr(query_jumble_ignore); + /* use ASC sort order for in_range tests? */ + bool inRangeAsc pg_node_attr(query_jumble_ignore); + /* nulls sort first for in_range tests? */ + bool inRangeNullsFirst pg_node_attr(query_jumble_ignore); Index winref; /* ID referenced by window functions */ - bool copiedOrder; /* did we copy orderClause from refname? */ + /* did we copy orderClause from refname? */ + bool copiedOrder pg_node_attr(query_jumble_ignore); } WindowClause; /* @@ -1346,7 +1628,7 @@ typedef struct WithClause NodeTag type; List *ctes; /* list of CommonTableExprs */ bool recursive; /* true = WITH RECURSIVE */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } WithClause; /* @@ -1361,7 +1643,7 @@ typedef struct InferClause List *indexElems; /* IndexElems to infer unique index */ Node *whereClause; /* qualification (partial-index predicate) */ char *conname; /* Constraint name, or NULL if unnamed */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } InferClause; /* @@ -1377,31 +1659,80 @@ typedef struct OnConflictClause InferClause *infer; /* Optional index inference clause */ List *targetList; /* the target list (of ResTarget) */ Node *whereClause; /* qualifications */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } OnConflictClause; /* * CommonTableExpr - * representation of WITH list element - * - * 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 CTESearchClause +{ + NodeTag type; + List *search_col_list; + bool search_breadth_first; + char *search_seq_column; + ParseLoc location; +} CTESearchClause; + +typedef struct CTECycleClause +{ + NodeTag type; + List *cycle_col_list; + char *cycle_mark_column; + Node *cycle_mark_value; + Node *cycle_mark_default; + char *cycle_path_column; + ParseLoc location; + /* These fields are set during parse analysis: */ + Oid cycle_mark_type; /* common type of _value and _default */ + int cycle_mark_typmod; + Oid cycle_mark_collation; + Oid cycle_mark_neop; /* <> operator for type */ +} CTECycleClause; + typedef struct CommonTableExpr { NodeTag type; - char *ctename; /* query name (never qualified) */ - List *aliascolnames; /* optional list of column names */ + + /* + * Query name (never qualified). The string name is included in the query + * jumbling because RTE_CTE RTEs need it. + */ + char *ctename; + /* optional list of column names */ + List *aliascolnames pg_node_attr(query_jumble_ignore); + 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 */ + CTESearchClause *search_clause pg_node_attr(query_jumble_ignore); + CTECycleClause *cycle_clause pg_node_attr(query_jumble_ignore); + ParseLoc location; /* token location, or -1 if unknown */ /* These fields are set during parse analysis: */ - bool cterecursive; /* is this CTE actually recursive? */ - int cterefcount; /* number of RTEs referencing this CTE - * (excluding internal self-references) */ - List *ctecolnames; /* list of output column names */ - List *ctecoltypes; /* OID list of output column type OIDs */ - List *ctecoltypmods; /* integer list of output column typmods */ - List *ctecolcollations; /* OID list of column collation OIDs */ + /* is this CTE actually recursive? */ + bool cterecursive pg_node_attr(query_jumble_ignore); + + /* + * Number of RTEs referencing this CTE (excluding internal + * self-references), irrelevant for query jumbling. + */ + int cterefcount pg_node_attr(query_jumble_ignore); + /* list of output column names */ + List *ctecolnames pg_node_attr(query_jumble_ignore); + /* OID list of output column type OIDs */ + List *ctecoltypes pg_node_attr(query_jumble_ignore); + /* integer list of output column typmods */ + List *ctecoltypmods pg_node_attr(query_jumble_ignore); + /* OID list of column collation OIDs */ + List *ctecolcollations pg_node_attr(query_jumble_ignore); } CommonTableExpr; /* Convenience macro to get the output tlist of a CTE's query */ @@ -1411,6 +1742,59 @@ typedef struct CommonTableExpr ((Query *) (cte)->ctequery)->targetList : \ ((Query *) (cte)->ctequery)->returningList) +/* + * MergeWhenClause - + * raw parser representation of a WHEN clause in a MERGE statement + * + * This is transformed into MergeAction by parse analysis + */ +typedef struct MergeWhenClause +{ + NodeTag type; + MergeMatchKind matchKind; /* MATCHED/NOT MATCHED BY SOURCE/TARGET */ + CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ + OverridingKind override; /* OVERRIDING clause */ + Node *condition; /* WHEN conditions (raw parser) */ + List *targetList; /* INSERT/UPDATE targetlist */ + /* the following members are only used in INSERT actions */ + List *values; /* VALUES to INSERT, or NULL */ +} MergeWhenClause; + +/* + * ReturningOptionKind - + * Possible kinds of option in RETURNING WITH(...) list + * + * Currently, this is used only for specifying OLD/NEW aliases. + */ +typedef enum ReturningOptionKind +{ + RETURNING_OPTION_OLD, /* specify alias for OLD in RETURNING */ + RETURNING_OPTION_NEW, /* specify alias for NEW in RETURNING */ +} ReturningOptionKind; + +/* + * ReturningOption - + * An individual option in the RETURNING WITH(...) list + */ +typedef struct ReturningOption +{ + NodeTag type; + ReturningOptionKind option; /* specified option */ + char *value; /* option's value */ + ParseLoc location; /* token location, or -1 if unknown */ +} ReturningOption; + +/* + * ReturningClause - + * List of RETURNING expressions, together with any WITH(...) options + */ +typedef struct ReturningClause +{ + NodeTag type; + List *options; /* list of ReturningOption elements */ + List *exprs; /* list of expressions to return */ +} ReturningClause; + /* * TriggerTransition - * representation of transition row or table naming clause @@ -1427,6 +1811,259 @@ typedef struct TriggerTransition bool isTable; } TriggerTransition; +/* Nodes for SQL/JSON support */ + +/* + * JsonOutput - + * representation of JSON output clause (RETURNING type [FORMAT format]) + */ +typedef struct JsonOutput +{ + NodeTag type; + TypeName *typeName; /* RETURNING type name, if specified */ + JsonReturning *returning; /* RETURNING FORMAT clause and type Oids */ +} JsonOutput; + +/* + * JsonArgument - + * representation of argument from JSON PASSING clause + */ +typedef struct JsonArgument +{ + NodeTag type; + JsonValueExpr *val; /* argument value expression */ + char *name; /* argument name */ +} JsonArgument; + +/* + * JsonQuotes - + * representation of [KEEP|OMIT] QUOTES clause for JSON_QUERY() + */ +typedef enum JsonQuotes +{ + JS_QUOTES_UNSPEC, /* unspecified */ + JS_QUOTES_KEEP, /* KEEP QUOTES */ + JS_QUOTES_OMIT, /* OMIT QUOTES */ +} JsonQuotes; + +/* + * JsonFuncExpr - + * untransformed representation of function expressions for + * SQL/JSON query functions + */ +typedef struct JsonFuncExpr +{ + NodeTag type; + JsonExprOp op; /* expression type */ + char *column_name; /* JSON_TABLE() column name or NULL if this is + * not for a JSON_TABLE() */ + JsonValueExpr *context_item; /* context item expression */ + Node *pathspec; /* JSON path specification expression */ + List *passing; /* list of PASSING clause arguments, if any */ + JsonOutput *output; /* output clause, if specified */ + JsonBehavior *on_empty; /* ON EMPTY behavior */ + JsonBehavior *on_error; /* ON ERROR behavior */ + JsonWrapper wrapper; /* array wrapper behavior (JSON_QUERY only) */ + JsonQuotes quotes; /* omit or keep quotes? (JSON_QUERY only) */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonFuncExpr; + +/* + * JsonTablePathSpec + * untransformed specification of JSON path expression with an optional + * name + */ +typedef struct JsonTablePathSpec +{ + NodeTag type; + + Node *string; + char *name; + ParseLoc name_location; + ParseLoc location; /* location of 'string' */ +} JsonTablePathSpec; + +/* + * JsonTable - + * untransformed representation of JSON_TABLE + */ +typedef struct JsonTable +{ + NodeTag type; + JsonValueExpr *context_item; /* context item expression */ + JsonTablePathSpec *pathspec; /* JSON path specification */ + List *passing; /* list of PASSING clause arguments, if any */ + List *columns; /* list of JsonTableColumn */ + JsonBehavior *on_error; /* ON ERROR behavior */ + Alias *alias; /* table alias in FROM clause */ + bool lateral; /* does it have LATERAL prefix? */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonTable; + +/* + * JsonTableColumnType - + * enumeration of JSON_TABLE column types + */ +typedef enum JsonTableColumnType +{ + JTC_FOR_ORDINALITY, + JTC_REGULAR, + JTC_EXISTS, + JTC_FORMATTED, + JTC_NESTED, +} JsonTableColumnType; + +/* + * JsonTableColumn - + * untransformed representation of JSON_TABLE column + */ +typedef struct JsonTableColumn +{ + NodeTag type; + JsonTableColumnType coltype; /* column type */ + char *name; /* column name */ + TypeName *typeName; /* column type name */ + JsonTablePathSpec *pathspec; /* JSON path specification */ + JsonFormat *format; /* JSON format clause, if specified */ + JsonWrapper wrapper; /* WRAPPER behavior for formatted columns */ + JsonQuotes quotes; /* omit or keep quotes on scalar strings? */ + List *columns; /* nested columns */ + JsonBehavior *on_empty; /* ON EMPTY behavior */ + JsonBehavior *on_error; /* ON ERROR behavior */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonTableColumn; + +/* + * JsonKeyValue - + * untransformed representation of JSON object key-value pair for + * JSON_OBJECT() and JSON_OBJECTAGG() + */ +typedef struct JsonKeyValue +{ + NodeTag type; + Expr *key; /* key expression */ + JsonValueExpr *value; /* JSON value expression */ +} JsonKeyValue; + +/* + * JsonParseExpr - + * untransformed representation of JSON() + */ +typedef struct JsonParseExpr +{ + NodeTag type; + JsonValueExpr *expr; /* string expression */ + JsonOutput *output; /* RETURNING clause, if specified */ + bool unique_keys; /* WITH UNIQUE KEYS? */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonParseExpr; + +/* + * JsonScalarExpr - + * untransformed representation of JSON_SCALAR() + */ +typedef struct JsonScalarExpr +{ + NodeTag type; + Expr *expr; /* scalar expression */ + JsonOutput *output; /* RETURNING clause, if specified */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonScalarExpr; + +/* + * JsonSerializeExpr - + * untransformed representation of JSON_SERIALIZE() function + */ +typedef struct JsonSerializeExpr +{ + NodeTag type; + JsonValueExpr *expr; /* json value expression */ + JsonOutput *output; /* RETURNING clause, if specified */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonSerializeExpr; + +/* + * JsonObjectConstructor - + * untransformed representation of JSON_OBJECT() constructor + */ +typedef struct JsonObjectConstructor +{ + NodeTag type; + List *exprs; /* list of JsonKeyValue pairs */ + JsonOutput *output; /* RETURNING clause, if specified */ + bool absent_on_null; /* skip NULL values? */ + bool unique; /* check key uniqueness? */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonObjectConstructor; + +/* + * JsonArrayConstructor - + * untransformed representation of JSON_ARRAY(element,...) constructor + */ +typedef struct JsonArrayConstructor +{ + NodeTag type; + List *exprs; /* list of JsonValueExpr elements */ + JsonOutput *output; /* RETURNING clause, if specified */ + bool absent_on_null; /* skip NULL elements? */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonArrayConstructor; + +/* + * JsonArrayQueryConstructor - + * untransformed representation of JSON_ARRAY(subquery) constructor + */ +typedef struct JsonArrayQueryConstructor +{ + NodeTag type; + Node *query; /* subquery */ + JsonOutput *output; /* RETURNING clause, if specified */ + JsonFormat *format; /* FORMAT clause for subquery, if specified */ + bool absent_on_null; /* skip NULL elements? */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonArrayQueryConstructor; + +/* + * JsonAggConstructor - + * common fields of untransformed representation of + * JSON_ARRAYAGG() and JSON_OBJECTAGG() + */ +typedef struct JsonAggConstructor +{ + NodeTag type; + JsonOutput *output; /* RETURNING clause, if any */ + Node *agg_filter; /* FILTER clause, if any */ + List *agg_order; /* ORDER BY clause, if any */ + struct WindowDef *over; /* OVER clause, if any */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonAggConstructor; + +/* + * JsonObjectAgg - + * untransformed representation of JSON_OBJECTAGG() + */ +typedef struct JsonObjectAgg +{ + NodeTag type; + JsonAggConstructor *constructor; /* common fields */ + JsonKeyValue *arg; /* object key-value pair */ + bool absent_on_null; /* skip NULL values? */ + bool unique; /* check key uniqueness? */ +} JsonObjectAgg; + +/* + * JsonArrayAgg - + * untransformed representation of JSON_ARRAYAGG() + */ +typedef struct JsonArrayAgg +{ + NodeTag type; + JsonAggConstructor *constructor; /* common fields */ + JsonValueExpr *arg; /* array element expression */ + bool absent_on_null; /* skip NULL elements? */ +} JsonArrayAgg; + + /***************************************************************************** * Raw Grammar Output Statements *****************************************************************************/ @@ -1442,13 +2079,18 @@ typedef struct TriggerTransition * * stmt_location/stmt_len identify the portion of the source text string * containing this raw statement (useful for multi-statement strings). + * + * This is irrelevant for query jumbling, as this is not used in parsed + * queries. */ typedef struct RawStmt { + pg_node_attr(no_query_jumble) + NodeTag type; Node *stmt; /* raw parse tree */ - int stmt_location; /* start location, or -1 if unknown */ - int stmt_len; /* length in bytes; 0 means "rest of string" */ + ParseLoc stmt_location; /* start location, or -1 if unknown */ + ParseLoc stmt_len; /* length in bytes; 0 means "rest of string" */ } RawStmt; /***************************************************************************** @@ -1470,7 +2112,7 @@ typedef struct InsertStmt List *cols; /* optional: names of the target columns */ Node *selectStmt; /* the source SELECT/VALUES, or NULL */ OnConflictClause *onConflictClause; /* ON CONFLICT clause */ - List *returningList; /* list of expressions to return */ + ReturningClause *returningClause; /* RETURNING clause */ WithClause *withClause; /* WITH clause */ OverridingKind override; /* OVERRIDING clause */ } InsertStmt; @@ -1485,7 +2127,7 @@ typedef struct DeleteStmt RangeVar *relation; /* relation to delete from */ List *usingClause; /* optional using clause for more tables */ Node *whereClause; /* qualifications */ - List *returningList; /* list of expressions to return */ + ReturningClause *returningClause; /* RETURNING clause */ WithClause *withClause; /* WITH clause */ } DeleteStmt; @@ -1500,10 +2142,25 @@ typedef struct UpdateStmt List *targetList; /* the target list (of ResTarget) */ Node *whereClause; /* qualifications */ List *fromClause; /* optional from clause for more tables */ - List *returningList; /* list of expressions to return */ + ReturningClause *returningClause; /* RETURNING clause */ WithClause *withClause; /* WITH clause */ } UpdateStmt; +/* ---------------------- + * Merge Statement + * ---------------------- + */ +typedef struct MergeStmt +{ + NodeTag type; + RangeVar *relation; /* target relation to merge into */ + Node *sourceRelation; /* source relation */ + Node *joinCondition; /* join condition between source and target */ + List *mergeWhenClauses; /* list of MergeWhenClause(es) */ + ReturningClause *returningClause; /* RETURNING clause */ + WithClause *withClause; /* WITH clause */ +} MergeStmt; + /* ---------------------- * Select Statement * @@ -1522,7 +2179,7 @@ typedef enum SetOperation SETOP_NONE = 0, SETOP_UNION, SETOP_INTERSECT, - SETOP_EXCEPT + SETOP_EXCEPT, } SetOperation; typedef struct SelectStmt @@ -1539,6 +2196,7 @@ typedef struct SelectStmt List *fromClause; /* the FROM clause */ Node *whereClause; /* WHERE qualification */ List *groupClause; /* GROUP BY clauses */ + bool groupDistinct; /* Is this GROUP BY DISTINCT? */ Node *havingClause; /* HAVING conditional-expression */ List *windowClause; /* WINDOW window_name AS (...), ... */ @@ -1559,6 +2217,7 @@ typedef struct SelectStmt List *sortClause; /* sort clause (a list of SortBy's) */ Node *limitOffset; /* # of result tuples to skip */ Node *limitCount; /* # of result tuples to return */ + LimitOption limitOption; /* limit type */ List *lockingClause; /* FOR UPDATE (list of LockingClause's) */ WithClause *withClause; /* WITH clause */ @@ -1601,15 +2260,48 @@ typedef struct SetOperationStmt Node *rarg; /* right child */ /* Eventually add fields for CORRESPONDING spec here */ - /* Fields derived during parse analysis: */ - List *colTypes; /* OID list of output column type OIDs */ - List *colTypmods; /* integer list of output column typmods */ - List *colCollations; /* OID list of output column collation OIDs */ - List *groupClauses; /* a list of SortGroupClause's */ + /* Fields derived during parse analysis (irrelevant for query jumbling): */ + /* OID list of output column type OIDs */ + List *colTypes pg_node_attr(query_jumble_ignore); + /* integer list of output column typmods */ + List *colTypmods pg_node_attr(query_jumble_ignore); + /* OID list of output column collation OIDs */ + List *colCollations pg_node_attr(query_jumble_ignore); + /* a list of SortGroupClause's */ + List *groupClauses pg_node_attr(query_jumble_ignore); /* groupClauses is NIL if UNION ALL, but must be set otherwise */ } SetOperationStmt; +/* + * RETURN statement (inside SQL function body) + */ +typedef struct ReturnStmt +{ + NodeTag type; + Node *returnval; +} ReturnStmt; + + +/* ---------------------- + * PL/pgSQL Assignment Statement + * + * Like SelectStmt, this is transformed into a SELECT Query. + * However, the targetlist of the result looks more like an UPDATE. + * ---------------------- + */ +typedef struct PLAssignStmt +{ + NodeTag type; + + char *name; /* initial column name */ + List *indirection; /* subscripts and field names, if any */ + int nnames; /* number of names to use in ColumnRef */ + SelectStmt *val; /* the PL/pgSQL expression to assign */ + ParseLoc location; /* name's token location, or -1 if unknown */ +} PLAssignStmt; + + /***************************************************************************** * Other Statements (no optimizations required) * @@ -1659,9 +2351,11 @@ typedef enum ObjectType OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, + OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, + OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, @@ -1681,7 +2375,7 @@ typedef enum ObjectType OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, - OBJECT_VIEW + OBJECT_VIEW, } ObjectType; /* ---------------------- @@ -1704,7 +2398,7 @@ typedef struct CreateSchemaStmt typedef enum DropBehavior { DROP_RESTRICT, /* drop fails if any dependent objects */ - DROP_CASCADE /* remove dependent objects too */ + DROP_CASCADE, /* remove dependent objects too */ } DropBehavior; /* ---------------------- @@ -1716,38 +2410,35 @@ typedef struct AlterTableStmt NodeTag type; RangeVar *relation; /* table to work on */ List *cmds; /* list of subcommands */ - ObjectType relkind; /* type of object */ + ObjectType objtype; /* type of object */ bool missing_ok; /* skip error if table missing */ } AlterTableStmt; typedef enum AlterTableType { AT_AddColumn, /* add column */ - AT_AddColumnRecurse, /* internal to commands/tablecmds.c */ AT_AddColumnToView, /* implicitly via CREATE OR REPLACE VIEW */ AT_ColumnDefault, /* alter column default */ + AT_CookedColumnDefault, /* add a pre-cooked column default */ AT_DropNotNull, /* alter column drop not null */ AT_SetNotNull, /* alter column set not null */ + AT_SetExpression, /* alter column set expression */ + AT_DropExpression, /* alter column drop expression */ AT_SetStatistics, /* alter column set statistics */ AT_SetOptions, /* alter column set ( options ) */ AT_ResetOptions, /* alter column reset ( options ) */ AT_SetStorage, /* alter column set storage */ + AT_SetCompression, /* alter column set compression */ AT_DropColumn, /* drop column */ - AT_DropColumnRecurse, /* internal to commands/tablecmds.c */ AT_AddIndex, /* add index */ AT_ReAddIndex, /* internal to commands/tablecmds.c */ AT_AddConstraint, /* add constraint */ - AT_AddConstraintRecurse, /* internal to commands/tablecmds.c */ AT_ReAddConstraint, /* internal to commands/tablecmds.c */ AT_ReAddDomainConstraint, /* internal to commands/tablecmds.c */ AT_AlterConstraint, /* alter constraint */ AT_ValidateConstraint, /* validate constraint */ - AT_ValidateConstraintRecurse, /* internal to commands/tablecmds.c */ - AT_ProcessedConstraint, /* pre-processed add constraint (local in - * parser/parse_utilcmd.c) */ AT_AddIndexConstraint, /* add constraint using existing index */ AT_DropConstraint, /* drop constraint */ - AT_DropConstraintRecurse, /* internal to commands/tablecmds.c */ AT_ReAddComment, /* internal to commands/tablecmds.c */ AT_AlterColumnType, /* alter column type */ AT_AlterColumnGenericOptions, /* alter column OPTIONS (...) */ @@ -1756,9 +2447,8 @@ 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_SetAccessMethod, /* SET ACCESS METHOD */ AT_SetTableSpace, /* SET TABLESPACE */ AT_SetRelOptions, /* SET (...) -- AM specific parameters */ AT_ResetRelOptions, /* RESET (...) -- AM specific parameters */ @@ -1787,24 +2477,19 @@ typedef enum AlterTableType AT_GenericOptions, /* OPTIONS (...) */ AT_AttachPartition, /* ATTACH PARTITION */ AT_DetachPartition, /* DETACH PARTITION */ + AT_DetachPartitionFinalize, /* DETACH PARTITION FINALIZE */ AT_AddIdentity, /* ADD IDENTITY */ AT_SetIdentity, /* SET identity column options */ - AT_DropIdentity /* DROP IDENTITY */ + AT_DropIdentity, /* DROP IDENTITY */ + AT_ReAddStatistics, /* internal to commands/tablecmds.c */ } AlterTableType; -typedef struct ReplicaIdentityStmt -{ - NodeTag type; - char identity_type; - char *name; -} ReplicaIdentityStmt; - typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ { NodeTag type; AlterTableType subtype; /* Type of table alteration to apply */ char *name; /* column, constraint, or trigger to act on, - * or tablespace */ + * or tablespace, access method */ int16 num; /* attribute number for columns referenced by * number */ RoleSpec *newowner; @@ -1812,8 +2497,31 @@ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ * constraint, or parent table */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ bool missing_ok; /* skip error if missing? */ + bool recurse; /* exec-time recursion */ } AlterTableCmd; +/* Ad-hoc node for AT_AlterConstraint */ +typedef struct ATAlterConstraint +{ + NodeTag type; + char *conname; /* Constraint name */ + bool alterEnforceability; /* changing enforceability properties? */ + bool is_enforced; /* ENFORCED? */ + bool alterDeferrability; /* changing deferrability properties? */ + bool deferrable; /* DEFERRABLE? */ + bool initdeferred; /* INITIALLY DEFERRED? */ + bool alterInheritability; /* changing inheritability properties */ + bool noinherit; +} ATAlterConstraint; + +/* Ad-hoc node for AT_ReplicaIdentity */ +typedef struct ReplicaIdentityStmt +{ + NodeTag type; + char identity_type; + char *name; +} ReplicaIdentityStmt; + /* ---------------------- * Alter Collation @@ -1860,7 +2568,7 @@ typedef enum GrantTargetType { ACL_TARGET_OBJECT, /* grant on specific named object(s) */ ACL_TARGET_ALL_IN_SCHEMA, /* grant on all objects in given schema(s) */ - ACL_TARGET_DEFAULTS /* ALTER DEFAULT PRIVILEGES */ + ACL_TARGET_DEFAULTS, /* ALTER DEFAULT PRIVILEGES */ } GrantTargetType; typedef struct GrantStmt @@ -1868,29 +2576,41 @@ typedef struct GrantStmt NodeTag type; bool is_grant; /* true = GRANT, false = REVOKE */ GrantTargetType targtype; /* type of the grant target */ - ObjectType objtype; /* kind of object being operated on */ + ObjectType objtype; /* kind of object being operated on */ List *objects; /* list of RangeVar nodes, ObjectWithArgs - * nodes, or plain names (as Value strings) */ + * nodes, or plain names (as String values) */ List *privileges; /* list of AccessPriv nodes */ /* privileges == NIL denotes ALL PRIVILEGES */ List *grantees; /* list of RoleSpec nodes */ bool grant_option; /* grant or revoke grant option */ + RoleSpec *grantor; DropBehavior behavior; /* drop behavior (for REVOKE) */ } GrantStmt; /* - * Note: ObjectWithArgs carries only the types of the input parameters of the - * function. So it is sufficient to identify an existing function, but it - * is not enough info to define a function nor to call it. + * ObjectWithArgs represents a function/procedure/operator name plus parameter + * identification. + * + * objargs includes only the types of the input parameters of the object. + * In some contexts, that will be all we have, and it's enough to look up + * objects according to the traditional Postgres rules (i.e., when only input + * arguments matter). + * + * objfuncargs, if not NIL, carries the full specification of the parameter + * list, including parameter mode annotations. + * + * Some grammar productions can set args_unspecified = true instead of + * providing parameter info. In this case, lookup will succeed only if + * the object name is unique. Note that otherwise, NIL parameter lists + * mean zero arguments. */ typedef struct ObjectWithArgs { NodeTag type; List *objname; /* qualified name of function/operator */ - List *objargs; /* list of Typename nodes */ - bool args_unspecified; /* argument list was omitted, so name must - * be unique (note that objargs == NIL - * means zero args) */ + List *objargs; /* list of Typename nodes (input args only) */ + List *objfuncargs; /* list of FunctionParameter nodes */ + bool args_unspecified; /* argument list was omitted? */ } ObjectWithArgs; /* @@ -1904,7 +2624,7 @@ typedef struct AccessPriv { NodeTag type; char *priv_name; /* string name of privilege */ - List *cols; /* list of Value strings */ + List *cols; /* list of String */ } AccessPriv; /* ---------------------- @@ -1913,7 +2633,7 @@ typedef struct AccessPriv * Note: because of the parsing ambiguity with the GRANT * statement, granted_roles is a list of AccessPriv; the execution code * should complain if any column lists appear. grantee_roles is a list - * of role names, as Value strings. + * of role names, as String values. * ---------------------- */ typedef struct GrantRoleStmt @@ -1922,7 +2642,7 @@ typedef struct GrantRoleStmt List *granted_roles; /* list of roles to be granted/revoked */ List *grantee_roles; /* list of member roles to add/delete */ bool is_grant; /* true = GRANT, false = REVOKE */ - bool admin_opt; /* with admin option */ + List *opt; /* options e.g. WITH GRANT OPTION */ RoleSpec *grantor; /* set grantor to other than current role */ DropBehavior behavior; /* drop behavior (for REVOKE) */ } GrantRoleStmt; @@ -1958,6 +2678,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; /* ---------------------- @@ -1967,23 +2688,38 @@ typedef struct CopyStmt * preserve the distinction in VariableSetKind for CreateCommandTag(). * ---------------------- */ -typedef enum +typedef enum VariableSetKind { VAR_SET_VALUE, /* SET var = value */ VAR_SET_DEFAULT, /* SET var TO DEFAULT */ VAR_SET_CURRENT, /* SET var FROM CURRENT */ VAR_SET_MULTI, /* special case for SET TRANSACTION ... */ VAR_RESET, /* RESET var */ - VAR_RESET_ALL /* RESET ALL */ + VAR_RESET_ALL, /* RESET ALL */ } VariableSetKind; typedef struct VariableSetStmt { + pg_node_attr(custom_query_jumble) + NodeTag type; VariableSetKind kind; - char *name; /* variable to be set */ - List *args; /* List of A_Const nodes */ - bool is_local; /* SET LOCAL? */ + /* variable to be set */ + char *name; + /* List of A_Const nodes */ + List *args; + + /* + * True if arguments should be accounted for in query jumbling. We use a + * separate flag rather than query_jumble_ignore on "args" as several + * grammar flavors of SET rely on a list of values that are parsed + * directly from the grammar's keywords. + */ + bool jumble_args; + /* SET LOCAL? */ + bool is_local; + /* token location, or -1 if unknown */ + ParseLoc location pg_node_attr(query_jumble_location); } VariableSetStmt; /* ---------------------- @@ -2000,10 +2736,10 @@ typedef struct VariableShowStmt * Create Table Statement * * NOTE: in the raw gram.y output, ColumnDef and Constraint nodes are - * intermixed in tableElts, and constraints is NIL. After parse analysis, - * tableElts contains just ColumnDefs, and constraints contains just - * Constraint nodes (in fact, only CONSTR_CHECK nodes, in the present - * implementation). + * intermixed in tableElts, and constraints and nnconstraints are NIL. After + * parse analysis, tableElts contains just ColumnDefs, nnconstraints contains + * Constraint nodes of CONSTR_NOTNULL type from various sources, and + * constraints contains just CONSTR_CHECK Constraint nodes. * ---------------------- */ @@ -2013,14 +2749,16 @@ typedef struct CreateStmt RangeVar *relation; /* relation to create */ List *tableElts; /* column definitions (list of ColumnDef) */ List *inhRelations; /* relations to inherit from (list of - * inhRelation) */ + * RangeVar) */ PartitionBoundSpec *partbound; /* FOR VALUES clause */ PartitionSpec *partspec; /* PARTITION BY clause */ TypeName *ofTypename; /* OF typename */ List *constraints; /* constraints (list of Constraint nodes) */ + List *nnconstraints; /* NOT NULL constraints (ditto) */ 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; @@ -2062,6 +2800,7 @@ typedef enum ConstrType /* types of constraints */ CONSTR_NOTNULL, CONSTR_DEFAULT, CONSTR_IDENTITY, + CONSTR_GENERATED, CONSTR_CHECK, CONSTR_PRIMARY, CONSTR_UNIQUE, @@ -2070,7 +2809,9 @@ typedef enum ConstrType /* types of constraints */ CONSTR_ATTR_DEFERRABLE, /* attributes for previous constraint node */ CONSTR_ATTR_NOT_DEFERRABLE, CONSTR_ATTR_DEFERRED, - CONSTR_ATTR_IMMEDIATE + CONSTR_ATTR_IMMEDIATE, + CONSTR_ATTR_ENFORCED, + CONSTR_ATTR_NOT_ENFORCED, } ConstrType; /* Foreign key action codes */ @@ -2089,33 +2830,32 @@ typedef struct Constraint { NodeTag type; ConstrType contype; /* see above */ - - /* Fields used for most/all constraint types: */ char *conname; /* Constraint name, or NULL if unnamed */ bool deferrable; /* DEFERRABLE? */ bool initdeferred; /* INITIALLY DEFERRED? */ - int location; /* token location, or -1 if unknown */ - - /* Fields used for constraints with expressions (CHECK and DEFAULT): */ + bool is_enforced; /* enforced constraint? */ + bool skip_validation; /* skip validation of existing rows? */ + bool initially_valid; /* mark the new constraint as valid? */ 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; - - /* Fields used for unique constraints (UNIQUE and PRIMARY KEY): */ + Node *raw_expr; /* CHECK or DEFAULT expression, as + * untransformed parse tree */ + char *cooked_expr; /* CHECK or DEFAULT expression, as + * nodeToString representation */ + char generated_when; /* ALWAYS or BY DEFAULT */ + char generated_kind; /* STORED or VIRTUAL */ + bool nulls_not_distinct; /* null treatment for UNIQUE constraints */ List *keys; /* String nodes naming referenced key - * column(s) */ + * column(s); for UNIQUE/PK/NOT NULL */ + bool without_overlaps; /* WITHOUT OVERLAPS specified */ List *including; /* String nodes naming referenced nonkey - * column(s) */ - - /* Fields used for EXCLUSION constraints: */ - List *exclusions; /* list of (IndexElem, operator name) pairs */ - - /* Fields used for index constraints (UNIQUE, PRIMARY KEY, EXCLUSION): */ + * column(s); for UNIQUE/PK */ + List *exclusions; /* list of (IndexElem, operator name) pairs; + * for exclusion constraints */ List *options; /* options from WITH clause */ char *indexname; /* existing index to use; otherwise NULL */ char *indexspace; /* index tablespace; NULL for default */ - /* These could be, but currently are not, used for UNIQUE/PKEY: */ + bool reset_default_tblspc; /* reset default_tablespace prior to + * creating the index */ char *access_method; /* index access method; NULL for default */ Node *where_clause; /* partial index predicate */ @@ -2123,16 +2863,17 @@ typedef struct Constraint RangeVar *pktable; /* Primary key table */ List *fk_attrs; /* Attributes of foreign key */ List *pk_attrs; /* Corresponding attrs in PK table */ + bool fk_with_period; /* Last attribute of FK uses PERIOD */ + bool pk_with_period; /* Last attribute of PK uses PERIOD */ char fk_matchtype; /* FULL, PARTIAL, SIMPLE */ char fk_upd_action; /* ON UPDATE action */ char fk_del_action; /* ON DELETE action */ + List *fk_del_set_cols; /* ON DELETE SET NULL/DEFAULT (col1, col2) */ List *old_conpfeqop; /* pg_constraint.conpfeqop of my former self */ Oid old_pktable_oid; /* pg_constraint.confrelid of my former * self */ - /* Fields used for constraints that allow a NOT VALID specification */ - bool skip_validation; /* skip validation of existing rows? */ - bool initially_valid; /* mark the new constraint as valid? */ + ParseLoc location; /* token location, or -1 if unknown */ } Constraint; /* ---------------------- @@ -2301,7 +3042,7 @@ typedef enum ImportForeignSchemaType { FDW_IMPORT_SCHEMA_ALL, /* all relations wanted */ FDW_IMPORT_SCHEMA_LIMIT_TO, /* include only listed tables in import */ - FDW_IMPORT_SCHEMA_EXCEPT /* exclude listed tables from import */ + FDW_IMPORT_SCHEMA_EXCEPT, /* exclude listed tables from import */ } ImportForeignSchemaType; typedef struct ImportForeignSchemaStmt @@ -2364,10 +3105,12 @@ typedef struct CreateAmStmt typedef struct CreateTrigStmt { NodeTag type; + bool replace; /* replace trigger if already exists */ + bool isconstraint; /* This is a constraint trigger */ char *trigname; /* TRIGGER's name */ RangeVar *relation; /* relation trigger is on */ List *funcname; /* qual. name of function to call */ - List *args; /* list of (T_String) Values or NIL */ + List *args; /* list of String or NIL */ bool row; /* ROW/STATEMENT */ /* timing uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ int16 timing; /* BEFORE, AFTER, or INSTEAD */ @@ -2375,7 +3118,6 @@ typedef struct CreateTrigStmt int16 events; /* "OR" of INSERT/UPDATE/DELETE/TRUNCATE */ List *columns; /* column names, or NIL for all columns */ Node *whenClause; /* qual expression, or NULL if none */ - bool isconstraint; /* This is a constraint trigger */ /* explicitly named transition data */ List *transitionRels; /* TriggerTransition nodes, or NIL if none */ /* The remaining fields are only used for constraint triggers */ @@ -2410,8 +3152,7 @@ typedef struct AlterEventTrigStmt } AlterEventTrigStmt; /* ---------------------- - * Create/Drop PROCEDURAL LANGUAGE Statements - * Create PROCEDURAL LANGUAGE Statements + * Create LANGUAGE Statements * ---------------------- */ typedef struct CreatePLangStmt @@ -2438,7 +3179,7 @@ typedef enum RoleStmtType { ROLESTMT_ROLE, ROLESTMT_USER, - ROLESTMT_GROUP + ROLESTMT_GROUP, } RoleStmtType; typedef struct CreateRoleStmt @@ -2505,10 +3246,11 @@ typedef struct DefineStmt NodeTag type; ObjectType kind; /* aggregate, operator, type */ bool oldstyle; /* hack to signal old CREATE AGG syntax */ - List *defnames; /* qualified name (list of Value strings) */ + List *defnames; /* qualified name (list of String) */ 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; /* ---------------------- @@ -2518,7 +3260,7 @@ typedef struct DefineStmt typedef struct CreateDomainStmt { NodeTag type; - List *domainname; /* qualified name (list of Value strings) */ + List *domainname; /* qualified name (list of String) */ TypeName *typeName; /* the base type */ CollateClause *collClause; /* untransformed COLLATE spec, if any */ List *constraints; /* constraints (list of Constraint nodes) */ @@ -2531,7 +3273,7 @@ typedef struct CreateDomainStmt typedef struct CreateOpClassStmt { NodeTag type; - List *opclassname; /* qualified name (list of Value strings) */ + List *opclassname; /* qualified name (list of String) */ List *opfamilyname; /* qualified name (ditto); NIL if omitted */ char *amname; /* name of index AM opclass is for */ TypeName *datatype; /* datatype of indexed column */ @@ -2563,7 +3305,7 @@ typedef struct CreateOpClassItem typedef struct CreateOpFamilyStmt { NodeTag type; - List *opfamilyname; /* qualified name (list of Value strings) */ + List *opfamilyname; /* qualified name (list of String) */ char *amname; /* name of index AM opfamily is for */ } CreateOpFamilyStmt; @@ -2574,7 +3316,7 @@ typedef struct CreateOpFamilyStmt typedef struct AlterOpFamilyStmt { NodeTag type; - List *opfamilyname; /* qualified name (list of Value strings) */ + List *opfamilyname; /* qualified name (list of String) */ char *amname; /* name of index AM opfamily is for */ bool isDrop; /* ADD or DROP the items? */ List *items; /* List of CreateOpClassItem nodes */ @@ -2644,12 +3386,13 @@ typedef struct SecLabelStmt #define CURSOR_OPT_SCROLL 0x0002 /* SCROLL explicitly given */ #define CURSOR_OPT_NO_SCROLL 0x0004 /* NO SCROLL explicitly given */ #define CURSOR_OPT_INSENSITIVE 0x0008 /* INSENSITIVE */ -#define CURSOR_OPT_HOLD 0x0010 /* WITH HOLD */ +#define CURSOR_OPT_ASENSITIVE 0x0010 /* ASENSITIVE */ +#define CURSOR_OPT_HOLD 0x0020 /* WITH HOLD */ /* these planner-control flags do not correspond to any SQL grammar: */ -#define CURSOR_OPT_FAST_PLAN 0x0020 /* prefer fast-start plan */ -#define CURSOR_OPT_GENERIC_PLAN 0x0040 /* force use of generic plan */ -#define CURSOR_OPT_CUSTOM_PLAN 0x0080 /* force use of custom plan */ -#define CURSOR_OPT_PARALLEL_OK 0x0100 /* parallel mode OK */ +#define CURSOR_OPT_FAST_PLAN 0x0100 /* prefer fast-start plan */ +#define CURSOR_OPT_GENERIC_PLAN 0x0200 /* force use of generic plan */ +#define CURSOR_OPT_CUSTOM_PLAN 0x0400 /* force use of custom plan */ +#define CURSOR_OPT_PARALLEL_OK 0x0800 /* parallel mode OK */ typedef struct DeclareCursorStmt { @@ -2681,7 +3424,7 @@ typedef enum FetchDirection FETCH_BACKWARD, /* for these, howMany indicates a position; only one row is fetched */ FETCH_ABSOLUTE, - FETCH_RELATIVE + FETCH_RELATIVE, } FetchDirection; #define FETCH_ALL LONG_MAX @@ -2704,10 +3447,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 @@ -2715,7 +3454,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 */ @@ -2726,15 +3464,22 @@ typedef struct IndexStmt List *excludeOpNames; /* exclusion operator names, or NIL if none */ char *idxcomment; /* comment to apply to index, or NULL */ Oid indexOid; /* OID of an existing index, if any */ - Oid oldNode; /* relfilenode of existing storage, if any */ + RelFileNumber oldNumber; /* relfilenumber of existing storage, if any */ + SubTransactionId oldCreateSubid; /* rd_createSubid of oldNumber */ + SubTransactionId oldFirstRelfilelocatorSubid; /* rd_firstRelfilelocatorSubid + * of oldNumber */ bool unique; /* is index unique? */ + bool nulls_not_distinct; /* null treatment for UNIQUE constraints */ bool primary; /* is index a primary key? */ bool isconstraint; /* is it for a pkey/unique constraint? */ + bool iswithoutoverlaps; /* is the constraint WITHOUT OVERLAPS? */ bool deferrable; /* is the constraint DEFERRABLE? */ bool initdeferred; /* is the constraint INITIALLY DEFERRED? */ 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; /* ---------------------- @@ -2744,14 +3489,42 @@ typedef struct IndexStmt typedef struct CreateStatsStmt { NodeTag type; - List *defnames; /* qualified name (list of Value strings) */ - List *stat_types; /* stat types (list of Value strings) */ + List *defnames; /* qualified name (list of String) */ + List *stat_types; /* stat types (list of String) */ List *exprs; /* expressions to build statistics on */ List *relations; /* rels to build stats on (list of RangeVar) */ char *stxcomment; /* comment to apply to stats, or NULL */ + bool transformed; /* true when transformStatsStmt is finished */ bool if_not_exists; /* do nothing if stats name already exists */ } CreateStatsStmt; +/* + * StatsElem - statistics parameters (used in CREATE STATISTICS) + * + * For a plain attribute, 'name' is the name of the referenced table column + * and 'expr' is NULL. For an expression, 'name' is NULL and 'expr' is the + * expression tree. + */ +typedef struct StatsElem +{ + NodeTag type; + char *name; /* name of attribute to index, or NULL */ + Node *expr; /* expression to index, or NULL */ +} StatsElem; + + +/* ---------------------- + * Alter Statistics Statement + * ---------------------- + */ +typedef struct AlterStatsStmt +{ + NodeTag type; + List *defnames; /* qualified name (list of String) */ + Node *stxstattarget; /* statistics target */ + bool missing_ok; /* skip error if statistics object is missing */ +} AlterStatsStmt; + /* ---------------------- * Create Function Statement * ---------------------- @@ -2765,6 +3538,7 @@ typedef struct CreateFunctionStmt List *parameters; /* a list of FunctionParameter */ TypeName *returnType; /* the return type */ List *options; /* a list of DefElem */ + Node *sql_body; } CreateFunctionStmt; typedef enum FunctionParameterMode @@ -2774,7 +3548,9 @@ typedef enum FunctionParameterMode FUNC_PARAM_OUT = 'o', /* output only */ FUNC_PARAM_INOUT = 'b', /* both */ FUNC_PARAM_VARIADIC = 'v', /* variadic (always input) */ - FUNC_PARAM_TABLE = 't' /* table function output column */ + FUNC_PARAM_TABLE = 't', /* table function output column */ + /* this is not used in pg_proc: */ + FUNC_PARAM_DEFAULT = 'd', /* default; effectively same as IN */ } FunctionParameterMode; typedef struct FunctionParameter @@ -2784,6 +3560,7 @@ typedef struct FunctionParameter TypeName *argType; /* TypeName for parameter type */ FunctionParameterMode mode; /* IN/OUT/etc */ Node *defexpr; /* raw default expr, or NULL if not given */ + ParseLoc location; /* token location, or -1 if unknown */ } FunctionParameter; typedef struct AlterFunctionStmt @@ -2808,29 +3585,44 @@ typedef struct DoStmt typedef struct InlineCodeBlock { + pg_node_attr(nodetag_only) /* this is not a member of parse trees */ + NodeTag type; char *source_text; /* source text of anonymous code block */ Oid langOid; /* OID of selected language */ bool langIsTrusted; /* trusted property of the language */ bool atomic; /* atomic execution context */ -} InlineCodeBlock; +} InlineCodeBlock; /* ---------------------- * CALL statement + * + * OUT-mode arguments are removed from the transformed funcexpr. The outargs + * list contains copies of the expressions for all output arguments, in the + * order of the procedure's declared arguments. (outargs is never evaluated, + * but is useful to the caller as a reference for what to assign to.) + * The transformed call state is not relevant in the query jumbling, only the + * function call is. * ---------------------- */ typedef struct CallStmt { NodeTag type; - FuncCall *funccall; /* from the parser */ - FuncExpr *funcexpr; /* transformed */ + /* from the parser */ + FuncCall *funccall pg_node_attr(query_jumble_ignore); + /* transformed call, with only input args */ + FuncExpr *funcexpr; + /* transformed output-argument expressions */ + List *outargs; } CallStmt; typedef struct CallContext { + pg_node_attr(nodetag_only) /* this is not a member of parse trees */ + NodeTag type; bool atomic; -} CallContext; +} CallContext; /* ---------------------- * Alter Object Rename Statement @@ -2860,7 +3652,8 @@ typedef struct AlterObjectDependsStmt ObjectType objectType; /* OBJECT_FUNCTION, OBJECT_TRIGGER, etc */ RangeVar *relation; /* in case a table is involved */ Node *object; /* name of the object */ - Value *extname; /* extension name */ + String *extname; /* extension name */ + bool remove; /* set true to remove dep rather than add */ } AlterObjectDependsStmt; /* ---------------------- @@ -2890,9 +3683,8 @@ typedef struct AlterOwnerStmt RoleSpec *newowner; /* the new owner */ } AlterOwnerStmt; - /* ---------------------- - * Alter Operator Set Restrict, Join + * Alter Operator Set ( this-n-that ) * ---------------------- */ typedef struct AlterOperatorStmt @@ -2902,6 +3694,16 @@ typedef struct AlterOperatorStmt List *options; /* List of DefElem nodes */ } AlterOperatorStmt; +/* ------------------------ + * Alter Type Set ( this-n-that ) + * ------------------------ + */ +typedef struct AlterTypeStmt +{ + NodeTag type; + List *typeName; /* type name (possibly qualified) */ + List *options; /* List of DefElem nodes */ +} AlterTypeStmt; /* ---------------------- * Create Rule Statement @@ -2965,7 +3767,7 @@ typedef enum TransactionStmtKind TRANS_STMT_ROLLBACK_TO, TRANS_STMT_PREPARE, TRANS_STMT_COMMIT_PREPARED, - TRANS_STMT_ROLLBACK_PREPARED + TRANS_STMT_ROLLBACK_PREPARED, } TransactionStmtKind; typedef struct TransactionStmt @@ -2973,8 +3775,13 @@ typedef struct TransactionStmt NodeTag type; TransactionStmtKind kind; /* see above */ List *options; /* for BEGIN/START commands */ - char *savepoint_name; /* for savepoint commands */ - char *gid; /* for two-phase-commit related commands */ + /* for savepoint commands */ + char *savepoint_name pg_node_attr(query_jumble_ignore); + /* for two-phase-commit related commands */ + char *gid pg_node_attr(query_jumble_ignore); + bool chain; /* AND CHAIN option */ + /* token location, or -1 if unknown */ + ParseLoc location pg_node_attr(query_jumble_location); } TransactionStmt; /* ---------------------- @@ -2995,8 +3802,8 @@ typedef struct CompositeTypeStmt typedef struct CreateEnumStmt { NodeTag type; - List *typeName; /* qualified name (list of Value strings) */ - List *vals; /* enum values (list of Value strings) */ + List *typeName; /* qualified name (list of String) */ + List *vals; /* enum values (list of String) */ } CreateEnumStmt; /* ---------------------- @@ -3006,7 +3813,7 @@ typedef struct CreateEnumStmt typedef struct CreateRangeStmt { NodeTag type; - List *typeName; /* qualified name (list of Value strings) */ + List *typeName; /* qualified name (list of String) */ List *params; /* range parameters (list of DefElem) */ } CreateRangeStmt; @@ -3017,7 +3824,7 @@ typedef struct CreateRangeStmt typedef struct AlterEnumStmt { NodeTag type; - List *typeName; /* qualified name (list of Value strings) */ + List *typeName; /* qualified name (list of String) */ char *oldVal; /* old enum value's name, if renaming */ char *newVal; /* new enum value's name */ char *newValNeighbor; /* neighboring enum value, if specified */ @@ -3033,7 +3840,7 @@ typedef enum ViewCheckOption { NO_CHECK_OPTION, LOCAL_CHECK_OPTION, - CASCADED_CHECK_OPTION + CASCADED_CHECK_OPTION, } ViewCheckOption; typedef struct ViewStmt @@ -3079,6 +3886,12 @@ typedef struct AlterDatabaseStmt List *options; /* List of DefElem nodes */ } AlterDatabaseStmt; +typedef struct AlterDatabaseRefreshCollStmt +{ + NodeTag type; + char *dbname; +} AlterDatabaseRefreshCollStmt; + typedef struct AlterDatabaseSetStmt { NodeTag type; @@ -3095,6 +3908,7 @@ typedef struct DropdbStmt NodeTag type; char *dbname; /* database to drop */ bool missing_ok; /* skip error if db is missing? */ + List *options; /* currently only FORCE is supported */ } DropdbStmt; /* ---------------------- @@ -3116,15 +3930,14 @@ typedef struct ClusterStmt NodeTag type; RangeVar *relation; /* relation being indexed, or NULL if all */ char *indexname; /* original index defined */ - bool verbose; /* print progress info */ + List *params; /* list of DefElem nodes */ } 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 @@ -3134,11 +3947,57 @@ typedef enum VacuumOption 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_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; +typedef struct VacuumStmt +{ + 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; + +/* + * 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 + * use default */ + int multixact_freeze_table_age; /* multixact age at which to scan + * whole table */ + bool is_wraparound; /* force a for-wraparound vacuum */ + 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; + /* * Info about a single target table of VACUUM/ANALYZE. * @@ -3154,13 +4013,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 * @@ -3194,7 +4046,7 @@ typedef struct CreateTableAsStmt NodeTag type; Node *query; /* the query (see comments above) */ IntoClause *into; /* destination table */ - ObjectType relkind; /* OBJECT_TABLE or OBJECT_MATVIEW */ + ObjectType objtype; /* OBJECT_TABLE or OBJECT_MATVIEW */ bool is_select_into; /* it was written as SELECT INTO */ bool if_not_exists; /* just do nothing if it already exists? */ } CreateTableAsStmt; @@ -3230,7 +4082,7 @@ typedef enum DiscardMode DISCARD_ALL, DISCARD_PLANS, DISCARD_SEQUENCES, - DISCARD_TEMP + DISCARD_TEMP, } DiscardMode; typedef struct DiscardStmt @@ -3266,17 +4118,13 @@ typedef struct ConstraintsSetStmt * REINDEX Statement * ---------------------- */ - -/* Reindex options */ -#define REINDEXOPT_VERBOSE 1 << 0 /* print progress info */ - typedef enum ReindexObjectType { REINDEX_OBJECT_INDEX, /* index */ REINDEX_OBJECT_TABLE, /* table or materialized view */ REINDEX_OBJECT_SCHEMA, /* schema */ REINDEX_OBJECT_SYSTEM, /* system catalogs */ - REINDEX_OBJECT_DATABASE /* database */ + REINDEX_OBJECT_DATABASE, /* database */ } ReindexObjectType; typedef struct ReindexStmt @@ -3286,7 +4134,7 @@ typedef struct ReindexStmt * etc. */ RangeVar *relation; /* Table or index to reindex */ const char *name; /* name of database to reindex */ - int options; /* Reindex options flags */ + List *params; /* list of DefElem nodes */ } ReindexStmt; /* ---------------------- @@ -3364,8 +4212,17 @@ typedef struct ExecuteStmt typedef struct DeallocateStmt { NodeTag type; - char *name; /* The name of the plan to remove */ - /* NULL means DEALLOCATE ALL */ + /* The name of the plan to remove, NULL if DEALLOCATE ALL */ + char *name pg_node_attr(query_jumble_ignore); + + /* + * True if DEALLOCATE ALL. This is redundant with "name == NULL", but we + * make it a separate field so that exactly this condition (and not the + * precise name) will be accounted for in query jumbling. + */ + bool isall; + /* token location, or -1 if unknown */ + ParseLoc location pg_node_attr(query_jumble_location); } DeallocateStmt; /* @@ -3394,7 +4251,7 @@ typedef struct ReassignOwnedStmt typedef struct AlterTSDictionaryStmt { NodeTag type; - List *dictname; /* qualified name (list of Value strings) */ + List *dictname; /* qualified name (list of String) */ List *options; /* List of DefElem nodes */ } AlterTSDictionaryStmt; @@ -3407,36 +4264,71 @@ typedef enum AlterTSConfigType ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN, ALTER_TSCONFIG_REPLACE_DICT, ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN, - ALTER_TSCONFIG_DROP_MAPPING + ALTER_TSCONFIG_DROP_MAPPING, } AlterTSConfigType; typedef struct AlterTSConfigurationStmt { NodeTag type; AlterTSConfigType kind; /* ALTER_TSCONFIG_ADD_MAPPING, etc */ - List *cfgname; /* qualified name (list of Value strings) */ + List *cfgname; /* qualified name (list of String) */ /* * dicts will be non-NIL if ADD/ALTER MAPPING was specified. If dicts is * NIL, but tokentype isn't, DROP MAPPING was specified. */ - List *tokentype; /* list of Value strings */ - List *dicts; /* list of list of Value strings */ + List *tokentype; /* list of String */ + List *dicts; /* list of list of String */ bool override; /* if true - remove old variant */ bool replace; /* if true - replace dictionary by another */ bool missing_ok; /* for DROP - skip error if missing? */ } AlterTSConfigurationStmt; +typedef struct PublicationTable +{ + NodeTag type; + RangeVar *relation; /* relation to be published */ + Node *whereClause; /* qualifications */ + List *columns; /* List of columns in a publication table */ +} PublicationTable; + +/* + * Publication object type + */ +typedef enum PublicationObjSpecType +{ + PUBLICATIONOBJ_TABLE, /* A table */ + PUBLICATIONOBJ_TABLES_IN_SCHEMA, /* All tables in schema */ + PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA, /* All tables in first element of + * search_path */ + PUBLICATIONOBJ_CONTINUATION, /* Continuation of previous type */ +} PublicationObjSpecType; + +typedef struct PublicationObjSpec +{ + NodeTag type; + PublicationObjSpecType pubobjtype; /* type of this publication object */ + char *name; + PublicationTable *pubtable; + ParseLoc location; /* token location, or -1 if unknown */ +} PublicationObjSpec; typedef struct CreatePublicationStmt { NodeTag type; char *pubname; /* Name of the publication */ List *options; /* List of DefElem nodes */ - List *tables; /* Optional list of tables to add */ + List *pubobjects; /* Optional list of publication objects */ bool for_all_tables; /* Special publication for all tables in db */ } CreatePublicationStmt; +typedef enum AlterPublicationAction +{ + AP_AddObjects, /* add objects to publication */ + AP_DropObjects, /* remove objects from publication */ + AP_SetObjects, /* set list of objects */ +} AlterPublicationAction; + typedef struct AlterPublicationStmt { NodeTag type; @@ -3445,10 +4337,14 @@ typedef struct AlterPublicationStmt /* parameters used for ALTER PUBLICATION ... WITH */ List *options; /* List of DefElem nodes */ - /* parameters used for ALTER PUBLICATION ... ADD/DROP TABLE */ - List *tables; /* List of tables to add/drop */ + /* + * Parameters used for ALTER PUBLICATION ... ADD/DROP/SET publication + * objects. + */ + List *pubobjects; /* Optional list of publication objects */ bool for_all_tables; /* Special publication for all tables in db */ - DefElemAction tableAction; /* What action to perform with the tables */ + AlterPublicationAction action; /* What action to perform with the given + * objects */ } AlterPublicationStmt; typedef struct CreateSubscriptionStmt @@ -3464,9 +4360,12 @@ typedef enum AlterSubscriptionType { ALTER_SUBSCRIPTION_OPTIONS, ALTER_SUBSCRIPTION_CONNECTION, - ALTER_SUBSCRIPTION_PUBLICATION, + ALTER_SUBSCRIPTION_SET_PUBLICATION, + ALTER_SUBSCRIPTION_ADD_PUBLICATION, + ALTER_SUBSCRIPTION_DROP_PUBLICATION, ALTER_SUBSCRIPTION_REFRESH, - ALTER_SUBSCRIPTION_ENABLED + ALTER_SUBSCRIPTION_ENABLED, + ALTER_SUBSCRIPTION_SKIP, } AlterSubscriptionType; typedef struct AlterSubscriptionStmt diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h index c5af026b6..70a08f145 100644 --- a/src/include/parser/parser.h +++ b/src/include/parser/parser.h @@ -5,8 +5,8 @@ * * This is the external API for the raw lexing/parsing functions. * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parser.h @@ -19,20 +19,47 @@ #include "parsenodes.h" +/* + * RawParseMode determines the form of the string that raw_parser() accepts: + * + * RAW_PARSE_DEFAULT: parse a semicolon-separated list of SQL commands, + * and return a List of RawStmt nodes. + * + * RAW_PARSE_TYPE_NAME: parse a type name, and return a one-element List + * containing a TypeName node. + * + * RAW_PARSE_PLPGSQL_EXPR: parse a PL/pgSQL expression, and return + * a one-element List containing a RawStmt node. + * + * RAW_PARSE_PLPGSQL_ASSIGNn: parse a PL/pgSQL assignment statement, + * and return a one-element List containing a RawStmt node. "n" + * gives the number of dotted names comprising the target ColumnRef. + */ +typedef enum +{ + RAW_PARSE_DEFAULT = 0, + RAW_PARSE_TYPE_NAME, + RAW_PARSE_PLPGSQL_EXPR, + RAW_PARSE_PLPGSQL_ASSIGN1, + RAW_PARSE_PLPGSQL_ASSIGN2, + RAW_PARSE_PLPGSQL_ASSIGN3, +} RawParseMode; + +/* Values for the backslash_quote GUC */ typedef enum { BACKSLASH_QUOTE_OFF, BACKSLASH_QUOTE_ON, - BACKSLASH_QUOTE_SAFE_ENCODING + BACKSLASH_QUOTE_SAFE_ENCODING, } BackslashQuoteType; /* GUC variables in scan.l (every one of these is a bad idea :-() */ -extern int backslash_quote; -extern bool escape_string_warning; +extern PGDLLIMPORT int backslash_quote; +extern PGDLLIMPORT bool escape_string_warning; extern PGDLLIMPORT bool standard_conforming_strings; /* Primary entry point for the raw parsing functions */ -extern List *raw_parser(const char *str, bool *error); +extern List *raw_parser(const char *str, RawParseMode mode, int len, bool *error, bool use_minimal); extern Node *raw_parser2(List *parse_tree_list); /* from src/backend/commands/define.c */ @@ -48,4 +75,7 @@ extern Node *makeTypeCast(Node *arg, TypeName *typename, int location); extern Node *makeStringConstCast(char *str, int location, TypeName *typename); extern Node *makeIntConst(int val, int location); +extern List *get_dummy_write_query_tree(void); +extern List *get_dummy_read_query_tree(void); +extern Node *get_dummy_insert_query_node(void); #endif /* PARSER_H */ diff --git a/src/include/parser/pg_class.h b/src/include/parser/pg_class.h index 466c58825..82438dede 100644 --- a/src/include/parser/pg_class.h +++ b/src/include/parser/pg_class.h @@ -4,8 +4,8 @@ * definition of the "relation" system catalog (pg_class) * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_class.h @@ -22,65 +22,120 @@ #if 0 /* NOT_USED_IN_PGPOOL */ #include "catalog/genbki.h" -#include "catalog/pg_class_d.h" +#include "catalog/pg_class_d.h" /* IWYU pragma: export */ -/* ---------------- - * pg_class definition. cpp turns this into - * typedef struct FormData_pg_class - * ---------------- - */ 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(pg_catalog) BKI_LOOKUP(pg_namespace); + + /* OID of entry in pg_type for relation's implicit row type, if any */ + Oid reltype BKI_LOOKUP_OPT(pg_type); + /* OID of entry in pg_type for underlying composite type, if any */ + Oid reloftype BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_type); + + /* class owner */ + Oid relowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); + + /* access method; 0 if not a table / index */ + Oid relam BKI_DEFAULT(heap) BKI_LOOKUP_OPT(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 BKI_DEFAULT(0); + + /* identifier of table space for relation (0 means default for database) */ + Oid reltablespace BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_tablespace); + + /* # of blocks (not always up-to-date) */ + int32 relpages BKI_DEFAULT(0); + + /* # of tuples (not always up-to-date; -1 means "unknown") */ + float4 reltuples BKI_DEFAULT(-1); + + /* # of all-visible blocks (not always up-to-date) */ + int32 relallvisible BKI_DEFAULT(0); + + /* # of all-frozen blocks (not always up-to-date) */ + int32 relallfrozen BKI_DEFAULT(0); + + /* OID of toast table; 0 if none */ + Oid reltoastrelid BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class); + + /* T if has (or has had) any indexes */ + bool relhasindex BKI_DEFAULT(f); + + /* T if shared across databases */ + bool relisshared BKI_DEFAULT(f); + + /* see RELPERSISTENCE_xxx constants below */ + char relpersistence BKI_DEFAULT(p); + + /* see RELKIND_xxx constants below */ + char relkind BKI_DEFAULT(r); + + /* number of user attributes */ + int16 relnatts BKI_DEFAULT(0); /* genbki.pl will fill this in */ /* * 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 BKI_DEFAULT(0); + + /* has (or has had) any rules */ + bool relhasrules BKI_DEFAULT(f); + + /* has (or has had) any TRIGGERs */ + bool relhastriggers BKI_DEFAULT(f); + + /* has (or has had) child tables or indexes */ + bool relhassubclass BKI_DEFAULT(f); + + /* row security is enabled or not */ + bool relrowsecurity BKI_DEFAULT(f); + + /* row security forced for owners or not */ + bool relforcerowsecurity BKI_DEFAULT(f); + + /* matview currently holds query results */ + bool relispopulated BKI_DEFAULT(t); + + /* see REPLICA_IDENTITY_xxx constants */ + char relreplident BKI_DEFAULT(n); + + /* is relation a partition? */ + bool relispartition BKI_DEFAULT(f); + + /* link to original rel during table rewrite; otherwise 0 */ + Oid relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class); + + /* all Xids < this are frozen in this rel */ + TransactionId relfrozenxid BKI_DEFAULT(3); /* FirstNormalTransactionId */ + + /* all multixacts in this rel are >= this; it is really a MultiXactId */ + TransactionId relminmxid BKI_DEFAULT(1); /* FirstMultiXactId */ #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] BKI_DEFAULT(_null_); + + /* access-method-specific options */ + text reloptions[1] BKI_DEFAULT(_null_); + + /* partition bound node tree */ + pg_node_tree relpartbound BKI_DEFAULT(_null_); #endif } FormData_pg_class; @@ -93,8 +148,14 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat * the format of pg_class relation. * ---------------- */ -typedef FormData_pg_class *Form_pg_class; +typedef FormData_pg_class * Form_pg_class; + +DECLARE_UNIQUE_INDEX_PKEY(pg_class_oid_index, 2662, ClassOidIndexId, pg_class, btree(oid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index, 2663, ClassNameNspIndexId, pg_class, btree(relname name_ops, relnamespace oid_ops)); +DECLARE_INDEX(pg_class_tblspc_relfilenode_index, 3455, ClassTblspcRelfilenodeIndexId, pg_class, btree(reltablespace oid_ops, relfilenode oid_ops)); +MAKE_SYSCACHE(RELOID, pg_class_oid_index, 128); +MAKE_SYSCACHE(RELNAMENSP, pg_class_relname_nsp_index, 128); #define RELKIND_RELATION 'r' /* ordinary table */ #define RELKIND_INDEX 'i' /* secondary index */ @@ -106,7 +167,7 @@ typedef FormData_pg_class *Form_pg_class; #define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ #define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ #define RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */ -#define RELKIND_PARTITIONED_INDEX 'I' /* partitioned index */ +#define RELKIND_PARTITIONED_INDEX 'I' /* partitioned index */ #endif /* NOT_USED_IN_PGPOOL */ @@ -126,10 +187,51 @@ typedef FormData_pg_class *Form_pg_class; /* * an explicitly chosen candidate key's columns are used as replica identity. * Note this will still be set if the index has been dropped; in that case it - * has the same meaning as 'd'. + * has the same meaning as 'n'. */ #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) + +#define RELKIND_HAS_PARTITIONS(relkind) \ + ((relkind) == RELKIND_PARTITIONED_TABLE || \ + (relkind) == RELKIND_PARTITIONED_INDEX) + +/* + * Relation kinds that support tablespaces: All relation kinds with storage + * support tablespaces, except that we don't support moving sequences around + * into different tablespaces. Partitioned tables and indexes don't have + * physical storage, but they have a tablespace settings so that their + * children can inherit it. + */ +#define RELKIND_HAS_TABLESPACE(relkind) \ + ((RELKIND_HAS_STORAGE(relkind) || RELKIND_HAS_PARTITIONS(relkind)) \ + && (relkind) != RELKIND_SEQUENCE) + +/* + * Relation kinds with a table access method (rd_tableam). Although sequences + * use the heap table AM, they are enough of a special case in most uses that + * they are not included here. Likewise, partitioned tables can have an access + * method defined so that their partitions can inherit it, but they do not set + * rd_tableam; hence, this is handled specially outside of this macro. + */ +#define RELKIND_HAS_TABLE_AM(relkind) \ + ((relkind) == RELKIND_RELATION || \ + (relkind) == RELKIND_TOASTVALUE || \ + (relkind) == RELKIND_MATVIEW) + +extern int errdetail_relkind_not_supported(char relkind); + #endif /* NOT_USED_IN_PGPOOL */ #endif /* PG_CLASS_H */ @@ -139,6 +241,9 @@ typedef FormData_pg_class *Form_pg_class; #define DATEOID 1082 #define TIMEOID 1083 +/* OIDS 0 - 99 */ +#define TEXTOID 25 + /* OIDS 1100 - 1199 */ #define TIMESTAMPOID 1114 #define TIMESTAMPTZOID 1184 diff --git a/src/include/parser/pg_config_manual.h b/src/include/parser/pg_config_manual.h index b4ba6f445..cbea7dc1d 100644 --- a/src/include/parser/pg_config_manual.h +++ b/src/include/parser/pg_config_manual.h @@ -6,8 +6,8 @@ * for developers. If you edit any of these, be sure to do a *full* * rebuild (and an initdb if noted). * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/pg_config_manual.h @@ -31,24 +31,15 @@ #define PG_PRINTF_ATTRIBUTE printf #endif -/* from postgresql/src/include/c.h */ -/* GCC and XLC support format attributes */ -#if defined(__GNUC__) || defined(__IBMC__) -#define pg_attribute_format_arg(a) __attribute__((format_arg(a))) -#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a))) -#else -#define pg_attribute_format_arg(a) -#define pg_attribute_printf(f,a) -#endif /* - * 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) /* * Maximum length for identifiers (e.g. table names, column names, - * function names). Names actually are limited to one less byte than this, + * function names). Names actually are limited to one fewer byte than this, * because the length must include a trailing zero byte. * * Changing this requires an initdb. @@ -69,6 +60,23 @@ */ #define FUNC_MAX_ARGS 100 +/* + * When creating a product derived from PostgreSQL with changes that cause + * incompatibilities for loadable modules, it is recommended to change this + * string so that dfmgr.c can refuse to load incompatible modules with a clean + * error message. Typical examples that cause incompatibilities are any + * changes to node tags or node structures. (Note that dfmgr.c already + * detects common sources of incompatibilities due to major version + * differences and due to some changed compile-time constants. This setting + * is for catching anything that cannot be detected in a straightforward way.) + * + * There is no prescribed format for the string. The suggestion is to include + * product or company name, and optionally any internally-relevant ABI + * version. Example: "ACME Postgres/1.2". Note that the string will appear + * in a user-facing error message if an ABI mismatch is detected. + */ +#define FMGR_ABI_EXTRA "PostgreSQL" + /* * Maximum number of columns in an index. There is little point in making * this anything but a multiple of 32, because the main cost is associated @@ -84,20 +92,18 @@ #define PARTITION_MAX_KEYS 32 /* - * When we don't have native spinlocks, we use semaphores to simulate them. - * Decreasing this value reduces consumption of OS resources; increasing it - * may improve performance, but supplying a real spinlock implementation is - * probably far better. + * Decide whether built-in 8-byte types, including float8, int8, and + * timestamp, are passed by value. This is on by default if sizeof(Datum) >= + * 8 (that is, on 64-bit platforms). If sizeof(Datum) < 8 (32-bit platforms), + * this must be off. We keep this here as an option so that it is easy to + * test the pass-by-reference code paths on 64-bit platforms. + * + * Changing this requires an initdb. */ -#define NUM_SPINLOCK_SEMAPHORES 128 +#if SIZEOF_VOID_P >= 8 +#define USE_FLOAT8_BYVAL 1 +#endif -/* - * When we have neither spinlocks nor atomic operations support we're - * implementing atomic operations on top of spinlock on top of semaphores. To - * be safe against atomic operations while holding a spinlock separate - * semaphores have to be used. - */ -#define NUM_ATOMICS_SEMAPHORES 64 /* * MAXPGPATH: standard size of a pathname buffer in PostgreSQL (hence, @@ -111,17 +117,6 @@ */ #define MAXPGPATH 1024 -/* - * PG_SOMAXCONN: maximum accept-queue length limit passed to - * listen(2). You'd think we should use SOMAXCONN from - * , but on many systems that symbol is much smaller - * than the kernel's actual limit. In any case, this symbol need be - * twiddled only if you have a kernel that refuses large limit values, - * rather than silently reducing the value to what it can handle - * (which is what most if not all Unixen do). - */ -#define PG_SOMAXCONN 10000 - /* * You can try changing this if you have a machine with bytes of * another size, but no guarantee... @@ -137,17 +132,16 @@ #define ALIGNOF_BUFFER 32 /* - * Disable UNIX sockets for certain operating systems. - */ -#if defined(WIN32) -#undef HAVE_UNIX_SOCKETS -#endif - -/* - * Define this if your operating system supports link() + * If EXEC_BACKEND is defined, the postmaster uses an alternative method for + * starting subprocesses: Instead of simply using fork(), as is standard on + * Unix platforms, it uses fork()+exec() or something equivalent on Windows, + * as well as lots of extra code to bring the required global state to those + * new processes. This must be enabled on Windows (because there is no + * fork()). On other platforms, it's only useful for verifying those + * otherwise Windows-specific code paths. */ -#if !defined(WIN32) && !defined(__CYGWIN__) -#define HAVE_WORKING_LINK 1 +#if defined(WIN32) && !defined(__CYGWIN__) +#define EXEC_BACKEND #endif /* @@ -163,7 +157,8 @@ /* * 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, + * as well as platform-specific APIs defined elsewhere.) */ #ifdef USE_POSIX_FADVISE #define USE_PREFETCH @@ -189,8 +184,7 @@ /* * USE_SSL code should be compiled only when compiling with an SSL - * implementation. (Currently, only OpenSSL is supported, but we might add - * more implementations in the future.) + * implementation. */ #ifdef USE_OPENSSL #define USE_SSL @@ -203,8 +197,21 @@ * directory. But if you just hate the idea of sockets in /tmp, * here's where to twiddle it. You can also override this at runtime * with the postmaster's -k switch. + * + * If set to an empty string, then AF_UNIX sockets are not used by default: A + * server will not create an AF_UNIX socket unless the run-time configuration + * is changed, a client will connect via TCP/IP by default and will only use + * an AF_UNIX socket if one is explicitly specified. + * + * This is done by default on Windows because there is no good standard + * location for AF_UNIX sockets and many installations on Windows don't + * support them yet. */ +#ifndef WIN32 #define DEFAULT_PGSOCKET_DIR "/tmp" +#else +#define DEFAULT_PGSOCKET_DIR "" +#endif /* * This is the default event source for Windows event log. @@ -212,53 +219,21 @@ #define DEFAULT_EVENT_SOURCE "PostgreSQL" /* - * The random() function is expected to yield values between 0 and - * MAX_RANDOM_VALUE. Currently, all known implementations yield - * 0..2^31-1, so we just hardwire this constant. We could do a - * configure test if it proves to be necessary. CAUTION: Think not to - * replace this with RAND_MAX. RAND_MAX defines the maximum value of - * the older rand() function, which is often different from --- and - * considerably inferior to --- random(). + * Assumed cache line size. This doesn't affect correctness, but can be used + * for low-level optimizations. This is mostly used to pad various data + * structures, to ensure that highly-contended fields are on different cache + * lines. Too small a value can hurt performance due to false sharing, while + * the only downside of too large a value is a few bytes of wasted memory. + * The default is 128, which should be large enough for all supported + * platforms. */ -#ifdef NOT_USED -#define MAX_RANDOM_VALUE PG_INT32_MAX -#endif -/* - * On PPC machines, decide whether to use the mutex hint bit in LWARX - * instructions. Setting the hint bit will slightly improve spinlock - * performance on POWER6 and later machines, but does nothing before that, - * and will result in illegal-instruction failures on some pre-POWER4 - * machines. By default we use the hint bit when building for 64-bit PPC, - * which should be safe in nearly all cases. You might want to override - * this if you are building 32-bit code for a known-recent PPC machine. - */ -#ifdef HAVE_PPC_LWARX_MUTEX_HINT /* must have assembler support in any case */ -#if defined(__ppc64__) || defined(__powerpc64__) -#define USE_PPC_LWARX_MUTEX_HINT -#endif -#endif - -/* - * On PPC machines, decide whether to use LWSYNC instructions in place of - * ISYNC and SYNC. This provides slightly better performance, but will - * result in illegal-instruction failures on some pre-POWER4 machines. - * By default we use LWSYNC when building for 64-bit PPC, which should be - * safe in nearly all cases. - */ -#if defined(__ppc64__) || defined(__powerpc64__) -#define USE_PPC_LWSYNC -#endif +#define PG_CACHE_LINE_SIZE 128 /* - * Assumed cache line size. This doesn't affect correctness, but can be used - * for low-level optimizations. Currently, this is used to pad some data - * structures in xlog.c, to ensure that highly-contended fields are on - * different cache lines. Too small a value can hurt performance due to false - * sharing, while the only downside of too large a value is a few bytes of - * wasted memory. The default is 128, which should be large enough for all - * supported platforms. + * Assumed alignment requirement for direct I/O. 4K corresponds to common + * sector and memory page size. */ -#define PG_CACHE_LINE_SIZE 128 +#define PG_IO_ALIGN_SIZE 4096 /* *------------------------------------------------------------------------ @@ -267,15 +242,31 @@ *------------------------------------------------------------------------ */ +/* + * Force use of the non-recursive JSON parser in all cases. This is useful + * to validate the working of the parser, and the regression tests should + * pass except for some different error messages about the stack limit. + */ +/* #define FORCE_JSON_PSTACK */ + /* * Include Valgrind "client requests", mostly in the memory allocator, so * Valgrind understands PostgreSQL memory contexts. This permits detecting - * memory errors that Valgrind would not detect on a vanilla build. See also - * src/tools/valgrind.supp. "make installcheck" runs 20-30x longer under - * Valgrind. Note that USE_VALGRIND slowed older versions of Valgrind by an - * additional order of magnitude; Valgrind 3.8.1 does not have this problem. - * The client requests fall in hot code paths, so USE_VALGRIND also slows - * native execution by a few percentage points. + * memory errors that Valgrind would not detect on a vanilla build. It also + * enables detection of buffer accesses that take place without holding a + * buffer pin (or without holding a buffer lock in the case of index access + * methods that superimpose their own custom client requests on top of the + * generic bufmgr.c requests). + * + * "make installcheck" is significantly slower under Valgrind. The client + * requests fall in hot code paths, so USE_VALGRIND slows execution by a few + * percentage points even when not run under Valgrind. + * + * Do not try to test the server under Valgrind without having built the + * server with USE_VALGRIND; else you will get false positives from sinval + * messaging (see comments in AddCatcacheInvalidationMessage). It's also + * important to use the suppression file src/tools/valgrind.supp to + * exclude other known false positives. * * You should normally use MEMORY_CONTEXT_CHECKING with USE_VALGRIND; * instrumentation of repalloc() is inferior without it. @@ -308,18 +299,70 @@ /* #define RANDOMIZE_ALLOCATED_MEMORY */ /* - * Define this to force all parse and plan trees to be passed through - * copyObject(), to facilitate catching errors and omissions in - * copyObject(). + * For cache-invalidation debugging, define DISCARD_CACHES_ENABLED to enable + * use of the debug_discard_caches GUC to aggressively flush + * syscache/relcache/relsynccache entries whenever it's possible to deliver + * invalidations. See AcceptInvalidationMessages() in + * src/backend/utils/cache/inval.c for details. + * + * USE_ASSERT_CHECKING builds default to enabling this. It's possible to use + * DISCARD_CACHES_ENABLED without a cassert build and the implied + * CLOBBER_FREED_MEMORY and MEMORY_CONTEXT_CHECKING options, but it's unlikely + * to be as effective at identifying problems. */ -/* #define COPY_PARSE_PLAN_TREES */ +/* #define DISCARD_CACHES_ENABLED */ + +#if defined(USE_ASSERT_CHECKING) && !defined(DISCARD_CACHES_ENABLED) +#define DISCARD_CACHES_ENABLED +#endif /* - * Define this to force all raw parse trees for DML statements to be scanned - * by raw_expression_tree_walker(), to facilitate catching errors and - * omissions in that function. + * Backwards compatibility for the older compile-time-only clobber-cache + * macros. */ -/* #define RAW_EXPRESSION_COVERAGE_TEST */ +#if !defined(DISCARD_CACHES_ENABLED) && (defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY)) +#define DISCARD_CACHES_ENABLED +#endif + +/* + * Recover memory used for relcache entries when invalidated. See + * RelationBuildDesc() in src/backend/utils/cache/relcache.c. + * + * This is active automatically for clobber-cache builds when clobbering is + * active, but can be overridden here by explicitly defining + * RECOVER_RELATION_BUILD_MEMORY. Define to 1 to always free relation cache + * memory even when clobber is off, or to 0 to never free relation cache + * memory even when clobbering is on. + */ + /* #define RECOVER_RELATION_BUILD_MEMORY 0 */ /* Force disable */ + /* #define RECOVER_RELATION_BUILD_MEMORY 1 */ /* Force enable */ + +/* + * Define DEBUG_NODE_TESTS_ENABLED to enable use of the GUCs + * debug_copy_parse_plan_trees, debug_write_read_parse_plan_trees, and + * debug_raw_expression_coverage_test, to test coverage of node support + * functions in src/backend/nodes/. + * + * USE_ASSERT_CHECKING builds default to enabling this. + */ +/* #define DEBUG_NODE_TESTS_ENABLED */ + +#if defined(USE_ASSERT_CHECKING) && !defined(DEBUG_NODE_TESTS_ENABLED) +#define DEBUG_NODE_TESTS_ENABLED +#endif + +/* + * Backwards compatibility for the older compile-time-only node-tests macros. + */ +#if !defined(DEBUG_NODE_TESTS_ENABLED) && (defined(COPY_PARSE_PLAN_TREES) || defined(WRITE_READ_PARSE_PLAN_TREES) || defined(RAW_EXPRESSION_COVERAGE_TEST)) +#define DEBUG_NODE_TESTS_ENABLED +#endif + +/* + * Define this to force Bitmapset reallocation on each modification. Helps + * to find dangling pointers to Bitmapset's. + */ +/* #define REALLOCATE_BITMAPSETS */ /* * Define this to force all raw parse trees for DML statements to be scanned @@ -339,19 +382,7 @@ */ /* #define WAL_DEBUG */ -/* - * Enable tracing of resource consumption during sort operations; - * see also the trace_sort GUC var. For 8.1 this is enabled by default. - */ -#define TRACE_SORT 1 - /* * Enable tracing of syncscan operations (see also the trace_syncscan GUC var). */ /* #define TRACE_SYNCSCAN */ - -/* - * Other debug #defines (documentation, anyone?) - */ -/* #define HEAPDEBUGALL */ -/* #define ACLDEBUG */ diff --git a/src/include/parser/pg_list.h b/src/include/parser/pg_list.h index afb2fbb0c..99f334b84 100644 --- a/src/include/parser/pg_list.h +++ b/src/include/parser/pg_list.h @@ -1,34 +1,36 @@ /*------------------------------------------------------------------------- * * 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: + * 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. * - * 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. - * - * We support three types of lists: + * We support four types of lists: * * T_List: lists of pointers * (in practice usually pointers to Nodes, but not always; * declared as "void *" to minimize casting annoyances) * T_IntList: lists of integers * T_OidList: lists of Oids + * T_XidList: lists of TransactionIds + * (the XidList infrastructure is less complete than the other cases) * - * (At the moment, ints and Oids are the same size, but they may not - * always be so; try to be careful to maintain the distinction.) + * (At the moment, ints, Oids, and XIDs are the same size, but they may not + * always be so; be careful to use the appropriate list type for your data.) * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/pg_list.h @@ -42,51 +44,118 @@ #include "pool_parser.h" #include "nodes.h" -typedef struct ListCell ListCell; +/* + * * include/c.h + * */ +typedef uint32 TransactionId; -typedef struct List + +typedef union ListCell { - NodeTag type; /* T_List, T_IntList, or T_OidList */ - int length; - ListCell *head; - ListCell *tail; -} List; + void *ptr_value; + int int_value; + Oid oid_value; + TransactionId xid_value; +} ListCell; -struct ListCell +typedef struct List { - union - { - void *ptr_value; - int int_value; - Oid oid_value; - } data; - ListCell *next; -}; + NodeTag type; /* T_List, T_IntList, T_OidList, or T_XidList */ + 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; /* * 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(List *l) +list_tail(const List *l) { - return l ? l->tail : NULL; + 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 list's length */ static inline int list_length(const List *l) { @@ -94,6 +163,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 @@ -101,75 +175,341 @@ 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_xid(lc) ((lc)->xid_value) #define lfirst_node(type,lc) castNode(type, lfirst(lc)) -#define linitial(l) lfirst(list_head(l)) -#define linitial_int(l) lfirst_int(list_head(l)) -#define linitial_oid(l) lfirst_oid(list_head(l)) +#define linitial(l) lfirst(list_nth_cell(l, 0)) +#define linitial_int(l) lfirst_int(list_nth_cell(l, 0)) +#define linitial_oid(l) lfirst_oid(list_nth_cell(l, 0)) #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_nth_cell(l, 1)) +#define lsecond_int(l) lfirst_int(list_nth_cell(l, 1)) +#define lsecond_oid(l) lfirst_oid(list_nth_cell(l, 1)) #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_nth_cell(l, 2)) +#define lthird_int(l) lfirst_int(list_nth_cell(l, 2)) +#define lthird_oid(l) lfirst_oid(list_nth_cell(l, 2)) #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_nth_cell(l, 3)) +#define lfourth_int(l) lfirst_int(list_nth_cell(l, 3)) +#define lfourth_oid(l) lfirst_oid(list_nth_cell(l, 3)) #define lfourth_node(type,l) castNode(type, lfourth(l)) -#define llast(l) lfirst(list_tail(l)) -#define llast_int(l) lfirst_int(list_tail(l)) -#define llast_oid(l) lfirst_oid(list_tail(l)) +#define llast(l) lfirst(list_last_cell(l)) +#define llast_int(l) lfirst_int(list_last_cell(l)) +#define llast_oid(l) lfirst_oid(list_last_cell(l)) +#define llast_xid(l) lfirst_xid(list_last_cell(l)) #define llast_node(type,l) castNode(type, llast(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_make_xid_cell(v) ((ListCell) {.xid_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_make5(x1,x2,x3,x4,x5) \ + list_make5_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \ + list_make_ptr_cell(x3), list_make_ptr_cell(x4), \ + list_make_ptr_cell(x5)) + +#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_make5_int(x1,x2,x3,x4,x5) \ + list_make5_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \ + list_make_int_cell(x3), list_make_int_cell(x4), \ + list_make_int_cell(x5)) + +#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)) +#define list_make5_oid(x1,x2,x3,x4,x5) \ + list_make5_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \ + list_make_oid_cell(x3), list_make_oid_cell(x4), \ + list_make_oid_cell(x5)) + +#define list_make1_xid(x1) \ + list_make1_impl(T_XidList, list_make_xid_cell(x1)) +#define list_make2_xid(x1,x2) \ + list_make2_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2)) +#define list_make3_xid(x1,x2,x3) \ + list_make3_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \ + list_make_xid_cell(x3)) +#define list_make4_xid(x1,x2,x3,x4) \ + list_make4_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \ + list_make_xid_cell(x3), list_make_xid_cell(x4)) +#define list_make5_xid(x1,x2,x3,x4,x5) \ + list_make5_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \ + list_make_xid_cell(x3), list_make_xid_cell(x4), \ + list_make_xid_cell(x5)) + +/* + * 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 last cell in a non-NIL List. + */ +static inline ListCell * +list_last_cell(const List *list) +{ + Assert(list != NIL); + return &list->elements[list->length - 1]; +} + +/* + * 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() or foreach_*() loop, returning the new List + * pointer; pass the name of the iterator variable. + * + * This is similar to list_delete_cell(), but it also adjusts the loop's state + * so that no list elements will be missed. Do not delete elements from an + * active foreach or foreach_* loop's list in any other way! + */ +#define foreach_delete_current(lst, var_or_cell) \ + ((List *) (var_or_cell##__state.l = list_delete_nth_cell(lst, var_or_cell##__state.i--))) + +/* + * foreach_current_index - + * get the zero-based list index of a surrounding foreach() or foreach_*() + * loop's current element; pass the name of the 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(var_or_cell) (var_or_cell##__state.i) + +/* + * for_each_from - + * Like foreach(), but start from the N'th (zero-based) list element, + * not necessarily the first one. + * + * It's okay for N to exceed the list length, but not for it to be negative. + * + * The caveats for foreach() apply equally here. + */ +#define for_each_from(cell, lst, N) \ + for (ForEachState cell##__state = for_each_from_setup(lst, N); \ + (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_from_setup(const List *lst, int N) +{ + ForEachState r = {lst, N}; + + Assert(N >= 0); + return r; +} /* * 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(const List *lst, const ListCell *initcell) +{ + ForEachState r = {lst, + initcell ? list_cell_number(lst, initcell) : list_length(lst)}; + + return r; +} + +/* + * Convenience macros that loop through a list without needing a separate + * "ListCell *" variable. Instead, the macros declare a locally-scoped loop + * variable with the provided name and the appropriate type. + * + * Since the variable is scoped to the loop, it's not possible to detect an + * early break by checking its value after the loop completes, as is common + * practice. If you need to do this, you can either use foreach() instead or + * manually track early breaks with a separate variable declared outside of the + * loop. + * + * Note that the caveats described in the comment above the foreach() macro + * also apply to these convenience macros. + */ +#define foreach_ptr(type, var, lst) foreach_internal(type, *, var, lst, lfirst) +#define foreach_int(var, lst) foreach_internal(int, , var, lst, lfirst_int) +#define foreach_oid(var, lst) foreach_internal(Oid, , var, lst, lfirst_oid) +#define foreach_xid(var, lst) foreach_internal(TransactionId, , var, lst, lfirst_xid) + +/* + * The internal implementation of the above macros. Do not use directly. + * + * This macro actually generates two loops in order to declare two variables of + * different types. The outer loop only iterates once, so we expect optimizing + * compilers will unroll it, thereby optimizing it away. + */ +#define foreach_internal(type, pointer, var, lst, func) \ + for (type pointer var = 0, pointer var##__outerloop = (type pointer) 1; \ + var##__outerloop; \ + var##__outerloop = 0) \ + for (ForEachState var##__state = {(lst), 0}; \ + (var##__state.l != NIL && \ + var##__state.i < var##__state.l->length && \ + (var = (type pointer) func(&var##__state.l->elements[var##__state.i]), true)); \ + var##__state.i++) + +/* + * foreach_node - + * The same as foreach_ptr, but asserts that the element is of the specified + * node type. + */ +#define foreach_node(type, var, lst) \ + for (type * var = 0, *var##__outerloop = (type *) 1; \ + var##__outerloop; \ + var##__outerloop = 0) \ + for (ForEachState var##__state = {(lst), 0}; \ + (var##__state.l != NIL && \ + var##__state.i < var##__state.l->length && \ + (var = lfirst_node(type, &var##__state.l->elements[var##__state.i]), true)); \ + var##__state.i++) /* * forboth - @@ -177,12 +517,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 - @@ -192,53 +542,127 @@ 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(const List *list1, const ListCell *initcell1, + const List *list2, const 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)) - -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 *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 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)) +#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 *list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3, ListCell datum4, + ListCell datum5); + +/* + * from PostgreSQL src/include/c.h + * + * pg_nodiscard means the compiler should warn if the result of a function + * call is ignored. The name "nodiscard" is chosen in alignment with + * (possibly future) C and C++ standards. For maximum compatibility, use it + * as a function declaration specifier, so it goes before the return type. + */ +#ifdef __GNUC__ +#define pg_nodiscard __attribute__((warn_unused_result)) +#else +#define pg_nodiscard +#endif + +pg_nodiscard extern List *lappend(List *list, void *datum); +pg_nodiscard extern List *lappend_int(List *list, int datum); +pg_nodiscard extern List *lappend_oid(List *list, Oid datum); +pg_nodiscard extern List *lappend_xid(List *list, TransactionId datum); + +pg_nodiscard extern List *list_insert_nth(List *list, int pos, void *datum); +pg_nodiscard extern List *list_insert_nth_int(List *list, int pos, int datum); +pg_nodiscard extern List *list_insert_nth_oid(List *list, int pos, Oid datum); + +pg_nodiscard extern List *lcons(void *datum, List *list); +pg_nodiscard extern List *lcons_int(int datum, List *list); +pg_nodiscard extern List *lcons_oid(Oid datum, List *list); + +pg_nodiscard extern List *list_concat(List *list1, const List *list2); +pg_nodiscard extern List *list_concat_copy(const List *list1, const List *list2); + +pg_nodiscard 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); extern bool list_member_int(const List *list, int datum); extern bool list_member_oid(const List *list, Oid datum); - -extern List *list_delete(List *list, void *datum); -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 bool list_member_xid(const List *list, TransactionId datum); + +pg_nodiscard extern List *list_delete(List *list, void *datum); +pg_nodiscard extern List *list_delete_ptr(List *list, void *datum); +pg_nodiscard extern List *list_delete_int(List *list, int datum); +pg_nodiscard extern List *list_delete_oid(List *list, Oid datum); +pg_nodiscard extern List *list_delete_first(List *list); +pg_nodiscard extern List *list_delete_last(List *list); +pg_nodiscard extern List *list_delete_first_n(List *list, int n); +pg_nodiscard extern List *list_delete_nth_cell(List *list, int n); +pg_nodiscard 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); @@ -255,92 +679,32 @@ extern List *list_difference_ptr(const List *list1, const List *list2); extern List *list_difference_int(const List *list1, const List *list2); extern List *list_difference_oid(const List *list1, const List *list2); -extern List *list_append_unique(List *list, void *datum); -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); +pg_nodiscard extern List *list_append_unique(List *list, void *datum); +pg_nodiscard extern List *list_append_unique_ptr(List *list, void *datum); +pg_nodiscard extern List *list_append_unique_int(List *list, int datum); +pg_nodiscard extern List *list_append_unique_oid(List *list, Oid datum); + +pg_nodiscard extern List *list_concat_unique(List *list1, const List *list2); +pg_nodiscard extern List *list_concat_unique_ptr(List *list1, const List *list2); +pg_nodiscard extern List *list_concat_unique_int(List *list1, const List *list2); +pg_nodiscard extern List *list_concat_unique_oid(List *list1, const List *list2); -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 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); - -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) +pg_nodiscard extern List *list_copy(const List *oldlist); +pg_nodiscard extern List *list_copy_head(const List *oldlist, int len); +pg_nodiscard extern List *list_copy_tail(const List *oldlist, int nskip); +pg_nodiscard extern List *list_copy_deep(const List *oldlist); -#define freeList(list) list_free(list) +typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b); +extern void list_sort(List *list, list_sort_comparator cmp); -#define listCopy(list) list_copy(list) +extern int list_int_cmp(const ListCell *p1, const ListCell *p2); +extern int list_oid_cmp(const ListCell *p1, const ListCell *p2); -extern int length(List *list); -#endif /* ENABLE_LIST_COMPAT */ +extern char *NameListToString(List *names); #endif /* PG_LIST_H */ diff --git a/src/include/parser/pg_trigger.h b/src/include/parser/pg_trigger.h index 3d41b559c..daec329dd 100644 --- a/src/include/parser/pg_trigger.h +++ b/src/include/parser/pg_trigger.h @@ -4,8 +4,8 @@ * definition of the "trigger" system catalog (pg_trigger) * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_trigger.h @@ -21,7 +21,7 @@ #if 0 #include "catalog/genbki.h" -#include "catalog/pg_trigger_d.h" +#include "catalog/pg_trigger_d.h" /* IWYU pragma: export */ /* ---------------- * pg_trigger definition. cpp turns this into @@ -35,17 +35,26 @@ */ CATALOG(pg_trigger,2620,TriggerRelationId) { - Oid tgrelid; /* relation trigger is attached to */ + Oid oid; /* oid */ + Oid tgrelid BKI_LOOKUP(pg_class); /* relation trigger is + * attached to */ + Oid tgparentid BKI_LOOKUP_OPT(pg_trigger); /* OID of parent + * trigger, if any */ NameData tgname; /* trigger's name */ - Oid tgfoid; /* OID of function to be called */ + Oid tgfoid BKI_LOOKUP(pg_proc); /* OID of function to be called */ int16 tgtype; /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT, * ROW/STATEMENT; see below */ char tgenabled; /* trigger's firing configuration WRT * session_replication_role */ bool tgisinternal; /* trigger is system-generated */ - Oid tgconstrrelid; /* constraint's FROM table, if any */ - Oid tgconstrindid; /* constraint's supporting index, if any */ - Oid tgconstraint; /* associated pg_constraint entry, if any */ + Oid tgconstrrelid BKI_LOOKUP_OPT(pg_class); /* constraint's FROM + * table, if any */ + Oid tgconstrindid BKI_LOOKUP_OPT(pg_class); /* constraint's + * supporting index, if + * any */ + Oid tgconstraint BKI_LOOKUP_OPT(pg_constraint); /* associated + * pg_constraint entry, + * if any */ bool tgdeferrable; /* constraint trigger is deferrable */ bool tginitdeferred; /* constraint trigger is deferred initially */ int16 tgnargs; /* # of extra arguments in tgargs */ @@ -54,7 +63,8 @@ CATALOG(pg_trigger,2620,TriggerRelationId) * Variable-length fields start here, but we allow direct access to * tgattr. Note: tgattr and tgargs must not be null. */ - int2vector tgattr; /* column numbers, if trigger is on columns */ + int2vector tgattr BKI_FORCE_NOT_NULL; /* column numbers, if trigger is + * on columns */ #ifdef CATALOG_VARLEN bytea tgargs BKI_FORCE_NOT_NULL; /* first\000second\000tgnargs\000 */ @@ -69,7 +79,15 @@ CATALOG(pg_trigger,2620,TriggerRelationId) * the format of pg_trigger relation. * ---------------- */ -typedef FormData_pg_trigger *Form_pg_trigger; +typedef FormData_pg_trigger * Form_pg_trigger; + +DECLARE_TOAST(pg_trigger, 2336, 2337); + +DECLARE_INDEX(pg_trigger_tgconstraint_index, 2699, TriggerConstraintIndexId, pg_trigger, btree(tgconstraint oid_ops)); +DECLARE_UNIQUE_INDEX(pg_trigger_tgrelid_tgname_index, 2701, TriggerRelidNameIndexId, pg_trigger, btree(tgrelid oid_ops, tgname name_ops)); +DECLARE_UNIQUE_INDEX_PKEY(pg_trigger_oid_index, 2702, TriggerOidIndexId, pg_trigger, btree(oid oid_ops)); + +DECLARE_ARRAY_FOREIGN_KEY((tgrelid, tgattr), pg_attribute, (attrelid, attnum)); #endif #define EXPOSE_TO_CLIENT_CODE diff --git a/src/include/parser/pg_wchar.h b/src/include/parser/pg_wchar.h index 58f353de0..8612afd07 100644 --- a/src/include/parser/pg_wchar.h +++ b/src/include/parser/pg_wchar.h @@ -3,17 +3,20 @@ * pg_wchar.h * multibyte-character support * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/mb/pg_wchar.h * * NOTES - * This is used both by the backend and by libpq, but should not be + * This is used both by the backend and by frontends, but should not be * included by libpq client programs. In particular, a libpq client * should not assume that the encoding IDs used by the version of libpq * it's linked to match up with the IDs declared here. + * To help prevent mistakes, relevant functions that are exported by + * libpq have a physically different name when being referenced + * statically. * *------------------------------------------------------------------------- */ @@ -222,11 +225,10 @@ typedef unsigned int pg_wchar; /* * PostgreSQL encoding identifiers * - * WARNING: the order of this enum must be same as order of entries - * in the pg_enc2name_tbl[] array (in mb/encnames.c), and - * in the pg_wchar_table[] array (in mb/wchar.c)! - * - * If you add some encoding don't forget to check + * WARNING: If you add some encoding don't forget to update + * the pg_enc2name_tbl[] array (in src/common/encnames.c), + * the pg_enc2gettext_tbl[] array (in src/common/encnames.c) and + * the pg_wchar_table[] array (in src/common/wchar.c) and to check * PG_ENCODING_BE_LAST macro. * * PG_SQL_ASCII is default encoding and must be = 0. @@ -290,7 +292,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) \ @@ -307,15 +309,42 @@ typedef enum pg_enc /* * When converting strings between different encodings, we assume that space - * for converted result is 4-to-1 growth in the worst case. The rate for + * for converted result is 4-to-1 growth in the worst case. The rate for * currently supported encoding pairs are within 3 (SJIS JIS X0201 half width - * kanna -> UTF8 is the worst case). So "4" should be enough for the moment. + * kana -> UTF8 is the worst case). So "4" should be enough for the moment. * * Note that this is not the same as the maximum character width in any * particular encoding. */ #define MAX_CONVERSION_GROWTH 4 +/* + * Maximum byte length of a string that's required in any encoding to convert + * at least one character to any other encoding. In other words, if you feed + * MAX_CONVERSION_INPUT_LENGTH bytes to any encoding conversion function, it + * is guaranteed to be able to convert something without needing more input + * (assuming the input is valid). + * + * Currently, the maximum case is the conversion UTF8 -> SJIS JIS X0201 half + * width kana, where a pair of UTF-8 characters is converted into a single + * SHIFT_JIS_2004 character (the reverse of the worst case for + * MAX_CONVERSION_GROWTH). It needs 6 bytes of input. In theory, a + * user-defined conversion function might have more complicated cases, although + * for the reverse mapping you would probably also need to bump up + * MAX_CONVERSION_GROWTH. But there is no need to be stingy here, so make it + * generous. + */ +#define MAX_CONVERSION_INPUT_LENGTH 16 + +/* + * Maximum byte length of the string equivalent to any one Unicode code point, + * in any backend encoding. The current value assumes that a 4-byte UTF-8 + * character might expand by MAX_CONVERSION_GROWTH, which is a huge + * overestimate. But in current usage we don't allocate large multiples of + * this, so there's little point in being stingy. + */ +#define MAX_UNICODE_EQUIVALENT_STRING 16 + /* * Table for mapping an encoding number to official encoding name and * possibly other subsidiary data. Be careful to check encoding number @@ -333,24 +362,12 @@ typedef struct pg_enc2name #endif } pg_enc2name; -extern const pg_enc2name pg_enc2name_tbl[]; +extern PGDLLIMPORT const pg_enc2name pg_enc2name_tbl[]; /* * Encoding names for gettext */ -typedef struct pg_enc2gettext -{ - pg_enc encoding; - const char *name; -} pg_enc2gettext; - -extern const pg_enc2gettext pg_enc2gettext_tbl[]; - -/* - * Encoding names for ICU - */ -extern bool is_encoding_supported_by_icu(int encoding); -extern const char *get_encoding_name_for_icu(int encoding); +extern PGDLLIMPORT const char *pg_enc2gettext_tbl[]; /* * pg_wchar stuff @@ -369,7 +386,9 @@ typedef int (*mbdisplaylen_converter) (const unsigned char *mbstr); typedef bool (*mbcharacter_incrementer) (unsigned char *mbstr, int len); -typedef int (*mbverifier) (const unsigned char *mbstr, int len); +typedef int (*mbchar_verifier) (const unsigned char *mbstr, int len); + +typedef int (*mbstr_verifier) (const unsigned char *mbstr, int len); typedef struct { @@ -379,11 +398,12 @@ typedef struct * to a multibyte */ mblen_converter mblen; /* get byte length of a char */ mbdisplaylen_converter dsplen; /* get display width of a char */ - mbverifier mbverify; /* verify multibyte sequence */ + mbchar_verifier mbverifychar; /* verify multibyte character */ + mbstr_verifier mbverifystr; /* verify multibyte string */ int maxmblen; /* max bytes for a char in this encoding */ } pg_wchar_tbl; -extern const pg_wchar_tbl pg_wchar_table[]; +extern PGDLLIMPORT const pg_wchar_tbl pg_wchar_table[]; /* * Data structures for conversions between UTF-8 and other encodings @@ -466,7 +486,7 @@ typedef struct uint8 b4_4_lower; /* min/max allowed value for 4th input byte */ uint8 b4_4_upper; -} pg_mb_radix_tree; +} pg_mb_radix_tree; /* * UTF-8 to local code conversion map (for combined characters) @@ -476,7 +496,7 @@ typedef struct uint32 utf1; /* UTF-8 code 1 */ uint32 utf2; /* UTF-8 code 2 */ uint32 code; /* local code */ -} pg_utf_to_local_combined; +} pg_utf_to_local_combined; /* * local code to UTF-8 conversion map (for combined characters) @@ -486,7 +506,7 @@ typedef struct uint32 code; /* local code */ uint32 utf1; /* UTF-8 code 1 */ uint32 utf2; /* UTF-8 code 2 */ -} pg_local_to_utf_combined; +} pg_local_to_utf_combined; /* * callback function for algorithmic encoding conversions (in either direction) @@ -509,6 +529,127 @@ typedef uint32 (*utf_local_conversion_func) (uint32 code); (destencoding)) +/* + * Some handy functions for Unicode-specific tests. + */ +static inline bool +is_valid_unicode_codepoint(pg_wchar c) +{ + return (c > 0 && c <= 0x10FFFF); +} + +static inline bool +is_utf16_surrogate_first(pg_wchar c) +{ + return (c >= 0xD800 && c <= 0xDBFF); +} + +static inline bool +is_utf16_surrogate_second(pg_wchar c) +{ + return (c >= 0xDC00 && c <= 0xDFFF); +} + +static inline pg_wchar +surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second) +{ + return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF); +} + +/* + * Convert a UTF-8 character to a Unicode code point. + * This is a one-character version of pg_utf2wchar_with_len. + * + * No error checks here, c must point to a long-enough string. + */ +static inline pg_wchar +utf8_to_unicode(const unsigned char *c) +{ + if ((*c & 0x80) == 0) + return (pg_wchar) c[0]; + else if ((*c & 0xe0) == 0xc0) + return (pg_wchar) (((c[0] & 0x1f) << 6) | + (c[1] & 0x3f)); + else if ((*c & 0xf0) == 0xe0) + return (pg_wchar) (((c[0] & 0x0f) << 12) | + ((c[1] & 0x3f) << 6) | + (c[2] & 0x3f)); + else if ((*c & 0xf8) == 0xf0) + return (pg_wchar) (((c[0] & 0x07) << 18) | + ((c[1] & 0x3f) << 12) | + ((c[2] & 0x3f) << 6) | + (c[3] & 0x3f)); + else + /* that is an invalid code on purpose */ + return 0xffffffff; +} + +/* + * Map a Unicode code point to UTF-8. utf8string must have at least + * unicode_utf8len(c) bytes available. + */ +static inline unsigned char * +unicode_to_utf8(pg_wchar c, unsigned char *utf8string) +{ + if (c <= 0x7F) + { + utf8string[0] = c; + } + else if (c <= 0x7FF) + { + utf8string[0] = 0xC0 | ((c >> 6) & 0x1F); + utf8string[1] = 0x80 | (c & 0x3F); + } + else if (c <= 0xFFFF) + { + utf8string[0] = 0xE0 | ((c >> 12) & 0x0F); + utf8string[1] = 0x80 | ((c >> 6) & 0x3F); + utf8string[2] = 0x80 | (c & 0x3F); + } + else + { + utf8string[0] = 0xF0 | ((c >> 18) & 0x07); + utf8string[1] = 0x80 | ((c >> 12) & 0x3F); + utf8string[2] = 0x80 | ((c >> 6) & 0x3F); + utf8string[3] = 0x80 | (c & 0x3F); + } + + return utf8string; +} + +/* + * Number of bytes needed to represent the given char in UTF8. + */ +static inline int +unicode_utf8len(pg_wchar c) +{ + if (c <= 0x7F) + return 1; + else if (c <= 0x7FF) + return 2; + else if (c <= 0xFFFF) + return 3; + else + return 4; +} + +/* + * The functions in this list are exported by libpq, and we need to be sure + * that we know which calls are satisfied by libpq and which are satisfied + * by static linkage to libpgcommon. (This is because we might be using a + * libpq.so that's of a different major version and has encoding IDs that + * differ from the current version's.) The nominal function names are what + * are actually used in and exported by libpq, while the names exported by + * libpgcommon.a and libpgcommon_srv.a end in "_private". + */ +#if defined(USE_PRIVATE_ENCODING_FUNCS) || !defined(FRONTEND) +#define pg_char_to_encoding pg_char_to_encoding_private +#define pg_encoding_to_char pg_encoding_to_char_private +#define pg_valid_server_encoding pg_valid_server_encoding_private +#define pg_valid_server_encoding_id pg_valid_server_encoding_id_private +#define pg_utf_mblen pg_utf_mblen_private +#endif + /* * These functions are considered part of libpq's exported API and * are also declared in libpq-fe.h. @@ -518,35 +659,53 @@ extern const char *pg_encoding_to_char(int encoding); extern int pg_valid_server_encoding_id(int encoding); /* - * Remaining functions are not considered part of libpq's API, though many - * of them do exist inside libpq. + * These functions are available to frontend code that links with libpgcommon + * (in addition to the ones just above). The constant tables declared + * earlier in this file are also available from libpgcommon. + */ +extern void pg_encoding_set_invalid(int encoding, char *dst); +extern int pg_encoding_mblen(int encoding, const char *mbstr); +extern int pg_encoding_mblen_or_incomplete(int encoding, const char *mbstr, + size_t remaining); +extern int pg_encoding_mblen_bounded(int encoding, const char *mbstr); +extern int pg_encoding_dsplen(int encoding, const char *mbstr); +extern int pg_encoding_verifymbchar(int encoding, const char *mbstr, int len); +extern int pg_encoding_verifymbstr(int encoding, const char *mbstr, int len); +extern int pg_encoding_max_length(int encoding); +extern int pg_valid_client_encoding(const char *name); +extern int pg_valid_server_encoding(const char *name); +extern bool is_encoding_supported_by_icu(int encoding); +extern const char *get_encoding_name_for_icu(int encoding); + +extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string); +extern pg_wchar utf8_to_unicode(const unsigned char *c); +extern bool pg_utf8_islegal(const unsigned char *source, int length); +extern int pg_utf_mblen(const unsigned char *s); +extern int pg_mule_mblen(const unsigned char *s); + +/* + * The remaining functions are backend-only. */ 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); -extern size_t pg_wchar_strlen(const pg_wchar *wstr); +extern size_t pg_wchar_strlen(const pg_wchar *str); extern int pg_mblen(const char *mbstr); extern int pg_dsplen(const char *mbstr); -extern int pg_encoding_mblen(int encoding, const char *mbstr); -extern int pg_encoding_dsplen(int encoding, const char *mbstr); -extern int pg_encoding_verifymb(int encoding, const char *mbstr, int len); -extern int pg_mule_mblen(const unsigned char *mbstr); -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_mbstrlen_with_len(const char *mbstr, int limit); 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_max_length(int encoding); +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_database_encoding_max_length(void); extern mbcharacter_incrementer pg_database_encoding_character_incrementer(void); @@ -566,72 +725,72 @@ extern int GetMessageEncoding(void); extern int pg_bind_textdomain_codeset(const char *domainname); #endif -extern int pg_valid_client_encoding(const char *name); -extern int pg_valid_server_encoding(const char *name); - -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 int pg_do_encoding_conversion_buf(Oid proc, + int src_encoding, + int dest_encoding, + unsigned char *src, int srclen, + unsigned char *dest, int destlen, + bool noError); extern char *pg_client_to_server(const char *s, int len); extern char *pg_server_to_client(const char *s, int len); extern char *pg_any_to_server(const char *s, int len, int encoding); extern char *pg_server_to_any(const char *s, int len, int encoding); +extern void pg_unicode_to_server(pg_wchar c, unsigned char *s); +extern bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s); + 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); -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); +extern int 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, bool noError); +extern int 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, bool noError); 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); - -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(); - -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); -extern void latin2mic(const unsigned char *l, unsigned char *p, int len, - int lc, int encoding); -extern void mic2latin(const unsigned char *mic, unsigned char *p, int len, - 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); -extern void mic2latin_with_table(const unsigned char *mic, unsigned char *p, - int len, int lc, int encoding, - const unsigned char *tab); - -extern bool pg_utf8_islegal(const unsigned char *source, int length); + int dest_encoding, + int len, + int expected_src_encoding, + int expected_dest_encoding); + +pg_noreturn extern void report_invalid_encoding(int encoding, const char *mbstr, int len); +pg_noreturn extern void report_untranslatable_char(int src_encoding, int dest_encoding, + const char *mbstr, int len); + +extern int local2local(const unsigned char *l, unsigned char *p, int len, + int src_encoding, int dest_encoding, + const unsigned char *tab, bool noError); +extern int latin2mic(const unsigned char *l, unsigned char *p, int len, + int lc, int encoding, bool noError); +extern int mic2latin(const unsigned char *mic, unsigned char *p, int len, + int lc, int encoding, bool noError); +extern int latin2mic_with_table(const unsigned char *l, unsigned char *p, + int len, int lc, int encoding, + const unsigned char *tab, bool noError); +extern int mic2latin_with_table(const unsigned char *mic, unsigned char *p, + int len, int lc, int encoding, + const unsigned char *tab, bool noError); #ifdef WIN32 -extern WCHAR *pgwin32_message_to_UTF16(const char *str, int len, int *utf16len); +extern WCHAR * pgwin32_message_to_UTF16(const char *str, int len, int *utf16len); #endif #endif /* PG_WCHAR_H */ diff --git a/src/include/parser/pool_parser.h b/src/include/parser/pool_parser.h index 0e90f7c19..6ea19070f 100644 --- a/src/include/parser/pool_parser.h +++ b/src/include/parser/pool_parser.h @@ -2,7 +2,7 @@ /* * $Header$ * - * Copyright (c) 2006-2015, pgpool Global Development Group + * Copyright (c) 2006-2024, pgpool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -30,16 +30,6 @@ extern int server_version_num; /* from include/postgresql_ext.h */ #define InvalidOid ((Oid) 0) -/* from include/pg_config_manual.h */ -/* - * NAMEDATALEN is the max length for system identifiers (e.g. table names, - * attribute names, function names, etc). It must be a multiple of - * sizeof(int) (typically 4). - * - * NOTE that databases with different NAMEDATALEN's cannot interoperate! - */ -#define NAMEDATALEN 64 - /* from include/c.h */ /* @@ -76,6 +66,26 @@ typedef unsigned int Index; */ #define endof(array) (&(array)[lengthof(array)]) +/* + * pg_noreturn corresponds to the C11 noreturn/_Noreturn function specifier. + * We can't use the standard name "noreturn" because some third-party code + * uses __attribute__((noreturn)) in headers, which would get confused if + * "noreturn" is defined to "_Noreturn", as is done by . + * + * In a declaration, function specifiers go before the function name. The + * common style is to put them before the return type. (The MSVC fallback has + * the same requirement. The GCC fallback is more flexible.) + */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define pg_noreturn _Noreturn +#elif defined(__GNUC__) || defined(__SUNPRO_C) +#define pg_noreturn __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define pg_noreturn __declspec(noreturn) +#else +#define pg_noreturn +#endif + /* GCC and XLC support format attributes */ #if defined(__GNUC__) || defined(__IBMC__) #define pg_attribute_format_arg(a) __attribute__((format_arg(a))) @@ -88,16 +98,13 @@ typedef unsigned int Index; /* GCC, Sunpro and XLC support aligned, packed and noreturn */ #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__) #define pg_attribute_aligned(a) __attribute__((aligned(a))) -#define pg_attribute_noreturn() __attribute__((noreturn)) #define pg_attribute_packed() __attribute__((packed)) -#define HAVE_PG_ATTRIBUTE_NORETURN 1 #else /* * NB: aligned and packed are not given default definitions because they * affect code functionality; they *must* be implemented by the compiler * if they are to be used. */ -#define pg_attribute_noreturn() #endif /* @@ -188,6 +195,14 @@ typedef int16 AttrNumber; #define MAX_TIME_PRECISION 6 - +/* + * We require C99, hence the compiler should understand flexible array + * members. However, for documentation purposes we still consider it to be + * project style to write "field[FLEXIBLE_ARRAY_MEMBER]" not just "field[]". + * When computing the size of such an object, use "offsetof(struct s, f)" + * for portability. Don't use "offsetof(struct s, f[0])", as this doesn't + * work with MSVC and with C++ compilers. + */ +#define FLEXIBLE_ARRAY_MEMBER /* empty */ #endif /* POOL_PARSER_H */ diff --git a/src/include/parser/primnodes.h b/src/include/parser/primnodes.h index a277bbb74..6fce8be0c 100644 --- a/src/include/parser/primnodes.h +++ b/src/include/parser/primnodes.h @@ -6,8 +6,8 @@ * Currently, these are mostly nodes for executable expressions * and join trees. * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/primnodes.h @@ -20,6 +20,20 @@ #include "pg_list.h" +/* + * include/c.h + */ +typedef uint32 SubTransactionId; +#define InvalidSubTransactionId ((SubTransactionId) 0) + +typedef enum OverridingKind +{ + OVERRIDING_NOT_SET = 0, + OVERRIDING_USER_VALUE, + OVERRIDING_SYSTEM_VALUE, +} OverridingKind; + + /* ---------------------------------------------------------------- * node definitions * ---------------------------------------------------------------- @@ -45,7 +59,7 @@ extern Bitmapset *bms_copy(const Bitmapset *a); * specifies an alias for a range variable; the alias might also * specify renaming of columns within the table. * - * Note: colnames is a list of Value nodes (always strings). In Alias structs + * Note: colnames is a list of String nodes. In Alias structs * associated with RTEs, there may be entries corresponding to dropped * columns; these are normally empty strings (""). See parsenodes.h for info. */ @@ -62,7 +76,7 @@ typedef enum OnCommitAction ONCOMMIT_NOOP, /* No ON COMMIT clause (do nothing) */ ONCOMMIT_PRESERVE_ROWS, /* ON COMMIT PRESERVE ROWS (do nothing) */ ONCOMMIT_DELETE_ROWS, /* ON COMMIT DELETE ROWS */ - ONCOMMIT_DROP /* ON COMMIT DROP */ + ONCOMMIT_DROP, /* ON COMMIT DROP */ } OnCommitAction; /* @@ -76,35 +90,78 @@ typedef enum OnCommitAction typedef struct RangeVar { NodeTag type; - char *catalogname; /* the catalog (database) name, or NULL */ - char *schemaname; /* the schema name, or NULL */ - char *relname; /* the relation/sequence name */ - bool inh; /* expand rel by inheritance? recursively act - * on children? */ - char relpersistence; /* see RELPERSISTENCE_* in pg_class.h */ - Alias *alias; /* table alias & optional column aliases */ - int location; /* token location, or -1 if unknown */ + + /* the catalog (database) name, or NULL */ + char *catalogname; + + /* the schema name, or NULL */ + char *schemaname; + + /* the relation/sequence name */ + char *relname; + + /* expand rel by inheritance? recursively act on children? */ + bool inh; + + /* see RELPERSISTENCE_* in pg_class.h */ + char relpersistence; + + /* table alias & optional column aliases */ + Alias *alias; + + /* token location, or -1 if unknown */ + ParseLoc location; } RangeVar; +typedef enum TableFuncType +{ + TFT_XMLTABLE, + TFT_JSON_TABLE, +} TableFuncType; + /* - * TableFunc - node for a table function, such as XMLTABLE. + * TableFunc - node for a table function, such as XMLTABLE and JSON_TABLE. + * + * Entries in the ns_names list are either String 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 */ - Node *docexpr; /* input document expression */ - Node *rowexpr; /* row filter expression */ - List *colnames; /* column names (list of String) */ - List *coltypes; /* OID list of column type OIDs */ - List *coltypmods; /* integer list of column typmods */ - List *colcollations; /* OID list of column collation OIDs */ - List *colexprs; /* list of column filter expressions */ - List *coldefexprs; /* list of column default expressions */ - Bitmapset *notnulls; /* nullability flag for each output column */ - int ordinalitycol; /* counts from 0; -1 if none specified */ - int location; /* token location, or -1 if unknown */ + /* XMLTABLE or JSON_TABLE */ + TableFuncType functype; + /* list of namespace URI expressions */ + List *ns_uris pg_node_attr(query_jumble_ignore); + /* list of namespace names or NULL */ + List *ns_names pg_node_attr(query_jumble_ignore); + /* input document expression */ + Node *docexpr; + /* row filter expression */ + Node *rowexpr; + /* column names (list of String) */ + List *colnames pg_node_attr(query_jumble_ignore); + /* OID list of column type OIDs */ + List *coltypes pg_node_attr(query_jumble_ignore); + /* integer list of column typmods */ + List *coltypmods pg_node_attr(query_jumble_ignore); + /* OID list of column collation OIDs */ + List *colcollations pg_node_attr(query_jumble_ignore); + /* list of column filter expressions */ + List *colexprs; + /* list of column default expressions */ + List *coldefexprs pg_node_attr(query_jumble_ignore); + /* JSON_TABLE: list of column value expressions */ + List *colvalexprs pg_node_attr(query_jumble_ignore); + /* JSON_TABLE: list of PASSING argument expressions */ + List *passingvalexprs pg_node_attr(query_jumble_ignore); + /* nullability flag for each output column */ + Bitmapset *notnulls pg_node_attr(query_jumble_ignore); + /* JSON_TABLE plan */ + Node *plan pg_node_attr(query_jumble_ignore); + /* counts from 0; -1 if none specified */ + int ordinalitycol pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + ParseLoc location; } TableFunc; /* @@ -112,8 +169,10 @@ typedef struct TableFunc * CREATE MATERIALIZED VIEW * * For CREATE MATERIALIZED VIEW, viewQuery is the parsed-but-not-rewritten - * SELECT Query for the view; otherwise it's NULL. (Although it's actually - * Query*, we declare it as Node* to avoid a forward reference.) + * SELECT Query for the view; otherwise it's NULL. This is irrelevant in + * the query jumbling as CreateTableAsStmt already includes a reference to + * its own Query, so ignore it. (We declare it as struct Query* to avoid a + * forward reference.) */ typedef struct IntoClause { @@ -121,10 +180,12 @@ 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 */ - Node *viewQuery; /* materialized view's SELECT query */ + /* materialized view's SELECT query */ + struct Query *viewQuery pg_node_attr(query_jumble_ignore); bool skipData; /* true for WITH NO DATA */ } IntoClause; @@ -144,51 +205,127 @@ typedef struct IntoClause */ typedef struct Expr { + pg_node_attr(abstract) + NodeTag type; } Expr; /* * Var - expression node representing a variable (ie, a table column) * - * Note: during parsing/planning, varnoold/varoattno are always just copies - * of varno/varattno. At the tail end of planning, Var nodes appearing in - * upper-level plan nodes are reassigned to point to the outputs of their - * subplans; for example, in a join node varno becomes INNER_VAR or OUTER_VAR - * and varattno becomes the index of the proper element of that subplan's - * target list. Similarly, INDEX_VAR is used to identify Vars that reference - * an index column rather than a heap column. (In ForeignScan and CustomScan - * plan nodes, INDEX_VAR is abused to signify references to columns of a - * custom scan tuple type.) In all these cases, varnoold/varoattno hold the - * original values. The code doesn't really need varnoold/varoattno, but they - * are very useful for debugging and interpreting completed plans, so we keep - * them around. - */ -#define INNER_VAR 65000 /* reference to inner subplan */ -#define OUTER_VAR 65001 /* reference to outer subplan */ -#define INDEX_VAR 65002 /* reference to index column */ - -#define IS_SPECIAL_VARNO(varno) ((varno) >= INNER_VAR) + * In the parser and planner, varno and varattno identify the semantic + * referent, which is a base-relation column unless the reference is to a join + * USING column that isn't semantically equivalent to either join input column + * (because it is a FULL join or the input column requires a type coercion). + * In those cases varno and varattno refer to the JOIN RTE. (Early in the + * planner, we replace such join references by the implied expression; but up + * till then we want join reference Vars to keep their original identity for + * query-printing purposes.) + * + * At the end of planning, Var nodes appearing in upper-level plan nodes are + * reassigned to point to the outputs of their subplans; for example, in a + * join node varno becomes INNER_VAR or OUTER_VAR and varattno becomes the + * index of the proper element of that subplan's target list. Similarly, + * INDEX_VAR is used to identify Vars that reference an index column rather + * than a heap column. (In ForeignScan and CustomScan plan nodes, INDEX_VAR + * is abused to signify references to columns of a custom scan tuple type.) + * + * ROWID_VAR is used in the planner to identify nonce variables that carry + * row identity information during UPDATE/DELETE/MERGE. This value should + * never be seen outside the planner. + * + * varnullingrels is the set of RT indexes of outer joins that can force + * the Var's value to null (at the point where it appears in the query). + * See optimizer/README for discussion of that. + * + * varlevelsup is greater than zero in Vars that represent outer references. + * Note that it affects the meaning of all of varno, varnullingrels, and + * varnosyn, all of which refer to the range table of that query level. + * + * varreturningtype is used for Vars that refer to the target relation in the + * RETURNING list of data-modifying queries. The default behavior is to + * return old values for DELETE and new values for INSERT and UPDATE, but it + * is also possible to explicitly request old or new values. + * + * In the parser, varnosyn and varattnosyn are either identical to + * varno/varattno, or they specify the column's position in an aliased JOIN + * RTE that hides the semantic referent RTE's refname. This is a syntactic + * identifier as opposed to the semantic identifier; it tells ruleutils.c + * how to print the Var properly. varnosyn/varattnosyn retain their values + * throughout planning and execution, so they are particularly helpful to + * identify Vars when debugging. Note, however, that a Var that is generated + * in the planner and doesn't correspond to any simple relation column may + * have varnosyn = varattnosyn = 0. + */ +#define INNER_VAR (-1) /* reference to inner subplan */ +#define OUTER_VAR (-2) /* reference to outer subplan */ +#define INDEX_VAR (-3) /* reference to index column */ +#define ROWID_VAR (-4) /* row identity column during planning */ + +#define IS_SPECIAL_VARNO(varno) ((int) (varno) < 0) /* Symbols for the indexes of the special RTE entries in rules */ #define PRS2_OLD_VARNO 1 #define PRS2_NEW_VARNO 2 +/* Returning behavior for Vars in RETURNING list */ +typedef enum VarReturningType +{ + VAR_RETURNING_DEFAULT, /* return OLD for DELETE, else return NEW */ + VAR_RETURNING_OLD, /* return OLD for DELETE/UPDATE, else NULL */ + VAR_RETURNING_NEW, /* return NEW for INSERT/UPDATE, else NULL */ +} VarReturningType; + typedef struct Var { Expr xpr; - Index varno; /* index of this var's relation in the range - * table, or INNER_VAR/OUTER_VAR/INDEX_VAR */ - AttrNumber varattno; /* attribute number of this var, or zero for - * all attrs ("whole-row Var") */ - Oid vartype; /* pg_type OID for the type of this var */ - int32 vartypmod; /* pg_attribute typmod value */ - Oid varcollid; /* OID of collation, or InvalidOid if none */ - Index varlevelsup; /* for subquery variables referencing outer - * relations; 0 in a normal var, >0 means N - * levels up */ - Index varnoold; /* original value of varno, for debugging */ - AttrNumber varoattno; /* original value of varattno */ - int location; /* token location, or -1 if unknown */ + + /* + * index of this var's relation in the range table, or + * INNER_VAR/OUTER_VAR/etc + */ + int varno; + + /* + * attribute number of this var, or zero for all attrs ("whole-row Var") + */ + AttrNumber varattno; + + /* pg_type OID for the type of this var */ + Oid vartype pg_node_attr(query_jumble_ignore); + /* pg_attribute typmod value */ + int32 vartypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid varcollid pg_node_attr(query_jumble_ignore); + + /* + * RT indexes of outer joins that can replace the Var's value with null. + * We can omit varnullingrels in the query jumble, because it's fully + * determined by varno/varlevelsup plus the Var's query location. + */ + Bitmapset *varnullingrels pg_node_attr(query_jumble_ignore); + + /* + * for subquery variables referencing outer relations; 0 in a normal var, + * >0 means N levels up + */ + Index varlevelsup; + + /* returning type of this var (see above) */ + VarReturningType varreturningtype; + + /* + * varnosyn/varattnosyn are ignored for equality, because Vars with + * different syntactic identifiers are semantically the same as long as + * their varno/varattno match. + */ + /* syntactic relation index (0 if unknown) */ + Index varnosyn pg_node_attr(equal_ignore, query_jumble_ignore); + /* syntactic attribute number */ + AttrNumber varattnosyn pg_node_attr(equal_ignore, query_jumble_ignore); + + /* token location, or -1 if unknown */ + ParseLoc location; } Var; /* @@ -198,22 +335,39 @@ typedef struct Var * must be in non-extended form (4-byte header, no compression or external * references). This ensures that the Const node is self-contained and makes * it more likely that equal() will see logically identical values as equal. + * + * Only the constant type OID is relevant for the query jumbling. */ typedef struct Const { + pg_node_attr(custom_copy_equal, custom_read_write) + Expr xpr; - Oid consttype; /* pg_type OID of the constant's datatype */ - int32 consttypmod; /* typmod value, if any */ - Oid constcollid; /* OID of collation, or InvalidOid if none */ - int constlen; /* typlen of the constant's datatype */ - Datum constvalue; /* the constant's value */ - bool constisnull; /* whether the constant is null (if true, - * constvalue is undefined) */ - bool constbyval; /* whether this datatype is passed by value. - * If true, then all the information is stored - * in the Datum. If false, then the Datum - * contains a pointer to the information. */ - int location; /* token location, or -1 if unknown */ + /* pg_type OID of the constant's datatype */ + Oid consttype; + /* typmod value, if any */ + int32 consttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid constcollid pg_node_attr(query_jumble_ignore); + /* typlen of the constant's datatype */ + int constlen pg_node_attr(query_jumble_ignore); + /* the constant's value */ + Datum constvalue pg_node_attr(query_jumble_ignore); + /* whether the constant is null (if true, constvalue is undefined) */ + bool constisnull pg_node_attr(query_jumble_ignore); + + /* + * Whether this datatype is passed by value. If true, then all the + * information is stored in the Datum. If false, then the Datum contains + * a pointer to the information. + */ + bool constbyval pg_node_attr(query_jumble_ignore); + + /* + * token location, or -1 if unknown. All constants are tracked as + * locations in query jumbling, to be marked as parameters. + */ + ParseLoc location pg_node_attr(query_jumble_location); } Const; /* @@ -248,18 +402,23 @@ typedef enum ParamKind PARAM_EXTERN, PARAM_EXEC, PARAM_SUBLINK, - PARAM_MULTIEXPR + PARAM_MULTIEXPR, } ParamKind; typedef struct Param { + pg_node_attr(custom_query_jumble) + Expr xpr; ParamKind paramkind; /* kind of parameter. See above */ int paramid; /* numeric ID for parameter */ Oid paramtype; /* pg_type OID of parameter's datatype */ - int32 paramtypmod; /* typmod value, if known */ - Oid paramcollid; /* OID of collation, or InvalidOid if none */ - int location; /* token location, or -1 if unknown */ + /* typmod value, if known */ + int32 paramtypmod; + /* OID of collation, or InvalidOid if none */ + Oid paramcollid; + /* token location, or -1 if unknown */ + ParseLoc location; } Param; /* @@ -267,7 +426,7 @@ typedef struct Param * * The aggregate's args list is a targetlist, ie, a list of TargetEntry nodes. * - * For a normal (non-ordered-set) aggregate, the non-resjunk TargetEntries + * For a normal (non-ordered-set) aggregate, the non-resjunk TargetEntry nodes * represent the aggregate's regular arguments (if any) and resjunk TLEs can * be added at the end to represent ORDER BY expressions that are not also * arguments. As in a top-level Query, the TLEs can be marked with @@ -294,34 +453,95 @@ typedef struct Param * replaced with a single argument representing the partial-aggregate * transition values. * + * aggpresorted is set by the query planner for ORDER BY and DISTINCT + * aggregates where the chosen plan provides presorted input for this + * aggregate during execution. + * * aggsplit indicates the expected partial-aggregation mode for the Aggref's * parent plan node. It's always set to AGGSPLIT_SIMPLE in the parser, but * the planner might change it to something else. We use this mainly as * a crosscheck that the Aggrefs match the plan; but note that when aggsplit * indicates a non-final mode, aggtype reflects the transition data type * not the SQL-level output type of the aggregate. + * + * aggno and aggtransno are -1 in the parse stage, and are set in planning. + * Aggregates with the same 'aggno' represent the same aggregate expression, + * and can share the result. Aggregates with same 'transno' but different + * 'aggno' can share the same transition state, only the final function needs + * to be called separately. + * + * Information related to collations, transition types and internal states + * are irrelevant for the query jumbling. */ typedef struct Aggref { Expr xpr; - Oid aggfnoid; /* pg_proc Oid of the aggregate */ - Oid aggtype; /* type Oid of result of the aggregate */ - Oid aggcollid; /* OID of collation of result */ - Oid inputcollid; /* OID of collation that function should use */ - Oid aggtranstype; /* type Oid of aggregate's transition value */ - List *aggargtypes; /* type Oids of direct and aggregated args */ - List *aggdirectargs; /* direct arguments, if an ordered-set agg */ - List *args; /* aggregated arguments and sort expressions */ - List *aggorder; /* ORDER BY (list of SortGroupClause) */ - List *aggdistinct; /* DISTINCT (list of SortGroupClause) */ - Expr *aggfilter; /* FILTER expression, if any */ - bool aggstar; /* true if argument list was really '*' */ - bool aggvariadic; /* true if variadic arguments have been - * combined into an array last argument */ - char aggkind; /* aggregate kind (see pg_aggregate.h) */ - Index agglevelsup; /* > 0 if agg belongs to outer query */ - AggSplit aggsplit; /* expected agg-splitting mode of parent Agg */ - int location; /* token location, or -1 if unknown */ + + /* pg_proc Oid of the aggregate */ + Oid aggfnoid; + + /* type Oid of result of the aggregate */ + Oid aggtype pg_node_attr(query_jumble_ignore); + + /* OID of collation of result */ + Oid aggcollid pg_node_attr(query_jumble_ignore); + + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + + /* + * type Oid of aggregate's transition value; ignored for equal since it + * might not be set yet + */ + Oid aggtranstype pg_node_attr(equal_ignore, query_jumble_ignore); + + /* type Oids of direct and aggregated args */ + List *aggargtypes pg_node_attr(query_jumble_ignore); + + /* direct arguments, if an ordered-set agg */ + List *aggdirectargs; + + /* aggregated arguments and sort expressions */ + List *args; + + /* ORDER BY (list of SortGroupClause) */ + List *aggorder; + + /* DISTINCT (list of SortGroupClause) */ + List *aggdistinct; + + /* FILTER expression, if any */ + Expr *aggfilter; + + /* true if argument list was really '*' */ + bool aggstar pg_node_attr(query_jumble_ignore); + + /* + * true if variadic arguments have been combined into an array last + * argument + */ + bool aggvariadic pg_node_attr(query_jumble_ignore); + + /* aggregate kind (see pg_aggregate.h) */ + char aggkind pg_node_attr(query_jumble_ignore); + + /* aggregate input already sorted */ + bool aggpresorted pg_node_attr(equal_ignore, query_jumble_ignore); + + /* > 0 if agg belongs to outer query */ + Index agglevelsup pg_node_attr(query_jumble_ignore); + + /* expected agg-splitting mode of parent Agg */ + AggSplit aggsplit pg_node_attr(query_jumble_ignore); + + /* unique ID within the Agg node */ + int aggno pg_node_attr(query_jumble_ignore); + + /* unique ID of transition state in the Agg */ + int aggtransno pg_node_attr(query_jumble_ignore); + + /* token location, or -1 if unknown */ + ParseLoc location; } Aggref; /* @@ -347,82 +567,178 @@ typedef struct Aggref * * In raw parse output we have only the args list; parse analysis fills in the * refs list, and the planner fills in the cols list. + * + * All the fields used as information for an internal state are irrelevant + * for the query jumbling. */ typedef struct GroupingFunc { Expr xpr; - List *args; /* arguments, not evaluated but kept for - * benefit of EXPLAIN etc. */ - List *refs; /* ressortgrouprefs of arguments */ - List *cols; /* actual column positions set by planner */ - Index agglevelsup; /* same as Aggref.agglevelsup */ - int location; /* token location */ + + /* arguments, not evaluated but kept for benefit of EXPLAIN etc. */ + List *args pg_node_attr(query_jumble_ignore); + + /* ressortgrouprefs of arguments */ + List *refs pg_node_attr(equal_ignore); + + /* actual column positions set by planner */ + List *cols pg_node_attr(equal_ignore, query_jumble_ignore); + + /* same as Aggref.agglevelsup */ + Index agglevelsup; + + /* token location */ + ParseLoc location; } GroupingFunc; /* * WindowFunc + * + * Collation information is irrelevant for the query jumbling, as is the + * internal state information of the node like "winstar" and "winagg". */ typedef struct WindowFunc { Expr xpr; - Oid winfnoid; /* pg_proc Oid of the function */ - Oid wintype; /* type Oid of result of the window function */ - Oid wincollid; /* OID of collation of result */ - Oid inputcollid; /* OID of collation that function should use */ - List *args; /* arguments to the window function */ - Expr *aggfilter; /* FILTER expression, if any */ - Index winref; /* index of associated WindowClause */ - bool winstar; /* true if argument list was really '*' */ - bool winagg; /* is function a simple aggregate? */ - int location; /* token location, or -1 if unknown */ + /* pg_proc Oid of the function */ + Oid winfnoid; + /* type Oid of result of the window function */ + Oid wintype pg_node_attr(query_jumble_ignore); + /* OID of collation of result */ + Oid wincollid pg_node_attr(query_jumble_ignore); + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + /* arguments to the window function */ + List *args; + /* FILTER expression, if any */ + Expr *aggfilter; + /* List of WindowFuncRunConditions to help short-circuit execution */ + List *runCondition pg_node_attr(query_jumble_ignore); + /* index of associated WindowClause */ + Index winref; + /* true if argument list was really '*' */ + bool winstar pg_node_attr(query_jumble_ignore); + /* is function a simple aggregate? */ + bool winagg pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + ParseLoc location; } 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 +/* + * WindowFuncRunCondition + * + * Represents intermediate OpExprs which will be used by WindowAgg to + * short-circuit execution. + */ +typedef struct WindowFuncRunCondition +{ + Expr xpr; + + /* PG_OPERATOR OID of the operator */ + Oid opno; + /* OID of collation that operator should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + + /* + * true of WindowFunc belongs on the left of the resulting OpExpr or false + * if the WindowFunc is on the right. + */ + bool wfunc_left; + + /* + * The Expr being compared to the WindowFunc to use in the OpExpr in the + * WindowAgg's runCondition + */ + Expr *arg; +} WindowFuncRunCondition; + +/* + * MergeSupportFunc + * + * A MergeSupportFunc is a merge support function expression that can only + * appear in the RETURNING list of a MERGE command. It returns information + * about the currently executing merge action. + * + * Currently, the only supported function is MERGE_ACTION(), which returns the + * command executed ("INSERT", "UPDATE", or "DELETE"). + */ +typedef struct MergeSupportFunc +{ + Expr xpr; + /* type Oid of result */ + Oid msftype; + /* OID of collation, or InvalidOid if none */ + Oid msfcollid; + /* token location, or -1 if unknown */ + ParseLoc location; +} MergeSupportFunc; + +/* + * 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 a container (e.g. an 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. * * In the slice case, individual expressions in the subscript lists can be * NULL, meaning "substitute the array's current lower or upper bound". - * - * Note: the result datatype is the element type when fetching a single - * 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 - * in-place and return the same object.) - * ---------------- + * (Non-array containers may or may not support this.) + * + * refcontainertype is the actual container type that determines the + * subscripting semantics. (This will generally be either the exposed type of + * refexpr, or the base type if that is a domain.) refelemtype is the type of + * the container's elements; this is saved for the use of the subscripting + * functions, but is not used by the core code. refrestype, reftypmod, and + * refcollid describe the type of the SubscriptingRef's result. In a store + * expression, refrestype will always match refcontainertype; in a fetch, + * it could be refelemtype for an element fetch, or refcontainertype for a + * slice fetch, or possibly something else as determined by type-specific + * subscripting logic. Likewise, reftypmod and refcollid will match the + * container's properties in a store, but could be different in a fetch. + * + * Any internal state data is ignored for the query jumbling. + * + * 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 refcollid; /* OID of collation, or InvalidOid if none */ - List *refupperindexpr; /* expressions that evaluate to upper - * array 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 */ - Expr *refassgnexpr; /* expression for the source value, or NULL if - * fetch */ -} ArrayRef; + /* type of the container proper */ + Oid refcontainertype pg_node_attr(query_jumble_ignore); + /* the container type's pg_type.typelem */ + Oid refelemtype pg_node_attr(query_jumble_ignore); + /* type of the SubscriptingRef's result */ + Oid refrestype pg_node_attr(query_jumble_ignore); + /* typmod of the result */ + int32 reftypmod pg_node_attr(query_jumble_ignore); + /* collation of result, or InvalidOid if none */ + Oid refcollid pg_node_attr(query_jumble_ignore); + /* expressions that evaluate to upper container indexes */ + List *refupperindexpr; + + /* + * expressions that evaluate to lower container indexes, or NIL for single + * container element. + */ + List *reflowerindexpr; + /* the expression that evaluates to a container value */ + Expr *refexpr; + /* expression for the source value, or NULL if fetch */ + Expr *refassgnexpr; +} SubscriptingRef; /* * CoercionContext - distinguishes the allowed set of type casts @@ -434,11 +750,15 @@ typedef enum CoercionContext { COERCION_IMPLICIT, /* coercion in context of expression */ COERCION_ASSIGNMENT, /* coercion in context of assignment */ - COERCION_EXPLICIT /* explicit cast operation */ + COERCION_PLPGSQL, /* if no assignment cast, use CoerceViaIO */ + COERCION_EXPLICIT, /* explicit cast operation */ } CoercionContext; /* - * CoercionForm - how to display a node that could have come from a cast + * CoercionForm - how to display a FuncExpr or related node + * + * "Coercion" is a bit of a misnomer, since this value records other + * special syntaxes besides casts, but for now we'll keep this naming. * * NB: equal() ignores CoercionForm fields, therefore this *must* not carry * any semantically significant information. We need that behavior so that @@ -450,25 +770,41 @@ typedef enum CoercionForm { COERCE_EXPLICIT_CALL, /* display as a function call */ COERCE_EXPLICIT_CAST, /* display as an explicit cast */ - COERCE_IMPLICIT_CAST /* implicit cast, so hide it */ + COERCE_IMPLICIT_CAST, /* implicit cast, so hide it */ + COERCE_SQL_SYNTAX, /* display with SQL-mandated special syntax */ } CoercionForm; /* * FuncExpr - expression node for a function call + * + * Collation information is irrelevant for the query jumbling, only the + * arguments and the function OID matter. */ typedef struct FuncExpr { Expr xpr; - Oid funcid; /* PG_PROC OID of the function */ - Oid funcresulttype; /* PG_TYPE OID of result value */ - bool funcretset; /* true if function returns set */ - bool funcvariadic; /* true if variadic arguments have been - * combined into an array last argument */ - CoercionForm funcformat; /* how to display this function call */ - Oid funccollid; /* OID of collation of result */ - Oid inputcollid; /* OID of collation that function should use */ - List *args; /* arguments to the function */ - int location; /* token location, or -1 if unknown */ + /* PG_PROC OID of the function */ + Oid funcid; + /* PG_TYPE OID of result value */ + Oid funcresulttype pg_node_attr(query_jumble_ignore); + /* true if function returns set */ + bool funcretset pg_node_attr(query_jumble_ignore); + + /* + * true if variadic arguments have been combined into an array last + * argument + */ + bool funcvariadic pg_node_attr(query_jumble_ignore); + /* how to display this function call */ + CoercionForm funcformat pg_node_attr(query_jumble_ignore); + /* OID of collation of result */ + Oid funccollid pg_node_attr(query_jumble_ignore); + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + /* arguments to the function */ + List *args; + /* token location, or -1 if unknown */ + ParseLoc location; } FuncExpr; /* @@ -488,10 +824,14 @@ typedef struct FuncExpr typedef struct NamedArgExpr { Expr xpr; - Expr *arg; /* the argument expression */ - char *name; /* the name */ - int argnumber; /* argument's number in positional notation */ - int location; /* argument name location, or -1 if unknown */ + /* the argument expression */ + Expr *arg; + /* the name */ + char *name pg_node_attr(query_jumble_ignore); + /* argument's number in positional notation */ + int argnumber; + /* argument name location, or -1 if unknown */ + ParseLoc location; } NamedArgExpr; /* @@ -502,18 +842,38 @@ typedef struct NamedArgExpr * Note that opfuncid is not necessarily filled in immediately on creation * of the node. The planner makes sure it is valid before passing the node * tree to the executor, but during parsing/planning opfuncid can be 0. + * Therefore, equal() will accept a zero value as being equal to other values. + * + * Internal state information and collation data is irrelevant for the query + * jumbling. */ typedef struct OpExpr { Expr xpr; - Oid opno; /* PG_OPERATOR OID of the operator */ - Oid opfuncid; /* PG_PROC OID of underlying function */ - Oid opresulttype; /* PG_TYPE OID of result value */ - bool opretset; /* true if operator returns set */ - Oid opcollid; /* OID of collation of result */ - Oid inputcollid; /* OID of collation that operator should use */ - List *args; /* arguments to the operator (1 or 2) */ - int location; /* token location, or -1 if unknown */ + + /* PG_OPERATOR OID of the operator */ + Oid opno; + + /* PG_PROC OID of underlying function */ + Oid opfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* PG_TYPE OID of result value */ + Oid opresulttype pg_node_attr(query_jumble_ignore); + + /* true if operator returns set */ + bool opretset pg_node_attr(query_jumble_ignore); + + /* OID of collation of result */ + Oid opcollid pg_node_attr(query_jumble_ignore); + + /* OID of collation that operator should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + + /* arguments to the operator (1 or 2) */ + List *args; + + /* token location, or -1 if unknown */ + ParseLoc location; } OpExpr; /* @@ -545,16 +905,55 @@ typedef OpExpr NullIfExpr; * is almost the same as for the underlying operator, but we need a useOr * flag to remember whether it's ANY or ALL, and we don't have to store * the result type (or the collation) because it must be boolean. + * + * A ScalarArrayOpExpr with a valid hashfuncid is evaluated during execution + * by building a hash table containing the Const values from the RHS arg. + * This table is probed during expression evaluation. The planner will set + * hashfuncid to the hash function which must be used to build and probe the + * hash table. The executor determines if it should use hash-based checks or + * the more traditional means based on if the hashfuncid is set or not. + * + * When performing hashed NOT IN, the negfuncid will also be set to the + * equality function which the hash table must use to build and probe the hash + * table. opno and opfuncid will remain set to the <> operator and its + * corresponding function and won't be used during execution. For + * non-hashtable based NOT INs, negfuncid will be set to InvalidOid. See + * convert_saop_to_hashed_saop(). + * + * Similar to OpExpr, opfuncid, hashfuncid, and negfuncid are not necessarily + * filled in right away, so will be ignored for equality if they are not set + * yet. + * + * OID entries of the internal function types are irrelevant for the query + * jumbling, but the operator OID and the arguments are. */ typedef struct ScalarArrayOpExpr { Expr xpr; - Oid opno; /* PG_OPERATOR OID of the operator */ - Oid opfuncid; /* PG_PROC OID of underlying function */ - bool useOr; /* true for ANY, false for ALL */ - Oid inputcollid; /* OID of collation that operator should use */ - List *args; /* the scalar and array operands */ - int location; /* token location, or -1 if unknown */ + + /* PG_OPERATOR OID of the operator */ + Oid opno; + + /* PG_PROC OID of comparison function */ + Oid opfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* PG_PROC OID of hash func or InvalidOid */ + Oid hashfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* PG_PROC OID of negator of opfuncid function or InvalidOid. See above */ + Oid negfuncid pg_node_attr(equal_ignore_if_zero, query_jumble_ignore); + + /* true for ANY, false for ALL */ + bool useOr; + + /* OID of collation that operator should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + + /* the scalar and array operands */ + List *args; + + /* token location, or -1 if unknown */ + ParseLoc location; } ScalarArrayOpExpr; /* @@ -571,10 +970,12 @@ typedef enum BoolExprType typedef struct BoolExpr { + pg_node_attr(custom_read_write) + Expr xpr; BoolExprType boolop; List *args; /* arguments to this expression */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } BoolExpr; /* @@ -637,7 +1038,7 @@ typedef enum SubLinkType EXPR_SUBLINK, MULTIEXPR_SUBLINK, ARRAY_SUBLINK, - CTE_SUBLINK /* for SubPlans only */ + CTE_SUBLINK, /* for SubPlans only */ } SubLinkType; @@ -647,9 +1048,11 @@ typedef struct SubLink SubLinkType subLinkType; /* see above */ int subLinkId; /* ID (1..n); 0 if not MULTIEXPR */ Node *testexpr; /* outer-query test for ALL/ANY/ROWCOMPARE */ - List *operName; /* originally specified operator name */ - Node *subselect; /* subselect as Query* or raw parsetree */ - int location; /* token location, or -1 if unknown */ + /* originally specified operator name */ + List *operName pg_node_attr(query_jumble_ignore); + /* subselect as Query* or raw parsetree */ + Node *subselect; + ParseLoc location; /* token location, or -1 if unknown */ } SubLink; /* @@ -682,9 +1085,9 @@ typedef struct SubLink * The values are assigned to the global PARAM_EXEC params indexed by parParam * (the parParam and args lists must have the same ordering). setParam is a * list of the PARAM_EXEC params that are computed by the sub-select, if it - * is an initplan; they are listed in order by sub-select output column - * position. (parParam and setParam are integer Lists, not Bitmapsets, - * because their ordering is significant.) + * is an initplan or MULTIEXPR plan; they are listed in order by sub-select + * output column position. (parParam and setParam are integer Lists, not + * Bitmapsets, because their ordering is significant.) * * Also, the planner computes startup and per-call costs for use of the * SubPlan. Note that these include the cost of the subquery proper, @@ -692,6 +1095,8 @@ typedef struct SubLink */ typedef struct SubPlan { + pg_node_attr(no_query_jumble) + Expr xpr; /* Fields copied from original SubLink: */ SubLinkType subLinkType; /* see above */ @@ -717,8 +1122,8 @@ typedef struct SubPlan /* Note: parallel_safe does not consider contents of testexpr or args */ /* Information for passing params into and out of the subselect: */ /* setParam and parParam are lists of integers (param IDs) */ - List *setParam; /* initplan subqueries have to set these - * Params for parent plan */ + List *setParam; /* initplan and MULTIEXPR subqueries have to + * set these Params for parent plan */ List *parParam; /* indices of input Params from parent plan */ List *args; /* exprs to pass as parParam values */ /* Estimated execution costs: */ @@ -729,6 +1134,9 @@ typedef struct SubPlan /* * AlternativeSubPlan - expression node for a choice among SubPlans * + * This is used only transiently during planning: by the time the plan + * reaches the executor, all AlternativeSubPlan nodes have been removed. + * * The subplans are given as a List so that the node definition need not * change if there's ever more than two alternatives. For the moment, * though, there are always exactly two; and the first one is the fast-start @@ -736,6 +1144,8 @@ typedef struct SubPlan */ typedef struct AlternativeSubPlan { + pg_node_attr(no_query_jumble) + Expr xpr; List *subplans; /* SubPlan(s) with equivalent results */ } AlternativeSubPlan; @@ -754,10 +1164,12 @@ typedef struct FieldSelect Expr xpr; Expr *arg; /* input expression */ AttrNumber fieldnum; /* attribute number of field to extract */ - Oid resulttype; /* type of the field (result type of this - * node) */ - int32 resulttypmod; /* output typmod (usually -1) */ - Oid resultcollid; /* OID of collation of the field */ + /* type of the field (result type of this node) */ + Oid resulttype pg_node_attr(query_jumble_ignore); + /* output typmod (usually -1) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation of the field */ + Oid resultcollid pg_node_attr(query_jumble_ignore); } FieldSelect; /* ---------------- @@ -765,7 +1177,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 @@ -783,8 +1195,10 @@ typedef struct FieldStore Expr xpr; Expr *arg; /* input tuple value */ List *newvals; /* new value(s) for field(s) */ - List *fieldnums; /* integer list of field attnums */ - Oid resulttype; /* type of result (same as type of arg) */ + /* integer list of field attnums */ + List *fieldnums pg_node_attr(query_jumble_ignore); + /* type of result (same as type of arg) */ + Oid resulttype pg_node_attr(query_jumble_ignore); /* Like RowExpr, we deliberately omit a typmod and collation here */ } FieldStore; @@ -806,10 +1220,13 @@ typedef struct RelabelType Expr xpr; Expr *arg; /* input expression */ Oid resulttype; /* output type of coercion expression */ - int32 resulttypmod; /* output typmod (usually -1) */ - Oid resultcollid; /* OID of collation, or InvalidOid if none */ - CoercionForm relabelformat; /* how to display this node */ - int location; /* token location, or -1 if unknown */ + /* output typmod (usually -1) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm relabelformat pg_node_attr(query_jumble_ignore); + ParseLoc location; /* token location, or -1 if unknown */ } RelabelType; /* ---------------- @@ -827,9 +1244,11 @@ typedef struct CoerceViaIO Expr *arg; /* input expression */ Oid resulttype; /* output type of coercion */ /* output typmod is not stored, but is presumed -1 */ - Oid resultcollid; /* OID of collation, or InvalidOid if none */ - CoercionForm coerceformat; /* how to display this node */ - int location; /* token location, or -1 if unknown */ + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm coerceformat pg_node_attr(query_jumble_ignore); + ParseLoc location; /* token location, or -1 if unknown */ } CoerceViaIO; /* ---------------- @@ -851,10 +1270,13 @@ typedef struct ArrayCoerceExpr Expr *arg; /* input expression (yields an array) */ Expr *elemexpr; /* expression representing per-element work */ Oid resulttype; /* output type of coercion (an array type) */ - int32 resulttypmod; /* output typmod (also element typmod) */ - Oid resultcollid; /* OID of collation, or InvalidOid if none */ - CoercionForm coerceformat; /* how to display this node */ - int location; /* token location, or -1 if unknown */ + /* output typmod (also element typmod) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm coerceformat pg_node_attr(query_jumble_ignore); + ParseLoc location; /* token location, or -1 if unknown */ } ArrayCoerceExpr; /* ---------------- @@ -876,8 +1298,9 @@ typedef struct ConvertRowtypeExpr Expr *arg; /* input expression */ Oid resulttype; /* output type (always a composite type) */ /* Like RowExpr, we deliberately omit a typmod and collation here */ - CoercionForm convertformat; /* how to display this node */ - int location; /* token location, or -1 if unknown */ + /* how to display this node */ + CoercionForm convertformat pg_node_attr(query_jumble_ignore); + ParseLoc location; /* token location, or -1 if unknown */ } ConvertRowtypeExpr; /*---------- @@ -892,7 +1315,7 @@ typedef struct CollateExpr Expr xpr; Expr *arg; /* input expression */ Oid collOid; /* collation's OID */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } CollateExpr; /*---------- @@ -920,12 +1343,14 @@ typedef struct CollateExpr typedef struct CaseExpr { Expr xpr; - Oid casetype; /* type of expression result */ - Oid casecollid; /* OID of collation, or InvalidOid if none */ + /* type of expression result */ + Oid casetype pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid casecollid pg_node_attr(query_jumble_ignore); Expr *arg; /* implicit equality comparison argument */ List *args; /* the arguments (list of WHEN clauses) */ Expr *defresult; /* the default result (ELSE clause) */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } CaseExpr; /* @@ -936,7 +1361,7 @@ typedef struct CaseWhen Expr xpr; Expr *expr; /* condition expression */ Expr *result; /* substitution result */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } CaseWhen; /* @@ -944,15 +1369,31 @@ 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(). + * * Placeholder for intermediate results in some SQL/JSON expression nodes, + * such as JsonConstructorExpr. + * + * 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 { Expr xpr; Oid typeId; /* type for substituted value */ - int32 typeMod; /* typemod for substituted value */ - Oid collation; /* collation for the substituted value */ + /* typemod for substituted value */ + int32 typeMod pg_node_attr(query_jumble_ignore); + /* collation for the substituted value */ + Oid collation pg_node_attr(query_jumble_ignore); } CaseTestExpr; /* @@ -966,12 +1407,22 @@ typedef struct CaseTestExpr typedef struct ArrayExpr { Expr xpr; - Oid array_typeid; /* type of expression result */ - Oid array_collid; /* OID of collation, or InvalidOid if none */ - Oid element_typeid; /* common type of array elements */ - List *elements; /* the array elements or sub-arrays */ - bool multidims; /* true if elements are sub-arrays */ - int location; /* token location, or -1 if unknown */ + /* type of expression result */ + Oid array_typeid pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid array_collid pg_node_attr(query_jumble_ignore); + /* common type of array elements */ + Oid element_typeid pg_node_attr(query_jumble_ignore); + /* the array elements or sub-arrays */ + List *elements pg_node_attr(query_jumble_squash); + /* true if elements are sub-arrays */ + bool multidims pg_node_attr(query_jumble_ignore); + /* location of the start of the elements list */ + ParseLoc list_start; + /* location of the end of the elements list */ + ParseLoc list_end; + /* token location, or -1 if unknown */ + ParseLoc location; } ArrayExpr; /* @@ -987,21 +1438,21 @@ typedef struct ArrayExpr * than vice versa.) It is important not to assume that length(args) is * the same as the number of columns logically present in the rowtype. * - * colnames provides field names in cases where the names can't easily be - * obtained otherwise. Names *must* be provided if row_typeid is RECORDOID. - * If row_typeid identifies a known composite type, colnames can be NIL to - * indicate the type's cataloged field names apply. Note that colnames can - * be non-NIL even for a composite type, and typically is when the RowExpr - * was created by expanding a whole-row Var. This is so that we can retain - * the column alias names of the RTE that the Var referenced (which would - * otherwise be very difficult to extract from the parsetree). Like the - * args list, colnames is one-for-one with physical fields of the rowtype. + * colnames provides field names if the ROW() result is of type RECORD. + * Names *must* be provided if row_typeid is RECORDOID; but if it is a + * named composite type, colnames will be ignored in favor of using the + * type's cataloged field names, so colnames should be NIL. Like the + * args list, colnames is defined to be one-for-one with physical fields + * of the rowtype (although dropped columns shouldn't appear in the + * RECORD case, so this fine point is currently moot). */ typedef struct RowExpr { Expr xpr; List *args; /* the fields */ - Oid row_typeid; /* RECORDOID or a composite type's ID */ + + /* RECORDOID or a composite type's ID */ + Oid row_typeid pg_node_attr(query_jumble_ignore); /* * row_typeid cannot be a domain over composite, only plain composite. To @@ -1015,11 +1466,44 @@ typedef struct RowExpr * We don't need to store a collation either. The result type is * necessarily composite, and composite types never have a collation. */ - CoercionForm row_format; /* how to display this node */ - List *colnames; /* list of String, or NIL */ - int location; /* token location, or -1 if unknown */ + + /* how to display this node */ + CoercionForm row_format pg_node_attr(query_jumble_ignore); + + /* list of String, or NIL */ + List *colnames pg_node_attr(query_jumble_ignore); + + ParseLoc location; /* token location, or -1 if unknown */ } RowExpr; +/* + * CompareType - fundamental semantics of certain operators + * + * These enum symbols represent the fundamental semantics of certain operators + * that the system needs to have some hardcoded knowledge about. (For + * example, RowCompareExpr needs to know which operators can be determined to + * act like =, <>, <, etc.) Index access methods map (some of) strategy + * numbers to these values so that the system can know about the meaning of + * (some of) the operators without needing hardcoded knowledge of index AM's + * strategy numbering. + * + * XXX Currently, this mapping is not fully developed and most values are + * chosen to match btree strategy numbers, which is not going to work very + * well for other access methods. + */ +typedef enum CompareType +{ + COMPARE_INVALID = 0, + COMPARE_LT = 1, /* BTLessStrategyNumber */ + COMPARE_LE = 2, /* BTLessEqualStrategyNumber */ + COMPARE_EQ = 3, /* BTEqualStrategyNumber */ + COMPARE_GE = 4, /* BTGreaterEqualStrategyNumber */ + COMPARE_GT = 5, /* BTGreaterStrategyNumber */ + COMPARE_NE = 6, /* no such btree strategy */ + COMPARE_OVERLAP, + COMPARE_CONTAINED_BY, +} CompareType; + /* * RowCompareExpr - row-wise comparison, such as (a, b) <= (1, 2) * @@ -1031,29 +1515,24 @@ typedef struct RowExpr * * A RowCompareExpr node is only generated for the < <= > >= cases; * the = and <> cases are translated to simple AND or OR combinations - * of the pairwise comparisons. However, we include = and <> in the - * RowCompareType enum for the convenience of parser logic. + * of the pairwise comparisons. */ -typedef enum RowCompareType -{ - /* Values of this enum are chosen to match btree strategy numbers */ - ROWCOMPARE_LT = 1, /* BTLessStrategyNumber */ - ROWCOMPARE_LE = 2, /* BTLessEqualStrategyNumber */ - ROWCOMPARE_EQ = 3, /* BTEqualStrategyNumber */ - ROWCOMPARE_GE = 4, /* BTGreaterEqualStrategyNumber */ - ROWCOMPARE_GT = 5, /* BTGreaterStrategyNumber */ - ROWCOMPARE_NE = 6 /* no such btree strategy */ -} RowCompareType; - typedef struct RowCompareExpr { Expr xpr; - RowCompareType rctype; /* LT LE GE or GT, never EQ or NE */ - List *opnos; /* OID list of pairwise comparison ops */ - List *opfamilies; /* OID list of containing operator families */ - List *inputcollids; /* OID list of collations for comparisons */ - List *largs; /* the left-hand input arguments */ - List *rargs; /* the right-hand input arguments */ + + /* LT LE GE or GT, never EQ or NE */ + CompareType cmptype; + /* OID list of pairwise comparison ops */ + List *opnos pg_node_attr(query_jumble_ignore); + /* OID list of containing operator families */ + List *opfamilies pg_node_attr(query_jumble_ignore); + /* OID list of collations for comparisons */ + List *inputcollids pg_node_attr(query_jumble_ignore); + /* the left-hand input arguments */ + List *largs; + /* the right-hand input arguments */ + List *rargs; } RowCompareExpr; /* @@ -1062,10 +1541,14 @@ typedef struct RowCompareExpr typedef struct CoalesceExpr { Expr xpr; - Oid coalescetype; /* type of expression result */ - Oid coalescecollid; /* OID of collation, or InvalidOid if none */ - List *args; /* the arguments */ - int location; /* token location, or -1 if unknown */ + /* type of expression result */ + Oid coalescetype pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid coalescecollid pg_node_attr(query_jumble_ignore); + /* the arguments */ + List *args; + /* token location, or -1 if unknown */ + ParseLoc location; } CoalesceExpr; /* @@ -1080,12 +1563,18 @@ typedef enum MinMaxOp typedef struct MinMaxExpr { Expr xpr; - Oid minmaxtype; /* common type of arguments and result */ - Oid minmaxcollid; /* OID of collation of result */ - Oid inputcollid; /* OID of collation that function should use */ - MinMaxOp op; /* function to execute */ - List *args; /* the arguments */ - int location; /* token location, or -1 if unknown */ + /* common type of arguments and result */ + Oid minmaxtype pg_node_attr(query_jumble_ignore); + /* OID of collation of result */ + Oid minmaxcollid pg_node_attr(query_jumble_ignore); + /* OID of collation that function should use */ + Oid inputcollid pg_node_attr(query_jumble_ignore); + /* function to execute */ + MinMaxOp op; + /* the arguments */ + List *args; + /* token location, or -1 if unknown */ + ParseLoc location; } MinMaxExpr; /* @@ -1115,16 +1604,21 @@ typedef enum SQLValueFunctionOp SVFOP_USER, SVFOP_SESSION_USER, SVFOP_CURRENT_CATALOG, - SVFOP_CURRENT_SCHEMA + SVFOP_CURRENT_SCHEMA, } SQLValueFunctionOp; typedef struct SQLValueFunction { Expr xpr; SQLValueFunctionOp op; /* which function this is */ - Oid type; /* result type/typmod */ + + /* + * Result type/typmod. Type is fully determined by "op", so no need to + * include this Oid in the query jumbling. + */ + Oid type pg_node_attr(query_jumble_ignore); int32 typmod; - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } SQLValueFunction; /* @@ -1146,30 +1640,351 @@ typedef enum XmlExprOp IS_XMLPARSE, /* XMLPARSE(text, is_doc, preserve_ws) */ IS_XMLPI, /* XMLPI(name [, args]) */ IS_XMLROOT, /* XMLROOT(xml, version, standalone) */ - IS_XMLSERIALIZE, /* XMLSERIALIZE(is_document, xmlval) */ - IS_DOCUMENT /* xmlval IS DOCUMENT */ + IS_XMLSERIALIZE, /* XMLSERIALIZE(is_document, xmlval, indent) */ + IS_DOCUMENT, /* xmlval IS DOCUMENT */ } XmlExprOp; -typedef enum +typedef enum XmlOptionType { XMLOPTION_DOCUMENT, - XMLOPTION_CONTENT + XMLOPTION_CONTENT, } XmlOptionType; typedef struct XmlExpr { Expr xpr; - XmlExprOp op; /* xml function ID */ - char *name; /* name in xml(NAME foo ...) syntaxes */ - List *named_args; /* non-XML expressions for xml_attributes */ - List *arg_names; /* parallel list of Value strings */ - List *args; /* list of expressions */ - XmlOptionType xmloption; /* DOCUMENT or CONTENT */ - Oid type; /* target type/typmod for XMLSERIALIZE */ - int32 typmod; - int location; /* token location, or -1 if unknown */ + /* xml function ID */ + XmlExprOp op; + /* name in xml(NAME foo ...) syntaxes */ + char *name pg_node_attr(query_jumble_ignore); + /* non-XML expressions for xml_attributes */ + List *named_args; + /* parallel list of String values */ + List *arg_names pg_node_attr(query_jumble_ignore); + /* list of expressions */ + List *args; + /* DOCUMENT or CONTENT */ + XmlOptionType xmloption pg_node_attr(query_jumble_ignore); + /* INDENT option for XMLSERIALIZE */ + bool indent; + /* target type/typmod for XMLSERIALIZE */ + Oid type pg_node_attr(query_jumble_ignore); + int32 typmod pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + ParseLoc location; } XmlExpr; +/* + * JsonEncoding - + * representation of JSON ENCODING clause + */ +typedef enum JsonEncoding +{ + JS_ENC_DEFAULT, /* unspecified */ + JS_ENC_UTF8, + JS_ENC_UTF16, + JS_ENC_UTF32, +} JsonEncoding; + +/* + * JsonFormatType - + * enumeration of JSON formats used in JSON FORMAT clause + */ +typedef enum JsonFormatType +{ + JS_FORMAT_DEFAULT, /* unspecified */ + JS_FORMAT_JSON, /* FORMAT JSON [ENCODING ...] */ + JS_FORMAT_JSONB, /* implicit internal format for RETURNING + * jsonb */ +} JsonFormatType; + +/* + * JsonFormat - + * representation of JSON FORMAT clause + */ +typedef struct JsonFormat +{ + NodeTag type; + JsonFormatType format_type; /* format type */ + JsonEncoding encoding; /* JSON encoding */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonFormat; + +/* + * JsonReturning - + * transformed representation of JSON RETURNING clause + */ +typedef struct JsonReturning +{ + NodeTag type; + JsonFormat *format; /* output JSON format */ + Oid typid; /* target type Oid */ + int32 typmod; /* target type modifier */ +} JsonReturning; + +/* + * JsonValueExpr - + * representation of JSON value expression (expr [FORMAT JsonFormat]) + * + * raw_expr is the user-specified value, while formatted_expr is the value + * obtained by coercing raw_expr to the type required by either the FORMAT + * clause or an enclosing node's RETURNING clause. + * + * When deparsing a JsonValueExpr, get_rule_expr() prints raw_expr. However, + * during the evaluation of a JsonValueExpr, the value of formatted_expr + * takes precedence over that of raw_expr. + */ +typedef struct JsonValueExpr +{ + NodeTag type; + Expr *raw_expr; /* user-specified expression */ + Expr *formatted_expr; /* coerced formatted expression */ + JsonFormat *format; /* FORMAT clause, if specified */ +} JsonValueExpr; + +typedef enum JsonConstructorType +{ + JSCTOR_JSON_OBJECT = 1, + JSCTOR_JSON_ARRAY = 2, + JSCTOR_JSON_OBJECTAGG = 3, + JSCTOR_JSON_ARRAYAGG = 4, + JSCTOR_JSON_PARSE = 5, + JSCTOR_JSON_SCALAR = 6, + JSCTOR_JSON_SERIALIZE = 7, +} JsonConstructorType; + +/* + * JsonConstructorExpr - + * wrapper over FuncExpr/Aggref/WindowFunc for SQL/JSON constructors + */ +typedef struct JsonConstructorExpr +{ + Expr xpr; + JsonConstructorType type; /* constructor type */ + List *args; + Expr *func; /* underlying json[b]_xxx() function call */ + Expr *coercion; /* coercion to RETURNING type */ + JsonReturning *returning; /* RETURNING clause */ + bool absent_on_null; /* ABSENT ON NULL? */ + bool unique; /* WITH UNIQUE KEYS? (JSON_OBJECT[AGG] only) */ + ParseLoc location; +} JsonConstructorExpr; + +/* + * JsonValueType - + * representation of JSON item type in IS JSON predicate + */ +typedef enum JsonValueType +{ + JS_TYPE_ANY, /* IS JSON [VALUE] */ + JS_TYPE_OBJECT, /* IS JSON OBJECT */ + JS_TYPE_ARRAY, /* IS JSON ARRAY */ + JS_TYPE_SCALAR, /* IS JSON SCALAR */ +} JsonValueType; + +/* + * JsonIsPredicate - + * representation of IS JSON predicate + */ +typedef struct JsonIsPredicate +{ + NodeTag type; + Node *expr; /* subject expression */ + JsonFormat *format; /* FORMAT clause, if specified */ + JsonValueType item_type; /* JSON item type */ + bool unique_keys; /* check key uniqueness? */ + ParseLoc location; /* token location, or -1 if unknown */ +} JsonIsPredicate; + +/* Nodes used in SQL/JSON query functions */ + +/* + * JsonWrapper - + * representation of WRAPPER clause for JSON_QUERY() + */ +typedef enum JsonWrapper +{ + JSW_UNSPEC, + JSW_NONE, + JSW_CONDITIONAL, + JSW_UNCONDITIONAL, +} JsonWrapper; + +/* + * JsonBehaviorType - + * enumeration of behavior types used in SQL/JSON ON ERROR/EMPTY clauses + * + * If enum members are reordered, get_json_behavior() from ruleutils.c + * must be updated accordingly. + */ +typedef enum JsonBehaviorType +{ + JSON_BEHAVIOR_NULL = 0, + JSON_BEHAVIOR_ERROR, + JSON_BEHAVIOR_EMPTY, + JSON_BEHAVIOR_TRUE, + JSON_BEHAVIOR_FALSE, + JSON_BEHAVIOR_UNKNOWN, + JSON_BEHAVIOR_EMPTY_ARRAY, + JSON_BEHAVIOR_EMPTY_OBJECT, + JSON_BEHAVIOR_DEFAULT, +} JsonBehaviorType; + +/* + * JsonBehavior + * Specifications for ON ERROR / ON EMPTY behaviors of SQL/JSON + * query functions specified by a JsonExpr + * + * 'expr' is the expression to emit when a given behavior (EMPTY or ERROR) + * occurs on evaluating the SQL/JSON query function. 'coerce' is set to true + * if 'expr' isn't already of the expected target type given by + * JsonExpr.returning. + */ +typedef struct JsonBehavior +{ + NodeTag type; + + JsonBehaviorType btype; + Node *expr; + bool coerce; + ParseLoc location; /* token location, or -1 if unknown */ +} JsonBehavior; + +/* + * JsonExprOp - + * enumeration of SQL/JSON query function types + */ +typedef enum JsonExprOp +{ + JSON_EXISTS_OP, /* JSON_EXISTS() */ + JSON_QUERY_OP, /* JSON_QUERY() */ + JSON_VALUE_OP, /* JSON_VALUE() */ + JSON_TABLE_OP, /* JSON_TABLE() */ +} JsonExprOp; + +/* + * JsonExpr - + * Transformed representation of JSON_VALUE(), JSON_QUERY(), and + * JSON_EXISTS() + */ +typedef struct JsonExpr +{ + Expr xpr; + + JsonExprOp op; + + char *column_name; /* JSON_TABLE() column name or NULL if this is + * not for a JSON_TABLE() */ + + /* jsonb-valued expression to query */ + Node *formatted_expr; + + /* Format of the above expression needed by ruleutils.c */ + JsonFormat *format; + + /* jsonpath-valued expression containing the query pattern */ + Node *path_spec; + + /* Expected type/format of the output. */ + JsonReturning *returning; + + /* Information about the PASSING argument expressions */ + List *passing_names; + List *passing_values; + + /* User-specified or default ON EMPTY and ON ERROR behaviors */ + JsonBehavior *on_empty; + JsonBehavior *on_error; + + /* + * Information about converting the result of jsonpath functions + * JsonPathQuery() and JsonPathValue() to the RETURNING type. + */ + bool use_io_coercion; + bool use_json_coercion; + + /* WRAPPER specification for JSON_QUERY */ + JsonWrapper wrapper; + + /* KEEP or OMIT QUOTES for singleton scalars returned by JSON_QUERY() */ + bool omit_quotes; + + /* JsonExpr's collation. */ + Oid collation; + + /* Original JsonFuncExpr's location */ + ParseLoc location; +} JsonExpr; + +/* + * JsonTablePath + * A JSON path expression to be computed as part of evaluating + * a JSON_TABLE plan node + */ +typedef struct JsonTablePath +{ + NodeTag type; + + Const *value; + char *name; +} JsonTablePath; + +/* + * JsonTablePlan - + * Abstract class to represent different types of JSON_TABLE "plans". + * A plan is used to generate a "row pattern" value by evaluating a JSON + * path expression against an input JSON document, which is then used for + * populating JSON_TABLE() columns + */ +typedef struct JsonTablePlan +{ + pg_node_attr(abstract) + + NodeTag type; +} JsonTablePlan; + +/* + * JSON_TABLE plan to evaluate a JSON path expression and NESTED paths, if + * any. + */ +typedef struct JsonTablePathScan +{ + JsonTablePlan plan; + + /* JSON path to evaluate */ + JsonTablePath *path; + + /* + * ERROR/EMPTY ON ERROR behavior; only significant in the plan for the + * top-level path. + */ + bool errorOnError; + + /* Plan(s) for nested columns, if any. */ + JsonTablePlan *child; + + /* + * 0-based index in TableFunc.colvalexprs of the 1st and the last column + * covered by this plan. Both are -1 if all columns are nested and thus + * computed by the child plan(s). + */ + int colMin; + int colMax; +} JsonTablePathScan; + +/* + * JsonTableSiblingJoin - + * Plan to join rows of sibling NESTED COLUMNS clauses in the same parent + * COLUMNS clause + */ +typedef struct JsonTableSiblingJoin +{ + JsonTablePlan plan; + + JsonTablePlan *lplan; + JsonTablePlan *rplan; +} JsonTableSiblingJoin; + /* ---------------- * NullTest * @@ -1199,8 +2014,9 @@ typedef struct NullTest Expr xpr; Expr *arg; /* input expression */ NullTestType nulltesttype; /* IS NULL, IS NOT NULL */ - bool argisrow; /* T to perform field-by-field null checks */ - int location; /* token location, or -1 if unknown */ + /* T to perform field-by-field null checks */ + bool argisrow pg_node_attr(query_jumble_ignore); + ParseLoc location; /* token location, or -1 if unknown */ } NullTest; /* @@ -1222,9 +2038,38 @@ typedef struct BooleanTest Expr xpr; Expr *arg; /* input expression */ BoolTestType booltesttype; /* test type */ - int location; /* token location, or -1 if unknown */ + ParseLoc location; /* token location, or -1 if unknown */ } BooleanTest; + +/* + * MergeAction + * + * Transformed representation of a WHEN clause in a MERGE statement + */ + +typedef enum MergeMatchKind +{ + MERGE_WHEN_MATCHED, + MERGE_WHEN_NOT_MATCHED_BY_SOURCE, + MERGE_WHEN_NOT_MATCHED_BY_TARGET +} MergeMatchKind; + +#define NUM_MERGE_MATCH_KINDS (MERGE_WHEN_NOT_MATCHED_BY_TARGET + 1) + +typedef struct MergeAction +{ + NodeTag type; + MergeMatchKind matchKind; /* MATCHED/NOT MATCHED BY SOURCE/TARGET */ + CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ + /* OVERRIDING clause */ + OverridingKind override pg_node_attr(query_jumble_ignore); + Node *qual; /* transformed WHEN conditions */ + List *targetList; /* the target list (of TargetEntry) */ + /* target attribute numbers of an UPDATE */ + List *updateColnos pg_node_attr(query_jumble_ignore); +} MergeAction; + /* * CoerceToDomain * @@ -1239,10 +2084,13 @@ typedef struct CoerceToDomain Expr xpr; Expr *arg; /* input expression */ Oid resulttype; /* domain type ID (result type) */ - int32 resulttypmod; /* output typmod (currently always -1) */ - Oid resultcollid; /* OID of collation, or InvalidOid if none */ - CoercionForm coercionformat; /* how to display this node */ - int location; /* token location, or -1 if unknown */ + /* output typmod (currently always -1) */ + int32 resulttypmod pg_node_attr(query_jumble_ignore); + /* OID of collation, or InvalidOid if none */ + Oid resultcollid pg_node_attr(query_jumble_ignore); + /* how to display this node */ + CoercionForm coercionformat pg_node_attr(query_jumble_ignore); + ParseLoc location; /* token location, or -1 if unknown */ } CoerceToDomain; /* @@ -1257,10 +2105,14 @@ typedef struct CoerceToDomain typedef struct CoerceToDomainValue { Expr xpr; - Oid typeId; /* type for substituted value */ - int32 typeMod; /* typemod for substituted value */ - Oid collation; /* collation for the substituted value */ - int location; /* token location, or -1 if unknown */ + /* type for substituted value */ + Oid typeId; + /* typemod for substituted value */ + int32 typeMod pg_node_attr(query_jumble_ignore); + /* collation for the substituted value */ + Oid collation pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + ParseLoc location; } CoerceToDomainValue; /* @@ -1273,10 +2125,14 @@ typedef struct CoerceToDomainValue typedef struct SetToDefault { Expr xpr; - Oid typeId; /* type for substituted value */ - int32 typeMod; /* typemod for substituted value */ - Oid collation; /* collation for the substituted value */ - int location; /* token location, or -1 if unknown */ + /* type for substituted value */ + Oid typeId; + /* typemod for substituted value */ + int32 typeMod pg_node_attr(query_jumble_ignore); + /* collation for the substituted value */ + Oid collation pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + ParseLoc location; } SetToDefault; /* @@ -1286,6 +2142,7 @@ typedef struct SetToDefault * of the target relation being constrained; this aids placing the expression * correctly during planning. We can assume however that its "levelsup" is * always zero, due to the syntactic constraints on where it can appear. + * Also, cvarno will always be a true RT index, never INNER_VAR etc. * * The referenced cursor can be represented either as a hardwired string * or as a reference to a run-time parameter of type REFCURSOR. The latter @@ -1328,6 +2185,30 @@ typedef struct InferenceElem Oid inferopclass; /* OID of att opclass, or InvalidOid */ } InferenceElem; +/* + * ReturningExpr - return OLD/NEW.(expression) in RETURNING list + * + * This is used when updating an auto-updatable view and returning a view + * column that is not simply a Var referring to the base relation. In such + * cases, OLD/NEW.viewcol can expand to an arbitrary expression, but the + * result is required to be NULL if the OLD/NEW row doesn't exist. To handle + * this, the rewriter wraps the expanded expression in a ReturningExpr, which + * is equivalent to "CASE WHEN (OLD/NEW row exists) THEN (expr) ELSE NULL". + * + * A similar situation can arise when rewriting the RETURNING clause of a + * rule, which may also contain arbitrary expressions. + * + * ReturningExpr nodes never appear in a parsed Query --- they are only ever + * inserted by the rewriter and the planner. + */ +typedef struct ReturningExpr +{ + Expr xpr; + int retlevelsup; /* > 0 if it belongs to outer query */ + bool retold; /* true for OLD, false for NEW */ + Expr *retexpr; /* expression to be returned */ +} ReturningExpr; + /*-------------------- * TargetEntry - * a target entry (used in query target lists) @@ -1343,13 +2224,14 @@ typedef struct InferenceElem * column for the item; so there may be missing or out-of-order resnos. * It is even legal to have duplicated resnos; consider * UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ... - * The two meanings come together in the executor, because the planner - * transforms INSERT/UPDATE tlists into a normalized form with exactly - * one entry for each column of the destination table. Before that's - * happened, however, it is risky to assume that resno == position. - * Generally get_tle_by_resno() should be used rather than list_nth() - * to fetch tlist entries by resno, and only in SELECT should you assume - * that resno is a unique identifier. + * In an INSERT, the rewriter and planner will normalize the tlist by + * reordering it into physical column order and filling in default values + * for any columns not assigned values by the original query. In an UPDATE, + * after the rewriter merges multiple assignments for the same column, the + * planner extracts the target-column numbers into a separate "update_colnos" + * list, and then renumbers the tlist elements serially. Thus, tlist resnos + * match ordinal position in all tlists seen by the executor; but it is wrong + * to assume that before planning has happened. * * resname is required to represent the correct column name in non-resjunk * entries of top-level SELECT targetlists, since it will be used as the @@ -1385,15 +2267,20 @@ typedef struct InferenceElem typedef struct TargetEntry { Expr xpr; - Expr *expr; /* expression to evaluate */ - AttrNumber resno; /* attribute number (see notes above) */ - char *resname; /* name of the column (could be NULL) */ - Index ressortgroupref; /* nonzero if referenced by a sort/group - * clause */ - Oid resorigtbl; /* OID of column's source table */ - AttrNumber resorigcol; /* column's number in source table */ - bool resjunk; /* set to true to eliminate the attribute from - * final target list */ + /* expression to evaluate */ + Expr *expr; + /* attribute number (see notes above) */ + AttrNumber resno; + /* name of the column (could be NULL) */ + char *resname pg_node_attr(query_jumble_ignore); + /* nonzero if referenced by a sort/group clause */ + Index ressortgroupref; + /* OID of column's source table */ + Oid resorigtbl pg_node_attr(query_jumble_ignore); + /* column's number in source table */ + AttrNumber resorigcol pg_node_attr(query_jumble_ignore); + /* set to true to eliminate the attribute from final target list */ + bool resjunk pg_node_attr(query_jumble_ignore); } TargetEntry; @@ -1456,6 +2343,11 @@ typedef struct RangeTblRef * alias has a critical impact on semantics, because a join with an alias * restricts visibility of the tables/columns inside it. * + * join_using_alias is an Alias node representing the join correlation + * name that SQL:2016 and later allow to be attached to JOIN/USING. + * Its column alias list includes only the common column names from USING, + * and it does not restrict visibility of the join's input tables. + * * During parse analysis, an RTE is created for the Join, and its index * is filled into rtindex. This RTE is present mainly so that Vars can * be created that refer to the outputs of the join. The planner sometimes @@ -1470,10 +2362,16 @@ typedef struct JoinExpr bool isNatural; /* Natural join? Will need to shape table */ Node *larg; /* left subtree */ Node *rarg; /* right subtree */ - List *usingClause; /* USING clause, if any (list of String) */ - Node *quals; /* qualifiers on join, if any */ - Alias *alias; /* user-written alias clause, if any */ - int rtindex; /* RT index assigned for join, or 0 */ + /* USING clause, if any (list of String) */ + List *usingClause pg_node_attr(query_jumble_ignore); + /* alias attached to USING clause, if any */ + Alias *join_using_alias pg_node_attr(query_jumble_ignore); + /* qualifiers on join, if any */ + Node *quals; + /* user-written alias clause, if any */ + Alias *alias pg_node_attr(query_jumble_ignore); + /* RT index assigned for join, or 0 */ + int rtindex; } JoinExpr; /*---------- @@ -1513,7 +2411,7 @@ typedef struct OnConflictExpr Oid constraint; /* pg_constraint OID for arbiter */ /* ON CONFLICT UPDATE */ - List *onConflictSet; /* List of ON CONFLICT SET TargetEntrys */ + List *onConflictSet; /* List of ON CONFLICT SET TargetEntry nodes */ Node *onConflictWhere; /* qualifiers to restrict UPDATE to */ int exclRelIndex; /* RT index of 'excluded' relation */ List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */ diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h index 91f56362e..69deaeb48 100644 --- a/src/include/parser/scanner.h +++ b/src/include/parser/scanner.h @@ -8,8 +8,8 @@ * higher-level API provided by parser.h. * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scanner.h @@ -21,6 +21,7 @@ #define SCANNER_H #include "keywords.h" +#include "utils/elog.h" /* * The scanner returns extra data about scanned tokens in this union type. @@ -49,7 +50,7 @@ typedef union core_YYSTYPE * However, those are not defined in this file, because bison insists on * defining them for itself. The token codes used by the core scanner are * the ASCII characters plus these: - * %token IDENT FCONST SCONST BCONST XCONST Op + * %token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op * %token ICONST PARAM * %token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER * %token LESS_EQUALS GREATER_EQUALS NOT_EQUALS @@ -74,10 +75,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 @@ -100,8 +101,13 @@ typedef struct core_yy_extra_type int literallen; /* actual current string length */ int literalalloc; /* current allocated buffer size */ + /* + * Random assorted scanner state. + */ + int state_before_str_stop; /* start cond. before end quote */ int xcdepth; /* depth of nesting in slash-star comments */ char *dolqstart; /* current $foo$ quote start string */ + YYLTYPE save_yylloc; /* one-element stack for PUSH_YYLLOC() */ /* first part of UTF16 surrogate pair for Unicode escapes */ int32 utf16_first_part; @@ -116,16 +122,32 @@ typedef struct core_yy_extra_type */ typedef void *core_yyscan_t; +/* Support for scanner_errposition_callback function */ +typedef struct ScannerCallbackState +{ + core_yyscan_t yyscanner; + int location; + ErrorContextCallback errcallback; +} ScannerCallbackState; + + +/* 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); + int slen, + 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 *yylval_param, YYLTYPE * yylloc_param, + 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(); +extern void setup_scanner_errposition_callback(ScannerCallbackState *scbstate, + core_yyscan_t yyscanner, + int location); +extern void cancel_scanner_errposition_callback(ScannerCallbackState *scbstate); +pg_noreturn extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner); #endif /* SCANNER_H */ diff --git a/src/include/parser/scansup.h b/src/include/parser/scansup.h index f73862ca3..ef5e618be 100644 --- a/src/include/parser/scansup.h +++ b/src/include/parser/scansup.h @@ -1,11 +1,10 @@ /*------------------------------------------------------------------------- * * scansup.h - * scanner support routines. used by both the bootstrap lexer - * as well as the normal lexer + * scanner support routines used by the core lexer * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scansup.h @@ -16,13 +15,11 @@ #ifndef SCANSUP_H #define SCANSUP_H -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/parser/stringinfo.h b/src/include/parser/stringinfo.h index ec4291636..1897c96bb 100644 --- a/src/include/parser/stringinfo.h +++ b/src/include/parser/stringinfo.h @@ -3,12 +3,13 @@ * stringinfo.h * Declarations/definitions for "StringInfo" functions. * - * StringInfo provides an indefinitely-extensible string data type. - * It can be used to buffer either ordinary C strings (null-terminated text) - * or arbitrary binary data. All storage is allocated with palloc(). + * StringInfo provides an extensible string data type (currently limited to a + * length of 1GB). It can be used to buffer either ordinary C strings + * (null-terminated text) or arbitrary binary data. All storage is allocated + * with palloc() (falling back to malloc in frontend code). * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/lib/stringinfo.h @@ -68,17 +69,27 @@ extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); /*------------------------- * StringInfoData holds information about an extensible string. - * data is the current buffer for the string (allocated with palloc). - * len is the current string length. There is guaranteed to be - * a terminating '\0' at data[len], although this is not very - * useful when the string holds binary data rather than text. + * data is the current buffer for the string. + * len is the current string length. Except in the case of read-only + * strings described below, there is guaranteed to be a + * terminating '\0' at data[len]. * maxlen is the allocated size in bytes of 'data', i.e. the maximum * string size (including the terminating '\0' char) that we can * currently store in 'data' without having to reallocate - * more space. We must always have maxlen > len. - * cursor is initialized to zero by makeStringInfo or initStringInfo, - * but is not otherwise touched by the stringinfo.c routines. - * Some routines use it to scan through a StringInfo. + * more space. We must always have maxlen > len, except + * in the read-only case described below. + * cursor is initialized to zero by makeStringInfo, initStringInfo, + * initReadOnlyStringInfo and initStringInfoFromString but is not + * otherwise touched by the stringinfo.c routines. Some routines + * use it to scan through a StringInfo. + * + * As a special case, a StringInfoData can be initialized with a read-only + * string buffer. In this case "data" does not necessarily point at a + * palloc'd chunk, and management of the buffer storage is the caller's + * responsibility. maxlen is set to zero to indicate that this is the case. + * Read-only StringInfoDatas cannot be appended to or reset. + * Also, it is caller's option whether a read-only string buffer has a + * terminating '\0' or not. This depends on the intended usage. *------------------------- */ typedef struct StringInfoData @@ -93,19 +104,52 @@ typedef StringInfoData *StringInfo; /*------------------------ - * There are two ways to create a StringInfo object initially: + * There are six ways to create a StringInfo object initially: * * StringInfo stringptr = makeStringInfo(); * Both the StringInfoData and the data buffer are palloc'd. * + * StringInfo stringptr = makeStringInfoExt(initsize); + * Same as makeStringInfo except the data buffer is allocated + * with size 'initsize'. + * * StringInfoData string; * initStringInfo(&string); * The data buffer is palloc'd but the StringInfoData is just local. * This is the easiest approach for a StringInfo object that will * only live as long as the current routine. * + * StringInfoData string; + * initStringInfoExt(&string, initsize); + * Same as initStringInfo except the data buffer is allocated + * with size 'initsize'. + * + * StringInfoData string; + * initReadOnlyStringInfo(&string, existingbuf, len); + * The StringInfoData's data field is set to point directly to the + * existing buffer and the StringInfoData's len is set to the given len. + * The given buffer can point to memory that's not managed by palloc or + * is pointing partway through a palloc'd chunk. The maxlen field is set + * to 0. A read-only StringInfo cannot be appended to using any of the + * appendStringInfo functions or reset with resetStringInfo(). The given + * buffer can optionally omit the trailing NUL. + * + * StringInfoData string; + * initStringInfoFromString(&string, palloced_buf, len); + * The StringInfoData's data field is set to point directly to the given + * buffer and the StringInfoData's len is set to the given len. This + * method of initialization is useful when the buffer already exists. + * StringInfos initialized this way can be appended to using the + * appendStringInfo functions and reset with resetStringInfo(). The + * given buffer must be NUL-terminated. The palloc'd buffer is assumed + * to be len + 1 in size. + * * To destroy a StringInfo, pfree() the data buffer, and then pfree() the - * StringInfoData if it was palloc'd. There's no special support for this. + * StringInfoData if it was palloc'd. For StringInfos created with + * makeStringInfo(), destroyStringInfo() is provided for this purpose. + * However, if the StringInfo was initialized using initReadOnlyStringInfo() + * then the caller will need to consider if it is safe to pfree the data + * buffer. * * NOTE: some routines build up a string using StringInfo, and then * release the StringInfoData but return the data string itself to their @@ -114,12 +158,22 @@ typedef StringInfoData *StringInfo; *------------------------- */ +#define STRINGINFO_DEFAULT_SIZE 1024 /* default initial allocation size */ + /*------------------------ * makeStringInfo * Create an empty 'StringInfoData' & return a pointer to it. */ extern StringInfo makeStringInfo(void); +/*------------------------ + * makeStringInfoExt + * Create an empty 'StringInfoData' & return a pointer to it. + * The data buffer is allocated with size 'initsize'. + * The valid range for 'initsize' is 1 to MaxAllocSize. + */ +extern StringInfo makeStringInfoExt(int initsize); + /*------------------------ * initStringInfo * Initialize a StringInfoData struct (with previously undefined contents) @@ -127,6 +181,56 @@ extern StringInfo makeStringInfo(void); */ extern void initStringInfo(StringInfo str); +/*------------------------ + * initStringInfoExt + * Initialize a StringInfoData struct (with previously undefined contents) to + * describe an empty string. The data buffer is allocated with size + * 'initsize'. The valid range for 'initsize' is 1 to MaxAllocSize. + */ +extern void initStringInfoExt(StringInfo str, int initsize); + +/*------------------------ + * initReadOnlyStringInfo + * Initialize a StringInfoData struct from an existing string without copying + * the string. The caller is responsible for ensuring the given string + * remains valid as long as the StringInfoData does. Calls to this are used + * in performance critical locations where allocating a new buffer and copying + * would be too costly. Read-only StringInfoData's may not be appended to + * using any of the appendStringInfo functions or reset with + * resetStringInfo(). + * + * 'data' does not need to point directly to a palloc'd chunk of memory and may + * omit the NUL termination character at data[len]. + */ +static inline void +initReadOnlyStringInfo(StringInfo str, char *data, int len) +{ + str->data = data; + str->len = len; + str->maxlen = 0; /* read-only */ + str->cursor = 0; +} + +/*------------------------ + * initStringInfoFromString + * Initialize a StringInfoData struct from an existing string without copying + * the string. 'data' must be a valid palloc'd chunk of memory that can have + * repalloc() called should more space be required during a call to any of the + * appendStringInfo functions. + * + * 'data' must be NUL terminated at 'len' bytes. + */ +static inline void +initStringInfoFromString(StringInfo str, char *data, int len) +{ + Assert(data[len] == '\0'); + + str->data = data; + str->len = len; + str->maxlen = len + 1; + str->cursor = 0; +} + /*------------------------ * resetStringInfo * Clears the current content of the StringInfo, if any. The @@ -190,7 +294,7 @@ extern void appendStringInfoSpaces(StringInfo str, int count); * if necessary. */ extern void appendBinaryStringInfo(StringInfo str, - const char *data, int datalen); + const void *data, int datalen); /*------------------------ * appendBinaryStringInfoNT @@ -198,7 +302,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 void *data, int datalen); /*------------------------ * enlargeStringInfo @@ -206,4 +310,10 @@ extern void appendBinaryStringInfoNT(StringInfo str, */ extern void enlargeStringInfo(StringInfo str, int needed); +/*------------------------ + * destroyStringInfo + * Frees a StringInfo and its buffer (opposite of makeStringInfo()). + */ +extern void destroyStringInfo(StringInfo str); + #endif /* STRINGINFO_H */ diff --git a/src/include/parser/unicode_east_asian_fw_table.h b/src/include/parser/unicode_east_asian_fw_table.h new file mode 100644 index 000000000..db8bd0ad8 --- /dev/null +++ b/src/include/parser/unicode_east_asian_fw_table.h @@ -0,0 +1,126 @@ +/* generated by src/common/unicode/generate-unicode_east_asian_fw_table.pl, do not edit */ + +static const struct mbinterval east_asian_fw[] = { + {0x1100, 0x115F}, + {0x231A, 0x231B}, + {0x2329, 0x232A}, + {0x23E9, 0x23EC}, + {0x23F0, 0x23F0}, + {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, + {0x2614, 0x2615}, + {0x2630, 0x2637}, + {0x2648, 0x2653}, + {0x267F, 0x267F}, + {0x268A, 0x268F}, + {0x2693, 0x2693}, + {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, + {0x26BD, 0x26BE}, + {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, + {0x26D4, 0x26D4}, + {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, + {0x26F5, 0x26F5}, + {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, + {0x2705, 0x2705}, + {0x270A, 0x270B}, + {0x2728, 0x2728}, + {0x274C, 0x274C}, + {0x274E, 0x274E}, + {0x2753, 0x2755}, + {0x2757, 0x2757}, + {0x2795, 0x2797}, + {0x27B0, 0x27B0}, + {0x27BF, 0x27BF}, + {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, + {0x2B55, 0x2B55}, + {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, + {0x2F00, 0x2FD5}, + {0x2FF0, 0x303E}, + {0x3041, 0x3096}, + {0x3099, 0x30FF}, + {0x3105, 0x312F}, + {0x3131, 0x318E}, + {0x3190, 0x31E5}, + {0x31EF, 0x321E}, + {0x3220, 0x3247}, + {0x3250, 0xA48C}, + {0xA490, 0xA4C6}, + {0xA960, 0xA97C}, + {0xAC00, 0xD7A3}, + {0xF900, 0xFAFF}, + {0xFE10, 0xFE19}, + {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, + {0xFE68, 0xFE6B}, + {0xFF01, 0xFF60}, + {0xFFE0, 0xFFE6}, + {0x16FE0, 0x16FE4}, + {0x16FF0, 0x16FF1}, + {0x17000, 0x187F7}, + {0x18800, 0x18CD5}, + {0x18CFF, 0x18D08}, + {0x1AFF0, 0x1AFF3}, + {0x1AFF5, 0x1AFFB}, + {0x1AFFD, 0x1AFFE}, + {0x1B000, 0x1B122}, + {0x1B132, 0x1B132}, + {0x1B150, 0x1B152}, + {0x1B155, 0x1B155}, + {0x1B164, 0x1B167}, + {0x1B170, 0x1B2FB}, + {0x1D300, 0x1D356}, + {0x1D360, 0x1D376}, + {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, + {0x1F18E, 0x1F18E}, + {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, + {0x1F210, 0x1F23B}, + {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, + {0x1F260, 0x1F265}, + {0x1F300, 0x1F320}, + {0x1F32D, 0x1F335}, + {0x1F337, 0x1F37C}, + {0x1F37E, 0x1F393}, + {0x1F3A0, 0x1F3CA}, + {0x1F3CF, 0x1F3D3}, + {0x1F3E0, 0x1F3F0}, + {0x1F3F4, 0x1F3F4}, + {0x1F3F8, 0x1F43E}, + {0x1F440, 0x1F440}, + {0x1F442, 0x1F4FC}, + {0x1F4FF, 0x1F53D}, + {0x1F54B, 0x1F54E}, + {0x1F550, 0x1F567}, + {0x1F57A, 0x1F57A}, + {0x1F595, 0x1F596}, + {0x1F5A4, 0x1F5A4}, + {0x1F5FB, 0x1F64F}, + {0x1F680, 0x1F6C5}, + {0x1F6CC, 0x1F6CC}, + {0x1F6D0, 0x1F6D2}, + {0x1F6D5, 0x1F6D7}, + {0x1F6DC, 0x1F6DF}, + {0x1F6EB, 0x1F6EC}, + {0x1F6F4, 0x1F6FC}, + {0x1F7E0, 0x1F7EB}, + {0x1F7F0, 0x1F7F0}, + {0x1F90C, 0x1F93A}, + {0x1F93C, 0x1F945}, + {0x1F947, 0x1F9FF}, + {0x1FA70, 0x1FA7C}, + {0x1FA80, 0x1FA89}, + {0x1FA8F, 0x1FAC6}, + {0x1FACE, 0x1FADC}, + {0x1FADF, 0x1FAE9}, + {0x1FAF0, 0x1FAF8}, + {0x20000, 0x2FFFD}, + {0x30000, 0x3FFFD}, +}; diff --git a/src/include/parser/unicode_nonspacing_table.h b/src/include/parser/unicode_nonspacing_table.h new file mode 100644 index 000000000..d67f5b3f2 --- /dev/null +++ b/src/include/parser/unicode_nonspacing_table.h @@ -0,0 +1,338 @@ +/* generated by src/common/unicode/generate-unicode_nonspacing_table.pl, do not edit */ + +static const struct mbinterval nonspacing[] = { + {0x00AD, 0x00AD}, + {0x0300, 0x036F}, + {0x0483, 0x0489}, + {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, + {0x05C1, 0x05C2}, + {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, + {0x0600, 0x0605}, + {0x0610, 0x061A}, + {0x061C, 0x061C}, + {0x064B, 0x065F}, + {0x0670, 0x0670}, + {0x06D6, 0x06DD}, + {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, + {0x06EA, 0x06ED}, + {0x070F, 0x070F}, + {0x0711, 0x0711}, + {0x0730, 0x074A}, + {0x07A6, 0x07B0}, + {0x07EB, 0x07F3}, + {0x07FD, 0x07FD}, + {0x0816, 0x0819}, + {0x081B, 0x0823}, + {0x0825, 0x0827}, + {0x0829, 0x082D}, + {0x0859, 0x085B}, + {0x0890, 0x089F}, + {0x08CA, 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}, + {0x0C3C, 0x0C3C}, + {0x0C3E, 0x0C40}, + {0x0C46, 0x0C56}, + {0x0C62, 0x0C63}, + {0x0C81, 0x0C81}, + {0x0CBC, 0x0CBC}, + {0x0CBF, 0x0CBF}, + {0x0CC6, 0x0CC6}, + {0x0CCC, 0x0CCD}, + {0x0CE2, 0x0CE3}, + {0x0D00, 0x0D01}, + {0x0D3B, 0x0D3C}, + {0x0D41, 0x0D44}, + {0x0D4D, 0x0D4D}, + {0x0D62, 0x0D63}, + {0x0D81, 0x0D81}, + {0x0DCA, 0x0DCA}, + {0x0DD2, 0x0DD6}, + {0x0E31, 0x0E31}, + {0x0E34, 0x0E3A}, + {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, + {0x0EB4, 0x0EBC}, + {0x0EC8, 0x0ECE}, + {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, 0x1733}, + {0x1752, 0x1753}, + {0x1772, 0x1773}, + {0x17B4, 0x17B5}, + {0x17B7, 0x17BD}, + {0x17C6, 0x17C6}, + {0x17C9, 0x17D3}, + {0x17DD, 0x17DD}, + {0x180B, 0x180F}, + {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}, + {0x200B, 0x200F}, + {0x202A, 0x202E}, + {0x2060, 0x206F}, + {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}, + {0xA82C, 0xA82C}, + {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}, + {0xFEFF, 0xFEFF}, + {0xFFF9, 0xFFFB}, + {0x101FD, 0x101FD}, + {0x102E0, 0x102E0}, + {0x10376, 0x1037A}, + {0x10A01, 0x10A0F}, + {0x10A38, 0x10A3F}, + {0x10AE5, 0x10AE6}, + {0x10D24, 0x10D27}, + {0x10D69, 0x10D6D}, + {0x10EAB, 0x10EAC}, + {0x10EFC, 0x10EFF}, + {0x10F46, 0x10F50}, + {0x10F82, 0x10F85}, + {0x11001, 0x11001}, + {0x11038, 0x11046}, + {0x11070, 0x11070}, + {0x11073, 0x11074}, + {0x1107F, 0x11081}, + {0x110B3, 0x110B6}, + {0x110B9, 0x110BA}, + {0x110BD, 0x110BD}, + {0x110C2, 0x110CD}, + {0x11100, 0x11102}, + {0x11127, 0x1112B}, + {0x1112D, 0x11134}, + {0x11173, 0x11173}, + {0x11180, 0x11181}, + {0x111B6, 0x111BE}, + {0x111C9, 0x111CC}, + {0x111CF, 0x111CF}, + {0x1122F, 0x11231}, + {0x11234, 0x11234}, + {0x11236, 0x11237}, + {0x1123E, 0x1123E}, + {0x11241, 0x11241}, + {0x112DF, 0x112DF}, + {0x112E3, 0x112EA}, + {0x11300, 0x11301}, + {0x1133B, 0x1133C}, + {0x11340, 0x11340}, + {0x11366, 0x11374}, + {0x113BB, 0x113C0}, + {0x113CE, 0x113CE}, + {0x113D0, 0x113D0}, + {0x113D2, 0x113D2}, + {0x113E1, 0x113E2}, + {0x11438, 0x1143F}, + {0x11442, 0x11444}, + {0x11446, 0x11446}, + {0x1145E, 0x1145E}, + {0x114B3, 0x114B8}, + {0x114BA, 0x114BA}, + {0x114BF, 0x114C0}, + {0x114C2, 0x114C3}, + {0x115B2, 0x115B5}, + {0x115BC, 0x115BD}, + {0x115BF, 0x115C0}, + {0x115DC, 0x115DD}, + {0x11633, 0x1163A}, + {0x1163D, 0x1163D}, + {0x1163F, 0x11640}, + {0x116AB, 0x116AB}, + {0x116AD, 0x116AD}, + {0x116B0, 0x116B5}, + {0x116B7, 0x116B7}, + {0x1171D, 0x1171D}, + {0x1171F, 0x1171F}, + {0x11722, 0x11725}, + {0x11727, 0x1172B}, + {0x1182F, 0x11837}, + {0x11839, 0x1183A}, + {0x1193B, 0x1193C}, + {0x1193E, 0x1193E}, + {0x11943, 0x11943}, + {0x119D4, 0x119DB}, + {0x119E0, 0x119E0}, + {0x11A01, 0x11A0A}, + {0x11A33, 0x11A38}, + {0x11A3B, 0x11A3E}, + {0x11A47, 0x11A47}, + {0x11A51, 0x11A56}, + {0x11A59, 0x11A5B}, + {0x11A8A, 0x11A96}, + {0x11A98, 0x11A99}, + {0x11C30, 0x11C3D}, + {0x11C3F, 0x11C3F}, + {0x11C92, 0x11CA7}, + {0x11CAA, 0x11CB0}, + {0x11CB2, 0x11CB3}, + {0x11CB5, 0x11CB6}, + {0x11D31, 0x11D45}, + {0x11D47, 0x11D47}, + {0x11D90, 0x11D91}, + {0x11D95, 0x11D95}, + {0x11D97, 0x11D97}, + {0x11EF3, 0x11EF4}, + {0x11F00, 0x11F01}, + {0x11F36, 0x11F3A}, + {0x11F40, 0x11F40}, + {0x11F42, 0x11F42}, + {0x11F5A, 0x11F5A}, + {0x13430, 0x13440}, + {0x13447, 0x13455}, + {0x1611E, 0x16129}, + {0x1612D, 0x1612F}, + {0x16AF0, 0x16AF4}, + {0x16B30, 0x16B36}, + {0x16F4F, 0x16F4F}, + {0x16F8F, 0x16F92}, + {0x16FE4, 0x16FE4}, + {0x1BC9D, 0x1BC9E}, + {0x1BCA0, 0x1BCA3}, + {0x1CF00, 0x1CF46}, + {0x1D167, 0x1D169}, + {0x1D173, 0x1D182}, + {0x1D185, 0x1D18B}, + {0x1D1AA, 0x1D1AD}, + {0x1D242, 0x1D244}, + {0x1DA00, 0x1DA36}, + {0x1DA3B, 0x1DA6C}, + {0x1DA75, 0x1DA75}, + {0x1DA84, 0x1DA84}, + {0x1DA9B, 0x1DAAF}, + {0x1E000, 0x1E02A}, + {0x1E08F, 0x1E08F}, + {0x1E130, 0x1E136}, + {0x1E2AE, 0x1E2AE}, + {0x1E2EC, 0x1E2EF}, + {0x1E4EC, 0x1E4EF}, + {0x1E5EE, 0x1E5EF}, + {0x1E8D0, 0x1E8D6}, + {0x1E944, 0x1E94A}, + {0xE0001, 0xE01EF}, +}; diff --git a/src/include/parser/value.h b/src/include/parser/value.h index 39ee6beca..0734c4ea2 100644 --- a/src/include/parser/value.h +++ b/src/include/parser/value.h @@ -1,11 +1,11 @@ /*------------------------------------------------------------------------- * * value.h - * interface for Value nodes + * interface for value nodes * * - * Copyright (c) 2003-2018, PgPool Global Development Group - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2025, PgPool Global Development Group + * Copyright (c) 2003-2025, PostgreSQL Global Development Group * * src/include/nodes/value.h * @@ -17,46 +17,75 @@ #include "nodes.h" -/*---------------------- - * Value node +/* + * The node types Integer, Float, String, and BitString are used to represent + * literals in the lexer and are also used to pass constants around in the + * parser. One difference between these node types and, say, a plain int or + * char * is that the nodes can be put into a List. * - * The same Value struct is used for five node types: T_Integer, - * T_Float, T_String, T_BitString, T_Null. - * - * Integral values are actually represented by a machine integer, - * but both floats and strings are represented as strings. - * Using T_Float as the node type simply indicates that - * the contents of the string look like a valid numeric literal. - * - * (Before Postgres 7.0, we used a double to represent T_Float, - * but that creates loss-of-precision problems when the value is - * ultimately destined to be converted to NUMERIC. Since Value nodes - * are only used in the parsing process, not for runtime data, it's - * better to use the more general representation.) - * - * Note that an integer-looking string will get lexed as T_Float if - * the value is too large to fit in an 'int'. + * (There used to be a Value node, which encompassed all these different node types. Hence the name of this file.) + */ + +typedef struct Integer +{ + pg_node_attr(special_read_write) + + NodeTag type; + int ival; +} Integer; + +/* + * Float is internally represented as string. Using T_Float as the node type + * simply indicates that the contents of the string look like a valid numeric + * literal. The value might end up being converted to NUMERIC, so we can't + * store it internally as a C double, since that could lose precision. Since + * these nodes are generally only used in the parsing process, not for runtime + * data, it's better to use the more general representation. * - * Nulls, of course, don't need the value part at all. - *---------------------- + * Note that an integer-looking string will get lexed as T_Float if the value + * is too large to fit in an 'int'. */ -typedef struct Value +typedef struct Float +{ + pg_node_attr(special_read_write) + + NodeTag type; + char *fval; +} Float; + +typedef struct Boolean +{ + pg_node_attr(special_read_write) + + NodeTag type; + bool boolval; +} Boolean; + +typedef struct String +{ + pg_node_attr(special_read_write) + + NodeTag type; + char *sval; +} String; + +typedef struct BitString { - NodeTag type; /* tag appropriately (eg. T_String) */ - union ValUnion - { - int ival; /* machine integer */ - char *str; /* string */ - } val; -} Value; - -#define intVal(v) (((Value *)(v))->val.ival) -#define floatVal(v) atof(((Value *)(v))->val.str) -#define strVal(v) (((Value *)(v))->val.str) - -extern Value *makeInteger(int i); -extern Value *makeFloat(char *numericStr); -extern Value *makeString(char *str); -extern Value *makeBitString(char *str); + pg_node_attr(special_read_write) + + NodeTag type; + char *bsval; +} BitString; + +#define intVal(v) (castNode(Integer, v)->ival) +#define floatVal(v) atof(castNode(Float, v)->fval) +#define boolVal(v) (castNode(Boolean, v)->boolval) +#define strVal(v) (castNode(String, v)->sval) + +extern Integer *makeInteger(int i); +extern Float *makeFloat(char *numericStr); +extern Boolean *makeBoolean(bool val); +extern String *makeString(char *str); +extern BitString *makeBitString(char *str); #endif /* VALUE_H */ diff --git a/src/include/pcp/libpcp_ext.h b/src/include/pcp/libpcp_ext.h index ae5ac8a9d..fe5d9a362 100644 --- a/src/include/pcp/libpcp_ext.h +++ b/src/include/pcp/libpcp_ext.h @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -26,9 +26,18 @@ #ifndef LIBPCP_EXT_H #define LIBPCP_EXT_H +#include + #include #include +#ifndef PGPOOL_ADM +#include "parser/pg_config_manual.h" +#endif + +/* returns number of bits in the data type or variable */ +#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) + /* * startup packet definitions (v2) stolen from PostgreSQL */ @@ -38,9 +47,16 @@ #define SM_UNUSED 64 #define SM_TTY 64 +/* + * Maximum hostname length including domain name and "." including NULL + * terminate. + * https://en.wikipedia.org/wiki/Hostname#cite_note-Raymond,_Microsoft_devblog,_2012-3 + */ +#define MAX_FDQN_HOSTNAME_LEN 254 + #define MAX_NUM_BACKENDS 128 #define MAX_CONNECTION_SLOTS MAX_NUM_BACKENDS -#define MAX_DB_HOST_NAMELEN 128 +#define MAX_DB_HOST_NAMELEN MAX_FDQN_HOSTNAME_LEN #define MAX_PATH_LENGTH 256 typedef enum @@ -49,7 +65,7 @@ typedef enum CON_CONNECT_WAIT, /* waiting for connection starting */ CON_UP, /* up and running */ CON_DOWN /* down, disconnected */ -} BACKEND_STATUS; +} BACKEND_STATUS; /* backend status name strings */ #define BACKEND_STATUS_CON_UNUSED "unused" @@ -64,15 +80,15 @@ typedef enum typedef struct { BACKEND_STATUS status[MAX_NUM_BACKENDS]; -} BackendStatusRecord; +} BackendStatusRecord; typedef enum { - ROLE_MASTER, - ROLE_SLAVE, + ROLE_MAIN, + ROLE_REPLICA, ROLE_PRIMARY, ROLE_STANDBY -} SERVER_ROLE; +} SERVER_ROLE; /* * PostgreSQL backend descriptor. Placed on shared memory area. @@ -82,18 +98,31 @@ typedef struct char backend_hostname[MAX_DB_HOST_NAMELEN]; /* backend host name */ int backend_port; /* backend port numbers */ BACKEND_STATUS backend_status; /* backend status */ + char pg_backend_status[NAMEDATALEN]; /* backend status examined by + * show pool_nodes and + * pcp_node_info */ time_t status_changed_time; /* backend status changed time */ double backend_weight; /* normalized backend load balance ratio */ - double unnormalized_weight; /* descripted parameter */ + double unnormalized_weight; /* described parameter */ char backend_data_directory[MAX_PATH_LENGTH]; + char backend_application_name[NAMEDATALEN]; /* application_name for + * walreceiver */ unsigned short flag; /* various flags */ bool quarantine; /* true if node is CON_DOWN because of * quarantine */ uint64 standby_delay; /* The replication delay against the primary */ + bool standby_delay_by_time; /* true if standby_delay is measured + * in microseconds, not bytes */ SERVER_ROLE role; /* Role of server. used by pcp_node_info and * failover() to keep track of quarantined * primary node */ -} BackendInfo; + char pg_role[NAMEDATALEN]; /* backend role examined by show + * pool_nodes and pcp_node_info */ + char replication_state[NAMEDATALEN]; /* "state" from + * pg_stat_replication */ + char replication_sync_state[NAMEDATALEN]; /* "sync_state" from + * pg_stat_replication */ +} BackendInfo; typedef struct { @@ -103,7 +132,21 @@ typedef struct * reloading pgpool.conf. */ BackendInfo backend_info[MAX_NUM_BACKENDS]; -} BackendDesc; +} BackendDesc; + +typedef enum +{ + WAIT_FOR_CONNECT, + COMMAND_EXECUTE, + IDLE, + IDLE_IN_TRANS, + CONNECTING +} ProcessStatus; + +/* + * mamimum cancel key length +*/ +#define MAX_CANCELKEY_LENGTH 256 /* * Connection pool information. Placed on shared memory area. @@ -116,9 +159,13 @@ typedef struct int major; /* protocol major version */ int minor; /* protocol minor version */ int pid; /* backend process id */ - int key; /* cancel key */ + char key[MAX_CANCELKEY_LENGTH]; /* cancel key */ + int32 keylen; /* cancel key length */ int counter; /* used counter */ time_t create_time; /* connection creation time */ + time_t client_connection_time; /* client connection time */ + time_t client_disconnection_time; /* client last disconnection time */ + int client_idle_duration; /* client idle duration time (s) */ int load_balancing_node; /* load balancing node */ char connected; /* True if frontend connected. Please note * that we use "char" instead of "bool". Since @@ -135,23 +182,40 @@ typedef struct * it should not be treated as a backend node failure. This flag is used * to handle pg_terminate_backend() */ -} ConnectionInfo; +} ConnectionInfo; /* * process information * This object put on shared memory. */ + +#define MAXSTMTLEN 1024 + typedef struct { pid_t pid; /* OS's process id */ time_t start_time; /* fork() time */ + char connected; /* if not 0 this process is already used */ + int wait_for_connect; /* waiting time for client connection (s) */ ConnectionInfo *connection_info; /* head of the connection info for * this process */ - char need_to_restart; /* If non 0, exit this child process as + int client_connection_count; /* how many times clients used + * this process */ + ProcessStatus status; + char client_host[NI_MAXHOST]; /* client host. Only valid if + * status != WAIT_FOR_CONNECT */ + char client_port[NI_MAXSERV]; /* client port. Only valid if + * status != WAIT_FOR_CONNECT */ + char statement[MAXSTMTLEN]; /* the last statement sent to backend */ + uint64 node_ids[2]; /* "statement" is sent to the node id (bitmap) */ + bool need_to_restart; /* If non 0, exit this child process as * soon as current session ends. Typical * case this flag being set is failback a * node in streaming replication mode. */ -} ProcessInfo; + bool exit_if_idle; + int pooled_connections; /* Total number of pooled connections by + * this child */ +} ProcessInfo; /* * reporting types @@ -167,14 +231,15 @@ typedef struct #define POOLCONFIG_MAXWEIGHTLEN 20 #define POOLCONFIG_MAXDATELEN 128 #define POOLCONFIG_MAXCOUNTLEN 16 - +#define POOLCONFIG_MAXLONGCOUNTLEN 20 +#define POOLCONFIG_MAXPROCESSSTATUSLEN 20 /* config report struct*/ typedef struct { char name[POOLCONFIG_MAXNAMELEN + 1]; char value[POOLCONFIG_MAXVALLEN + 1]; char desc[POOLCONFIG_MAXDESCLEN + 1]; -} POOL_REPORT_CONFIG; +} POOL_REPORT_CONFIG; /* nodes report struct */ typedef struct @@ -183,47 +248,106 @@ typedef struct char hostname[MAX_DB_HOST_NAMELEN + 1]; char port[POOLCONFIG_MAXPORTLEN + 1]; char status[POOLCONFIG_MAXSTATLEN + 1]; + char pg_status[POOLCONFIG_MAXSTATLEN + 1]; char lb_weight[POOLCONFIG_MAXWEIGHTLEN + 1]; char role[POOLCONFIG_MAXWEIGHTLEN + 1]; + char pg_role[POOLCONFIG_MAXWEIGHTLEN + 1]; char select[POOLCONFIG_MAXWEIGHTLEN + 1]; char load_balance_node[POOLCONFIG_MAXWEIGHTLEN + 1]; char delay[POOLCONFIG_MAXWEIGHTLEN + 1]; + char rep_state[POOLCONFIG_MAXWEIGHTLEN + 1]; + char rep_sync_state[POOLCONFIG_MAXWEIGHTLEN + 1]; char last_status_change[POOLCONFIG_MAXDATELEN]; -} POOL_REPORT_NODES; +} POOL_REPORT_NODES; /* processes report struct */ typedef struct { char pool_pid[POOLCONFIG_MAXCOUNTLEN + 1]; - char start_time[POOLCONFIG_MAXDATELEN + 1]; + char process_start_time[POOLCONFIG_MAXDATELEN + 1]; + char client_connection_count[POOLCONFIG_MAXCOUNTLEN + 1]; char database[POOLCONFIG_MAXIDENTLEN + 1]; char username[POOLCONFIG_MAXIDENTLEN + 1]; - char create_time[POOLCONFIG_MAXDATELEN + 1]; + char backend_connection_time[POOLCONFIG_MAXDATELEN + 1]; char pool_counter[POOLCONFIG_MAXCOUNTLEN + 1]; -} POOL_REPORT_PROCESSES; + char status[POOLCONFIG_MAXPROCESSSTATUSLEN + 1]; +} POOL_REPORT_PROCESSES; /* pools reporting struct */ typedef struct { - int pool_pid; - time_t start_time; - int pool_id; - int backend_id; + char pool_pid[POOLCONFIG_MAXCOUNTLEN + 1]; + char process_start_time[POOLCONFIG_MAXDATELEN + 1]; + char client_connection_count[POOLCONFIG_MAXCOUNTLEN + 1]; + char pool_id[POOLCONFIG_MAXCOUNTLEN + 1]; + char backend_id[POOLCONFIG_MAXCOUNTLEN + 1]; char database[POOLCONFIG_MAXIDENTLEN + 1]; char username[POOLCONFIG_MAXIDENTLEN + 1]; - time_t create_time; - int pool_majorversion; - int pool_minorversion; - int pool_counter; - int pool_backendpid; - int pool_connected; -} POOL_REPORT_POOLS; + char backend_connection_time[POOLCONFIG_MAXDATELEN + 1]; + char client_connection_time[POOLCONFIG_MAXDATELEN + 1]; + char client_disconnection_time[POOLCONFIG_MAXDATELEN + 1]; + char client_idle_duration[POOLCONFIG_MAXDATELEN + 1]; + char pool_majorversion[POOLCONFIG_MAXCOUNTLEN + 1]; + char pool_minorversion[POOLCONFIG_MAXCOUNTLEN + 1]; + char pool_counter[POOLCONFIG_MAXCOUNTLEN + 1]; + char pool_backendpid[POOLCONFIG_MAXCOUNTLEN + 1]; + char pool_connected[POOLCONFIG_MAXCOUNTLEN + 1]; + char status[POOLCONFIG_MAXPROCESSSTATUSLEN + 1]; + char load_balance_node[POOLCONFIG_MAXPROCESSSTATUSLEN + 1]; + char client_host[NI_MAXHOST]; + char client_port[NI_MAXSERV]; + char statement[MAXSTMTLEN]; +} POOL_REPORT_POOLS; /* version struct */ typedef struct { char version[POOLCONFIG_MAXVALLEN + 1]; -} POOL_REPORT_VERSION; +} POOL_REPORT_VERSION; + +/* health check statistics report struct */ +typedef struct +{ + char node_id[POOLCONFIG_MAXIDLEN + 1]; + char hostname[MAX_DB_HOST_NAMELEN + 1]; + char port[POOLCONFIG_MAXPORTLEN + 1]; + char status[POOLCONFIG_MAXSTATLEN + 1]; + char role[POOLCONFIG_MAXWEIGHTLEN + 1]; + char last_status_change[POOLCONFIG_MAXDATELEN]; + char total_count[POOLCONFIG_MAXLONGCOUNTLEN + 1]; + char success_count[POOLCONFIG_MAXLONGCOUNTLEN + 1]; + char fail_count[POOLCONFIG_MAXLONGCOUNTLEN + 1]; + char skip_count[POOLCONFIG_MAXLONGCOUNTLEN + 1]; + char retry_count[POOLCONFIG_MAXLONGCOUNTLEN + 1]; + char average_retry_count[POOLCONFIG_MAXLONGCOUNTLEN + 1]; + char max_retry_count[POOLCONFIG_MAXCOUNTLEN + 1]; + char max_health_check_duration[POOLCONFIG_MAXCOUNTLEN + 1]; + char min_health_check_duration[POOLCONFIG_MAXCOUNTLEN + 1]; + char average_health_check_duration[POOLCONFIG_MAXLONGCOUNTLEN + 1]; + char last_health_check[POOLCONFIG_MAXDATELEN]; + char last_successful_health_check[POOLCONFIG_MAXDATELEN]; + char last_skip_health_check[POOLCONFIG_MAXDATELEN]; + char last_failed_health_check[POOLCONFIG_MAXDATELEN]; +} POOL_HEALTH_CHECK_STATS; + +/* show backend statistics report struct */ +typedef struct +{ + char node_id[POOLCONFIG_MAXIDLEN + 1]; + char hostname[MAX_DB_HOST_NAMELEN + 1]; + char port[POOLCONFIG_MAXPORTLEN + 1]; + char status[POOLCONFIG_MAXSTATLEN + 1]; + char role[POOLCONFIG_MAXWEIGHTLEN + 1]; + char select_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char insert_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char update_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char delete_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char ddl_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char other_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char panic_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char fatal_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; + char error_cnt[POOLCONFIG_MAXWEIGHTLEN + 1]; +} POOL_BACKEND_STATS; typedef enum { @@ -273,7 +397,7 @@ typedef struct PCPConnInfo char *errMsg; /* error message, or NULL if no error */ ConnStateType connState; PCPResultInfo *pcpResInfo; - FILE *Pfdebug; /* File pointer to output debug infor */ + FILE *Pfdebug; /* File pointer to output debug info */ } PCPConnInfo; struct WdInfo; @@ -281,20 +405,23 @@ struct WdInfo; extern PCPConnInfo * pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug); extern void pcp_disconnect(PCPConnInfo * pcpConn); -extern PCPResultInfo * pcp_terminate_pgpool(PCPConnInfo * pcpCon, char mode); +extern PCPResultInfo * pcp_terminate_pgpool(PCPConnInfo * pcpConn, char mode, char command_scope); extern PCPResultInfo * pcp_node_count(PCPConnInfo * pcpCon); extern PCPResultInfo * pcp_node_info(PCPConnInfo * pcpCon, int nid); - +extern PCPResultInfo * pcp_health_check_stats(PCPConnInfo * pcpCon, int nid); extern PCPResultInfo * pcp_process_count(PCPConnInfo * pcpConn); extern PCPResultInfo * pcp_process_info(PCPConnInfo * pcpConn, int pid); +extern PCPResultInfo * pcp_reload_config(PCPConnInfo * pcpConn, char command_scope); +extern PCPResultInfo * pcp_log_rotate(PCPConnInfo * pcpConn, char command_scope); +extern PCPResultInfo * pcp_invalidate_query_cache(PCPConnInfo * pcpConn); extern PCPResultInfo * pcp_detach_node(PCPConnInfo * pcpConn, int nid); extern PCPResultInfo * pcp_detach_node_gracefully(PCPConnInfo * pcpConn, int nid); extern PCPResultInfo * pcp_attach_node(PCPConnInfo * pcpConn, int nid); extern PCPResultInfo * pcp_pool_status(PCPConnInfo * pcpConn); extern PCPResultInfo * pcp_recovery_node(PCPConnInfo * pcpConn, int nid); -extern PCPResultInfo * pcp_promote_node(PCPConnInfo * pcpConn, int nid); -extern PCPResultInfo * pcp_promote_node_gracefully(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool promote); +extern PCPResultInfo * pcp_promote_node_gracefully(PCPConnInfo * pcpConn, int nid, bool promote); extern PCPResultInfo * pcp_watchdog_info(PCPConnInfo * pcpConn, int nid); extern PCPResultInfo * pcp_set_backend_parameter(PCPConnInfo * pcpConn, char *parameter_name, char *value); @@ -313,6 +440,9 @@ extern int pcp_result_is_empty(PCPResultInfo * res); extern char *role_to_str(SERVER_ROLE role); +extern int *pool_health_check_stats_offsets(int *n); +extern int *pool_report_pools_offsets(int *n); + /* ------------------------------ * pcp_error.c * ------------------------------ diff --git a/src/include/pcp/pcp.h b/src/include/pcp/pcp.h index 68d2586fd..b2ed0f55a 100644 --- a/src/include/pcp/pcp.h +++ b/src/include/pcp/pcp.h @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2016 PgPool Global Development Group + * Copyright (c) 2003-2020 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -18,7 +18,7 @@ * is" without express or implied warranty. * * - * pcp.h - master header file. + * pcp.h - pcp header file. */ #ifndef PCP_H @@ -38,24 +38,30 @@ typedef struct PCPWDNodeInfo { int state; + int membership_status; char nodeName[WD_MAX_HOST_NAMELEN]; char hostName[WD_MAX_HOST_NAMELEN]; /* host name */ char stateName[WD_MAX_HOST_NAMELEN]; /* state name */ + char membership_status_string[WD_MAX_HOST_NAMELEN]; /* membership status of + * this node */ int wd_port; /* watchdog port */ int wd_priority; /* node priority in leader election */ int pgpool_port; /* pgpool port */ char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ + bool lifecheck_started; /* True if lifecheck has started */ int id; } PCPWDNodeInfo; typedef struct PCPWDClusterInfo { int remoteNodeCount; + int memberRemoteNodeCount; + int nodesRequiredForQuorum; int quorumStatus; int aliveNodeCount; bool escalated; - char masterNodeName[WD_MAX_HOST_NAMELEN]; - char masterHostName[WD_MAX_HOST_NAMELEN]; + char leaderNodeName[WD_MAX_HOST_NAMELEN]; + char leaderHostName[WD_MAX_HOST_NAMELEN]; int nodeCount; PCPWDNodeInfo nodeList[1]; } PCPWDClusterInfo; diff --git a/src/include/pcp/pcp_stream.h b/src/include/pcp/pcp_stream.h index b1f9efb59..ad006b4f5 100644 --- a/src/include/pcp/pcp_stream.h +++ b/src/include/pcp/pcp_stream.h @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2008 PgPool Global Development Group + * Copyright (c) 2003-2020 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -17,7 +17,7 @@ * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * - * pcp_stream.h - master header file. + * pcp_stream.h - pcp_stream header file. */ #ifndef PCP_STREAM_H @@ -41,13 +41,13 @@ typedef struct int po; /* pending data offset */ int bufsz; /* pending data buffer size */ int len; /* pending data length */ -} PCP_CONNECTION; +} PCP_CONNECTION; -extern PCP_CONNECTION * pcp_open(int fd); -extern void pcp_close(PCP_CONNECTION * pc); -extern int pcp_read(PCP_CONNECTION * pc, void *buf, int len); -extern int pcp_write(PCP_CONNECTION * pc, void *buf, int len); -extern int pcp_flush(PCP_CONNECTION * pc); +extern PCP_CONNECTION *pcp_open(int fd); +extern void pcp_close(PCP_CONNECTION *pc); +extern int pcp_read(PCP_CONNECTION *pc, void *buf, int len); +extern int pcp_write(PCP_CONNECTION *pc, void *buf, int len); +extern int pcp_flush(PCP_CONNECTION *pc); #define UNIX_DOMAIN_PATH "/tmp" diff --git a/src/include/pcp/pcp_worker.h b/src/include/pcp/pcp_worker.h new file mode 100644 index 000000000..90e6f82a3 --- /dev/null +++ b/src/include/pcp/pcp_worker.h @@ -0,0 +1,32 @@ +/* +* +* pgpool: a language independent connection pool server for PostgreSQL +* written by Tatsuo Ishii +* +* Copyright (c) 2003-2020 PgPool Global Development Group +* +* Permission to use, copy, modify, and distribute this software and +* its documentation for any purpose and without fee is hereby +* granted, provided that the above copyright notice appear in all +* copies and that both that copyright notice and this permission +* notice appear in supporting documentation, and that the name of the +* author not be used in advertising or publicity pertaining to +* distribution of the software without specific, written prior +* permission. The author makes no representations about the +* suitability of this software for any purpose. It is provided "as +* is" without express or implied warranty. +* +* +*/ + +#ifndef pcp_worker_h +#define pcp_worker_h + +extern int send_to_pcp_frontend(char *data, int len, bool flush); +extern int pcp_frontend_exists(void); +extern void pcp_worker_main(int port); +extern void pcp_mark_recovery_finished(void); +extern bool pcp_mark_recovery_in_progress(void); + + +#endif /* pcp_worker_h */ diff --git a/src/include/pcp/recovery.h b/src/include/pcp/recovery.h new file mode 100644 index 000000000..2280a766c --- /dev/null +++ b/src/include/pcp/recovery.h @@ -0,0 +1,30 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + + +#ifndef recovery_h +#define recovery_h + +extern void start_recovery(int recovery_node); +extern void finish_recovery(void); +extern int wait_connection_closed(void); +extern int ensure_conn_counter_validity(void); + +#endif /* recovery_h */ diff --git a/src/include/pgproto/fe_memutils.h b/src/include/pgproto/fe_memutils.h index 0167b968d..dd1a8f0b8 100644 --- a/src/include/pgproto/fe_memutils.h +++ b/src/include/pgproto/fe_memutils.h @@ -84,7 +84,7 @@ extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) p memset(_vstart, _val, _len); \ } while (0) -/* originaly gettext staff */ +/* originally gettext staff */ #define _(x) x /* Get a bit mask of the bits set in non-long aligned addresses */ diff --git a/src/include/pgproto/read.h b/src/include/pgproto/read.h index b60f1a90c..c7f2dd0ce 100644 --- a/src/include/pgproto/read.h +++ b/src/include/pgproto/read.h @@ -16,5 +16,5 @@ #ifndef READ_H #define READ_H -extern void read_until_ready_for_query(PGconn *conn, int check_input); +extern void read_until_ready_for_query(PGconn *conn, int check_input, int wait_for_ready_for_query); #endif diff --git a/src/include/pool.h b/src/include/pool.h index c27a375d6..ef0876c84 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -4,7 +4,9 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Portions Copyright (c) 2003-2026 PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -17,7 +19,7 @@ * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * - * pool.h.: master definition header file + * pool.h.: pool definition header file * */ @@ -27,14 +29,9 @@ #include "config.h" #include "pool_type.h" #include "pcp/libpcp_ext.h" -#include "utils/pool_signal.h" #include "auth/pool_passwd.h" +#include "utils/pool_params.h" #include "parser/nodes.h" -#include -#include -#include -#include -#include #ifdef USE_SSL #include @@ -52,19 +49,6 @@ #define POOLKEYFILE ".pgpoolkey" #define POOLKEYFILEENV "PGPOOLKEYFILE" -/* - * Brought from PostgreSQL's pg_config_manual.h. - * - * Maximum length for identifiers (e.g. table names, column names, - * function names). Names actually are limited to one less byte than this, - * because the length must include a trailing zero byte. - * - * Please note that in version 2 protocol, maximum user name length is - * SM_USER, which is 32. - */ -#define NAMEDATALEN 64 - -/* configuration file name */ #define POOL_CONF_FILE_NAME "pgpool.conf" /* PCP user/password file name */ @@ -88,9 +72,15 @@ /* status file name */ #define STATUS_FILE_NAME "pgpool_status" +/* query cache lock file name */ +#define QUERY_CACHE_LOCK_FILE "memq_lock_file" + /* default string used to identify pgpool on syslog output */ #define DEFAULT_SYSLOG_IDENT "pgpool" +/* Pgpool node id file name */ +#define NODE_ID_FILE_NAME "pgpool_node_id" + /* function return codes */ #define GENERAL_ERROR (-1) #define RETRY (-2) @@ -105,7 +95,7 @@ typedef enum POOL_ERROR, POOL_FATAL, POOL_DEADLOCK -} POOL_STATUS; +} POOL_STATUS; typedef enum { @@ -113,7 +103,42 @@ typedef enum POOL_SOCKET_VALID, POOL_SOCKET_ERROR, POOL_SOCKET_EOF -} POOL_SOCKET_STATE; +} POOL_SOCKET_STATE; + +/* + * Imported from src/include/libpq/pqcomm.h as of PostgreSQL 18. + * + * These manipulate the frontend/backend protocol version number. + * + * The major number should be incremented for incompatible changes. The minor + * number should be incremented for compatible changes (eg. additional + * functionality). + * + * If a backend supports version m.n of the protocol it must actually support + * versions m.[0..n]. Backend support for version m-1 can be dropped after a + * `reasonable' length of time. + * + * A frontend isn't required to support anything other than the current + * version. + */ + +#define PG_PROTOCOL_MAJOR(v) ((v) >> 16) +#define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff) +#define PG_PROTOCOL_FULL(v) (PG_PROTOCOL_MAJOR(v) * 10000 + PG_PROTOCOL_MINOR(v)) +#define PG_PROTOCOL(m,n) (((m) << 16) | (n)) + +/* + * The earliest and latest frontend/backend protocol version supported. + */ + +#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(3,0) +#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,2) + +typedef uint32 ProtocolVersion; /* FE/BE protocol version number */ + +typedef ProtocolVersion MsgType; + +/* end of importing */ /* protocol major version numbers */ #define PROTO_MAJOR_V2 2 @@ -139,7 +164,7 @@ typedef struct StartupPacket_v2 char options[SM_OPTIONS]; /* Optional additional args */ char unused[SM_UNUSED]; /* Unused */ char tty[SM_TTY]; /* Tty for debug output */ -} StartupPacket_v2; +} StartupPacket_v2; /* startup packet info */ typedef struct @@ -160,17 +185,11 @@ typedef struct CancelPacket { int protoVersion; /* Protocol version */ int pid; /* backend process id */ - int key; /* cancel key */ -} CancelPacket; + char key[MAX_CANCELKEY_LENGTH]; /* cancel key */ +} CancelPacket; #define MAX_PASSWORD_SIZE 1024 -typedef struct -{ - int num; /* number of entries */ - char **names; /* parameter names */ - char **values; /* values */ -} ParamStatus; /* * HbaLines is declared in pool_hba.h @@ -178,6 +197,7 @@ typedef struct */ typedef struct HbaLine HbaLine; + /* * stream connection structure */ @@ -265,7 +285,7 @@ typedef struct PasswordMapping *passwordMapping; ConnectionInfo *con_info; /* shared memory coninfo used for handling the * query containing pg_terminate_backend */ -} POOL_CONNECTION; +} POOL_CONNECTION; /* * connection pool structure @@ -274,43 +294,40 @@ typedef struct { StartupPacket *sp; /* startup packet info */ int pid; /* backend pid */ - int key; /* cancel key */ + char key[MAX_CANCELKEY_LENGTH]; /* cancel key */ + + /* + * Cancel key length. In protocol version 3.0, it is 4. In 3.2 or later, + * the maximum length is 256. + */ + int32 keylen; POOL_CONNECTION *con; time_t closetime; /* absolute time in second when the connection * closed if 0, that means the connection is * under use. */ -} POOL_CONNECTION_POOL_SLOT; -typedef struct -{ - ConnectionInfo *info; /* connection info on shmem */ - POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; -} POOL_CONNECTION_POOL; + /* + * Protocol version after negotiation. If nplen == 0, no negotiation has + * been done. + */ + int negotiated_major; + int negotiated_minor; + char *negotiateProtocolMsg; /* Raw NegotiateProtocol messag */ + int32 nplen; /* message length of NegotiateProtocol messag */ -/* - * for pool_clear_cache() in pool_query_cache.c - * - * used to specify the time which cached data created before it to be deleted. - */ -typedef enum -{ - second, seconds, - minute, minutes, - hour, hours, - day, days, - week, weeks, - month, months, - year, years, - decade, decades, - century, centuries, - millennium, millenniums -} UNIT; +} POOL_CONNECTION_POOL_SLOT; typedef struct { - int quantity; - UNIT unit; -} Interval; + /* + * info is initialized by pool_init_cp() at the startup of pgpool child + * process. pool_coninfo(child id, pool index, backend id = 0) is used to + * refer to the appropriate pointer on shared memory. + */ + ConnectionInfo *info; + POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; +} POOL_CONNECTION_POOL; + /* Defined in pool_session_context.h */ extern int pool_get_major_version(void); @@ -326,12 +343,13 @@ extern int pool_get_major_version(void); * no query is in progress and the DB node is healthy */ extern bool pool_is_node_to_be_sent_in_current_query(int node_id); -extern int pool_virtual_master_db_node_id(void); -extern BACKEND_STATUS * my_backend_status[]; -extern int my_master_node_id; +extern int pool_virtual_main_db_node_id(void); + +extern volatile BACKEND_STATUS *my_backend_status[]; +extern int my_main_node_id; #define VALID_BACKEND(backend_id) \ - ((RAW_MODE && (backend_id) == REAL_MASTER_NODE_ID) || \ + ((RAW_MODE && (backend_id) == REAL_MAIN_NODE_ID) || \ (pool_is_node_to_be_sent_in_current_query((backend_id)) && \ ((*(my_backend_status[(backend_id)]) == CON_UP) || \ (*(my_backend_status[(backend_id)]) == CON_CONNECT_WAIT)))) @@ -350,15 +368,15 @@ extern int my_master_node_id; * The first DB node id appears in pgpool.conf or the first "live" DB * node otherwise. */ -#define REAL_MASTER_NODE_ID (Req_info->master_node_id) +#define REAL_MAIN_NODE_ID (Req_info->main_node_id) /* * The primary node id in streaming replication mode. If not in the * mode or there's no primary node, this macro returns - * REAL_MASTER_NODE_ID. + * REAL_MAIN_NODE_ID. */ #define PRIMARY_NODE_ID (Req_info->primary_node_id >=0 && VALID_BACKEND_RAW(Req_info->primary_node_id) ? \ - Req_info->primary_node_id:REAL_MASTER_NODE_ID) + Req_info->primary_node_id:REAL_MAIN_NODE_ID) #define IS_PRIMARY_NODE_ID(node_id) (node_id == PRIMARY_NODE_ID) /* @@ -368,14 +386,14 @@ extern int my_master_node_id; #define REAL_PRIMARY_NODE_ID (Req_info->primary_node_id) /* - * "Virtual" master node id. It's same as REAL_MASTER_NODE_ID if not + * "Virtual" main node id. It's same as REAL_MAIN_NODE_ID if not * in load balance mode. If in load balance, it's the first load * balance node. */ -#define MASTER_NODE_ID (pool_virtual_master_db_node_id()) -#define IS_MASTER_NODE_ID(node_id) (MASTER_NODE_ID == (node_id)) -#define MASTER_CONNECTION(p) ((p)->slots[MASTER_NODE_ID]) -#define MASTER(p) MASTER_CONNECTION(p)->con +#define MAIN_NODE_ID (pool_virtual_main_db_node_id()) +#define IS_MAIN_NODE_ID(node_id) (MAIN_NODE_ID == (node_id)) +#define MAIN_CONNECTION(p) ((p)->slots[MAIN_NODE_ID]) +#define MAIN(p) MAIN_CONNECTION(p)->con /* * Backend node status in streaming replication mode. @@ -383,19 +401,21 @@ extern int my_master_node_id; typedef enum { POOL_NODE_STATUS_UNUSED, /* unused */ - POOL_NODE_STATUS_PRIMARY, /* primary ndoe */ + POOL_NODE_STATUS_PRIMARY, /* primary node */ POOL_NODE_STATUS_STANDBY, /* standby node */ - POOL_NODE_STATUS_INVALID /* invalid node (split branin, stand alone) */ -} POOL_NODE_STATUS; - -#define REPLICATION (pool_config->replication_mode) -#define MASTER_SLAVE (pool_config->master_slave_mode) -#define STREAM (MASTER_SLAVE && pool_config->master_slave_sub_mode == STREAM_MODE) -#define LOGICAL (MASTER_SLAVE && pool_config->master_slave_sub_mode == LOGICAL_MODE) -#define SLONY (MASTER_SLAVE && pool_config->master_slave_sub_mode == SLONY_MODE) -#define DUAL_MODE (REPLICATION || MASTER_SLAVE) -#define RAW_MODE (!REPLICATION && !MASTER_SLAVE) + POOL_NODE_STATUS_INVALID /* invalid node (split brain, stand alone) */ +} POOL_NODE_STATUS; + +/* Clustering mode macros */ +#define REPLICATION (pool_config->backend_clustering_mode == CM_NATIVE_REPLICATION || \ + pool_config->backend_clustering_mode == CM_SNAPSHOT_ISOLATION) +#define MAIN_REPLICA (pool_config->backend_clustering_mode == CM_STREAMING_REPLICATION || \ + pool_config->backend_clustering_mode == CM_LOGICAL_REPLICATION) +#define STREAM (pool_config->backend_clustering_mode == CM_STREAMING_REPLICATION) +#define LOGICAL (pool_config->backend_clustering_mode == CM_LOGICAL_REPLICATION) +#define RAW_MODE (pool_config->backend_clustering_mode == CM_RAW) #define SL_MODE (STREAM || LOGICAL) /* streaming or logical replication mode */ + #define MAJOR(p) (pool_get_major_version()) #define TSTATE(p, i) (CONNECTION(p, i)->tstate) #define INTERNAL_TRANSACTION_STARTED(p, i) (CONNECTION(p, i)->is_internal_transaction_started) @@ -403,23 +423,21 @@ typedef enum #define Max(x, y) ((x) > (y) ? (x) : (y)) #define Min(x, y) ((x) < (y) ? (x) : (y)) -#define LOCK_COMMENT "/*INSERT LOCK*/" -#define LOCK_COMMENT_SZ (sizeof(LOCK_COMMENT)-1) -#define NO_LOCK_COMMENT "/*NO INSERT LOCK*/" -#define NO_LOCK_COMMENT_SZ (sizeof(NO_LOCK_COMMENT)-1) -#define NO_LOAD_BALANCE "/*NO LOAD BALANCE*/" -#define NO_LOAD_BALANCE_COMMENT_SZ (sizeof(NO_LOAD_BALANCE)-1) -#define MAX_NUM_SEMAPHORES 6 +#define MAX_NUM_SEMAPHORES 9 #define CONN_COUNTER_SEM 0 #define REQUEST_INFO_SEM 1 -#define SHM_CACHE_SEM 2 -#define QUERY_CACHE_STATS_SEM 3 -#define PCP_REQUEST_SEM 4 -#define ACCEPT_FD_SEM 5 +#define QUERY_CACHE_STATS_SEM 2 +#define PCP_REQUEST_SEM 3 +#define ACCEPT_FD_SEM 4 +#define SI_CRITICAL_REGION_SEM 5 +#define FOLLOW_PRIMARY_SEM 6 +#define MAIN_EXIT_HANDLER_SEM 7 /* used in exit_hander in pgpool main + * process */ +#define TRACK_TABLE_MUTATION_TABLE_SEM 8 #define MAX_REQUEST_QUEUE_SIZE 10 -#define MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION 10 /* time in seconds to keep +#define MAX_SEC_WAIT_FOR_CLUSTER_TRANSACTION 10 /* time in seconds to keep * retrying for a watchdog * command if the cluster is * not in stable state */ @@ -449,14 +467,18 @@ typedef enum CLOSE_IDLE_REQUEST, PROMOTE_NODE_REQUEST, NODE_QUARANTINE_REQUEST -} POOL_REQUEST_KIND; +} POOL_REQUEST_KIND; #define REQ_DETAIL_SWITCHOVER 0x00000001 /* failover due to switch over */ #define REQ_DETAIL_WATCHDOG 0x00000002 /* failover req from watchdog */ #define REQ_DETAIL_CONFIRMED 0x00000004 /* failover req that does not * require majority vote */ -#define REQ_DETAIL_UPDATE 0x00000008 /* failover req is just and update +#define REQ_DETAIL_UPDATE 0x00000008 /* failover req is just an update * node status request */ +#define REQ_DETAIL_PROMOTE 0x00000010 /* failover req is actually + * promoting the specified standby + * node. current primary will be + * detached */ typedef struct { @@ -464,21 +486,59 @@ typedef struct unsigned char request_details; /* option flags kind */ int node_id[MAX_NUM_BACKENDS]; /* request node id */ int count; /* request node ids count */ -} POOL_REQUEST_NODE; +} POOL_REQUEST_NODE; + +/* + * Maximum number of pcp worker child process. * Since pcp worker process is + * forked whenever failover/failback request is made, it should be equal to + * MAX_REQUEST_QUEUE_SIZE + some room. 10 is an arbitrary number. +*/ +#define MAX_PCP_WORKER_PIDS MAX_REQUEST_QUEUE_SIZE + 10 typedef struct { POOL_REQUEST_NODE request[MAX_REQUEST_QUEUE_SIZE]; int request_queue_head; int request_queue_tail; - int master_node_id; /* the youngest node id which is not in down + int main_node_id; /* the youngest node id which is not in down * status */ int primary_node_id; /* the primary node id in streaming * replication mode */ - int conn_counter; + int conn_counter; /* number of connections from clients to + * pgpool */ bool switching; /* it true, failover or failback is in * progress */ -} POOL_REQUEST_INFO; + + /* + * greater than 0 if follow primary command or detach_false_primary in + * execution + */ + bool follow_primary_count; + bool follow_primary_lock_pending; /* watchdog process can't wait + * for follow_primary lock + * acquisition in case it is + * held at the time of + * request. This flag + * indicates that lock was + * requested by watchdog + * coordinator and next + * contender should wait for + * the coordinator to release + * the lock */ + bool follow_primary_lock_held_remotely; /* true when lock is held + * by watchdog coordinator */ + bool follow_primary_ongoing; /* true if follow primary command is + * ongoing */ + bool query_cache_invalidate_request; /* true if + * pcp_invalidate_query_cache + * requested */ + + /* + * pcp worker child pids. This is inherited to new pcp main process to + * track pcp worker child when new pcp worker child starts. + */ + pid_t pcp_worker_pids[MAX_PCP_WORKER_PIDS]; +} POOL_REQUEST_INFO; /* description of row. corresponding to RowDescription message */ typedef struct @@ -490,13 +550,13 @@ typedef struct int typeoid; /* data type oid */ int size; /* data length minus means variable data type */ int mod; /* data type modifier */ -} AttrInfo; +} AttrInfo; typedef struct { int num_attrs; /* number of attributes */ AttrInfo *attrinfo; -} RowDesc; +} RowDesc; typedef struct { @@ -506,7 +566,7 @@ typedef struct * excluding termination null */ char **data; /* actual row character data terminated with * null */ -} POOL_SELECT_RESULT; +} POOL_SELECT_RESULT; /* * recovery mode @@ -520,13 +580,13 @@ typedef enum } POOL_RECOVERY_MODE; /* - * global variables + * Process types. DO NOT change the order of each enum member! If you do + * that, you must change application_name array in src/main/pgpool_main.c + * accordingly. */ -extern pid_t mypid; /* parent pid */ - typedef enum { - PT_MAIN, + PT_MAIN = 0, PT_CHILD, PT_WORKER, PT_HB_SENDER, @@ -537,40 +597,67 @@ typedef enum PT_WATCHDOG_UTILITY, PT_PCP, PT_PCP_WORKER, - PT_HEALTH_CHECK -} ProcessType; + PT_HEALTH_CHECK, + PT_LOGGER, + PT_LAST_PTYPE /* last ptype marker. any ptype must be above + * this. */ +} ProcessType; -extern ProcessType processType; typedef enum { INITIALIZING, PERFORMING_HEALTH_CHECK, SLEEPING, - WAITIG_FOR_CONNECTION, + WAITING_FOR_CONNECTION, BACKEND_CONNECTING, PROCESSING, EXITING -} ProcessState; +} ProcessState; + +/* + * Snapshot isolation manage area in shared memory + */ +typedef struct +{ + uint32 commit_counter; /* number of committing children */ + uint32 snapshot_counter; /* number of snapshot acquiring children */ + pid_t *snapshot_waiting_children; /* array size is num_init_children */ + pid_t *commit_waiting_children; /* array size is num_init_children */ +} SI_ManageInfo; +/* + * global variables + * pool_global.c + */ +extern pid_t mypid; /* parent pid */ +extern pid_t myProcPid; /* process pid */ +extern ProcessType processType; extern ProcessState processState; +extern bool reset_query_error; /* true if error occurs in reset queries */ +extern void set_application_name(ProcessType ptype); +extern void set_application_name_with_string(char *string); +extern void set_application_name_with_suffix(ProcessType ptype, int suffix); +extern char *get_application_name(void); +extern char *get_application_name_for_process(ProcessType ptype); + +void SetProcessGlobalVariables(ProcessType pType); + +extern volatile SI_ManageInfo *si_manage_info; +extern volatile sig_atomic_t sigusr2_received; -extern POOL_CONNECTION_POOL * pool_connection_pool; /* connection pool */ extern volatile sig_atomic_t backend_timer_expired; /* flag for connection * closed timer is expired */ extern volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check * timer expired */ -extern long int weight_master; /* normalized weight of master (0-RAND_MAX - * range) */ extern int my_proc_id; /* process table id (!= UNIX's PID) */ -extern ProcessInfo * process_info; /* shmem process information table */ -extern ConnectionInfo * con_info; /* shmem connection info table */ -extern POOL_REQUEST_INFO * Req_info; +extern ProcessInfo *process_info; /* shmem process information table */ +extern ConnectionInfo *con_info; /* shmem connection info table */ +extern POOL_REQUEST_INFO *Req_info; extern volatile sig_atomic_t *InRecovery; -extern char remote_ps_data[]; /* used for set_ps_display */ extern volatile sig_atomic_t got_sighup; extern volatile sig_atomic_t exit_request; - +extern volatile sig_atomic_t ignore_sigusr1; #define QUERY_STRING_BUFFER_LEN 1024 extern char query_string_buffer[]; /* last query string sent to simpleQuery() */ @@ -580,231 +667,82 @@ extern BACKEND_STATUS private_backend_status[MAX_NUM_BACKENDS]; extern char remote_host[]; /* client host */ extern char remote_port[]; /* client port */ + /* * public functions */ -extern void register_watchdog_quorum_change_interupt(void); -extern void register_watchdog_state_change_interupt(void); -extern void register_backend_state_sync_req_interupt(void); -extern void register_inform_quarantine_nodes_req(void); -extern bool register_node_operation_request(POOL_REQUEST_KIND kind, int *node_id_set, int count, unsigned char flags); +/*main.c*/ extern char *get_config_file_name(void); extern char *get_hba_file_name(void); -extern void do_child(int *fds); -extern void pcp_main(int unix_fd, int inet_fd); -extern int select_load_balancing_node(void); -extern int pool_init_cp(void); -extern POOL_STATUS pool_process_query(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, - int reset_request); - -extern void connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password); -extern int pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern int pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp); -extern void authenticate_frontend(POOL_CONNECTION * frontend); - -extern bool is_backend_cache_empty(POOL_CONNECTION_POOL * backend); - -/* SSL functionality */ -extern void pool_ssl_negotiate_serverclient(POOL_CONNECTION * cp); -extern void pool_ssl_negotiate_clientserver(POOL_CONNECTION * cp); -extern void pool_ssl_close(POOL_CONNECTION * cp); -extern int pool_ssl_read(POOL_CONNECTION * cp, void *buf, int size); -extern int pool_ssl_write(POOL_CONNECTION * cp, const void *buf, int size); -extern bool pool_ssl_pending(POOL_CONNECTION * cp); -extern int SSL_ServerSide_init(void); - -extern POOL_STATUS ErrorResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); - -extern void NoticeResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); - -extern void notice_backend_error(int node_id, unsigned char flags); -extern bool degenerate_backend_set(int *node_id_set, int count, unsigned char flags); -extern bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, bool error, bool test_only); -extern bool promote_backend(int node_id, unsigned char flags); -extern bool send_failback_request(int node_id, bool throw_error, unsigned char flags); - - -extern void pool_set_timeout(int timeoutval); -extern int pool_check_fd(POOL_CONNECTION * cp); - -extern void pool_send_frontend_exits(POOL_CONNECTION_POOL * backend); - -extern int pool_read_message_length(POOL_CONNECTION_POOL * cp); -extern int *pool_read_message_length2(POOL_CONNECTION_POOL * cp); -extern signed char pool_read_kind(POOL_CONNECTION_POOL * cp); -extern int pool_read_int(POOL_CONNECTION_POOL * cp); - -extern POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS ParameterStatus(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); - -extern int pool_init_params(ParamStatus * params); -extern void pool_discard_params(ParamStatus * params); -extern char *pool_find_name(ParamStatus * params, char *name, int *pos); -extern int pool_get_param(ParamStatus * params, int index, char **name, char **value); -extern int pool_add_param(ParamStatus * params, char *name, char *value); -extern void pool_param_debug_print(ParamStatus * params); - -extern void pool_send_error_message(POOL_CONNECTION * frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - int line); -extern void pool_send_fatal_message(POOL_CONNECTION * frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - int line); -extern void pool_send_severity_message(POOL_CONNECTION * frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - char *severity, - int line); -extern void pool_send_readyforquery(POOL_CONNECTION * frontend); -extern void send_startup_packet(POOL_CONNECTION_POOL_SLOT * cp); -extern void pool_free_startup_packet(StartupPacket *sp); -extern void child_exit(int code); - -extern void init_prepared_list(void); -extern void proc_exit(int); - -extern void *pool_shared_memory_create(size_t size); -extern void pool_shmem_exit(int code); +extern char *get_pool_key(void); -extern void pool_semaphore_create(int numSems); -extern void pool_semaphore_lock(int semNum); -extern void pool_semaphore_unlock(int semNum); -extern BackendInfo * pool_get_node_info(int node_number); -extern int pool_get_node_count(void); -extern int *pool_get_process_list(int *array_size); -extern ProcessInfo * pool_get_process_info(pid_t pid); -extern POOL_STATUS OneNode_do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, char *query, char *database); +/*pcp_child.c*/ +extern void pcp_main(int *fds); -/* child.c */ -extern POOL_CONNECTION_POOL_SLOT * make_persistent_db_connection( - int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); -extern POOL_CONNECTION_POOL_SLOT * make_persistent_db_connection_noerror( - int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); -extern void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT * cp); -/* define pool_system.c */ -extern void pool_close_libpq_connection(void); -/* pool_ip.c */ -extern void pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port); +/*child.c*/ -/* strlcpy.c */ -#ifndef HAVE_STRLCPY -extern size_t strlcpy(char *dst, const char *src, size_t siz); -#endif +extern void do_child(int *fds); +extern void child_exit(int code); -/* ps_status.c */ -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); -extern void set_ps_display(const char *activity, bool force); -extern const char *get_ps_display(int *displen); -extern void pool_ps_idle_display(POOL_CONNECTION_POOL * backend); - -/* recovery.c */ -extern void start_recovery(int recovery_node); -extern void finish_recovery(void); -extern int wait_connection_closed(void); - -/* child.c */ -extern void cancel_request(CancelPacket * sp); +extern void cancel_request(CancelPacket *sp, int32 len); extern void check_stop_request(void); extern void pool_initialize_private_backend_status(void); -extern bool is_session_connected(void); extern int send_to_pg_frontend(char *data, int len, bool flush); extern int pg_frontend_exists(void); extern int set_pg_frontend_blocking(bool blocking); extern int get_frontend_protocol_version(void); +extern void set_process_status(ProcessStatus status); -/* pool_process_query.c */ -extern void reset_variables(void); -extern void reset_connection(void); -extern void per_node_statement_log(POOL_CONNECTION_POOL * backend, int node_id, char *query); -extern void per_node_error_log(POOL_CONNECTION_POOL * backend, int node_id, char *query, char *prefix, bool unread); -extern int pool_extract_error_message(bool read_kind, POOL_CONNECTION * backend, int major, bool unread, char **message); -extern POOL_STATUS do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, - char *query, int protoMajor, int pid, int key, int no_ready_for_query); -extern void do_query(POOL_CONNECTION * backend, char *query, POOL_SELECT_RESULT * *result, int major); -extern void free_select_result(POOL_SELECT_RESULT * result); -extern int compare(const void *p1, const void *p2); -extern void do_error_execute_command(POOL_CONNECTION_POOL * backend, int node_id, int major); -extern POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL * cp); -extern void pool_dump_valid_backend(int backend_id); -extern bool pool_push_pending_data(POOL_CONNECTION * backend); - -/* pool_auth.c */ -extern void pool_random_salt(char *md5Salt); -extern void pool_random(void *buf, size_t len); - -/* main.c */ -extern void pool_sleep(unsigned int second); -extern char *get_pool_key(void); +/*pool_shmem.c*/ +extern void *pool_shared_memory_create(size_t size); +extern void pool_shmem_exit(int code); +extern void initialize_shared_memory_main_segment(size_t size); +extern void *pool_shared_memory_segment_get_chunk(size_t size); -/* pool_worker_child.c */ -extern void do_worker_child(void); -extern int get_query_result(POOL_CONNECTION_POOL_SLOT * *slots, int backend_id, char *query, POOL_SELECT_RESULT * *res); - -/* md5.c */ -extern bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); - -/* pool_connection_pool.c */ -extern int pool_init_cp(void); -extern POOL_CONNECTION_POOL * pool_create_cp(void); -extern POOL_CONNECTION_POOL * pool_get_cp(char *user, char *database, int protoMajor, int check_socket); -extern void pool_discard_cp(char *user, char *database, int protoMajor); -extern void pool_backend_timer(void); -extern void pool_connection_pool_timer(POOL_CONNECTION_POOL * backend); -extern RETSIGTYPE pool_backend_timer_handler(int sig); -extern int connect_inet_domain_socket(int slot, bool retry); -extern int connect_unix_domain_socket(int slot, bool retry); -extern int connect_inet_domain_socket_by_port(char *host, int port, bool retry); -extern int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry); -extern int pool_pool_index(void); - -/* utils/statistics.c */ -size_t stat_shared_memory_size(void); -void stat_set_stat_area(void *address); -void stat_init_stat_area(void); -void stat_count_up(int backend_node_id, Node *parsetree); -uint64 stat_get_select_count(int backend_node_id); +/* pgpool_main.c*/ +extern BackendInfo *pool_get_node_info(int node_number); +extern int pool_get_node_count(void); +extern int *pool_get_process_list(int *array_size); +extern ProcessInfo *pool_get_process_info(pid_t pid); +extern void pool_sleep(unsigned int second); extern int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps); - -/* pcp_child.c */ -extern int send_to_pcp_frontend(char *data, int len, bool flush); -extern int pcp_frontend_exists(void); -extern void pcp_worker_main(int port); -extern void pcp_mark_recovery_finished(void); -extern bool pcp_mark_recovery_in_progress(void); - - -/* pgpool_main.c */ extern int pool_send_to_frontend(char *data, int len, bool flush); extern int pool_frontend_exists(void); extern pid_t pool_waitpid(int *status); extern int write_status_file(void); -extern void do_health_check_child(int *node_id); -extern POOL_NODE_STATUS * verify_backend_node_status(POOL_CONNECTION_POOL_SLOT * *slots); -extern POOL_NODE_STATUS * pool_get_node_status(void); +extern POOL_NODE_STATUS *verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots); +extern POOL_NODE_STATUS *pool_get_node_status(void); extern void pool_set_backend_status_changed_time(int backend_id); -extern int get_next_master_node(void); +extern int get_next_main_node(void); +extern bool pool_acquire_follow_primary_lock(bool block, bool remote_reques); +extern void pool_release_follow_primary_lock(bool remote_reques); +extern void pool_signal_logrotate(void); + +/* + * Close listening sockets + * following defines are for "kind" param. + */ +#define POOL_CLOSE_PGPOOL_LISTENING_SOCKS 0x01 /* pgpool sockets */ +#define POOL_CLOSE_PCP_LISTENING_SOCKS 0x02 /* pcp sockets */ +extern void close_listening_sockets(int kind); + + +/* strlcpy.c */ +#ifndef HAVE_STRLCPY +extern size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +/* pool_worker_child.c */ +extern void do_worker_child(void *params); +extern int get_query_result(POOL_CONNECTION_POOL_SLOT **slots, int backend_id, char *query, POOL_SELECT_RESULT **res); + +/* utils/pg_strong_random.c */ +void pg_strong_random_init(void); +bool pg_strong_random(void *buf, size_t len); #endif /* POOL_H */ diff --git a/src/include/pool_config.h b/src/include/pool_config.h index f98e0cf2f..b8abadd50 100644 --- a/src/include/pool_config.h +++ b/src/include/pool_config.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -33,7 +33,7 @@ /* * watchdog */ -#define WD_MAX_HOST_NAMELEN (128) +#define WD_MAX_HOST_NAMELEN MAX_FDQN_HOSTNAME_LEN #define WD_MAX_NODE_NAMELEN (WD_MAX_HOST_NAMELEN + POOLCONFIG_MAXPORTLEN + sizeof(((struct utsname *)NULL)->sysname) + sizeof(((struct utsname *)NULL)->nodename) + 3) #define WD_MAX_PATH_LEN (128) #define MAX_WATCHDOG_NUM (128) @@ -43,11 +43,11 @@ #include "utils/regex_array.h" /* - * Regex support in white and black list function + * Regex support in write and readonly list function */ #include -#define BLACKLIST 0 -#define WHITELIST 1 +#define WRITELIST 0 +#define READONLYLIST 1 #define PATTERN_ARR_SIZE 16 /* Default length of regex array: 16 patterns */ typedef struct { @@ -55,67 +55,109 @@ typedef struct int type; int flag; regex_t regexv; -} RegPattern; +} RegPattern; -typedef enum MasterSlaveSubModes +typedef enum ProcessManagementModes { - SLONY_MODE = 1, - STREAM_MODE, - LOGICAL_MODE -} MasterSlaveSubModes; + PM_STATIC = 1, + PM_DYNAMIC +} ProcessManagementModes; + +typedef enum ProcessManagementSstrategies +{ + PM_STRATEGY_AGGRESSIVE = 1, + PM_STRATEGY_GENTLE, + PM_STRATEGY_LAZY +} ProcessManagementSstrategies; + +typedef enum ClusteringModes +{ + CM_STREAMING_REPLICATION = 1, + CM_NATIVE_REPLICATION, + CM_LOGICAL_REPLICATION, + CM_RAW, + CM_SNAPSHOT_ISOLATION +} ClusteringModes; typedef enum LogStandbyDelayModes { LSD_ALWAYS = 1, LSD_OVER_THRESHOLD, LSD_NONE -} LogStandbyDelayModes; - +} LogStandbyDelayModes; typedef enum MemCacheMethod { SHMEM_CACHE = 1, MEMCACHED_CACHE -} MemCacheMethod; +} MemCacheMethod; typedef enum WdLifeCheckMethod { LIFECHECK_BY_QUERY = 1, LIFECHECK_BY_HB, LIFECHECK_BY_EXTERNAL -} WdLifeCheckMethod; +} WdLifeCheckMethod; typedef enum DLBOW_OPTION { DLBOW_OFF = 1, DLBOW_TRANSACTION, DLBOW_TRANS_TRANSACTION, - DLBOW_ALWAYS -} DLBOW_OPTION; + DLBOW_ALWAYS, + DLBOW_DML_ADAPTIVE, + DLBOW_DML_ADAPTIVE_GLOBAL +} DLBOW_OPTION; + +#define DLBOW_IS_DML_ADAPTIVE(opt) \ + ((opt) == DLBOW_DML_ADAPTIVE || (opt) == DLBOW_DML_ADAPTIVE_GLOBAL) + +typedef enum RELQTARGET_OPTION +{ + RELQTARGET_PRIMARY = 1, + RELQTARGET_LOAD_BALANCE_NODE +} RELQTARGET_OPTION; + +typedef enum CHECK_TEMP_TABLE_OPTION +{ + CHECK_TEMP_CATALOG = 1, + CHECK_TEMP_TRACE, + CHECK_TEMP_NONE, + CHECK_TEMP_ON, + CHECK_TEMP_OFF, +} CHECK_TEMP_TABLE_OPTION; + +/* log_backend_messages */ +typedef enum BGMSG_OPTION +{ + BGMSG_NONE = 1, + BGMSG_TERSE, + BGMSG_VERBOSE, +} BGMSG_OPTION; /* * Flags for backendN_flag */ #define POOL_FAILOVER (1 << 0) /* allow or disallow failover */ -#define POOL_ALWAYS_MASTER (1 << 1) /* this backend is always master */ +#define POOL_ALWAYS_PRIMARY (1 << 1) /* this backend is always primary */ #define POOL_DISALLOW_TO_FAILOVER(x) ((unsigned short)(x) & POOL_FAILOVER) #define POOL_ALLOW_TO_FAILOVER(x) (!(POOL_DISALLOW_TO_FAILOVER(x))) /* * watchdog list */ -typedef struct WdRemoteNodeInfo +typedef struct WdNodeInfo { char hostname[WD_MAX_HOST_NAMELEN]; /* host name */ int pgpool_port; /* pgpool port */ int wd_port; /* watchdog port */ -} WdRemoteNodeInfo; +} WdNodeInfo; -typedef struct WdRemoteNodesConfig +typedef struct WdNodesConfig { int num_wd; /* number of watchdogs */ - WdRemoteNodeInfo wd_remote_node_info[MAX_WATCHDOG_NUM]; -} WdRemoteNodesConfig; + WdNodeInfo wd_node_info[MAX_WATCHDOG_NUM]; +} WdNodesConfig; typedef struct @@ -123,10 +165,10 @@ typedef struct char addr[WD_MAX_HOST_NAMELEN]; char if_name[WD_MAX_IF_NAME_LEN]; int dest_port; -} WdHbIf; +} WdHbIf; -#define WD_INFO(wd_id) (pool_config->wd_remote_nodes.wd_remote_node_info[(wd_id)]) -#define WD_HB_IF(if_id) (pool_config->hb_if[(if_id)]) +#define WD_INFO(wd_id) (pool_config->wd_nodes.wd_node_info[(wd_id)]) +#define WD_HB_IF(if_id) (pool_config->hb_dest_if[(if_id)]) /* * Per node health check parameters @@ -137,28 +179,60 @@ typedef struct int health_check_period; /* health check period */ char *health_check_user; /* PostgreSQL user name for health check */ char *health_check_password; /* password for health check username */ - char *health_check_database; /* database name for health check - * username */ + char *health_check_database; /* database name for health check */ int health_check_max_retries; /* health check max retries */ int health_check_retry_delay; /* amount of time to wait between * retries */ int connect_timeout; /* timeout value before giving up * connecting to backend */ -} HealthCheckParams; +} HealthCheckParams; + +/* + * For dml adaptive object relations + * Currently we only require functions + * and relations + * + */ +typedef enum +{ + OBJECT_TYPE_FUNCTION, + OBJECT_TYPE_RELATION, + OBJECT_TYPE_UNKNOWN +} DBObjectTypes; + +typedef struct +{ + char *name; + DBObjectTypes object_type; +} DBObject; + +typedef struct +{ + DBObject left_token; + DBObject right_token; +} DBObjectRelation; /* * configuration parameters */ typedef struct { - char *listen_addresses; /* hostnames/IP addresses to listen on */ + ClusteringModes backend_clustering_mode; /* Backend clustering mode */ + ProcessManagementModes process_management; + ProcessManagementSstrategies process_management_strategy; + char **listen_addresses; /* hostnames/IP addresses to listen on */ int port; /* port # to bind */ - char *pcp_listen_addresses; /* PCP listen address to listen on */ + char **pcp_listen_addresses; /* PCP listen address to listen on */ int pcp_port; /* PCP port # to bind */ - char *socket_dir; /* pgpool socket directory */ + char **unix_socket_directories; /* pgpool socket directories */ + char *unix_socket_group; /* owner group of pgpool sockets */ + int unix_socket_permissions; /* pgpool sockets permissions */ char *wd_ipc_socket_dir; /* watchdog command IPC socket directory */ - char *pcp_socket_dir; /* PCP socket directory */ - int num_init_children; /* # of children initially pre-forked */ + char **pcp_socket_dir; /* PCP socket directory */ + int num_init_children; /* Maximum number of child to accept + * connections */ + int min_spare_children; /* Minimum number of idle children */ + int max_spare_children; /* Minimum number of idle children */ int listen_backlog_multiplier; /* determines the size of the * connection queue */ int reserved_connections; /* # of reserved connections */ @@ -182,7 +256,8 @@ typedef struct int authentication_timeout; /* maximum time in seconds to complete * client authentication */ int max_pool; /* max # of connection pool per child */ - char *logdir; /* logging directory */ + char *work_dir; /* directory to create pgpool_status and lock + * files */ char *log_destination_str; /* log destination: stderr and/or * syslog */ int log_destination; /* log destination */ @@ -191,6 +266,8 @@ typedef struct char *pid_file_name; /* pid file name */ bool replication_mode; /* replication mode */ bool log_connections; /* logs incoming connections */ + bool log_disconnections; /* logs closing connections */ + bool log_pcp_processes; /* logs pcp processes */ bool log_hostname; /* resolve hostname */ bool enable_pool_hba; /* enables pool_hba.conf file * authentication */ @@ -199,7 +276,7 @@ typedef struct bool load_balance_mode; /* load balance mode */ bool replication_stop_on_mismatch; /* if there's a data mismatch - * between master and + * between primary and * secondary start * degeneration to stop * replication mode */ @@ -214,15 +291,21 @@ typedef struct * false, just abort the * transaction to keep * the consistency. */ + bool auto_failback; /* If true, backend node reattach, when + * backend node detached and + * replication_status is 'stream' */ + int auto_failback_interval; /* min interval of executing + * auto_failback */ bool replicate_select; /* replicate SELECT statement when load * balancing is disabled. */ char **reset_query_list; /* comma separated list of queries to be * issued at the end of session */ - char **white_function_list; /* list of functions with no side - * effects */ - char **black_function_list; /* list of functions with side effects */ - char **black_query_pattern_list; /* list of query patterns that - * should be sent to primary node */ + char **read_only_function_list; /* list of functions with no side + * effects */ + char **write_function_list; /* list of functions with side effects */ + char **primary_routing_query_pattern_list; /* list of query patterns + * that should be sent to + * primary node */ char *log_line_prefix; /* printf-style string to output at * beginning of each log line */ int log_error_verbosity; /* controls how much detail about @@ -231,8 +314,15 @@ typedef struct * sent to client */ int log_min_messages; /* controls which message should be * emitted to server log */ - bool master_slave_mode; /* operate in master/slave mode */ - MasterSlaveSubModes master_slave_sub_mode; /* either "slony" or "stream" */ + /* log collector settings */ + bool logging_collector; + int log_rotation_age; + int log_rotation_size; + char *log_directory; + char *log_filename; + bool log_truncate_on_rotation; + int log_file_mode; + int64 delay_threshold; /* If the standby server delays more than * delay_threshold, any query goes to the * primary only. The unit is in bytes. 0 @@ -240,14 +330,30 @@ typedef struct * that health_check_period required to be * greater than 0 to enable the * functionality. */ + + int delay_threshold_by_time; /* If the standby server delays + * more than + * delay_threshold_in_time, any + * query goes to the primary only. + * The unit is in seconds. 0 + * disables the check. Default is + * 0. If delay_threshold_in_time + * is greater than 0, + * delay_threshold will be + * ignored. Note that + * health_check_period required to + * be greater than 0 to enable the + * functionality. */ + + bool prefer_lower_delay_standby; + LogStandbyDelayModes log_standby_delay; /* how to log standby lag */ bool connection_cache; /* cache connection pool? */ int health_check_timeout; /* health check timeout */ int health_check_period; /* health check period */ char *health_check_user; /* PostgreSQL user name for health check */ char *health_check_password; /* password for health check username */ - char *health_check_database; /* database name for health check - * username */ + char *health_check_database; /* database name for health check */ int health_check_max_retries; /* health check max retries */ int health_check_retry_delay; /* amount of time to wait between * retries */ @@ -261,12 +367,28 @@ typedef struct char *sr_check_password; /* password for sr_check_user */ char *sr_check_database; /* PostgreSQL database name for streaming * replication check */ + char *replication_delay_source_cmd; /* external command for + * replication delay */ + int replication_delay_source_timeout; /* timeout for external + * command in seconds */ + + /* Track table mutation configuration */ + double track_table_mutation_ttl_factor; /* TTL multiplier for + * replication delay */ + int track_table_mutation_max_staleness; /* max staleness duration + * ms */ + int track_table_mutation_cold_start_duration; /* cold start duration + * ms */ + int track_table_mutation_table_buckets; /* hash buckets for table + * map */ + int track_table_mutation_table_size; /* max table map entries */ + char *failover_command; /* execute command when failover happens */ - char *follow_master_command; /* execute command when failover is + char *follow_primary_command; /* execute command when failover is * ended */ char *failback_command; /* execute command when failback happens */ - bool failover_on_backend_error; /* If true, trigger fail over when + bool failover_on_backend_error; /* If true, trigger fail over when * writing to the backend * communication socket fails. * This is the same behavior of @@ -274,10 +396,13 @@ typedef struct * set to false, pgpool will * report an error and disconnect * the session. */ + bool failover_on_backend_shutdown; /* If true, trigger fail over + * when backend is going down */ bool detach_false_primary; /* If true, detach false primary */ char *recovery_user; /* PostgreSQL user name for online recovery */ char *recovery_password; /* PostgreSQL user password for online * recovery */ + char *recovery_database; /* Database name for recovery */ char *recovery_1st_stage_command; /* Online recovery command in 1st * stage */ char *recovery_2nd_stage_command; /* Online recovery command in 2nd @@ -299,7 +424,10 @@ typedef struct bool log_statement; /* logs all SQL statements */ bool log_per_node_statement; /* logs per node detailed SQL * statements */ + bool notice_per_node_statement; /* logs notice message for per + * node detailed SQL statements */ bool log_client_messages; /* If true, logs any client messages */ + int log_backend_messages; /* logs any backend messages */ char *lobj_lock_table; /* table name to lock for rewriting * lo_creat */ @@ -312,19 +440,29 @@ typedef struct /* followings till syslog, does not exist in the configuration file */ int num_reset_queries; /* number of queries in reset_query_list */ - int num_white_function_list; /* number of functions in - * white_function_list */ - int num_black_function_list; /* number of functions in - * black_function_list */ - int num_white_memqcache_table_list; /* number of functions in - * white_memqcache_table_list */ - int num_black_memqcache_table_list; /* number of functions in - * black_memqcache_table_list */ - int num_black_query_pattern_list; /* number of query patterns in - * black_query_pattern_list */ + int num_listen_addresses; /* number of entries in + * listen_addresses */ + int num_pcp_listen_addresses; /* number of entries in + * pcp_listen_addresses */ + int num_unix_socket_directories; /* number of entries in + * unix_socket_directories */ + int num_pcp_socket_directories; /* number of entries in + * pcp_socket_dir */ + int num_read_only_function_list; /* number of functions in + * read_only_function_list */ + int num_write_function_list; /* number of functions in + * write_function_list */ + int num_cache_safe_memqcache_table_list; /* number of functions + * in + * cache_safe_memqcache_table_list */ + int num_cache_unsafe_memqcache_table_list; /* number of functions + * in + * cache_unsafe_memqcache_table_list */ + int num_primary_routing_query_pattern_list; /* number of query + * patterns in + * primary_routing_query_pattern_list */ int num_wd_monitoring_interfaces_list; /* number of items in * wd_monitoring_interfaces_list */ - /* ssl configuration */ bool ssl; /* if non 0, activate ssl support * (frontend+backend) */ @@ -333,23 +471,37 @@ typedef struct char *ssl_ca_cert; /* path to root (CA) certificate */ char *ssl_ca_cert_dir; /* path to directory containing CA * certificates */ - + char *ssl_crl_file; /* path to the SSL certificate revocation list + * file */ + char *ssl_ciphers; /* allowed ssl ciphers */ + bool ssl_prefer_server_ciphers; /* Use SSL cipher preferences, + * rather than the client's */ + char *ssl_ecdh_curve; /* the curve to use in ECDH key exchange */ + char *ssl_dh_params_file; /* path to the Diffie-Hellman parameters + * contained file */ + char *ssl_passphrase_command; /* path to the Diffie-Hellman + * parameters contained file */ int64 relcache_expire; /* relation cache life time in seconds */ int relcache_size; /* number of relation cache life entry */ - bool check_temp_table; /* enable temporary table check */ + CHECK_TEMP_TABLE_OPTION check_temp_table; /* how to check temporary + * table */ bool check_unlogged_table; /* enable unlogged table check */ + bool enable_shared_relcache; /* If true, relation cache stored in + * memory cache */ + RELQTARGET_OPTION relcache_query_target; /* target node to send + * relcache queries */ /* * followings are for regex support and do not exist in the configuration * file */ - RegPattern *lists_patterns; /* Precompiled regex patterns for black/white - * lists */ + RegPattern *lists_patterns; /* Precompiled regex patterns for + * write/readonly lists */ int pattc; /* number of regexp pattern */ int current_pattern_size; /* size of the regex pattern array */ RegPattern *lists_query_patterns; /* Precompiled regex patterns for - * black query pattern lists */ + * primary routing query pattern lists */ int query_pattc; /* number of regexp pattern */ int current_query_pattern_size; /* size of the regex pattern array */ @@ -382,15 +534,27 @@ typedef struct * by default */ char *memqcache_oiddir; /* Temporary work directory to record * table oids */ - char **white_memqcache_table_list; /* list of tables to memqcache */ - char **black_memqcache_table_list; /* list of tables not to memqcache */ + char **cache_safe_memqcache_table_list; /* list of tables to + * memqcache */ + char **cache_unsafe_memqcache_table_list; /* list of tables not to + * memqcache */ RegPattern *lists_memqcache_table_patterns; /* Precompiled regex patterns - * for black/white lists */ + * for cache safe/unsafe lists */ int memqcache_table_pattc; /* number of regexp pattern */ int current_memqcache_table_pattern_size; /* size of the regex * pattern array */ + /* + * user_redirect_preference_list = + * 'postgres:primary,user[0-4]:1,user[5-9]:2' + */ + char *user_redirect_preference_list; /* raw string in pgpool.conf */ + RegArray *redirect_usernames; /* Precompiled regex patterns for db + * preference list */ + Left_right_tokens *user_redirect_tokens; /* db redirect for dbname and + * node string */ + /* * database_redirect_preference_list = * 'postgres:primary,mydb[0-4]:1,mydb[5-9]:2' @@ -398,7 +562,7 @@ typedef struct char *database_redirect_preference_list; /* raw string in * pgpool.conf */ RegArray *redirect_dbnames; /* Precompiled regex patterns for db - * prefrence list */ + * preference list */ Left_right_tokens *db_redirect_tokens; /* db redirect for dbname and node * string */ @@ -409,7 +573,7 @@ typedef struct char *app_name_redirect_preference_list; /* raw string in * pgpool.conf */ RegArray *redirect_app_names; /* Precompiled regex patterns for app name - * prefrence list */ + * preference list */ Left_right_tokens *app_name_redirect_tokens; /* app name redirect for * app_name and node * string */ @@ -419,7 +583,7 @@ typedef struct * possible. If off, SQL comments * effectively prevent the judgment (pre * 3.4 behavior). For backward - * compatibilty sake, default is off. */ + * compatibility sake, default is off. */ DLBOW_OPTION disable_load_balance_on_write; /* Load balance behavior when * write query is issued in an @@ -440,6 +604,14 @@ typedef struct * will not be load balanced * until the session ends. */ + char *dml_adaptive_object_relationship_list; /* objects relationship + * list */ + DBObjectRelation *parsed_dml_adaptive_object_relationship_list; + + bool statement_level_load_balance; /* if on, select load + * balancing node per + * statement */ + /* * add for watchdog */ @@ -447,11 +619,33 @@ typedef struct bool failover_when_quorum_exists; /* Do failover only when wd * cluster holds the quorum */ bool failover_require_consensus; /* Only do failover when majority - * aggrees */ + * agrees */ bool allow_multiple_failover_requests_from_node; /* One Pgpool-II node * can send multiple * failover requests to * build consensus */ + bool enable_consensus_with_half_votes; + + /* + * apply majority rule for consensus and quorum computation at 50% of + * votes in a cluster with an even number of nodes. + */ + bool wd_remove_shutdown_nodes; + + /* + * revoke membership of properly shutdown watchdog nodes. + */ + int wd_lost_node_removal_timeout; + + /* + * timeout in seconds to revoke membership of LOST watchdog nodes + */ + int wd_no_show_node_removal_timeout; + + /* + * time in seconds to revoke membership of NO-SHOW watchdog node + */ + WdLifeCheckMethod wd_lifecheck_method; /* method of lifecheck. * 'heartbeat' or 'query' */ bool clear_memqcache_on_escalation; /* Clear query cache on shmem @@ -459,14 +653,15 @@ typedef struct char *wd_escalation_command; /* Executes this command at escalation * on new active pgpool. */ char *wd_de_escalation_command; /* Executes this command when - * master pgpool goes down. */ - char *wd_hostname; /* watchdog hostname */ - int wd_port; /* watchdog port */ + * leader pgpool goes down. */ int wd_priority; /* watchdog node priority, during leader * election */ - WdRemoteNodesConfig wd_remote_nodes; /* watchdog lists */ + int pgpool_node_id; /* pgpool (watchdog) node id */ + WdNodesConfig wd_nodes; /* watchdog lists */ char *trusted_servers; /* icmp reachable server list (A,B,C) */ - char *delegate_IP; /* delegate IP address */ + char *trusted_server_command; /* Executes this command when upper + * servers are observed */ + char *delegate_ip; /* delegate IP address */ int wd_interval; /* lifecheck interval (sec) */ char *wd_authkey; /* Authentication key for watchdog * communication */ @@ -482,19 +677,30 @@ typedef struct * lifecheck */ char *wd_lifecheck_user; /* PostgreSQL user name for watchdog */ char *wd_lifecheck_password; /* password for watchdog user */ - int wd_heartbeat_port; /* Port number for heartbeat lifecheck */ + char *wd_listen_address; /* listen address for watchdog */ + int wd_listen_port; /* listen port for watchdog */ int wd_heartbeat_keepalive; /* Interval time of sending heartbeat * signal (sec) */ int wd_heartbeat_deadtime; /* Deadtime interval for heartbeat * signal (sec) */ - WdHbIf hb_if[WD_MAX_IF_NUM]; /* interface devices */ - int num_hb_if; /* number of interface devices */ + WdHbIf hb_ifs[WD_MAX_IF_NUM]; /* heartbeat interfaces of all + * watchdog nodes */ + WdHbIf hb_local_if[WD_MAX_IF_NUM]; /* local heartbeat interfaces */ + int num_hb_local_if; /* number of local interface */ + WdHbIf hb_dest_if[WD_MAX_IF_NUM]; /* heartbeat destination + * interfaces */ + int num_hb_dest_if; /* number of destination interface */ + char *wd_heartbeat_listen_addresses; /* listen hostnames/IP + * addresses for heartbeat */ + int wd_heartbeat_listen_port; /* listen port for heartbeat */ char **wd_monitoring_interfaces_list; /* network interface name list * to be monitored by watchdog */ + bool health_check_test; /* if on, enable health check testing */ -} POOL_CONFIG; +} POOL_CONFIG; -extern POOL_CONFIG * pool_config; +extern POOL_CONFIG *pool_config; +extern char config_file_dir[]; /* directory path of config file pgpool.conf */ typedef enum { @@ -503,7 +709,7 @@ typedef enum CFGCXT_RELOAD, CFGCXT_PCP, CFGCXT_SESSION -} ConfigContext; +} ConfigContext; typedef struct ConfigVariable { @@ -513,17 +719,13 @@ typedef struct ConfigVariable struct ConfigVariable *next; } ConfigVariable; - extern int pool_init_config(void); extern bool pool_get_config(const char *config_file, ConfigContext context); extern int eval_logical(const char *str); extern char *pool_flag_to_str(unsigned short flag); -extern char *backend_status_to_str(BackendInfo * bi); +extern char *backend_status_to_str(BackendInfo *bi); /* methods used for regexp support */ extern int add_regex_pattern(const char *type, char *s); -extern int growFunctionPatternArray(RegPattern item); -extern int growMemqcacheTablePatternArray(RegPattern item); -extern int growQueryPatternArray(RegPattern item); #endif /* POOL_CONFIG_H */ diff --git a/src/include/pool_config_variables.h b/src/include/pool_config_variables.h index 7bf4f51be..1c6a2955e 100644 --- a/src/include/pool_config_variables.h +++ b/src/include/pool_config_variables.h @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2020 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -29,13 +29,13 @@ typedef enum { CONNECTION_CONFIG, CONNECTION_POOL_CONFIG, - LOGING_CONFIG, + LOGGING_CONFIG, HEALTH_CHECK_CONFIG, FILE_LOCATION_CONFIG, LOAD_BALANCE_CONFIG, REPLICATION_CONFIG, STREAMING_REPLICATION_CONFIG, - MASTER_SLAVE_CONFIG, + MAIN_REPLICA_CONFIG, WATCHDOG_CONFIG, SSL_CONFIG, FAILOVER_CONFIG, @@ -43,7 +43,7 @@ typedef enum WATCHDOG_LIFECHECK, GENERAL_CONFIG, CACHE_CONFIG -} config_group; +} config_group; typedef enum { @@ -58,7 +58,7 @@ typedef enum CONFIG_VAR_TYPE_DOUBLE_ARRAY, CONFIG_VAR_TYPE_STRING_ARRAY, CONFIG_VAR_TYPE_GROUP -} config_type; +} config_type; /* * The possible values of an enum variable are specified by an array of @@ -91,10 +91,24 @@ typedef enum #define VAR_NO_RESET_ALL 0x0008 /* for variables not to be reset * with reset all */ #define ARRAY_VAR_ALLOW_NO_INDEX 0x0010 /* for array type vars that also - * alows variable with same naem + * allows variable with same name * with out index */ #define DEFAULT_FOR_NO_VALUE_ARRAY_VAR 0x0020 +/* From PG's src/include/utils/guc.h */ +#define GUC_UNIT_KB 0x1000 /* value is in kilobytes */ +#define GUC_UNIT_BLOCKS 0x2000 /* value is in blocks */ +#define GUC_UNIT_XBLOCKS 0x3000 /* value is in xlog blocks */ +#define GUC_UNIT_MB 0x4000 /* value is in megabytes */ +#define GUC_UNIT_BYTE 0x8000 /* value is in bytes */ +#define GUC_UNIT_MEMORY 0xF000 /* mask for size-related units */ + +#define GUC_UNIT_MS 0x10000 /* value is in milliseconds */ +#define GUC_UNIT_S 0x20000 /* value is in seconds */ +#define GUC_UNIT_MIN 0x30000 /* value is in minutes */ +#define GUC_UNIT_TIME 0xF0000 /* mask for time-related units */ +#define GUC_UNIT (GUC_UNIT_MEMORY | GUC_UNIT_TIME) + /* * Signatures for per-variable check/assign/show functions */ @@ -142,15 +156,15 @@ struct config_generic GucSource *sources; /* source of the current actual value, For * array type config elements it contains the - * corosponding source of each individual + * corresponding source of each individual * element */ GucSource *reset_sources; /* source of the reset value, For array type * config elements it contains the - * corosponding source of each individual + * corresponding source of each individual * element */ ConfigContext *scontexts; /* context that set the current value, For * array type config elements it contains the - * corosponding context of each individual + * corresponding context of each individual * element */ }; @@ -288,7 +302,7 @@ struct config_string_list char ***variable; int *list_elements_count; const char *boot_val; - const char *seperator; + const char *separator; bool compute_regex; ConfigStringListAssignFunc assign_func; ConfigStringListAssignFunc check_func; @@ -321,17 +335,17 @@ struct config_grouped_array_var extern void InitializeConfigOptions(void); extern bool set_one_config_option(const char *name, const char *value, - ConfigContext context, GucSource source, int elevel); + ConfigContext context, GucSource source, int elevel); extern bool set_config_options(ConfigVariable *head_p, - ConfigContext context, GucSource source, int elevel); + ConfigContext context, GucSource source, int elevel); #ifndef POOL_PRIVATE -extern bool report_config_variable(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *var_name); -extern bool report_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern bool set_config_option_for_session(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *name, const char *value); -bool reset_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern bool report_config_variable(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *var_name); +extern bool report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern bool set_config_option_for_session(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *name, const char *value); +bool reset_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); #endif #endif /* POOL_CONFIG_VARIABLES_H */ diff --git a/src/include/pool_type.h b/src/include/pool_type.h index 43f29a595..078376b50 100644 --- a/src/include/pool_type.h +++ b/src/include/pool_type.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2015 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -31,32 +31,34 @@ #include #include #include "libpq-fe.h" -/* Define common boolean type. C++ and BEOS already has it so exclude them. */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif /* __cplusplus */ -#endif /* c_plusplus */ - -#ifndef __BEOS__ -#ifndef __cplusplus -#ifndef bool -typedef char bool; -#endif -#ifndef true -#define true ((bool) 1) -#endif + +/* ---------------------------------------------------------------- + * Section 2: bool, true, false + * ---------------------------------------------------------------- + */ + +/* + * bool + * Boolean value, either true or false. + * + * PostgreSQL currently cannot deal with bool of size other than 1; there are + * static assertions around the code to prevent that. + */ + +#include + +/* + * Pgpool-II still uses TRUE/FALSE, that are only used Windows build in + * PostgreSQL. In the feature, we should replace TRUE/FALSE with true/false, + * but until that day... + */ + #ifndef TRUE #define TRUE ((bool) 1) #endif -#ifndef false -#define false ((bool) 0) -#endif #ifndef FALSE #define FALSE ((bool) 0) #endif -#endif /* not C++ */ -#endif /* __BEOS__ */ /* ---------------------------------------------------------------- * Section 5: offsetof, lengthof, endof, alignment @@ -108,12 +110,12 @@ typedef enum { LOAD_UNSELECTED = 0, LOAD_SELECTED -} LOAD_BALANCE_STATUS; +} LOAD_BALANCE_STATUS; extern int assert_enabled; extern void ExceptionalCondition(const char *conditionName, - const char *errorType, - const char *fileName, int lineNumber) __attribute__((noreturn)); + const char *errorType, + const char *fileName, int lineNumber) __attribute__((noreturn)); #define MAXIMUM_ALIGNOF 8 @@ -222,6 +224,12 @@ typedef uint8 bits8; /* >= 8 bits */ typedef uint16 bits16; /* >= 16 bits */ typedef uint32 bits32; /* >= 32 bits */ +/* + * 64-bit integers + */ +#define INT64CONST(x) INT64_C(x) +#define UINT64CONST(x) UINT64_C(x) + /* * stdint.h limits aren't guaranteed to be present and aren't guaranteed to * have compatible types with our fixed width types. So just define our own. @@ -500,4 +508,19 @@ typedef void (*pg_on_exit_callback) (int code, Datum arg); } while (0) +/* + * Hints to the compiler about the likelihood of a branch. Both likely() and + * unlikely() return the boolean value of the contained expression. + * + * These should only be used sparingly, in very hot code paths. It's very easy + * to mis-estimate likelihoods. + */ +#if __GNUC__ >= 3 +#define likely(x) __builtin_expect((x) != 0, 1) +#define unlikely(x) __builtin_expect((x) != 0, 0) +#else +#define likely(x) ((x) != 0) +#define unlikely(x) ((x) != 0) +#endif + #endif /* POOL_TYPE_H */ diff --git a/src/include/protocol/pool_connection_pool.h b/src/include/protocol/pool_connection_pool.h new file mode 100644 index 000000000..225b9c09d --- /dev/null +++ b/src/include/protocol/pool_connection_pool.h @@ -0,0 +1,43 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2024 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + + +#ifndef pool_connection_pool_h +#define pool_connection_pool_h + +extern POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ + +extern int pool_init_cp(void); +extern POOL_CONNECTION_POOL *pool_create_cp(void); +extern POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket); +extern void pool_discard_cp(char *user, char *database, int protoMajor); +extern void pool_backend_timer(void); +extern void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend); +extern RETSIGTYPE pool_backend_timer_handler(int sig); +extern int connect_inet_domain_socket(int slot, bool retry); +extern int connect_unix_domain_socket(int slot, bool retry); +extern int connect_inet_domain_socket_by_port(char *host, int port, bool retry); +extern int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry); +extern int pool_pool_index(void); +extern void close_all_backend_connections(void); +extern void update_pooled_connection_count(void); +extern int in_use_backend_id(POOL_CONNECTION_POOL *pool); + +#endif /* pool_connection_pool_h */ diff --git a/src/include/protocol/pool_pg_utils.h b/src/include/protocol/pool_pg_utils.h new file mode 100644 index 000000000..7a9117788 --- /dev/null +++ b/src/include/protocol/pool_pg_utils.h @@ -0,0 +1,64 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + + +#ifndef pool_pg_utils_h +#define pool_pg_utils_h + +#include "pool.h" + +#define MAX_PG_VERSION_STRING 512 + +/* + * PostgreSQL version descriptor + */ +typedef struct +{ + short major; /* major version number in up to 3 digits + * decimal. Examples: 120, 110, 100, 96. */ + short minor; /* minor version number in up to 2 digits + * decimal. Examples: 0, 1, 2, 10, 23. */ + char version_string[MAX_PG_VERSION_STRING + 1]; /* original version + * string */ +} PGVersion; + + +extern void send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp); +extern void pool_free_startup_packet(StartupPacket *sp); + +extern POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( + int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); +extern POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection_noerror( + int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); +extern void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT *cp); +extern int select_load_balancing_node(void); + +extern PGVersion *Pgversion(POOL_CONNECTION_POOL *backend); + +/* pool_pg_utils.c */ +extern bool si_snapshot_prepared(void); +extern bool si_snapshot_acquire_command(Node *node); +extern void si_acquire_snapshot(void); +extern void si_snapshot_acquired(void); +extern void si_commit_request(void); +extern void si_commit_done(void); +extern int check_replication_delay(int node_id); + +#endif /* pool_pg_utils_h */ diff --git a/src/include/protocol/pool_process_query.h b/src/include/protocol/pool_process_query.h new file mode 100644 index 000000000..f54b694a1 --- /dev/null +++ b/src/include/protocol/pool_process_query.h @@ -0,0 +1,86 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2025 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + + +#ifndef pool_process_query_h +#define pool_process_query_h + +#define LOCK_COMMENT "/*INSERT LOCK*/" +#define LOCK_COMMENT_SZ (sizeof(LOCK_COMMENT)-1) +#define NO_LOCK_COMMENT "/*NO INSERT LOCK*/" +#define NO_LOCK_COMMENT_SZ (sizeof(NO_LOCK_COMMENT)-1) + + +extern void reset_variables(void); +extern void reset_connection(void); +extern void per_node_statement_log(POOL_CONNECTION_POOL *backend, + int node_id, char *query); +extern int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, + int major, bool unread, char **message); +extern POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, + char *query, int protoMajor, int pid, char *key, int keylen, int no_ready_for_query); +extern void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int major); +extern void free_select_result(POOL_SELECT_RESULT *result); +extern int compare(const void *p1, const void *p2); +extern void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int major); +extern POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL *cp); +extern void pool_dump_valid_backend(int backend_id); +extern bool pool_push_pending_data(POOL_CONNECTION *backend); + + +extern void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend); +extern POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +extern void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line); +extern void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line); +extern void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + char *severity, + int line); + +extern POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents); + +extern POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + int reset_request); +extern bool is_backend_cache_empty(POOL_CONNECTION_POOL *backend); +extern void pool_send_readyforquery(POOL_CONNECTION *frontend); + +extern char *extract_error_kind(char *message, int major); + +#endif /* pool_process_query_h */ diff --git a/src/include/protocol/pool_proto_modules.h b/src/include/protocol/pool_proto_modules.h index a4ab34d94..ae6ec5269 100644 --- a/src/include/protocol/pool_proto_modules.h +++ b/src/include/protocol/pool_proto_modules.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2017 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -34,8 +34,6 @@ #include "utils/pool_process_reporting.h" #define SPECIFIED_ERROR 1 -#define POOL_DUMMY_WRITE_QUERY "DELETE FROM foo WHERE col = 'pgpool: unable to parse the query'" -#define POOL_DUMMY_READ_QUERY "SELECT 'pgpool: unable to parse the query'" #define POOL_ERROR_QUERY "send invalid query from pgpool to abort transaction" extern char *copy_table; /* copy table name */ @@ -50,146 +48,174 @@ extern char *parsed_query; /* * modules defined in pool_proto_modules.c */ -extern POOL_STATUS SimpleQuery(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS Execute(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS Execute(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS Parse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS Parse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS Bind(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS Bind(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS Describe(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS Describe(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS Close(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS Close(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS FunctionCall3(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS FunctionCall3(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS ReadyForQuery(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, bool send_ready, bool cache_commit); +extern POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, bool send_ready, bool cache_commit); -extern POOL_STATUS ParseComplete(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS ParseComplete(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS BindComplete(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS BindComplete(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS CloseComplete(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS CloseComplete(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS ParameterDescription(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS ParameterDescription(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS ErrorResponse3(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS ErrorResponse3(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS CopyInResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS CopyOutResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS CopyDataRows(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, int copyin); +extern POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int copyin); -extern POOL_STATUS FunctionCall(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS ProcessBackendResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int *state, short *num_fields); -extern void handle_query_context(POOL_CONNECTION_POOL * backend);; +extern void handle_query_context(POOL_CONNECTION_POOL *backend);; + +extern void pool_emit_log_for_message_length_diff(int *length_array, char *name); + +extern void per_node_statement_notice(POOL_CONNECTION_POOL *backend, int node_id, char *query); + +extern void log_backend_messages(unsigned char kind, int backend_id); /* * modules defined in pool_proto2.c */ -extern POOL_STATUS AsciiRow(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, short num_fields); -extern POOL_STATUS BinaryRow(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, +extern POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, short num_fields); -extern POOL_STATUS CompletedResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS CursorResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS CursorResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern void EmptyQueryResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern void EmptyQueryResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS FunctionResultResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern POOL_STATUS NotificationResponse(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend); +extern POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); -extern int RowDescription(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, - short *result); +extern int RowDescription(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + short *result); -extern void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion, int pid, int key); -extern POOL_STATUS wait_for_query_response(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion); +extern void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, + int protoVersion, int pid, char *key, int keylen); +extern POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoVersion); extern bool is_select_query(Node *node, char *sql); extern bool is_commit_query(Node *node); extern bool is_rollback_query(Node *node); extern bool is_commit_or_rollback_query(Node *node); +extern bool is_rollback_to_query(Node *node); extern bool is_strict_query(Node *node); /* returns non 0 if this is strict * query */ -extern int need_insert_lock(POOL_CONNECTION_POOL * backend, char *query, Node *node); -extern POOL_STATUS insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *query, InsertStmt *node, int lock_kind); +extern int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node); +extern POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *query, InsertStmt *node, int lock_kind); extern char *parse_copy_data(char *buf, int len, char delimiter, int col_id); extern int check_copy_from_stdin(Node *node); /* returns non 0 if this is a * COPY FROM STDIN */ -extern void query_ps_status(char *query, POOL_CONNECTION_POOL * backend); /* show ps status */ -extern POOL_STATUS start_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, Node *node); -extern POOL_STATUS end_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern int detect_deadlock_error(POOL_CONNECTION * master, int major); -extern int detect_serialization_error(POOL_CONNECTION * master, int major, bool unread); -extern int detect_active_sql_transaction_error(POOL_CONNECTION * backend, int major); -extern int detect_query_cancel_error(POOL_CONNECTION * backend, int major); -extern int detect_idle_in_transaction_sesion_timeout_error(POOL_CONNECTION * backend, int major); -extern bool is_partition_table(POOL_CONNECTION_POOL * backend, Node *node); -extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL * cp); -extern void query_cache_register(char kind, POOL_CONNECTION * frontend, char *database, char *data, int data_len); +extern void query_ps_status(char *query, POOL_CONNECTION_POOL *backend); /* show ps status */ +extern POOL_STATUS start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node); +extern POOL_STATUS end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern int detect_deadlock_error(POOL_CONNECTION *backend, int major); +extern int detect_serialization_error(POOL_CONNECTION *backend, int major, bool unread); +extern int detect_active_sql_transaction_error(POOL_CONNECTION *backend, int major); +extern int detect_query_cancel_error(POOL_CONNECTION *backend, int major); +extern int detect_idle_in_transaction_session_timeout_error(POOL_CONNECTION *backend, int major); +extern int detect_idle_session_timeout_error(POOL_CONNECTION *backend, int major); +extern bool is_partition_table(POOL_CONNECTION_POOL *backend, Node *node); +extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp); +extern void query_cache_register(char kind, POOL_CONNECTION *frontend, char *database, char *data, int data_len); extern int is_drop_database(Node *node); /* returns non 0 if this is a DROP * DATABASE command */ -extern void send_simplequery_message(POOL_CONNECTION * backend, int len, char *string, int major); -extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL * backend, +extern void send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major); +extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend, int node_id, char *kind, int len, char *string); -extern int synchronize(POOL_CONNECTION * cp); -extern void read_kind_from_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *decided_kind); -extern void read_kind_from_one_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *kind, int node); -extern void do_error_command(POOL_CONNECTION * backend, int major); -extern void raise_intentional_error_if_need(POOL_CONNECTION_POOL * backend); +extern int synchronize(POOL_CONNECTION *cp); +extern void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *decided_kind); +extern void read_kind_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *kind, int node); +extern void do_error_command(POOL_CONNECTION *backend, int major); +extern void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend); -extern void pool_at_command_success(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); /* * modules defined in CommandComplete.c */ -extern POOL_STATUS CommandComplete(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, bool command_complete); +extern POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, bool command_complete); + +extern int pool_read_message_length(POOL_CONNECTION_POOL *cp); +extern int *pool_read_message_length2(POOL_CONNECTION_POOL *cp); +extern signed char pool_read_kind(POOL_CONNECTION_POOL *cp); +extern int pool_read_int(POOL_CONNECTION_POOL *cp); + +/* pool_proto2.c */ +extern POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +extern void NoticeResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +extern char per_node_error_log(POOL_CONNECTION_POOL *backend, int node_id, + char *query, char *prefix, bool unread); + +extern void init_pi_set(void); +extern void pi_set(int node_id); +extern bool is_pi_set(uint64 *node_ids, int node_id); #endif diff --git a/src/include/protocol/protocol_defs.h b/src/include/protocol/protocol_defs.h index 14da4c424..cb9016cf2 100644 --- a/src/include/protocol/protocol_defs.h +++ b/src/include/protocol/protocol_defs.h @@ -17,11 +17,17 @@ #ifndef pgpool_protocol_defs_h #define pgpool_protocol_defs_h -#define SEQUENCETABLEQUERY "SELECT d.adsrc FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s' AND d.adsrc ~ 'nextval'" +#define SEQUENCETABLEQUERY (Pgversion(backend)->major >= 73 ? \ + "SELECT pg_get_expr(d.adbin, d.adrelid) FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s' AND d.pg_get_expr(d.adbin, d.adrelid) ~ 'nextval'" : \ + "SELECT d.adsrc FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s' AND d.adsrc ~ 'nextval'") -#define SEQUENCETABLEQUERY2 "SELECT d.adsrc FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s') AND d.adsrc ~ 'nextval'" +#define SEQUENCETABLEQUERY2 (Pgversion(backend)->major >= 73 ? \ + "SELECT pg_get_expr(d.adbin, d.adrelid) FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s') AND pg_get_expr(d.adbin, d.adrelid) ~ 'nextval'" : \ + "SELECT d.adsrc FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s') AND d.adsrc ~ 'nextval'") -#define SEQUENCETABLEQUERY3 "SELECT d.adsrc FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pg_catalog.to_regclass('%s') AND d.adsrc ~ 'nextval'" +#define SEQUENCETABLEQUERY3 (Pgversion(backend)->major >= 73 ? \ + "SELECT pg_get_expr(d.adbin, d.adrelid) FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pg_catalog.to_regclass('%s') AND pg_get_expr(d.adbin, d.adrelid) ~ 'nextval'" : \ + "SELECT d.adsrc FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pg_catalog.to_regclass('%s') AND d.adsrc ~ 'nextval'") /* query to lock a row by only the specified table name without regard to the schema */ #define ROWLOCKQUERY "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = '%s' ORDER BY oid LIMIT 1) FOR UPDATE" diff --git a/src/include/query_cache/pool_memqcache.h b/src/include/query_cache/pool_memqcache.h index ee0d23bac..8c809b37e 100644 --- a/src/include/query_cache/pool_memqcache.h +++ b/src/include/query_cache/pool_memqcache.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2012 PgPool Global Development Group + * Copyright (c) 2003-2024 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -29,6 +29,9 @@ #include "pool.h" #include +#define FORCE_QUERY_CACHE "/*FORCE QUERY CACHE*/" +#define FORCE_QUERY_CACHE_COMMENT_SZ (sizeof(FORCE_QUERY_CACHE)-1) + #define NO_QUERY_CACHE "/*NO QUERY CACHE*/" #define NO_QUERY_CACHE_COMMENT_SZ (sizeof(NO_QUERY_CACHE)-1) @@ -39,7 +42,7 @@ * block". Each block is assigned a "cache block id", which is * starting with 0. */ -typedef char *POOL_CACH_BLOCK; /* pointer to cache block */ +typedef char *POOL_CACHE_BLOCK; /* pointer to cache block */ typedef unsigned int POOL_CACHE_BLOCKID; /* cache block id */ typedef unsigned int POOL_CACHE_ITEMID; /* cache item id */ @@ -50,7 +53,7 @@ typedef struct { POOL_CACHE_BLOCKID blockid; POOL_CACHE_ITEMID itemid; -} POOL_CACHEID; /* cache id */ +} POOL_CACHEID; /* cache id */ /* * Each block has management space called "cache block header" at the @@ -59,33 +62,39 @@ typedef struct #define POOL_BLOCK_USED 0x0001 /* is this block used? */ +/* + * Cache block header (12 bytes) + */ typedef struct { unsigned char flags; /* flags. see above */ unsigned int num_items; /* number of items */ unsigned int free_bytes; /* total free space in bytes */ -} POOL_CACHE_BLOCK_HEADER; +} POOL_CACHE_BLOCK_HEADER; typedef struct { char query_hash[POOL_MD5_HASHKEYLEN]; -} POOL_QUERY_HASH; +} POOL_QUERY_HASH; #define POOL_ITEM_USED 0x0001 /* is this item used? */ #define POOL_ITEM_HAS_NEXT 0x0002 /* is this item has "next" item? */ #define POOL_ITEM_DELETED 0x0004 /* is this item deleted? */ +/* + * Cache item pointer (48 bytes) + */ typedef struct { POOL_QUERY_HASH query_hash; /* md5 hashed query signature */ POOL_CACHEID next; /* next cache item if any */ unsigned int offset; /* item offset in this block */ unsigned char flags; /* flags. see above */ -} POOL_CACHE_ITEM_POINTER; +} POOL_CACHE_ITEM_POINTER; /* * Each block holds several "cache item", which consists of variable - * length of Data(header plus RowDescription packet and DataRow + * length of Data (header plus RowDescription packet and DataRow * packet). Each cache item is assigned "cache item id", which * represents the cache item order in a block. */ @@ -98,18 +107,20 @@ typedef struct /* * "Cache Item header" structure is used to manage each cache item. + * (16 bytes) */ typedef struct { unsigned int total_length; /* total length in bytes including myself */ time_t timestamp; /* cache creation time */ -} POOL_CACHE_ITEM_HEADER; + int64 expire; /* cache expire duration in seconds */ +} POOL_CACHE_ITEM_HEADER; typedef struct { POOL_CACHE_ITEM_HEADER header; /* cache item header */ char data[1]; /* variable length data follows */ -} POOL_CACHE_ITEM; +} POOL_CACHE_ITEM; /* * Possible the largest free space size in bytes @@ -123,7 +134,7 @@ typedef struct extern int memcached_connect(void); extern void memcached_disconnect(void); -extern void memqcache_register(char kind, POOL_CONNECTION * frontend, char *data, int data_len); +extern void memqcache_register(char kind, POOL_CONNECTION *frontend, char *data, int data_len); /* * Cache key @@ -133,7 +144,7 @@ typedef union POOL_CACHEID cacheid; /* cache key (shmem configuration) */ char hashkey[POOL_MD5_HASHKEYLEN]; /* cache key (memcached * configuration) */ -} POOL_CACHEKEY; +} POOL_CACHEKEY; /* * Internal buffer structure @@ -143,7 +154,7 @@ typedef struct size_t bufsize; /* buffer size */ size_t buflen; /* used length */ char *buf; /* buffer */ -} POOL_INTERNAL_BUFFER; +} POOL_INTERNAL_BUFFER; /* * Temporary query cache buffer @@ -157,7 +168,7 @@ typedef struct POOL_INTERNAL_BUFFER *buffer; int num_oids; POOL_INTERNAL_BUFFER *oids; -} POOL_TEMP_QUERY_CACHE; +} POOL_TEMP_QUERY_CACHE; /* * Temporary query cache buffer array @@ -167,7 +178,7 @@ typedef struct int num_caches; int array_size; POOL_TEMP_QUERY_CACHE *caches[1]; /* actual data continues... */ -} POOL_QUERY_CACHE_ARRAY; +} POOL_QUERY_CACHE_ARRAY; /* * Query cache statistics structure. This area must be placed on shared @@ -178,7 +189,7 @@ typedef struct time_t start_time; /* start time when the statistics begins */ long long int num_selects; /* number of successful SELECTs */ long long int num_cache_hits; /* number of SELECTs extracted from cache */ -} POOL_QUERY_CACHE_STATS; +} POOL_QUERY_CACHE_STATS; /* * Shared memory cache stats interface. @@ -196,29 +207,29 @@ typedef struct * fragment(unusable) cache * entries */ POOL_QUERY_CACHE_STATS cache_stats; -} POOL_SHMEM_STATS; +} POOL_SHMEM_STATS; /*-------------------------------------------------------------------------------- * On shared memory hash table implementation *-------------------------------------------------------------------------------- */ -/* Hash element */ +/* Hash element (48 bytes) */ typedef struct POOL_HASH_ELEMENT { struct POOL_HASH_ELEMENT *next; /* link to next entry */ POOL_QUERY_HASH hashkey; /* MD5 hash key */ POOL_CACHEID cacheid; /* logical location of this cache element */ -} POOL_HASH_ELEMENT; +} POOL_HASH_ELEMENT; typedef uint32 POOL_HASH_KEY; -/* Hash header element */ +/* Hash header element (16 bytes) */ typedef struct { POOL_HASH_KEY hashkey; /* hash key */ POOL_HASH_ELEMENT *element; /* hash element */ -} POOL_HEADER_ELEMENT; +} POOL_HEADER_ELEMENT; /* Hash header */ typedef struct @@ -226,22 +237,33 @@ typedef struct long nhash; /* number of hash keys (power of 2) */ uint32 mask; /* mask for hash function */ POOL_HEADER_ELEMENT elements[1]; /* actual hash elements follows */ -} POOL_HASH_HEADER; +} POOL_HASH_HEADER; + +typedef enum +{ + POOL_MEMQ_SHARED_LOCK = 0, + POOL_MEMQ_EXCLUSIVE_LOCK, +} POOL_MEMQ_LOCK_TYPE; extern int pool_hash_init(int nelements); -extern POOL_CACHEID * pool_hash_search(POOL_QUERY_HASH * key); -extern int pool_hash_delete(POOL_QUERY_HASH * key); +extern size_t pool_hash_size(int nelements); +extern POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key); +extern int pool_hash_delete(POOL_QUERY_HASH *key); extern uint32 hash_any(unsigned char *k, int keylen); -extern POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION * frontend, - POOL_CONNECTION_POOL * backend, - char *contents, bool *foundp); +extern POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + char *contents, bool use_fake_cache, bool *foundp); + +extern int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, char **buf, size_t *len); +extern int pool_catalog_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *data, size_t datalen); extern bool pool_is_likely_select(char *query); -extern bool pool_is_table_in_black_list(const char *table_name); -extern bool pool_is_table_in_white_list(const char *table_name); +extern bool pool_is_table_in_unsafe_list(const char *table_name); +extern bool pool_is_table_in_safe_list(const char *table_name); extern bool pool_is_allow_to_cache(Node *node, char *query); extern int pool_extract_table_oids(Node *node, int **oidsp); +extern int pool_extract_withclause_oids(Node *with, int *oidsp); extern void pool_add_dml_table_oid(int oid); extern void pool_discard_oid_maps(void); extern int pool_get_database_oid_from_dbname(char *dbname); @@ -254,27 +276,38 @@ extern size_t pool_shared_memory_fsmm_size(void); extern int pool_init_fsmm(size_t size); extern void pool_allocate_fsmm_clock_hand(void); -extern POOL_QUERY_CACHE_ARRAY * pool_create_query_cache_array(void); -extern void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY * cache_array); +extern POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void); +extern void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array); -extern POOL_TEMP_QUERY_CACHE * pool_create_temp_query_cache(char *query); -extern void pool_handle_query_cache(POOL_CONNECTION_POOL * backend, char *query, Node *node, char state); +extern POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query); +extern void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *node, char state, + bool partial_fetch); extern int pool_init_memqcache_stats(void); -extern POOL_QUERY_CACHE_STATS * pool_get_memqcache_stats(void); +extern POOL_QUERY_CACHE_STATS *pool_get_memqcache_stats(void); extern void pool_reset_memqcache_stats(void); extern long long int pool_stats_count_up_num_selects(long long int num); extern long long int pool_stats_count_up_num_cache_hits(void); extern long long int pool_tmp_stats_count_up_num_selects(void); extern long long int pool_tmp_stats_get_num_selects(void); extern void pool_tmp_stats_reset_num_selects(void); -extern POOL_SHMEM_STATS * pool_get_shmem_storage_stats(void); +extern POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void); -extern POOL_TEMP_QUERY_CACHE * pool_get_current_cache(void); -extern POOL_TEMP_QUERY_CACHE * pool_get_current_cache(void); -extern void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE * temp_cache); +extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); +extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); +extern void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache); +extern void pool_discard_current_temp_query_cache(void); -extern void pool_shmem_lock(void); +extern void pool_shmem_lock(POOL_MEMQ_LOCK_TYPE type); extern void pool_shmem_unlock(void); +extern bool pool_is_shmem_lock(void); + +extern void InvalidateQueryCache(int tableoid, int dboid); + +extern void pool_init_whole_cache_blocks(void); + +extern void clear_query_cache(void); + +extern bool query_cache_delete_by_stmt(char *query, POOL_CONNECTION_POOL *backend); #endif /* POOL_MEMQCACHE_H */ diff --git a/src/include/rewrite/pool_lobj.h b/src/include/rewrite/pool_lobj.h index edd1373eb..192fab2b1 100644 --- a/src/include/rewrite/pool_lobj.h +++ b/src/include/rewrite/pool_lobj.h @@ -27,6 +27,6 @@ #define POOL_LOBJ_H #include "pool.h" -extern char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int *len); +extern char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int *len); #endif /* POOL_LOBJ_H */ diff --git a/src/include/rewrite/pool_timestamp.h b/src/include/rewrite/pool_timestamp.h index e58ddfb0b..d8472ab58 100644 --- a/src/include/rewrite/pool_timestamp.h +++ b/src/include/rewrite/pool_timestamp.h @@ -31,8 +31,8 @@ #include "parser/nodes.h" #include "context/pool_session_context.h" -extern char *rewrite_timestamp(POOL_CONNECTION_POOL * backend, Node *node, bool rewrite_to_params, POOL_SENT_MESSAGE * message); -extern char *bind_rewrite_timestamp(POOL_CONNECTION_POOL * backend, POOL_SENT_MESSAGE * message, const char *orig_msg, int *len); +extern char *rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, bool rewrite_to_params, POOL_SENT_MESSAGE *message); +extern char *bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, POOL_SENT_MESSAGE *message, const char *orig_msg, int *len); extern bool isSystemType(Node *node, const char *name); #endif /* POOL_TIMESTAMP_H */ diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 4acec995f..70960fd08 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) 2003-2014, PgPool Global Development Group + * Portions Copyright (c) 2003-2024, PgPool Global Development Group * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * @@ -121,8 +121,10 @@ typedef enum /* pgpool-II extension. This is same as ERROR but sets the * do not cache connection flag before transforming to ERROR. */ -#define FRONTEND_ERROR 23 /* transformed to ERROR at errstart */ -#define FRONTEND_ONLY_ERROR 24 /* this is treated as LOG message +#define FRONTEND_DEBUG 23 /* transformed to DEBUG at errstart */ +#define FRONTEND_LOG 24 /* transformed to LOG at errstart */ +#define FRONTEND_ERROR 25 /* transformed to ERROR at errstart */ +#define FRONTEND_ONLY_ERROR 26 /* this is treated as LOG message * internally for pgpool-II but forwarded * to frontend clients just like normal * errors followed by readyForQuery @@ -205,8 +207,9 @@ typedef enum #define TEXTDOMAIN NULL +extern bool message_level_is_interesting(int elevel); 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,...); #define errcode(sqlerrcode) \ @@ -219,56 +222,56 @@ extern int return_code(int retcode); extern int get_return_code(void); extern int -errmsg(const char *fmt,...) + errmsg(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int -errmsg_internal(const char *fmt,...) + errmsg_internal(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int -errmsg_plural(const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) + errmsg_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4))) -__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4))) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4))); extern int -errdetail(const char *fmt,...) + errdetail(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int -errdetail_internal(const char *fmt,...) + errdetail_internal(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int -errdetail_log(const char *fmt,...) + errdetail_log(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int -errdetail_plural(const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) + errdetail_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4))) -__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4))) + __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4))); extern int -errhint(const char *fmt,...) + errhint(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); /* * errcontext() is typically called in error context callback functions, not @@ -282,10 +285,10 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int set_errcontext_domain(const char *domain); extern int -errcontext_msg(const char *fmt,...) + errcontext_msg(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int errhidestmt(bool hide_stmt); @@ -339,10 +342,10 @@ extern int getinternalerrposition(void); extern void elog_start(const char *filename, int lineno, const char *funcname); extern void -elog_finish(int elevel, const char *fmt,...) + elog_finish(int elevel, const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); /* Support for attaching context information to error reports */ @@ -478,6 +481,7 @@ extern void ReThrowError(ErrorData *edata) __attribute__((noreturn)); extern void pg_re_throw(void) __attribute__((noreturn)); extern char *GetErrorContextStack(void); +extern void proc_exit(int); /* Hook for intercepting messages before they are sent to the server log */ typedef void (*emit_log_hook_type) (ErrorData *edata); @@ -502,7 +506,7 @@ typedef enum extern bool in_error_recursion_trouble(void); -#ifdef HAVE_VSYSLOG +#ifdef HAVE_SYSLOG extern void set_syslog_parameters(const char *ident, int facility); #endif @@ -512,10 +516,10 @@ extern void set_syslog_parameters(const char *ident, int facility); * safely (memory context, GUC load etc) */ extern void -write_stderr(const char *fmt,...) + write_stderr(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ -__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); + __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); void shmem_exit(int code); void on_exit_reset(void); @@ -524,4 +528,5 @@ void on_proc_exit(pg_on_exit_callback function, Datum arg); void on_shmem_exit(pg_on_exit_callback function, Datum arg); void on_system_exit(pg_on_exit_callback function, Datum arg); + #endif /* ELOG_H */ diff --git a/src/include/utils/fe_ports.h b/src/include/utils/fe_ports.h index 0561e993f..d7c783024 100644 --- a/src/include/utils/fe_ports.h +++ b/src/include/utils/fe_ports.h @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2014 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -28,48 +28,50 @@ #error "This file is not expected to be compiled for pgpool utilities only" #endif +#include #include #ifndef FE_PORTS #define FE_PORTS - +#include "parser/pool_parser.h" +#include "parser/pg_config_manual.h" #include "pool_type.h" extern char *simple_prompt(const char *prompt, int maxlen, bool echo); extern int _fe_error_level; -void *pg_malloc(size_t size); +void *pg_malloc(Size size); void *pg_malloc0(size_t size); -void *pg_realloc(void *ptr, size_t size); +void *pg_realloc(void *ptr, Size size); char *pg_strdup(const char *in); void pg_free(void *ptr); -void *palloc(unsigned int size); -void *palloc0(unsigned int size); +void *palloc(Size size); +void *palloc0(Size size); void pfree(void *pointer); char *pstrdup(const char *in); -void *repalloc(void *pointer, unsigned int size); +void *repalloc(void *pointer, Size size); #ifdef __GNUC__ extern int -errhint(const char *fmt,...) -__attribute__((format(printf, 1, 2))); + errhint(const char *fmt,...) + __attribute__((format(printf, 1, 2))); extern int -errdetail(const char *fmt,...) -__attribute__((format(printf, 1, 2))); + errdetail(const char *fmt,...) + __attribute__((format(printf, 1, 2))); extern void -errmsg(const char *fmt,...) -__attribute__((format(printf, 1, 2))); + errmsg(const char *fmt,...) + __attribute__((format(printf, 1, 2))); #else extern int errhint(const char *fmt,...); extern int errdetail(const char *fmt,...); extern void errmsg(const char *fmt,...); #endif -extern int errstart(int elevel, const char *filename, int lineno, - const char *funcname); +extern bool errstart(int elevel, const char *filename, int lineno, + const char *funcname, const char *domain); extern void errfinish(int dummy,...); /* @@ -112,18 +114,27 @@ extern void errfinish(int dummy,...); #define FATAL 21 /* fatal error - abort process */ #define PANIC 22 /* take down the other backends with me */ -#define FRONTEND_ERROR 23 /* transformed to ERROR at errstart */ -#define FRONTEND_ONLY_ERROR 24 /* this is treated as LOG message +#define FRONTEND_DEBUG 23 /* transformed to DEBUG at errstart */ +#define FRONTEND_LOG 24 /* transformed to LOG at errstart */ +#define FRONTEND_ERROR 25 /* transformed to ERROR at errstart */ +#define FRONTEND_ONLY_ERROR 26 /* this is treated as LOG message * internally for pgpool-II but forwarded * to frontend clients just like normal * errors followed by readyForQuery * message */ +#define exprLocation(x) errcode_ign(0) +#define _(x) (x) +#define gettext(x) (x) +#define dgettext(d,x) (x) +#define ngettext(s,p,n) ((n) == 1 ? (s) : (p)) +#define dngettext(d,s,p,n) ((n) == 1 ? (s) : (p)) + #define ereport(elevel, rest) \ do { \ const int elevel_ = (elevel); \ _fe_error_level = elevel_; \ - if (errstart(elevel_, __FILE__, __LINE__, __FUNCTION__)) \ + if (errstart(elevel_, __FILE__, __LINE__, __FUNCTION__, "")) \ rest; \ if (elevel_ >= ERROR && elevel_ != FRONTEND_ONLY_ERROR) \ exit(-1); \ @@ -137,4 +148,8 @@ typedef enum PGERROR_VERBOSE /* all the facts, ma'am */ } PGErrorVerbosity; +/* sprintf into a palloc'd buffer --- these are in psprintf.c */ +extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2); +extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0); + #endif /* FE_PORTS */ diff --git a/src/include/utils/getopt_long.h b/src/include/utils/getopt_long.h index dd5d123e2..a5432c712 100644 --- a/src/include/utils/getopt_long.h +++ b/src/include/utils/getopt_long.h @@ -36,9 +36,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/utils/json.h b/src/include/utils/json.h index 67cc0255a..8bf5b8f52 100644 --- a/src/include/utils/json.h +++ b/src/include/utils/json.h @@ -95,7 +95,7 @@ extern "C" size_t value_extra; /* how much extra space to allocate for * values? */ - } json_settings; + } json_settings; #define json_enable_comments 0x01 @@ -110,7 +110,7 @@ extern "C" json_boolean, json_null - } json_type; + } json_type; extern const struct _json_value json_value_none; @@ -121,7 +121,7 @@ extern "C" struct _json_value *value; - } json_object_entry; + } json_object_entry; typedef struct _json_value { @@ -285,13 +285,13 @@ extern "C" #endif - } json_value; + } json_value; json_value *json_parse(const json_char * json, size_t length); #define json_error_max 128 - json_value *json_parse_ex(json_settings * settings, + json_value *json_parse_ex(json_settings *settings, const json_char * json, size_t length, char *error); @@ -302,7 +302,7 @@ extern "C" /* Not usually necessary, unless you used a custom mem_alloc and now want to * use a custom mem_free. */ - void json_value_free_ex(json_settings * settings, + void json_value_free_ex(json_settings *settings, json_value *); @@ -311,10 +311,10 @@ extern "C" #endif /* pgpool-II extensions */ -json_value *json_get_value_for_key(json_value * source, const char *key); -int json_get_int_value_for_key(json_value * source, const char *key, int *value); -int json_get_long_value_for_key(json_value * source, const char *key, long *value); -char *json_get_string_value_for_key(json_value * source, const char *key); -int json_get_bool_value_for_key(json_value * source, const char *key, bool *value); +json_value *json_get_value_for_key(json_value *source, const char *key); +int json_get_int_value_for_key(json_value *source, const char *key, int *value); +int json_get_llong_value_for_key(json_value *source, const char *key, long long *value); +char *json_get_string_value_for_key(json_value *source, const char *key); +int json_get_bool_value_for_key(json_value *source, const char *key, bool *value); #endif diff --git a/src/include/utils/json_writer.h b/src/include/utils/json_writer.h index 87bca0d0d..028e03234 100644 --- a/src/include/utils/json_writer.h +++ b/src/include/utils/json_writer.h @@ -22,19 +22,19 @@ #ifndef pgpool_xcode_json_writer_h #define pgpool_xcode_json_writer_h - +#include "parser/stringinfo.h" #define MAX_STACK_DEPTH 10 typedef enum JWElementType { JWOBJECT, JWARRAY -} JWElementType; +} JWElementType; typedef struct JWStack { JWElementType elementType; int elementCount; -} JWStack; +} JWStack; typedef struct JsonNode { @@ -42,28 +42,28 @@ typedef struct JsonNode bool pretty; int stack_ptr; JWStack stack[MAX_STACK_DEPTH]; -} JsonNode; +} JsonNode; -extern JsonNode * jw_create(JWElementType rootElement, bool pretty_output); -extern JsonNode * jw_create_with_array(bool pretty_output); -extern JsonNode * jw_create_with_object(bool pretty_output); -extern bool jw_put_string(JsonNode * jNode, char *key, char *value); -extern bool jw_put_int(JsonNode * jNode, char *key, int value); -extern bool jw_put_bool(JsonNode * jNode, char *key, bool value); -extern bool jw_put_long(JsonNode * jNode, char *key, long value); -extern bool jw_put_null(JsonNode * jNode, char *key); -extern bool jw_put_string_value(JsonNode * jNode, char *value); -extern bool jw_put_int_value(JsonNode * jNode, int value); -extern bool jw_put_bool_value(JsonNode * jNode, bool value); -extern bool jw_put_long_value(JsonNode * jNode, long value); -extern bool jw_put_null_value(JsonNode * jNode); -extern bool jw_start_element(JsonNode * jNode, JWElementType element, char *key); -extern bool jw_start_array(JsonNode * jNode, char *key); -extern bool jw_start_object(JsonNode * jNode, char *key); -extern bool jw_end_element(JsonNode * jNode); -extern bool jw_finish_document(JsonNode * jNode); -extern char *jw_get_json_string(JsonNode * jNode); -extern int jw_get_json_length(JsonNode * jNode); -extern void jw_destroy(JsonNode * jNode); +extern JsonNode *jw_create(JWElementType rootElement, bool pretty_output); +extern JsonNode *jw_create_with_array(bool pretty_output); +extern JsonNode *jw_create_with_object(bool pretty_output); +extern bool jw_put_string(JsonNode *jNode, char *key, char *value); +extern bool jw_put_int(JsonNode *jNode, char *key, int value); +extern bool jw_put_bool(JsonNode *jNode, char *key, bool value); +extern bool jw_put_long(JsonNode *jNode, char *key, long value); +extern bool jw_put_null(JsonNode *jNode, char *key); +extern bool jw_put_string_value(JsonNode *jNode, char *value); +extern bool jw_put_int_value(JsonNode *jNode, int value); +extern bool jw_put_bool_value(JsonNode *jNode, bool value); +extern bool jw_put_long_value(JsonNode *jNode, long value); +extern bool jw_put_null_value(JsonNode *jNode); +extern bool jw_start_element(JsonNode *jNode, JWElementType element, char *key); +extern bool jw_start_array(JsonNode *jNode, char *key); +extern bool jw_start_object(JsonNode *jNode, char *key); +extern bool jw_end_element(JsonNode *jNode); +extern bool jw_finish_document(JsonNode *jNode); +extern char *jw_get_json_string(JsonNode *jNode); +extern int jw_get_json_length(JsonNode *jNode); +extern void jw_destroy(JsonNode *jNode); #endif diff --git a/src/include/utils/memdebug.h b/src/include/utils/memdebug.h index d258935ff..f28341d27 100644 --- a/src/include/utils/memdebug.h +++ b/src/include/utils/memdebug.h @@ -31,4 +31,17 @@ #define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size) do {} while (0) #endif +#ifdef CLOBBER_FREED_MEMORY + +/* Wipe freed memory for debugging purposes */ +static inline void +wipe_mem(void *ptr, size_t size) +{ + VALGRIND_MAKE_MEM_UNDEFINED(ptr, size); + memset(ptr, 0x7F, size); + VALGRIND_MAKE_MEM_NOACCESS(ptr, size); +} + +#endif /* CLOBBER_FREED_MEMORY */ + #endif /* MEMDEBUG_H */ diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index 0df8cd138..bdf93ea2a 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -73,14 +73,14 @@ extern void MemoryContextResetOnly(MemoryContext context); extern void MemoryContextResetChildren(MemoryContext context); extern void MemoryContextDeleteChildren(MemoryContext context); 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 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); @@ -129,9 +129,9 @@ GetMemoryChunkContext(void *pointer) * specific creation routines, and noplace else. */ extern MemoryContext MemoryContextCreate(NodeTag tag, Size size, - MemoryContextMethods *methods, - MemoryContext parent, - const char *name); + MemoryContextMethods *methods, + MemoryContext parent, + const char *name); /* @@ -140,16 +140,16 @@ extern MemoryContext MemoryContextCreate(NodeTag tag, Size size, /* aset.c */ extern MemoryContext AllocSetContextCreate(MemoryContext parent, - const char *name, - Size minContextSize, - Size initBlockSize, - Size maxBlockSize); + const char *name, + Size minContextSize, + Size initBlockSize, + Size maxBlockSize); /* slab.c */ extern MemoryContext SlabContextCreate(MemoryContext parent, - const char *name, - Size blockSize, - Size chunkSize); + const char *name, + Size blockSize, + Size chunkSize); /* * Recommended default alloc parameters, suitable for "ordinary" contexts diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 4b6359ca8..541e8e57e 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-2017, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/palloc.h @@ -29,7 +29,10 @@ #define PALLOC_H #include + #include "parser/pg_config_manual.h" +#include "parser/pool_parser.h" + /* * Type MemoryContextData is declared in nodes/memnodes.h. Most users * of memory allocation should just treat it as an abstract type, so we @@ -58,7 +61,7 @@ typedef struct MemoryContextCallback * Avoid accessing it directly! Instead, use MemoryContextSwitchTo() * to change the setting. */ -extern PGDLLIMPORT MemoryContext CurrentMemoryContext; +extern MemoryContext CurrentMemoryContext; /* * Flags for MemoryContextAllocExtended. @@ -72,9 +75,8 @@ extern PGDLLIMPORT MemoryContext CurrentMemoryContext; */ 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); @@ -82,19 +84,6 @@ extern void *palloc_extended(Size size, int flags); extern void *repalloc(void *pointer, Size size); extern void pfree(void *pointer); -/* - * The result of palloc() is always word-aligned, so we can skip testing - * alignment of the pointer when deciding which MemSet variant to use. - * Note that this variant does not offer any advantage, and should not be - * used, unless its "sz" argument is a compile-time constant; therefore, the - * issue that it evaluates the argument multiple times isn't a problem in - * practice. - */ -#define palloc0fast(sz) \ - ( MemSetTest(0, sz) ? \ - MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \ - MemoryContextAllocZero(CurrentMemoryContext, sz) ) - /* Higher-limit allocators. */ extern void *MemoryContextAllocHuge(MemoryContext context, Size size); extern void *repalloc_huge(void *pointer, Size size); @@ -119,7 +108,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/pg_prng.h b/src/include/utils/pg_prng.h new file mode 100644 index 000000000..edc20bee6 --- /dev/null +++ b/src/include/utils/pg_prng.h @@ -0,0 +1,68 @@ +/* + * This file was imported from PostgreSQL source code + * (src/include/common/pg_prng.h). + */ + +/*------------------------------------------------------------------------- + * + * Pseudo-Random Number Generator + * + * Portions Copyright (c) 2025, PgPool Global Development Group + * Portions Copyright (c) 2021-2025, PostgreSQL Global Development Group + * + * src/include/common/pg_prng.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PRNG_H +#define PG_PRNG_H + +/* + * State vector for PRNG generation. Callers should treat this as an + * opaque typedef, but we expose its definition to allow it to be + * embedded in other structs. + */ +typedef struct pg_prng_state +{ + uint64 s0, + s1; +} pg_prng_state; + +/* + * Callers not needing local PRNG series may use this global state vector, + * after initializing it with one of the pg_prng_...seed functions. + */ +extern PGDLLIMPORT pg_prng_state pg_global_prng_state; + +extern void pg_prng_seed(pg_prng_state *state, uint64 seed); +extern void pg_prng_fseed(pg_prng_state *state, double fseed); +extern bool pg_prng_seed_check(pg_prng_state *state); + +/* + * Initialize the PRNG state from the pg_strong_random source, + * taking care that we don't produce all-zeroes. If this returns false, + * caller should initialize the PRNG state from some other random seed, + * using pg_prng_[f]seed. + * + * We implement this as a macro, so that the pg_strong_random() call is + * in the caller. If it were in pg_prng.c, programs using pg_prng.c + * but not needing strong seeding would nonetheless be forced to pull in + * pg_strong_random.c and thence OpenSSL. + */ +#define pg_prng_strong_seed(state) \ + (pg_strong_random(state, sizeof(pg_prng_state)) ? \ + pg_prng_seed_check(state) : false) + +extern uint64 pg_prng_uint64(pg_prng_state *state); +extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax); +extern int64 pg_prng_int64(pg_prng_state *state); +extern int64 pg_prng_int64p(pg_prng_state *state); +extern int64 pg_prng_int64_range(pg_prng_state *state, int64 rmin, int64 rmax); +extern uint32 pg_prng_uint32(pg_prng_state *state); +extern int32 pg_prng_int32(pg_prng_state *state); +extern int32 pg_prng_int32p(pg_prng_state *state); +extern double pg_prng_double(pg_prng_state *state); +extern double pg_prng_double_normal(pg_prng_state *state); +extern bool pg_prng_bool(pg_prng_state *state); + +#endif /* PG_PRNG_H */ diff --git a/src/include/utils/pgstrcasecmp.h b/src/include/utils/pgstrcasecmp.h new file mode 100644 index 000000000..fd065f37d --- /dev/null +++ b/src/include/utils/pgstrcasecmp.h @@ -0,0 +1,27 @@ +/*------------------------------------------------------------------------- + * + * pgstrcasecmp.h + * Header for src/utils/pgstrcasecmp.c compatibility functions. + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/pgstrcasecmp.h + * + *------------------------------------------------------------------------- + */ +#ifndef POOL_PGSTRCASECMP +#define POOL_PGSTRCASECMP + +/* msb for char */ +#define HIGHBIT (0x80) +#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT) + + +/* Portable SQL-like case-independent comparisons and conversions */ +extern int pg_strcasecmp(const char *s1, const char *s2); +extern int pg_strncasecmp(const char *s1, const char *s2, size_t n); +extern unsigned char pg_toupper(unsigned char ch); +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); +#endif diff --git a/src/include/utils/pool_ip.h b/src/include/utils/pool_ip.h index b43c2ecb3..caa1a7cc8 100644 --- a/src/include/utils/pool_ip.h +++ b/src/include/utils/pool_ip.h @@ -9,7 +9,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Portions Copyright (c) 2003-2008 PgPool Global Development Group + * Portions Copyright (c) 2003-2020 PgPool Global Development Group * Portions Copyright (c) 2003-2005, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and @@ -32,24 +32,24 @@ #include "pool_type.h" -extern int SockAddr_cidr_mask(struct sockaddr_storage *mask, - char *numbits, int family); +extern int SockAddr_cidr_mask(struct sockaddr_storage *mask, + char *numbits, int family); typedef void (*PgIfAddrCallback) (struct sockaddr *addr, struct sockaddr *netmask, void *cb_data); -extern int getaddrinfo_all(const char *hostname, const char *servname, - const struct addrinfo *hintp, - struct addrinfo **result); +extern int getaddrinfo_all(const char *hostname, const char *servname, + const struct addrinfo *hintp, + struct addrinfo **result); extern void freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai); -extern int getnameinfo_all(const struct sockaddr_storage *addr, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags); +extern int getnameinfo_all(const struct sockaddr_storage *addr, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags); -extern int rangeSockAddr(const struct sockaddr_storage *addr, - const struct sockaddr_storage *netaddr, - const struct sockaddr_storage *netmask); +extern int rangeSockAddr(const struct sockaddr_storage *addr, + const struct sockaddr_storage *netaddr, + const struct sockaddr_storage *netmask); /* imported from PostgreSQL getaddrinfo.c */ @@ -62,6 +62,8 @@ extern void promote_v4_to_v6_mask(struct sockaddr_storage *addr); extern int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data); +extern void pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port); + #define IS_AF_INET(fam) ((fam) == AF_INET) #define IS_AF_UNIX(fam) ((fam) == AF_UNIX) diff --git a/src/include/utils/pool_ipc.h b/src/include/utils/pool_ipc.h index c65de05b5..45cd5f8ca 100644 --- a/src/include/utils/pool_ipc.h +++ b/src/include/utils/pool_ipc.h @@ -29,4 +29,10 @@ extern void shmem_exit(int code); extern void on_shmem_exit(void (*function) (int code, Datum arg), Datum arg); extern void on_exit_reset(void); +/*pool_sema.c*/ +extern void pool_semaphore_create(int numSems); +extern void pool_semaphore_lock(int semNum); +extern int pool_semaphore_lock_allow_interrupt(int semNum); +extern void pool_semaphore_unlock(int semNum); + #endif /* IPC_H */ diff --git a/src/include/utils/pool_params.h b/src/include/utils/pool_params.h new file mode 100644 index 000000000..7a95ede28 --- /dev/null +++ b/src/include/utils/pool_params.h @@ -0,0 +1,39 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + +#ifndef pool_params_h +#define pool_params_h + +typedef struct +{ + int num; /* number of entries */ + char **names; /* parameter names */ + char **values; /* values */ +} ParamStatus; + +extern int pool_init_params(ParamStatus *params); +extern void pool_discard_params(ParamStatus *params); +extern char *pool_find_name(ParamStatus *params, char *name, int *pos); +extern int pool_get_param(ParamStatus *params, int index, char **name, char **value); +extern int pool_add_param(ParamStatus *params, char *name, char *value); +extern void pool_param_debug_print(ParamStatus *params); + + +#endif /* pool_params_h */ diff --git a/src/include/utils/pool_process_reporting.h b/src/include/utils/pool_process_reporting.h index eb75f3def..087a93c93 100644 --- a/src/include/utils/pool_process_reporting.h +++ b/src/include/utils/pool_process_reporting.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2012 PgPool Global Development Group + * Copyright (c) 2003-2022 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -26,22 +26,30 @@ #ifndef POOL_PROCESS_REPORTING_H #define POOL_PROCESS_REPORTING_H -extern void send_row_description(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, - short num_fields, char **field_names); -extern void send_complete_and_ready(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *message, const int num_rows); -extern POOL_REPORT_CONFIG * get_config(int *nrows); -extern POOL_REPORT_POOLS * get_pools(int *nrows); -extern POOL_REPORT_PROCESSES * get_processes(int *nrows); -extern POOL_REPORT_NODES * get_nodes(int *nrows); -extern POOL_REPORT_VERSION * get_version(void); -extern void config_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern void pools_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern void processes_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern void nodes_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern void version_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern void cache_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, + short num_fields, char **field_names); +extern void send_complete_and_ready(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *message, const int num_rows); +extern POOL_REPORT_CONFIG *get_config(int *nrows); +extern POOL_REPORT_POOLS *get_pools(int *nrows); +extern POOL_REPORT_PROCESSES *get_processes(int *nrows); +extern POOL_REPORT_NODES *get_nodes(int *nrows, int node_id); +extern POOL_REPORT_VERSION *get_version(void); +extern POOL_HEALTH_CHECK_STATS *get_health_check_stats(int *nrows); +extern POOL_BACKEND_STATS *get_backend_stats(int *nrows); -extern void send_config_var_detail_row(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *name, const char *value, const char *description); -extern void send_config_var_value_only_row(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *value); +extern void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void show_health_check_stats(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void show_backend_stats(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); + + +extern void send_config_var_detail_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *name, const char *value, const char *description); +extern void send_config_var_value_only_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *value); extern char *get_backend_status_string(BACKEND_STATUS status); + +extern int *pool_report_pools_offsets(int *n); #endif diff --git a/src/include/utils/pool_relcache.h b/src/include/utils/pool_relcache.h index 6b090523a..b19d71ebc 100644 --- a/src/include/utils/pool_relcache.h +++ b/src/include/utils/pool_relcache.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2010 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -34,8 +34,6 @@ /* Relation lookup cache structure */ -typedef void *(*func_ptr) (); - typedef struct { char dbname[MAX_ITEM_LENGTH]; /* database name */ @@ -44,41 +42,43 @@ typedef struct int refcnt; /* reference count */ int session_id; /* LocalSessionId */ time_t expire; /* cache expiration absolute time in seconds */ -} PoolRelCache; +} PoolRelCache; +#define MAX_QUERY_LENGTH 1500 typedef struct { int num; /* number of cache items */ - char sql[MAX_ITEM_LENGTH]; /* Query to relation */ + char sql[MAX_QUERY_LENGTH]; /* Query to relation */ /* * User defined function to be called at data register. Argument is * POOL_SELECT_RESULT *. This function must return a pointer to be saved * in cache->data. */ - func_ptr register_func; + void *(*register_func) (POOL_SELECT_RESULT *data); /* * User defined function to be called at data unregister. Argument * cache->data. */ - func_ptr unregister_func; + void *(*unregister_func) (void *data); bool cache_is_session_local; /* True if cache life time is session * local */ bool no_cache_if_zero; /* if register func returns 0, do not * cache the data */ PoolRelCache *cache; /* cache data */ -} POOL_RELCACHE; +} POOL_RELCACHE; -extern POOL_RELCACHE * pool_create_relcache(int cachesize, char *sql, - func_ptr register_func, func_ptr unregister_func, - bool issessionlocal); -extern void pool_discard_relcache(POOL_RELCACHE * relcache); -extern void *pool_search_relcache(POOL_RELCACHE * relcache, POOL_CONNECTION_POOL * backend, char *table); +extern POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql, + void *(*register_func) (POOL_SELECT_RESULT *), void *(*unregister_func) (void *), + bool issessionlocal); +extern void pool_discard_relcache(POOL_RELCACHE *relcache); +extern void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table); extern char *remove_quotes_and_schema_from_relname(char *table); -extern void *int_register_func(POOL_SELECT_RESULT * res); +extern void *int_register_func(POOL_SELECT_RESULT *res); extern void *int_unregister_func(void *data); -extern void *string_register_func(POOL_SELECT_RESULT * res); +extern void *string_register_func(POOL_SELECT_RESULT *res); extern void *string_unregister_func(void *data); +extern bool SplitIdentifierString(char *rawstring, char separator, Node **namelist); #endif /* POOL_RELCACHE_H */ diff --git a/src/include/utils/pool_select_walker.h b/src/include/utils/pool_select_walker.h index 10323b08f..3c067c61a 100644 --- a/src/include/utils/pool_select_walker.h +++ b/src/include/utils/pool_select_walker.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2012 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -32,7 +32,6 @@ #include "parser/makefuncs.h" #define POOL_MAX_SELECT_OIDS 128 -#define POOL_NAMEDATALEN 64 /* from NAMEDATALEN of PostgreSQL */ typedef struct { @@ -42,17 +41,21 @@ typedef struct bool has_view; /* True if view is used */ bool has_function_call; /* True if write function call is used */ int pg_terminate_backend_pid; /* pid argument of - * pg_terminate_backedn_call(if + * pg_terminate_backend_call(if * used) */ bool has_non_immutable_function_call; /* True if non immutable * functions are used */ bool has_insertinto_or_locking_clause; /* True if it has SELECT * INTO or FOR * SHARE/UPDATE */ + bool row_security; /* true if row security enabled */ int num_oids; /* number of oids */ int table_oids[POOL_MAX_SELECT_OIDS]; /* table oids */ - char table_names[POOL_MAX_SELECT_OIDS][POOL_NAMEDATALEN]; /* table names */ -} SelectContext; + char table_names[POOL_MAX_SELECT_OIDS][NAMEDATALEN]; /* table names */ +} SelectContext; + + +typedef bool (*tree_walker_callback) (Node *node, void *context); extern int pool_get_terminate_backend_pid(Node *node); extern bool pool_has_function_call(Node *node); @@ -62,14 +65,16 @@ extern bool pool_has_temp_table(Node *node); extern void discard_temp_table_relcache(void); extern bool pool_has_unlogged_table(Node *node); extern bool pool_has_view(Node *node); +extern bool pool_has_row_security(Node *node); extern bool pool_has_insertinto_or_locking_clause(Node *node); extern bool pool_has_pgpool_regclass(void); extern bool pool_has_to_regclass(void); -extern bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context); +extern bool raw_expression_tree_walker(Node *node, tree_walker_callback walker, void *context); extern int pool_table_name_to_oid(char *table_name); -extern int pool_extract_table_oids_from_select_stmt(Node *node, SelectContext * ctx); +extern int pool_extract_table_oids_from_select_stmt(Node *node, SelectContext *ctx); extern RangeVar *makeRangeVarFromNameList(List *names); extern char *make_table_name_from_rangevar(RangeVar *rangevar); +extern char *make_function_name_from_funccall(FuncCall *fcall); extern int pattern_compare(char *str, const int type, const char *param_name); extern bool is_unlogged_table(char *table_name); extern bool is_view(char *table_name); diff --git a/src/include/utils/pool_signal.h b/src/include/utils/pool_signal.h index 012f3d1ce..ddaf76010 100644 --- a/src/include/utils/pool_signal.h +++ b/src/include/utils/pool_signal.h @@ -20,7 +20,7 @@ * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * - * pool.h.: master definition header file + * pool_signal.h.: pool_signal definition header file * */ @@ -30,6 +30,7 @@ /* * Signal stuff. Stolen from PostgreSQL source code. */ +#include "config.h" #include #ifdef HAVE_SIGPROCMASK diff --git a/src/include/utils/pool_ssl.h b/src/include/utils/pool_ssl.h new file mode 100644 index 000000000..6171c0a70 --- /dev/null +++ b/src/include/utils/pool_ssl.h @@ -0,0 +1,84 @@ +/* + * + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Portions Copyright (c) 2003-2026 PgPool Global Development Group + * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + +#ifndef pool_ssl_h +#define pool_ssl_h + +#ifdef USE_SSL +/* + * Hardcoded DH parameters, used in ephemeral DH keying. + * + * 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\ +MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n\ +IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n\ +awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n\ +mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n\ +fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n\ +5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n\ +-----END DH PARAMETERS-----\n" +#endif + +/* + * Macro that allows to cast constness 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 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)) +#else +#define unconstify(underlying_type, expr) \ + ((underlying_type) (expr)) +#endif + + +extern void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp); +extern void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp); +extern void pool_ssl_close(POOL_CONNECTION *cp); +extern int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size); +extern int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size); +extern bool pool_ssl_pending(POOL_CONNECTION *cp); +extern int SSL_ServerSide_init(void); + + +#endif /* pool_ssl_h */ diff --git a/src/include/utils/pool_stream.h b/src/include/utils/pool_stream.h index 6206543cc..6d639af15 100644 --- a/src/include/utils/pool_stream.h +++ b/src/include/utils/pool_stream.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2015 PgPool Global Development Group + * Copyright (c) 2003-2019 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -26,6 +26,8 @@ #ifndef POOL_STREAM_H #define POOL_STREAM_H +#include "utils/socket_stream.h" + #define READBUFSZ 1024 #define WRITEBUFSZ 8192 @@ -42,31 +44,30 @@ (connection)->len = 0; \ } while (0) -extern POOL_CONNECTION * pool_open(int fd, bool backend_connection); -extern void pool_close(POOL_CONNECTION * cp); -extern int pool_read(POOL_CONNECTION * cp, void *buf, int len); -extern void pool_read_with_error(POOL_CONNECTION * cp, void *buf, int len, - const char *err_context); +extern POOL_CONNECTION *pool_open(int fd, bool backend_connection); +extern void pool_close(POOL_CONNECTION *cp); +extern int pool_read(POOL_CONNECTION *cp, void *buf, int len); +extern void pool_read_with_error(POOL_CONNECTION *cp, void *buf, int len, + const char *err_context); -extern char *pool_read2(POOL_CONNECTION * cp, int len); -extern int pool_write(POOL_CONNECTION * cp, void *buf, int len); -extern int pool_write_noerror(POOL_CONNECTION * cp, void *buf, int len); -extern int pool_flush(POOL_CONNECTION * cp); -extern int pool_flush_noerror(POOL_CONNECTION * cp); -extern int pool_flush_it(POOL_CONNECTION * cp); -extern void pool_write_and_flush(POOL_CONNECTION * cp, void *buf, int len); -extern int pool_write_and_flush_noerror(POOL_CONNECTION * cp, void *buf, int len); -extern char *pool_read_string(POOL_CONNECTION * cp, int *len, int line); -extern int pool_unread(POOL_CONNECTION * cp, void *data, int len); -extern int pool_push(POOL_CONNECTION * cp, void *data, int len); -extern void pool_pop(POOL_CONNECTION * cp, int *len); -extern int pool_stacklen(POOL_CONNECTION * cp); -extern void pool_set_nonblock(int fd); -extern void pool_unset_nonblock(int fd); +extern char *pool_read2(POOL_CONNECTION *cp, int len); +extern int pool_write(POOL_CONNECTION *cp, void *buf, int len); +extern int pool_write_noerror(POOL_CONNECTION *cp, void *buf, int len); +extern int pool_flush(POOL_CONNECTION *cp); +extern int pool_flush_noerror(POOL_CONNECTION *cp); +extern int pool_flush_it(POOL_CONNECTION *cp); +extern void pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len); +extern int pool_write_and_flush_noerror(POOL_CONNECTION *cp, void *buf, int len); +extern char *pool_read_string(POOL_CONNECTION *cp, int *len, int line); +extern int pool_unread(POOL_CONNECTION *cp, void *data, int len); +extern int pool_push(POOL_CONNECTION *cp, void *data, int len); +extern void pool_pop(POOL_CONNECTION *cp, int *len); +extern int pool_stacklen(POOL_CONNECTION *cp); -extern int socket_read(int sock, void *buf, size_t len, int timeout); -extern int socket_write(int fd, void *buf, size_t len); +extern void pool_set_db_node_id(POOL_CONNECTION *con, int db_node_id); -extern void pool_set_db_node_id(POOL_CONNECTION * con, int db_node_id); +extern void pool_set_timeout(int timeoutval); +extern int pool_get_timeout(void); +extern int pool_check_fd(POOL_CONNECTION *cp); #endif /* POOL_STREAM_H */ diff --git a/src/include/utils/pool_track_table_mutation.h b/src/include/utils/pool_track_table_mutation.h new file mode 100644 index 000000000..b60088c06 --- /dev/null +++ b/src/include/utils/pool_track_table_mutation.h @@ -0,0 +1,167 @@ +/* -*-pgsql-c-*- */ +/* + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2026 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool_track_table_mutation.h: In-memory tracking of + * recently written tables to prevent stale reads. + */ + +#ifndef POOL_TRACK_TABLE_MUTATION_H +#define POOL_TRACK_TABLE_MUTATION_H + +#include "pool.h" +#include + +/* + * Invalid index marker for linked lists + */ +#define TRACK_TABLE_MUTATION_INVALID_INDEX (-1) + +/* + * Default TTL in microseconds (100ms) used when replication delay is unknown + */ +#define TRACK_TABLE_MUTATION_DEFAULT_TTL_US (100 * 1000) + +/* + * Entry in the table mutation hash table (keyed by table/database oids) + */ +typedef struct TrackTableMutationEntry +{ + int table_oid; /* Table oid */ + int dboid; /* Database oid */ + struct timeval first_write_time; /* When the entry was first created */ + struct timeval last_write_time; /* When the table was last written */ + uint32 hash; /* Pre-computed hash value */ + int next; /* Next in collision chain */ + bool in_use; /* Is this entry in use? */ +} TrackTableMutationEntry; + +/* + * Header for the table mutation hash table in shared memory + */ +typedef struct TrackTableMutationHashTable +{ + int num_buckets; /* Number of hash buckets */ + int max_entries; /* Maximum entries allowed */ + int num_entries; /* Current number of entries */ + int free_list_head; /* Head of free entry list */ + + /* + * Flexible array members follow in shared memory: int + * buckets[num_buckets]; TrackTableMutationEntry entries[max_entries]; + */ +} TrackTableMutationHashTable; + +/* + * Global state for track table mutation feature + */ +typedef struct TrackTableMutationState +{ + bool initialized; /* Shmem initialized? */ + uint64 current_ttl_us; /* Current TTL in microseconds */ + struct timeval ttl_last_updated; /* When TTL was last updated */ + struct timeval last_cleanup_time; /* When last expired cleanup ran */ + struct timeval global_cold_start_until; /* Global cold start end time */ + uint32 stats_queries_checked; /* Queries checked */ + uint32 stats_forced_primary; /* Forced to primary */ + uint32 stats_allowed_replica; /* Allowed to replica */ +} TrackTableMutationState; + +/* + * Main shared memory structure containing all components + */ +typedef struct TrackTableMutationShmem +{ + TrackTableMutationState state; + TrackTableMutationHashTable *table_map; +} TrackTableMutationShmem; + +/* ---------------- + * Public API functions + * ---------------- + */ + +/* + * Initialize shared memory structures for track table mutation. + * Called from pgpool_main.c after pool_init_pool_info(). + */ +extern void pool_track_table_mutation_init(void); + +/* + * Initialize per-child process state for track table mutation. + * Called from child.c when a new child process starts. + * Sets up cold start tracking. + */ +extern void pool_track_table_mutation_child_init(void); + +/* + * Check if the child process is in cold start period. + * During cold start, all queries are routed to primary. + * Returns true if in cold start, false otherwise. + */ +extern bool pool_track_table_mutation_in_cold_start(void); + +/* + * Trigger a global cold start period for all processes. + * Used after watchdog leader change to avoid stale reads. + */ +extern void pool_track_table_mutation_trigger_global_cold_start(void); + +/* + * Get oid of current database. + */ +extern int pool_track_table_mutation_get_database_oid(void); + +/* + * Check if a table was recently written to (is "stale"). + * If stale, reads from this table should go to primary. + * Returns true if table is stale (recently written), false otherwise. + */ +extern bool pool_track_table_mutation_table_is_stale( + int table_oid, int dboid); + +/* + * Mark tables as recently written. + * Called after INSERT/UPDATE/DELETE queries complete. + * table_oids: array of table oids + * num_tables: number of tables in array + * dboid: database oid + */ +extern void pool_track_table_mutation_mark_tables_written( + const int *table_oids, int num_tables, int dboid); + +/* + * Convenience function to mark a single table as written. + * table_oid: table oid + * dboid: database oid + */ +extern void pool_track_table_mutation_mark_table_written( + int table_oid, int dboid); + +/* + * Update the TTL based on current replication delay. + * Called from pool_worker_child.c when replication delay is updated. + * delay_us: replication delay in microseconds + */ +extern void pool_track_table_mutation_update_ttl(uint64 delay_us); + +/* + * Calculate required shared memory size for track table mutation. + */ +extern Size pool_track_table_mutation_shmem_size(void); + +#endif /* POOL_TRACK_TABLE_MUTATION_H */ diff --git a/src/include/utils/pqexpbuffer.h b/src/include/utils/pqexpbuffer.h new file mode 100644 index 000000000..020e94e35 --- /dev/null +++ b/src/include/utils/pqexpbuffer.h @@ -0,0 +1,192 @@ +/*------------------------------------------------------------------------- + * + * pqexpbuffer.h + * Declarations/definitions for "PQExpBuffer" functions. + * + * PQExpBuffer provides an indefinitely-extensible string data type. + * It can be used to buffer either ordinary C strings (null-terminated text) + * or arbitrary binary data. All storage is allocated with malloc(). + * + * This module is essentially the same as the backend's StringInfo data type, + * but it is intended for use in frontend libpq and client applications. + * Thus, it does not rely on palloc() nor elog(). + * + * It does rely on vsnprintf(); if configure finds that libc doesn't provide + * a usable vsnprintf(), then a copy of our own implementation of it will + * be linked into libpq. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/libpq/pqexpbuffer.h + * + *------------------------------------------------------------------------- + */ +#ifndef PQEXPBUFFER_H +#define PQEXPBUFFER_H + +/*------------------------- + * PQExpBufferData holds information about an extensible string. + * data is the current buffer for the string (allocated with malloc). + * len is the current string length. There is guaranteed to be + * a terminating '\0' at data[len], although this is not very + * useful when the string holds binary data rather than text. + * maxlen is the allocated size in bytes of 'data', i.e. the maximum + * string size (including the terminating '\0' char) that we can + * currently store in 'data' without having to reallocate + * more space. We must always have maxlen > len. + * + * An exception occurs if we failed to allocate enough memory for the string + * buffer. In that case data points to a statically allocated empty string, + * and len = maxlen = 0. + *------------------------- + */ +typedef struct PQExpBufferData +{ + char *data; + size_t len; + size_t maxlen; +} PQExpBufferData; + +typedef PQExpBufferData *PQExpBuffer; + +/*------------------------ + * Test for a broken (out of memory) PQExpBuffer. + * When a buffer is "broken", all operations except resetting or deleting it + * are no-ops. + *------------------------ + */ +#define PQExpBufferBroken(str) \ + ((str) == NULL || (str)->maxlen == 0) + +/*------------------------ + * Same, but for use when using a static or local PQExpBufferData struct. + * For that, a null-pointer test is useless and may draw compiler warnings. + *------------------------ + */ +#define PQExpBufferDataBroken(buf) \ + ((buf).maxlen == 0) + +/*------------------------ + * Initial size of the data buffer in a PQExpBuffer. + * NB: this must be large enough to hold error messages that might + * be returned by PQrequestCancel(). + *------------------------ + */ +#define INITIAL_EXPBUFFER_SIZE 256 + +/*------------------------ + * There are two ways to create a PQExpBuffer object initially: + * + * PQExpBuffer stringptr = createPQExpBuffer(); + * Both the PQExpBufferData and the data buffer are malloc'd. + * + * PQExpBufferData string; + * initPQExpBuffer(&string); + * The data buffer is malloc'd but the PQExpBufferData is presupplied. + * This is appropriate if the PQExpBufferData is a field of another + * struct. + *------------------------- + */ + +/*------------------------ + * createPQExpBuffer + * Create an empty 'PQExpBufferData' & return a pointer to it. + */ +extern PQExpBuffer createPQExpBuffer(void); + +/*------------------------ + * initPQExpBuffer + * Initialize a PQExpBufferData struct (with previously undefined contents) + * to describe an empty string. + */ +extern void initPQExpBuffer(PQExpBuffer str); + +/*------------------------ + * To destroy a PQExpBuffer, use either: + * + * destroyPQExpBuffer(str); + * free()s both the data buffer and the PQExpBufferData. + * This is the inverse of createPQExpBuffer(). + * + * termPQExpBuffer(str) + * free()s the data buffer but not the PQExpBufferData itself. + * This is the inverse of initPQExpBuffer(). + * + * NOTE: some routines build up a string using PQExpBuffer, and then + * release the PQExpBufferData but return the data string itself to their + * caller. At that point the data string looks like a plain malloc'd + * string. + */ +extern void destroyPQExpBuffer(PQExpBuffer str); +extern void termPQExpBuffer(PQExpBuffer str); + +/*------------------------ + * resetPQExpBuffer + * Reset a PQExpBuffer to empty + * + * Note: if possible, a "broken" PQExpBuffer is returned to normal. + */ +extern void resetPQExpBuffer(PQExpBuffer str); + +/*------------------------ + * enlargePQExpBuffer + * Make sure there is enough space for 'needed' more bytes in the buffer + * ('needed' does not include the terminating null). + * + * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case + * the buffer is left in "broken" state.) + */ +extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed); + +/*------------------------ + * printfPQExpBuffer + * Format text data under the control of fmt (an sprintf-like format string) + * and insert it into str. More space is allocated to str if necessary. + * This is a convenience routine that does the same thing as + * resetPQExpBuffer() followed by appendPQExpBuffer(). + */ +extern void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); + +/*------------------------ + * appendPQExpBuffer + * Format text data under the control of fmt (an sprintf-like format string) + * and append it to whatever is already in str. More space is allocated + * to str if necessary. This is sort of like a combination of sprintf and + * strcat. + */ +extern void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); + +/*------------------------ + * appendPQExpBufferVA + * 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". + */ +extern bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) pg_attribute_printf(2, 0); + +/*------------------------ + * appendPQExpBufferStr + * Append the given string to a PQExpBuffer, allocating more space + * if necessary. + */ +extern void appendPQExpBufferStr(PQExpBuffer str, const char *data); + +/*------------------------ + * appendPQExpBufferChar + * Append a single byte to str. + * Like appendPQExpBuffer(str, "%c", ch) but much faster. + */ +extern void appendPQExpBufferChar(PQExpBuffer str, char ch); + +/*------------------------ + * appendBinaryPQExpBuffer + * Append arbitrary binary data to a PQExpBuffer, allocating more space + * if necessary. + */ +extern void appendBinaryPQExpBuffer(PQExpBuffer str, + const char *data, size_t datalen); + +#endif /* PQEXPBUFFER_H */ diff --git a/src/include/utils/ps_status.h b/src/include/utils/ps_status.h new file mode 100644 index 000000000..12f9f22d5 --- /dev/null +++ b/src/include/utils/ps_status.h @@ -0,0 +1,38 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + +#ifndef ps_status_h +#define ps_status_h + +#include "pool.h" +#include + +extern char remote_ps_data[NI_MAXHOST + NI_MAXSERV + 2]; /* used for + * set_ps_display */ + +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); +extern void set_ps_display(const char *activity, bool force); +extern const char *get_ps_display(int *displen); +extern void pool_ps_idle_display(POOL_CONNECTION_POOL *backend); + + +#endif /* ps_status_h */ diff --git a/src/include/utils/psqlscan.h b/src/include/utils/psqlscan.h new file mode 100644 index 000000000..e3c117749 --- /dev/null +++ b/src/include/utils/psqlscan.h @@ -0,0 +1,91 @@ +/*------------------------------------------------------------------------- + * + * psqlscan.h + * lexical scanner for SQL commands + * + * This lexer used to be part of psql, and that heritage is reflected in + * the file name as well as function and typedef names, though it can now + * be used by other frontend programs as well. It's also possible to extend + * this lexer with a compatible add-on lexer to handle program-specific + * backslash commands. + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/psqlscan.h + * + *------------------------------------------------------------------------- + */ +#ifndef PSQLSCAN_H +#define PSQLSCAN_H + +#include "parser/pool_parser.h" +#include "pqexpbuffer.h" + + +/* Abstract type for lexer's internal state */ +typedef struct PsqlScanStateData *PsqlScanState; + +/* Termination states for psql_scan() */ +typedef enum +{ + PSCAN_SEMICOLON, /* found command-ending semicolon */ + PSCAN_BACKSLASH, /* found backslash command */ + PSCAN_INCOMPLETE, /* end of line, SQL statement incomplete */ + PSCAN_EOL /* end of line, SQL possibly complete */ +} PsqlScanResult; + +/* Prompt type returned by psql_scan() */ +typedef enum _promptStatus +{ + PROMPT_READY, + PROMPT_CONTINUE, + PROMPT_COMMENT, + PROMPT_SINGLEQUOTE, + PROMPT_DOUBLEQUOTE, + PROMPT_DOLLARQUOTE, + PROMPT_PAREN, + PROMPT_COPY +} promptStatus_t; + +/* Quoting request types for get_variable() callback */ +typedef enum +{ + PQUOTE_PLAIN, /* just return the actual value */ + PQUOTE_SQL_LITERAL, /* add quotes to make a valid SQL literal */ + PQUOTE_SQL_IDENT, /* quote if needed to make a SQL identifier */ + PQUOTE_SHELL_ARG /* quote if needed to be safe in a shell cmd */ +} PsqlScanQuoteType; + +/* Callback functions to be used by the lexer */ +typedef struct PsqlScanCallbacks +{ + /* Fetch value of a variable, as a free'able string; NULL if unknown */ + /* This pointer can be NULL if no variable substitution is wanted */ + char *(*get_variable) (const char *varname, PsqlScanQuoteType quote, + void *passthrough); +} PsqlScanCallbacks; + + +extern PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks); +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); +extern void psql_scan_finish(PsqlScanState state); + +extern PsqlScanResult psql_scan(PsqlScanState state, + PQExpBuffer query_buf, + promptStatus_t *prompt); + +extern void psql_scan_reset(PsqlScanState state); + +extern void psql_scan_reselect_sql_lexer(PsqlScanState state); + +extern bool psql_scan_in_quote(PsqlScanState state); + +#endif /* PSQLSCAN_H */ diff --git a/src/include/utils/psqlscan_int.h b/src/include/utils/psqlscan_int.h new file mode 100644 index 000000000..87debbfcc --- /dev/null +++ b/src/include/utils/psqlscan_int.h @@ -0,0 +1,157 @@ +/*------------------------------------------------------------------------- + * + * psqlscan_int.h + * lexical scanner internal declarations + * + * This file declares the PsqlScanStateData structure used by psqlscan.l + * and shared by other lexers compatible with it, such as psqlscanslash.l. + * + * One difficult aspect of this code is that we need to work in multibyte + * encodings that are not ASCII-safe. A "safe" encoding is one in which each + * byte of a multibyte character has the high bit set (it's >= 0x80). Since + * all our lexing rules treat all high-bit-set characters alike, we don't + * really need to care whether such a byte is part of a sequence or not. + * In an "unsafe" encoding, we still expect the first byte of a multibyte + * sequence to be >= 0x80, but later bytes might not be. If we scan such + * a sequence as-is, the lexing rules could easily be fooled into matching + * such bytes to ordinary ASCII characters. Our solution for this is to + * substitute 0xFF for each non-first byte within the data presented to flex. + * The flex rules will then pass the FF's through unmolested. The + * psqlscan_emit() subroutine is responsible for looking back to the original + * string and replacing FF's with the corresponding original bytes. + * + * Another interesting thing we do here is scan different parts of the same + * input with physically separate flex lexers (ie, lexers written in separate + * .l files). We can get away with this because the only part of the + * persistent state of a flex lexer that depends on its parsing rule tables + * 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 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-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/fe_utils/psqlscan_int.h + * + *------------------------------------------------------------------------- + */ +#ifndef PSQLSCAN_INT_H +#define PSQLSCAN_INT_H + +#include "utils/psqlscan.h" + +/* + * These are just to allow this file to be compilable standalone for header + * validity checking; in actual use, this file should always be included + * from the body of a flex file, where these symbols are already defined. + */ +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void *yyscan_t; +#endif + +/* + * We use a stack of flex buffers to handle substitution of psql variables. + * Each stacked buffer contains the as-yet-unread text from one psql variable. + * When we pop the stack all the way, we resume reading from the outer buffer + * identified by scanbufhandle. + */ +typedef struct StackElem +{ + YY_BUFFER_STATE buf; /* flex input control structure */ + char *bufstring; /* data actually being scanned by flex */ + char *origstring; /* copy of original data, if needed */ + char *varname; /* name of variable providing data, or NULL */ + struct StackElem *next; +} StackElem; + +/* + * All working state of the lexer must be stored in PsqlScanStateData + * between calls. This allows us to have multiple open lexer operations, + * which is needed for nested include files. The lexer itself is not + * recursive, but it must be re-entrant. + */ +typedef struct PsqlScanStateData +{ + yyscan_t scanner; /* Flex's state for this PsqlScanState */ + + PQExpBuffer output_buf; /* current output buffer */ + + StackElem *buffer_stack; /* stack of variable expansion buffers */ + + /* + * These variables always refer to the outer buffer, never to any stacked + * variable-expansion buffer. + */ + YY_BUFFER_STATE scanbufhandle; + char *scanbuf; /* start of outer-level input buffer */ + const char *scanline; /* current input line at outer level */ + + /* safe_encoding, curline, refline are used by emit() to replace FFs */ + int encoding; /* encoding being used now */ + bool safe_encoding; /* is current encoding "safe"? */ + bool std_strings; /* are string literals standard? */ + const char *curline; /* actual flex input string for cur buf */ + const char *refline; /* original data for cur buffer */ + + /* + * All this state lives across successive input lines, until explicitly + * reset by psql_scan_reset. start_state is adopted by yylex() on entry, + * and updated with its finishing state on exit. + */ + int start_state; /* yylex's starting/finishing state */ + int state_before_str_stop; /* start cond. before end quote */ + int paren_depth; /* depth of nesting in parentheses */ + int xcdepth; /* depth of nesting in slash-star comments */ + char *dolqstart; /* current $foo$ quote start string */ + + /* + * State to track boundaries of BEGIN ... END blocks in function + * definitions, so that semicolons do not send query too early. + */ + int identifier_count; /* identifiers since start of statement */ + char identifiers[4]; /* records the first few identifiers */ + int begin_depth; /* depth of begin/end pairs */ + + /* + * Callback functions provided by the program making use of the lexer, + * plus a void* callback passthrough argument. + */ + const PsqlScanCallbacks *callbacks; + void *cb_passthrough; +} PsqlScanStateData; + + +/* + * Functions exported by psqlscan.l, but only meant for use within + * compatible lexers. + */ +extern void psqlscan_push_new_buffer(PsqlScanState state, + 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); +extern YY_BUFFER_STATE psqlscan_prepare_buffer(PsqlScanState state, + 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); +extern void psqlscan_escape_variable(PsqlScanState state, + const char *txt, int len, + PsqlScanQuoteType quote); +extern void psqlscan_test_variable(PsqlScanState state, + const char *txt, int len); + +#endif /* PSQLSCAN_INT_H */ diff --git a/src/include/utils/regex_array.h b/src/include/utils/regex_array.h index a50d1ea29..1ad9d7283 100644 --- a/src/include/utils/regex_array.h +++ b/src/include/utils/regex_array.h @@ -34,12 +34,12 @@ typedef struct int size; /* regex array size */ int pos; /* next regex array index position */ regex_t **regex; /* regular expression array */ -} RegArray; +} RegArray; RegArray *create_regex_array(void); -int add_regex_array(RegArray * ar, char *pattern); -int regex_array_match(RegArray * ar, char *pattern); -void destroy_regex_arrary(RegArray * ar); +int add_regex_array(RegArray *ar, char *pattern); +int regex_array_match(RegArray *ar, char *pattern); +void destroy_regex_array(RegArray *ar); /* * String left-right token type @@ -49,16 +49,16 @@ typedef struct char *left_token; char *right_token; double weight_token; -} Left_right_token; +} Left_right_token; typedef struct { int pos; int size; Left_right_token *token; -} Left_right_tokens; +} Left_right_tokens; Left_right_tokens *create_lrtoken_array(void); -void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_tokens * lrtokens); +void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_tokens *lrtokens); #endif diff --git a/src/include/utils/sha2.h b/src/include/utils/sha2.h index 85104b3b6..487b26dbc 100644 --- a/src/include/utils/sha2.h +++ b/src/include/utils/sha2.h @@ -95,22 +95,22 @@ typedef struct pg_sha512_ctx pg_sha384_ctx; /* 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/parser/pool_string.h b/src/include/utils/socket_stream.h similarity index 54% rename from src/include/parser/pool_string.h rename to src/include/utils/socket_stream.h index d943cdf05..47f06041c 100644 --- a/src/include/parser/pool_string.h +++ b/src/include/utils/socket_stream.h @@ -1,8 +1,12 @@ /* -*-pgsql-c-*- */ /* + * * $Header$ * - * Copyright (c) 2006-2008, pgpool Global Development Group + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -14,25 +18,19 @@ * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. + * + * pool_steam.h.: pool_stream.c related header file + * */ -#ifndef POOL_STRING_H -#define POOL_STRING_H -#include "pg_list.h" -#define STRING_SIZE 128 +#ifndef SOCKET_STREAM_H +#define SOCKET_STREAM_H + +extern void socket_set_nonblock(int fd); +extern void socket_unset_nonblock(int fd); -typedef struct -{ - int size; - int len; - char *data; -} String; +extern int socket_read(int sock, void *buf, size_t len, int timeout); +extern int socket_write(int fd, void *buf, size_t len); -extern char *NameListToString(List *names); -extern String * init_string(char *str); -extern void string_append_string(String * string, String * append_data); -extern void string_append_char(String * string, char *append_data); -extern void free_string(String * string); -extern String * copy_string(String * string); -#endif /* POOL_STRING_H */ +#endif /* SOCKET_STREAM_H */ diff --git a/src/include/utils/ssl_utils.h b/src/include/utils/ssl_utils.h index e6aabcac7..39effa1f9 100644 --- a/src/include/utils/ssl_utils.h +++ b/src/include/utils/ssl_utils.h @@ -26,9 +26,9 @@ #define SSL_UTILS_H extern void calculate_hmac_sha256(const char *data, int len, char *buf); -extern int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, - const char *password, unsigned char *plaintext); -extern int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, - const char *password, unsigned char *ciphertext); +extern int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, + const char *password, unsigned char *plaintext); +extern int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, + const char *password, unsigned char *ciphertext); #endif diff --git a/src/include/utils/statistics.h b/src/include/utils/statistics.h new file mode 100644 index 000000000..6e12a79eb --- /dev/null +++ b/src/include/utils/statistics.h @@ -0,0 +1,39 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + */ + +#ifndef statistics_h +#define statistics_h + +extern size_t stat_shared_memory_size(void); +extern void stat_set_stat_area(void *address); +extern void stat_init_stat_area(void); +extern void stat_count_up(int backend_node_id, Node *parsetree); +extern void error_stat_count_up(int backend_node_id, char *str); +extern uint64 stat_get_select_count(int backend_node_id); +extern uint64 stat_get_insert_count(int backend_node_id); +extern uint64 stat_get_update_count(int backend_node_id); +extern uint64 stat_get_delete_count(int backend_node_id); +extern uint64 stat_get_ddl_count(int backend_node_id); +extern uint64 stat_get_other_count(int backend_node_id); +extern uint64 stat_get_panic_count(int backend_node_id); +extern uint64 stat_get_fatal_count(int backend_node_id); +extern uint64 stat_get_error_count(int backend_node_id); + +#endif /* statistics_h */ diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h new file mode 100644 index 000000000..d4be6e31d --- /dev/null +++ b/src/include/utils/timestamp.h @@ -0,0 +1,214 @@ +/* + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pgpool_logger.h.: pgpool_logger definition header file + * + */ +/*------------------------------------------------------------------------- + * + * From: PostgreSQL + * src/include/datatype/timestamp.h + * Timestamp and Interval typedefs and related macros. + * + * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + *------------------------------------------------------------------------- + */ +#ifndef DATATYPE_TIMESTAMP_H +#define DATATYPE_TIMESTAMP_H + +/* + * Timestamp represents absolute time. + * + * Interval represents delta time. Keep track of months (and years), days, + * and hours/minutes/seconds separately since the elapsed time spanned is + * unknown until instantiated relative to an absolute time. + * + * Note that Postgres uses "time interval" to mean a bounded interval, + * consisting of a beginning and ending time, not a time span - thomas 97/03/20 + * + * Timestamps, as well as the h/m/s fields of intervals, are stored as + * int64 values with units of microseconds. (Once upon a time they were + * double values with units of seconds.) + * + * TimeOffset and fsec_t are convenience typedefs for temporary variables. + * Do not use fsec_t in values stored on-disk. + * Also, fsec_t is only meant for *fractional* seconds; beware of overflow + * if the value you need to store could be many seconds. + */ + +typedef int64 Timestamp; +typedef int64 TimestampTz; +typedef int64 TimeOffset; +typedef int32 fsec_t; /* fractional seconds (in microseconds) */ + +typedef struct +{ + TimeOffset time; /* all time units other than days, months and + * years */ + int32 day; /* days, after time for alignment */ + int32 month; /* months and years, after time for alignment */ +} Interval; + + +/* Limits on the "precision" option (typmod) for these data types */ +#define MAX_TIMESTAMP_PRECISION 6 +#define MAX_INTERVAL_PRECISION 6 + +/* + * Round off to MAX_TIMESTAMP_PRECISION decimal places. + * Note: this is also used for rounding off intervals. + */ +#define TS_PREC_INV 1000000.0 +#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV) + + +/* + * Assorted constants for datetime-related calculations + */ + +#define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */ +#define MONTHS_PER_YEAR 12 +/* + * DAYS_PER_MONTH is very imprecise. The more accurate value is + * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only + * return an integral number of days, but someday perhaps we should + * also return a 'time' value to be used as well. ISO 8601 suggests + * 30 days. + */ +#define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */ +#define HOURS_PER_DAY 24 /* assume no daylight savings time changes */ + +/* + * This doesn't adjust for uneven daylight savings time intervals or leap + * seconds, and it crudely estimates leap years. A more accurate value + * for days per years is 365.2422. + */ +#define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */ +#define SECS_PER_DAY 86400 +#define SECS_PER_HOUR 3600 +#define SECS_PER_MINUTE 60 +#define MINS_PER_HOUR 60 + +#define USECS_PER_DAY INT64CONST(86400000000) +#define USECS_PER_HOUR INT64CONST(3600000000) +#define USECS_PER_MINUTE INT64CONST(60000000) +#define USECS_PER_SEC INT64CONST(1000000) + +/* + * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich. + * Currently, the record holders for wackiest offsets in actual use are zones + * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42 + * until 1867. If we were to reject such values we would fail to dump and + * restore old timestamptz values with these zone settings. + */ +#define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */ +#define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR) + +/* + * DT_NOBEGIN represents timestamp -infinity; DT_NOEND represents +infinity + */ +#define DT_NOBEGIN PG_INT64_MIN +#define DT_NOEND PG_INT64_MAX + +#define TIMESTAMP_NOBEGIN(j) \ + do {(j) = DT_NOBEGIN;} while (0) + +#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN) + +#define TIMESTAMP_NOEND(j) \ + do {(j) = DT_NOEND;} while (0) + +#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND) + +#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j)) + + +/* + * Julian date support. + * + * date2j() and j2date() nominally handle the Julian date range 0..INT_MAX, + * or 4714-11-24 BC to 5874898-06-03 AD. In practice, date2j() will work and + * give correct negative Julian dates for dates before 4714-11-24 BC as well. + * We rely on it to do so back to 4714-11-01 BC. Allowing at least one day's + * slop is necessary so that timestamp rotation doesn't produce dates that + * would be rejected on input. For example, '4714-11-24 00:00 GMT BC' is a + * legal timestamptz value, but in zones east of Greenwich it would print as + * sometime in the afternoon of 4714-11-23 BC; if we couldn't process such a + * date we'd have a dump/reload failure. So the idea is for IS_VALID_JULIAN + * to accept a slightly wider range of dates than we really support, and + * then we apply the exact checks in IS_VALID_DATE or IS_VALID_TIMESTAMP, + * after timezone rotation if any. To save a few cycles, we can make + * IS_VALID_JULIAN check only to the month boundary, since its exact cutoffs + * are not very critical in this scheme. + * + * It is correct that JULIAN_MINYEAR is -4713, not -4714; it is defined to + * allow easy comparison to tm_year values, in which we follow the convention + * that tm_year <= 0 represents abs(tm_year)+1 BC. + */ + +#define JULIAN_MINYEAR (-4713) +#define JULIAN_MINMONTH (11) +#define JULIAN_MINDAY (24) +#define JULIAN_MAXYEAR (5874898) +#define JULIAN_MAXMONTH (6) +#define JULIAN_MAXDAY (3) + +#define IS_VALID_JULIAN(y,m,d) \ + (((y) > JULIAN_MINYEAR || \ + ((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \ + ((y) < JULIAN_MAXYEAR || \ + ((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH)))) + +/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */ +#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */ +#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */ + +/* + * Range limits for dates and timestamps. + * + * We have traditionally allowed Julian day zero as a valid datetime value, + * so that is the lower bound for both dates and timestamps. + * + * The upper limit for dates is 5874897-12-31, which is a bit less than what + * the Julian-date code can allow. For timestamps, the upper limit is + * 294276-12-31. The int64 overflow limit would be a few days later; again, + * leaving some slop avoids worries about corner-case overflow, and provides + * a simpler user-visible definition. + */ + +/* First allowed date, and first disallowed date, in Julian-date form */ +#define DATETIME_MIN_JULIAN (0) +#define DATE_END_JULIAN (2147483494) /* == date2j(JULIAN_MAXYEAR, 1, 1) */ +#define TIMESTAMP_END_JULIAN (109203528) /* == date2j(294277, 1, 1) */ + +/* Timestamp limits */ +#define MIN_TIMESTAMP INT64CONST(-211813488000000000) +/* == (DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ +#define END_TIMESTAMP INT64CONST(9223371331200000000) +/* == (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ + +/* Range-check a date (given in Postgres, not Julian, numbering) */ +#define IS_VALID_DATE(d) \ + ((DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) <= (d) && \ + (d) < (DATE_END_JULIAN - POSTGRES_EPOCH_JDATE)) + +/* Range-check a timestamp */ +#define IS_VALID_TIMESTAMP(t) (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP) + +#endif /* DATATYPE_TIMESTAMP_H */ diff --git a/src/include/version.h b/src/include/version.h index eec5cbdaf..861500331 100644 --- a/src/include/version.h +++ b/src/include/version.h @@ -1 +1 @@ -#define PGPOOLVERSION "karasukiboshi" +#define PGPOOLVERSION "mitsukakeboshi" diff --git a/src/include/watchdog/watchdog.h b/src/include/watchdog/watchdog.h index 78df76c88..f7699e564 100644 --- a/src/include/watchdog/watchdog.h +++ b/src/include/watchdog/watchdog.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2017 PgPool Global Development Group + * Copyright (c) 2003-2019 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -37,8 +37,34 @@ #define WD_TIME_DIFF_SEC(a,b) (int)(((a).tv_sec - (b).tv_sec) + \ ((a).tv_usec - (b).tv_usec) / 1000000.0) +/* + * Data version number of watchdog messages + * The version number is in major.minor format + * The major versions are always kept compatible. + * + * Increment the minor version whenever a minor change is + * made to message data, where the older versions can still + * work even when that change is not present in it. + * + * while incrementing the major version would mean that + * the watchdog node with older major version will not be + * allowed to join the cluster + * + * Since the message data version was not present from the + * beginning, so the default version is considered to be 1.0 + * meaning if the data version number is not present in the + * watchdog node info then it will be considered as version 1.0 + */ + +#define WD_MESSAGE_DATA_VERSION_MAJOR "1" +#define WD_MESSAGE_DATA_VERSION_MINOR "2" +#define WD_MESSAGE_DATA_VERSION WD_MESSAGE_DATA_VERSION_MAJOR "." WD_MESSAGE_DATA_VERSION_MINOR +#define MAX_VERSION_STR_LEN 10 + /* * watchdog state + * If you add a new state. Remember to add entry in + * wd_state_names (watchdog.c) */ typedef enum { @@ -55,8 +81,9 @@ typedef enum WD_IN_NW_TROUBLE, /* the following states are only valid on remote nodes */ WD_SHUTDOWN, - WD_ADD_MESSAGE_SENT -} WD_STATES; + WD_ADD_MESSAGE_SENT, + WD_NETWORK_ISOLATION +} WD_STATES; typedef enum { @@ -66,7 +93,7 @@ typedef enum WD_SOCK_CONNECTED, WD_SOCK_ERROR, WD_SOCK_CLOSED -} WD_SOCK_STATE; +} WD_SOCK_STATE; typedef enum { @@ -89,9 +116,39 @@ typedef enum WD_EVENT_NODE_CON_LOST, WD_EVENT_NODE_CON_FOUND, - WD_EVENT_CLUSTER_QUORUM_CHANGED + WD_EVENT_CLUSTER_QUORUM_CHANGED, + WD_EVENT_WD_STATE_REQUIRE_RELOAD, + WD_EVENT_I_AM_APPEARING_LOST, + WD_EVENT_I_AM_APPEARING_FOUND +} WD_EVENTS; + +/* + * If you add a new lost reason. Remember to add entry in + * wd_node_lost_reasons (watchdog.c) + */ +typedef enum +{ + NODE_LOST_UNKNOWN_REASON = 0, + NODE_LOST_BY_LIFECHECK, + NODE_LOST_BY_SEND_FAILURE, + NODE_LOST_BY_MISSING_BEACON, + NODE_LOST_BY_RECEIVE_TIMEOUT, + NODE_LOST_BY_NOT_REACHABLE, + NODE_LOST_SHUTDOWN +} WD_NODE_LOST_REASONS; -} WD_EVENTS; +/* + * If you add a new membership status. Remember to add entry in + * wd_cluster_membership_status (watchdog.c) + */ + +typedef enum +{ + WD_NODE_MEMBERSHIP_ACTIVE, + WD_NODE_REVOKED_SHUTDOWN, + WD_NODE_REVOKED_NO_SHOW, + WD_NODE_REVOKED_LOST +} WD_NODE_MEMBERSHIP_STATUS; typedef struct SocketConnection { @@ -99,7 +156,7 @@ typedef struct SocketConnection struct timeval tv; /* connect time of socket */ char addr[48]; /* ip address of socket connection */ WD_SOCK_STATE sock_state; /* current state of socket */ -} SocketConnection; +} SocketConnection; typedef struct WatchdogNode { @@ -111,18 +168,37 @@ typedef struct WatchdogNode * from the node */ struct timeval last_sent_time; /* timestamp when last packet was sent on * the node */ + struct timeval lost_time; /* timestamp when the remote node was lost on + * coordinator */ + WD_NODE_MEMBERSHIP_STATUS membership_status; /* status of node + * membership in watchdog + * cluster Only valid for + * remote nodes */ + bool has_lost_us; /* True when this remote node thinks we are + * lost */ + int sending_failures_count; /* number of times we have failed to + * send message to the node. Gets + * reset after successful sent */ + int missed_beacon_count; /* number of times the node has failed + * to reply for beacon. message */ + WD_NODE_LOST_REASONS node_lost_reason; + + char pgp_version[MAX_VERSION_STR_LEN]; /* Pgpool-II version */ + int wd_data_major_version; /* watchdog messaging version major */ + int wd_data_minor_version; /* watchdog messaging version minor */ + char nodeName[WD_MAX_NODE_NAMELEN]; /* name of this node */ char hostname[WD_MAX_HOST_NAMELEN]; /* host name */ int wd_port; /* watchdog port */ int pgpool_port; /* pgpool port */ int wd_priority; /* watchdog priority */ char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ - int private_id; /* ID assigned to this node This id is - * consumed locally */ + int pgpool_node_id; /* pgpool node id specified in pgpool_node_id + * file */ int standby_nodes_count; /* number of standby nodes joined the * cluster only applicable when this * WatchdogNode is the - * master/coordinator node */ + * leader/coordinator node */ int quorum_status; /* quorum status on the node */ bool escalated; /* true if the Watchdog node has performed * escalation */ @@ -130,7 +206,21 @@ typedef struct WatchdogNode * initiated by remote */ SocketConnection client_socket; /* socket connections for this node * initiated by local */ -} WatchdogNode; + bool lifecheck_started; /* True means lifecheck is started, + * false means lifecheck is not started */ +} WatchdogNode; + +/* + * Argument for WD Exec cluster command + */ +#define WD_MAX_ARG_NAME_LEN 64 +#define WD_MAX_ARG_VALUE_LEN 64 + +typedef struct WDExecCommandArg +{ + char arg_name[WD_MAX_ARG_NAME_LEN]; + char arg_value[WD_MAX_ARG_VALUE_LEN]; +} WDExecCommandArg; extern pid_t initialize_watchdog(void); diff --git a/src/include/watchdog/wd_commands.h b/src/include/watchdog/wd_commands.h new file mode 100644 index 000000000..f3d579efb --- /dev/null +++ b/src/include/watchdog/wd_commands.h @@ -0,0 +1,70 @@ + +/* -*-pgsql-c-*- */ +/* + * + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * + */ + +#ifndef WD_COMMANDS_H +#define WD_COMMANDS_H + +#include "watchdog/wd_ipc_defines.h" +#include "watchdog/wd_ipc_conn.h" + +typedef struct WDNodeInfo +{ + int state; + int membership_status; + char membership_status_string[WD_MAX_HOST_NAMELEN]; + char nodeName[WD_MAX_HOST_NAMELEN]; + char hostName[WD_MAX_HOST_NAMELEN]; /* host name */ + char stateName[WD_MAX_HOST_NAMELEN]; /* watchdog state name */ + int wd_port; /* watchdog port */ + int pgpool_port; /* pgpool port */ + int wd_priority; /* node priority */ + char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ + int id; + bool lifecheck_started /* True means lifecheck is started, + * false means lifecheck is not started */; +} WDNodeInfo; + +typedef struct WDGenericData +{ + WDValueDataType valueType; + union data + { + char *stringVal; + int intVal; + bool boolVal; + long long longVal; + } data; +} WDGenericData; + + + +extern WDGenericData *get_wd_runtime_variable_value(char *wd_authkey, char *varName); +extern WD_STATES get_watchdog_local_node_state(char *wd_authkey); +extern int get_watchdog_quorum_state(char *wd_authkey); +extern char *wd_get_watchdog_nodes_json(char *wd_authkey, int nodeID); +extern void set_wd_command_timeout(int sec); +extern char *get_request_json(char *key, char *value, char *authKey); +extern WDNodeInfo *parse_watchdog_node_info_from_wd_node_json(json_value *source); +#endif /* WD_COMMANDS_H */ diff --git a/src/include/watchdog/wd_ipc_commands.h b/src/include/watchdog/wd_internal_commands.h similarity index 63% rename from src/include/watchdog/wd_ipc_commands.h rename to src/include/watchdog/wd_internal_commands.h index 78c78c6cd..9bde69115 100644 --- a/src/include/watchdog/wd_ipc_commands.h +++ b/src/include/watchdog/wd_internal_commands.h @@ -7,7 +7,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2016 PgPool Global Development Group + * Copyright (c) 2003-2019 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -23,50 +23,27 @@ * */ -#ifndef WD_IPC_COMMANDS_H -#define WD_IPC_COMMANDS_H +#ifndef WD_INTERNAL_COMMANDS_H +#define WD_INTERNAL_COMMANDS_H #include "watchdog/wd_ipc_defines.h" #include "watchdog/wd_json_data.h" +#include "watchdog/wd_ipc_conn.h" +#include "watchdog/wd_commands.h" +#include "parser/pg_list.h" -typedef enum WdCommandResult -{ - CLUSTER_IN_TRANSATIONING, - COMMAND_OK, - COMMAND_FAILED, - COMMAND_TIMEOUT -} WdCommandResult; - - -typedef struct WDIPCCmdResult -{ - char type; - int length; - char *data; -} WDIPCCmdResult; - -typedef struct WDGenericData +/* + * These lock can only be acquired by + * coordinator watchdog node on standby + * watchdog node. + */ +typedef enum WD_LOCK_STANDBY_TYPE { - WDValueDataType valueType; - union data - { - char *stringVal; - int intVal; - bool boolVal; - long longVal; - } data; -} WDGenericData; - + WD_INVALID_LOCK, + /* currently we have only one lock */ + WD_FOLLOW_PRIMARY_LOCK +} WD_LOCK_STANDBY_TYPE; -extern void wd_ipc_initialize_data(void); -extern char *get_watchdog_ipc_address(void); -extern unsigned int *get_ipc_shared_key(void); -extern void set_watchdog_process_needs_cleanup(void); -extern void reset_watchdog_process_needs_cleanup(void); -extern bool get_watchdog_process_needs_cleanup(void); -extern void set_watchdog_node_escalated(void); -extern void reset_watchdog_node_escalated(void); -extern bool get_watchdog_node_escalation_state(void); extern WdCommandResult wd_start_recovery(void); extern WdCommandResult wd_end_recovery(void); @@ -74,20 +51,30 @@ extern WDFailoverCMDResults wd_send_failback_request(int node_id, unsigned char extern WDFailoverCMDResults wd_degenerate_backend_set(int *node_id_set, int count, unsigned char flags); extern WDFailoverCMDResults wd_promote_backend(int node_id, unsigned char flags); -extern WDPGBackendStatus * get_pg_backend_status_from_master_wd_node(void); -extern WDGenericData * get_wd_runtime_variable_value(char *varName); -extern WD_STATES get_watchdog_local_node_state(void); -extern int get_watchdog_quorum_state(void); +extern WdCommandResult wd_execute_cluster_command(char *clusterCommand, List *argsList); -extern char *wd_get_watchdog_nodes(int nodeID); +extern WDPGBackendStatus *get_pg_backend_status_from_leader_wd_node(void); -extern WDIPCCmdResult * issue_command_to_watchdog(char type, int timeout_sec, char *data, int data_len, bool blocking); +extern WD_STATES wd_internal_get_watchdog_local_node_state(void); +extern int wd_internal_get_watchdog_quorum_state(void); +extern char *wd_internal_get_watchdog_nodes_json(int nodeID); +extern void wd_ipc_initialize_data(void); /* functions for failover commands interlocking */ extern WDFailoverCMDResults wd_failover_end(void); extern WDFailoverCMDResults wd_failover_start(void); +extern unsigned int *get_ipc_shared_key(void); +extern void set_watchdog_process_needs_cleanup(void); +extern void reset_watchdog_process_needs_cleanup(void); +extern bool get_watchdog_process_needs_cleanup(void); +extern void set_watchdog_node_escalated(void); +extern void reset_watchdog_node_escalated(void); +extern bool get_watchdog_node_escalation_state(void); +extern size_t wd_ipc_get_shared_mem_size(void); +extern WdCommandResult wd_lock_standby(WD_LOCK_STANDBY_TYPE lock_type); +extern WdCommandResult wd_unlock_standby(WD_LOCK_STANDBY_TYPE lock_type); -#endif /* WD_IPC_COMMANDS_H */ +#endif /* WD_INTERNAL_COMMANDS_H */ diff --git a/src/include/watchdog/wd_ipc_conn.h b/src/include/watchdog/wd_ipc_conn.h new file mode 100644 index 000000000..abc50ddee --- /dev/null +++ b/src/include/watchdog/wd_ipc_conn.h @@ -0,0 +1,58 @@ + +/* -*-pgsql-c-*- */ +/* + * + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2019 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * + */ + +#ifndef WD_IPC_CONN_H +#define WD_IPC_CONN_H + +#include "watchdog/wd_ipc_defines.h" +#include "watchdog/wd_json_data.h" + +typedef enum WdCommandResult +{ + CLUSTER_IN_TRANSACTIONING, + COMMAND_OK, + COMMAND_FAILED, + COMMAND_TIMEOUT +} WdCommandResult; + + +typedef struct WDIPCCmdResult +{ + char type; + int length; + char *data; +} WDIPCCmdResult; + + +extern void wd_ipc_conn_initialize(void); +extern void wd_set_ipc_address(char *socket_dir, int port); +extern size_t estimate_ipc_socket_addr_len(void); +extern char *get_watchdog_ipc_address(void); + +extern WDIPCCmdResult *issue_command_to_watchdog(char type, int timeout_sec, char *data, int data_len, bool blocking); + +extern void FreeCmdResult(WDIPCCmdResult *res); + +#endif /* WD_IPC_CONN_H */ diff --git a/src/include/watchdog/wd_ipc_defines.h b/src/include/watchdog/wd_ipc_defines.h index 1e19e8e5b..9a8b85e7d 100644 --- a/src/include/watchdog/wd_ipc_defines.h +++ b/src/include/watchdog/wd_ipc_defines.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2017 PgPool Global Development Group + * Copyright (c) 2003-2020 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -38,11 +38,11 @@ typedef enum WDFailoverCMDResults FAILOVER_RES_WILL_BE_DONE, FAILOVER_RES_NOT_ALLOWED, FAILOVER_RES_INVALID_FUNCTION, - FAILOVER_RES_MASTER_REJECTED, + FAILOVER_RES_LEADER_REJECTED, FAILOVER_RES_BUILDING_CONSENSUS, FAILOVER_RES_CONSENSUS_MAY_FAIL, FAILOVER_RES_TIMEOUT -} WDFailoverCMDResults; +} WDFailoverCMDResults; typedef enum WDValueDataType { @@ -50,7 +50,7 @@ typedef enum WDValueDataType VALUE_DATA_TYPE_STRING, VALUE_DATA_TYPE_BOOL, VALUE_DATA_TYPE_LONG -} WDValueDataType; +} WDValueDataType; /* IPC MESSAGES TYPES */ #define WD_REGISTER_FOR_NOTIFICATION '0' @@ -62,13 +62,23 @@ typedef enum WDValueDataType #define WD_IPC_CMD_RESULT_OK '7' #define WD_IPC_CMD_TIMEOUT '8' +#define WD_EXECUTE_CLUSTER_COMMAND 'c' #define WD_IPC_FAILOVER_COMMAND 'f' -#define WD_IPC_ONLINE_RECOVERY_COMMAND 'r' -#define WD_FAILOVER_LOCKING_REQUEST 's' -#define WD_GET_MASTER_DATA_REQUEST 'd' +#define WD_IPC_ONLINE_RECOVERY_COMMAND 'r' +#define WD_FAILOVER_LOCKING_REQUEST 's' +#define WD_GET_LEADER_DATA_REQUEST 'd' #define WD_GET_RUNTIME_VARIABLE_VALUE 'v' #define WD_FAILOVER_INDICATION 'i' + +#define WD_COMMAND_RESTART_CLUSTER "RESTART_CLUSTER" +#define WD_COMMAND_REELECT_LEADER "REELECT_LEADER" +#define WD_COMMAND_SHUTDOWN_CLUSTER "SHUTDOWN_CLUSTER" +#define WD_COMMAND_RELOAD_CONFIG_CLUSTER "RELOAD_CONFIG_CLUSTER" +#define WD_COMMAND_LOGROTATE_CLUSTER "LOGROTATE_CLUSTER" +#define WD_COMMAND_LOCK_ON_STANDBY "APPLY_LOCK_ON_STANDBY" + + #define WD_FUNCTION_START_RECOVERY "START_RECOVERY" #define WD_FUNCTION_END_RECOVERY "END_RECOVERY" #define WD_FUNCTION_FAILBACK_REQUEST "FAILBACK_REQUEST" @@ -112,9 +122,9 @@ typedef enum WDValueDataType #define WD_RUNTIME_VAR_ESCALATION_STATE "Escalated" /* Use to inform node new node status by lifecheck */ -#define WD_LIFECHECK_NODE_STATUS_DEAD 1 +#define WD_LIFECHECK_NODE_STATUS_DEAD 1 #define WD_LIFECHECK_NODE_STATUS_ALIVE 2 - +#define WD_LIFECHECK_NODE_LIFECHECK_STARTED 3 #endif diff --git a/src/include/watchdog/wd_json_data.h b/src/include/watchdog/wd_json_data.h index 1e22ee531..01e40e784 100644 --- a/src/include/watchdog/wd_json_data.h +++ b/src/include/watchdog/wd_json_data.h @@ -23,27 +23,15 @@ */ #include "utils/json.h" #include "pool_config.h" +#include "parser/pg_list.h" #include "watchdog/watchdog.h" #ifndef WD_JSON_DATA_H #define WD_JSON_DATA_H -typedef struct WDNodeInfo -{ - int state; - char nodeName[WD_MAX_HOST_NAMELEN]; - char hostName[WD_MAX_HOST_NAMELEN]; /* host name */ - char stateName[WD_MAX_HOST_NAMELEN]; /* watchdog state name */ - int wd_port; /* watchdog port */ - int pgpool_port; /* pgpool port */ - int wd_priority; /* node priority */ - char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ - int id; -} WDNodeInfo; - /* * The structure to hold the parsed PG backend node status data fetched - * from the master watchdog node + * from the leader watchdog node */ typedef struct WDPGBackendStatus { @@ -52,35 +40,41 @@ typedef struct WDPGBackendStatus BACKEND_STATUS backend_status[MAX_NUM_BACKENDS]; char nodeName[WD_MAX_HOST_NAMELEN]; /* name of the watchdog node * that sent the data */ -} WDPGBackendStatus; +} WDPGBackendStatus; -extern WatchdogNode * get_watchdog_node_from_json(char *json_data, int data_len, char **authkey); -extern char *get_watchdog_node_info_json(WatchdogNode * wdNode, char *authkey); -extern POOL_CONFIG * get_pool_config_from_json(char *json_data, int data_len); +extern WatchdogNode *get_watchdog_node_from_json(char *json_data, int data_len, char **authkey); +extern char *get_watchdog_node_info_json(WatchdogNode *wdNode, char *authkey); +extern POOL_CONFIG *get_pool_config_from_json(char *json_data, int data_len); extern char *get_pool_config_json(void); extern char *get_lifecheck_node_status_change_json(int nodeID, int nodeStatus, char *message, char *authKey); extern bool parse_node_status_json(char *json_data, int data_len, int *nodeID, int *nodeStatus, char **message); -extern WDNodeInfo * get_WDNodeInfo_from_wd_node_json(json_value * source); extern bool parse_beacon_message_json(char *json_data, int data_len, int *state, - long *seconds_since_node_startup, - long *seconds_since_current_state, - int *quorumStatus, - int *standbyNodesCount, - bool *escalated); -extern char *get_beacon_message_json(WatchdogNode * wdNode); + long long *seconds_since_node_startup, + long long *seconds_since_current_state, + int *quorumStatus, + int *standbyNodesCount, + bool *escalated); +extern char *get_beacon_message_json(WatchdogNode *wdNode); extern char *get_wd_node_function_json(char *func_name, int *node_id_set, int count, unsigned char flags, unsigned int sharedKey, char *authKey); extern bool parse_wd_node_function_json(char *json_data, int data_len, char **func_name, int **node_id_set, int *count, unsigned char *flags); extern char *get_wd_simple_message_json(char *message); -extern WDPGBackendStatus * get_pg_backend_node_status_from_json(char *json_data, int data_len); -extern char *get_backend_node_status_json(WatchdogNode * wdNode); +extern WDPGBackendStatus *get_pg_backend_node_status_from_json(char *json_data, int data_len); +extern char *get_backend_node_status_json(WatchdogNode *wdNode); extern char *get_simple_request_json(char *key, char *value, unsigned int sharedKey, char *authKey); extern bool parse_data_request_json(char *json_data, int data_len, char **request_type); extern char *get_data_request_json(char *request_type, unsigned int sharedKey, char *authKey); +extern bool + parse_wd_exec_cluster_command_json(char *json_data, int data_len, + char **clusterCommand, List **args_list); + +extern char *get_wd_exec_cluster_command_json(char *clusterCommand, List *args_list, + unsigned int sharedKey, char *authKey); + #endif diff --git a/src/include/watchdog/wd_lifecheck.h b/src/include/watchdog/wd_lifecheck.h index d612ab38e..669ad5b7d 100644 --- a/src/include/watchdog/wd_lifecheck.h +++ b/src/include/watchdog/wd_lifecheck.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2012 PgPool Global Development Group + * Copyright (c) 2003-2021 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -33,38 +33,41 @@ typedef enum NodeState { NODE_EMPTY, NODE_DEAD, - NODE_ALIVE -} NodeStates; + NODE_ALIVE, + NODE_LIFECHECK_STARTED +} NodeStates; typedef struct LifeCheckNode { NodeStates nodeState; - int ID; - char hostName[128]; - char nodeName[128]; + int ID; + WD_STATES wdState; + char stateName[128]; + char hostName[WD_MAX_HOST_NAMELEN]; + char nodeName[WD_MAX_NODE_NAMELEN]; int wdPort; int pgpoolPort; int retry_lives; struct timeval hb_send_time; /* send time */ struct timeval hb_last_recv_time; /* recv time */ -} LifeCheckNode; +} LifeCheckNode; typedef struct lifeCheckCluster { int nodeCount; struct LifeCheckNode *lifeCheckNodes; -} LifeCheckCluster; +} LifeCheckCluster; -extern LifeCheckCluster * gslifeCheckCluster; /* lives in shared memory */ +extern LifeCheckCluster *gslifeCheckCluster; /* lives in shared memory */ /* wd_lifecheck.c */ extern pid_t initialize_watchdog_lifecheck(void); -/* wd_hearbeat.c */ -extern pid_t wd_hb_receiver(int fork_wait_time, WdHbIf * hb_if); -extern pid_t wd_hb_sender(int fork_wait_time, WdHbIf * hb_if); +/* wd_heartbeat.c */ +extern pid_t wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if); +extern pid_t wd_hb_sender(int fork_wait_time, WdHbIf *hb_if); #endif diff --git a/src/include/watchdog/wd_utils.h b/src/include/watchdog/wd_utils.h index cdf829c63..5df1fa1e9 100644 --- a/src/include/watchdog/wd_utils.h +++ b/src/include/watchdog/wd_utils.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -26,6 +26,7 @@ #define WD_UTILS_H #include +#include #include "parser/pg_list.h" #define WD_NG (0) @@ -38,20 +39,18 @@ extern void wd_check_network_command_configurations(void); extern int watchdog_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); extern char *string_replace(const char *string, const char *pattern, const char *replacement); extern void wd_calc_hash(const char *str, int len, char *buf); -extern int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, - const char *password, unsigned char *plaintext); -extern int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, - const char *password, unsigned char *ciphertext); +extern int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, + const char *password, unsigned char *plaintext); +extern int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, + const char *password, unsigned char *ciphertext); /* wd_escalation.c */ extern pid_t fork_escalation_process(void); extern pid_t fork_plunging_process(void); /* wd_ping.c */ -extern int wd_is_upper_ok(char *server_list); extern bool wd_is_ip_exists(char *ip); -extern bool wd_get_ping_result(char *hostname, int exit_status, int outfd); -extern pid_t wd_issue_ping_command(char *hostname, int *outfd); +extern pid_t wd_trusted_server_command(char *hostname); /* wd_if.c */ extern List *get_all_local_ips(void); diff --git a/src/libs/Makefile.in b/src/libs/Makefile.in deleted file mode 100644 index 8c9c08381..000000000 --- a/src/libs/Makefile.in +++ /dev/null @@ -1,630 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/libs -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -depcomp = -am__depfiles_maybe = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -SUBDIRS = pcp -all: all-recursive - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps src/libs/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps src/libs/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-recursive - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool cscopelist-am ctags \ - ctags-am distclean distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/libs/pcp/Makefile.am b/src/libs/pcp/Makefile.am index ccd9115bb..cfab51be4 100644 --- a/src/libs/pcp/Makefile.am +++ b/src/libs/pcp/Makefile.am @@ -1,13 +1,16 @@ AM_CPPFLAGS = -D_GNU_SOURCE -DPOOL_PRIVATE -I @PGSQL_INCLUDE_DIR@ -lib_LTLIBRARIES = libpcp.la -libpcp_la_LDFLAGS = -version-info 1:0:0 -dist_libpcp_la_SOURCES = pcp.c \ +lib_LTLIBRARIES = libpgpoolpcp.la +libpgpoolpcp_la_LDFLAGS = -version-info 3:0:0 +dist_libpgpoolpcp_la_SOURCES = pcp.c \ ../../utils/pool_path.c \ ../../tools/fe_port.c \ ../../tools/fe_memutils.c \ - ../../utils/strlcpy.c -nodist_libpcp_la_SOURCES = pcp_stream.c \ + ../../utils/strlcpy.c \ + ../../utils/pool_health_check_stats.c \ + ../../utils/sprompt.c + +nodist_libpgpoolpcp_la_SOURCES = pcp_stream.c \ md5.c \ json.c @@ -24,4 +27,4 @@ json.c: ../../../src/utils/json.c rm -f $@ && ln -s $< . clean-local: - -rm -f $(nodist_libpcp_la_SOURCES) + -rm -f $(nodist_libpgpoolpcp_la_SOURCES) diff --git a/src/libs/pcp/Makefile.in b/src/libs/pcp/Makefile.in deleted file mode 100644 index 6d87693d0..000000000 --- a/src/libs/pcp/Makefile.in +++ /dev/null @@ -1,710 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/libs/pcp -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs $(include_HEADERS) -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libpcp_la_LIBADD = -am__dirstamp = $(am__leading_dot)dirstamp -dist_libpcp_la_OBJECTS = pcp.lo ../../utils/pool_path.lo \ - ../../tools/fe_port.lo ../../tools/fe_memutils.lo \ - ../../utils/strlcpy.lo -nodist_libpcp_la_OBJECTS = pcp_stream.lo md5.lo json.lo -libpcp_la_OBJECTS = $(dist_libpcp_la_OBJECTS) \ - $(nodist_libpcp_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libpcp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libpcp_la_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/include -depcomp = -am__depfiles_maybe = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(dist_libpcp_la_SOURCES) $(nodist_libpcp_la_SOURCES) -DIST_SOURCES = $(dist_libpcp_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(include_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AM_CPPFLAGS = -D_GNU_SOURCE -DPOOL_PRIVATE -I @PGSQL_INCLUDE_DIR@ -lib_LTLIBRARIES = libpcp.la -libpcp_la_LDFLAGS = -version-info 1:0:0 -dist_libpcp_la_SOURCES = pcp.c \ - ../../utils/pool_path.c \ - ../../tools/fe_port.c \ - ../../tools/fe_memutils.c \ - ../../utils/strlcpy.c - -nodist_libpcp_la_SOURCES = pcp_stream.c \ - md5.c \ - json.c - -include_HEADERS = ../../../src/include/pcp/pcp.h \ - ../../../src/include/pcp/libpcp_ext.h \ - ../../../src/include/pool_type.h \ - ../../../src/include/utils/pool_process_reporting.h - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps src/libs/pcp/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps src/libs/pcp/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -../../utils/$(am__dirstamp): - @$(MKDIR_P) ../../utils - @: > ../../utils/$(am__dirstamp) -../../utils/pool_path.lo: ../../utils/$(am__dirstamp) -../../tools/$(am__dirstamp): - @$(MKDIR_P) ../../tools - @: > ../../tools/$(am__dirstamp) -../../tools/fe_port.lo: ../../tools/$(am__dirstamp) -../../tools/fe_memutils.lo: ../../tools/$(am__dirstamp) -../../utils/strlcpy.lo: ../../utils/$(am__dirstamp) - -libpcp.la: $(libpcp_la_OBJECTS) $(libpcp_la_DEPENDENCIES) $(EXTRA_libpcp_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpcp_la_LINK) -rpath $(libdir) $(libpcp_la_OBJECTS) $(libpcp_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f ../../tools/*.$(OBJEXT) - -rm -f ../../tools/*.lo - -rm -f ../../utils/*.$(OBJEXT) - -rm -f ../../utils/*.lo - -distclean-compile: - -rm -f *.tab.c - -.c.o: - $(AM_V_CC)$(COMPILE) -c -o $@ $< - -.c.obj: - $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: - $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf ../../tools/.libs ../../tools/_libs - -rm -rf ../../utils/.libs ../../utils/_libs -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../../tools/$(am__dirstamp) - -rm -f ../../utils/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ - mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-includeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-local cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES - - -md5.c: ../../../src/auth/md5.c - rm -f $@ && ln -s $< . -pcp_stream.c: ../../../src/utils/pcp/pcp_stream.c - rm -f $@ && ln -s $< . -json.c: ../../../src/utils/json.c - rm -f $@ && ln -s $< . - -clean-local: - -rm -f $(nodist_libpcp_la_SOURCES) - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/libs/pcp/pcp.c b/src/libs/pcp/pcp.c index 50c5bf7c1..e0df470b0 100644 --- a/src/libs/pcp/pcp.c +++ b/src/libs/pcp/pcp.c @@ -1,5 +1,5 @@ /* -FILE * $Header$ + * $Header$ * * Handles PCP connection, and protocol communication with pgpool-II * These are client APIs. Server program should use APIs in pcp_stream.c @@ -8,7 +8,7 @@ FILE * $Header$ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2016 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -41,6 +41,7 @@ FILE * $Header$ #include "pool.h" #include "pcp/pcp.h" #include "pcp/pcp_stream.h" +#include "utils/fe_ports.h" #include "utils/pool_path.h" #include "utils/palloc.h" #include "utils/pool_process_reporting.h" @@ -56,7 +57,7 @@ static int pcp_authorize(PCPConnInfo * pcpConn, char *username, char *password); static void pcp_internal_error(PCPConnInfo * pcpConn, const char *fmt,...); static PCPResultInfo * _pcp_detach_node(PCPConnInfo * pcpConn, int nid, bool gracefully); -static PCPResultInfo * _pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully); +static PCPResultInfo * _pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully, bool promote); static PCPResultInfo * process_pcp_response(PCPConnInfo * pcpConn, char sentMsg); static void setCommandSuccessful(PCPConnInfo * pcpConn); static void setResultStatus(PCPConnInfo * pcpConn, ResultStateType resultState); @@ -65,6 +66,7 @@ static int setNextResultBinaryData(PCPResultInfo * res, void *value, int datalen static void setResultIntData(PCPResultInfo * res, unsigned int slotno, int value); static void process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_health_check_stats_response(PCPConnInfo * pcpConn, char *buf, int len); static void process_command_complete_response(PCPConnInfo * pcpConn, char *buf, int len); static void process_watchdog_info_response(PCPConnInfo * pcpConn, char *buf, int len); static void process_process_info_response(PCPConnInfo * pcpConn, char *buf, int len); @@ -76,7 +78,6 @@ static void process_error_response(PCPConnInfo * pcpConn, char toc, char *buff); static void setResultSlotCount(PCPConnInfo * pcpConn, unsigned int slotCount); -static void free_processInfo(struct PCPConnInfo *pcpConn, void *ptr); static int PCPFlush(PCPConnInfo * pcpConn); static bool getPoolPassFilename(char *pgpassfile); @@ -91,25 +92,23 @@ static char *pwdfMatchesString(char *buf, char *token); */ /* Check if PCP connection is connected and authenticated - * return 1 on successfull 0 otherwise + * return 1 on successful 0 otherwise */ PCPConnInfo * pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug) { - struct sockaddr_in addr; struct sockaddr_un unix_addr; - struct hostent *hp; - char *password_fron_file = NULL; + char *password_from_file = NULL; char os_user[256]; PCPConnInfo *pcpConn = palloc0(sizeof(PCPConnInfo)); int fd; int on = 1; - int len; pcpConn->connState = PCP_CONNECTION_NOT_CONNECTED; pcpConn->Pfdebug = Pfdebug; + /* Unix domain socket? */ if (hostname == NULL || *hostname == '\0' || *hostname == '/') { char *path; @@ -153,49 +152,83 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde } else { - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) + /* Inet domain socket case */ + char *portstr; + int ret; + struct addrinfo *res; + struct addrinfo *walk; + struct addrinfo hints; + + /* + * getaddrinfo() requires a string because it also accepts service + * names, such as "http". + */ + if (asprintf(&portstr, "%d", port) == -1) { pcp_internal_error(pcpConn, - "ERROR: failed to create INET domain socket with error \"%s\"", strerror(errno)); + "ERROR: asprintf() failed"); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, - (char *) &on, sizeof(on)) < 0) - { - close(fd); + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if ((ret = getaddrinfo(hostname, portstr, &hints, &res)) != 0) + { pcp_internal_error(pcpConn, - "ERROR: set socket option failed with error \"%s\"", strerror(errno)); + "ERROR: getaddrinfo failed \"%s\"", + gai_strerror(ret)); pcpConn->connState = PCP_CONNECTION_BAD; + free(portstr); return pcpConn; } - memset((char *) &addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - hp = gethostbyname(hostname); - if ((hp == NULL) || (hp->h_addrtype != AF_INET)) + free(portstr); + + fd = -1; + for (walk = res; walk != NULL; walk = walk->ai_next) { - close(fd); - pcp_internal_error(pcpConn, - "ERROR: could not retrieve hostname. gethostbyname failed with error \"%s\"", strerror(errno)); - pcpConn->connState = PCP_CONNECTION_BAD; - return pcpConn; + fd = socket(walk->ai_family, walk->ai_socktype, walk->ai_protocol); + if (fd < 0) + { + pcp_internal_error(pcpConn, + "ERROR: failed to create INET domain socket with error \"%s\"", + strerror(errno)); + freeaddrinfo(res); + return pcpConn; + } + + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, + (char *) &on, sizeof(on)) < 0) + { + close(fd); + freeaddrinfo(res); + pcp_internal_error(pcpConn, + "ERROR: set socket option failed with error \"%s\"", strerror(errno)); + pcpConn->connState = PCP_CONNECTION_BAD; + return pcpConn; + } + if (connect(fd, walk->ai_addr, walk->ai_addrlen) < 0) + { + close(fd); + freeaddrinfo(res); + pcp_internal_error(pcpConn, + "ERROR: connection to host \"%s\" failed with error \"%s\"", hostname, strerror(errno)); + pcpConn->connState = PCP_CONNECTION_BAD; + return pcpConn; + } + break; /* successfully connected */ } - memmove((char *) &(addr.sin_addr), - (char *) hp->h_addr, - hp->h_length); - addr.sin_port = htons(port); - len = sizeof(struct sockaddr_in); - if (connect(fd, (struct sockaddr *) &addr, len) < 0) + freeaddrinfo(res); + /* no address available */ + if (fd == -1) { - close(fd); pcp_internal_error(pcpConn, - "ERROR: connection to host \"%s\" failed with error \"%s\"", hostname, strerror(errno)); + "ERROR: connection to host \"%s\" failed", hostname); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } @@ -210,6 +243,7 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } + pcpConn->connState = PCP_CONNECTION_CONNECTED; /* @@ -227,8 +261,15 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde char port_str[100]; snprintf(port_str, sizeof(port_str), "%d", port); - password_fron_file = PasswordFromFile(pcpConn, hostname, port_str, username); - password = password_fron_file; + password_from_file = PasswordFromFile(pcpConn, hostname, port_str, username); + password = password_from_file; + + /* + * If reading password from .pcppass file fails, try to read it from + * prompt. + */ + if (password == NULL || *password == '\0') + password = simple_prompt("Password: ", 100, false); } if (pcp_authorize(pcpConn, username, password) < 0) @@ -240,8 +281,8 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde else pcpConn->connState = PCP_CONNECTION_OK; - if (password_fron_file) - pfree(password_fron_file); + if (password_from_file) + pfree(password_from_file); return pcpConn; } @@ -365,6 +406,7 @@ static PCPResultInfo * process_pcp_response(PCPConnInfo * pcpConn, char sentMsg) setResultStatus(pcpConn, PCP_RES_ERROR); return pcpConn->pcpResInfo; } + if (pcp_read(pcpConn->pcpConn, &rsize, sizeof(int))) { pcp_internal_error(pcpConn, @@ -389,111 +431,140 @@ static PCPResultInfo * process_pcp_response(PCPConnInfo * pcpConn, char sentMsg) switch (toc) { - case 'r': /* Authentication Response */ - { - if (sentMsg != 'R') - { - setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); - } - else if (strcmp(buf, "AuthenticationOK") == 0) - { - pcpConn->connState = PCP_CONNECTION_OK; - setResultStatus(pcpConn, PCP_RES_COMMAND_OK); - } - else - { - pcp_internal_error(pcpConn, - "ERROR: authentication failed. reason=\"%s\"", buf); - setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR); - } - } + case 'a': /* set configuration parameter */ + if (sentMsg != 'A') + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + else + process_command_complete_response(pcpConn, buf, rsize); break; - case 'm': - if (sentMsg != 'M') + + case 'b': /* status request */ + if (sentMsg != 'B') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_salt_info_response(pcpConn, buf, rsize); + process_pool_status_response(pcpConn, buf, rsize); break; - case 'E': + case 'c': /* attach node */ + if (sentMsg != 'C' && sentMsg != 'O') + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + else + process_command_complete_response(pcpConn, buf, rsize); + break; + + case 'd': /* detach node */ + if (sentMsg != 'D' && sentMsg != 'J') + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + else + process_command_complete_response(pcpConn, buf, rsize); + break; + + case 'E': /* error */ setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR); process_error_response(pcpConn, toc, buf); break; - case 'N': - process_error_response(pcpConn, toc, buf); - pfree(buf); - continue; + case 'g': /* invalidate query cache */ + if (sentMsg != 'G') + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + else + process_command_complete_response(pcpConn, buf, rsize); + break; + + case 'h': /* health check stats */ + if (sentMsg != 'H') + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + else + process_health_check_stats_response(pcpConn, buf, rsize); break; - case 'i': + case 'i': /* node info */ if (sentMsg != 'I') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else process_node_info_response(pcpConn, buf, rsize); break; - case 'l': + case 'l': /* node count */ if (sentMsg != 'L') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else process_pcp_node_count_response(pcpConn, buf, rsize); break; - case 'c': - if (sentMsg != 'C' && sentMsg != 'O') + case 'm': /* salt info response */ + if (sentMsg != 'M') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_command_complete_response(pcpConn, buf, rsize); + process_salt_info_response(pcpConn, buf, rsize); break; - case 'd': - if (sentMsg != 'D' && sentMsg != 'J') - setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); - else - process_command_complete_response(pcpConn, buf, rsize); + case 'N': /* error response */ + process_error_response(pcpConn, toc, buf); + pfree(buf); + continue; break; - case 'a': - if (sentMsg != 'A') + case 'n': /* process count */ + if (sentMsg != 'N') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_command_complete_response(pcpConn, buf, rsize); + process_process_count_response(pcpConn, buf, rsize); break; - case 'w': - if (sentMsg != 'W') + case 'p': /* process info */ + if (sentMsg != 'P') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_watchdog_info_response(pcpConn, buf, rsize); + process_process_info_response(pcpConn, buf, rsize); break; - case 'p': - if (sentMsg != 'P') + case 'r': /* Authentication Response */ + { + if (sentMsg != 'R') + { + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + } + else if (strcmp(buf, "AuthenticationOK") == 0) + { + pcpConn->connState = PCP_CONNECTION_OK; + setResultStatus(pcpConn, PCP_RES_COMMAND_OK); + } + else + { + pcp_internal_error(pcpConn, + "ERROR: authentication failed. reason=\"%s\"", buf); + setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR); + } + } + break; + + case 't': /* shutdown request */ + if (sentMsg != 'T') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_process_info_response(pcpConn, buf, rsize); + setResultStatus(pcpConn, PCP_RES_COMMAND_OK); break; - case 'n': - if (sentMsg != 'N') + case 'v': /* pcp_log_rotate */ + if (sentMsg != 'V') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_process_count_response(pcpConn, buf, rsize); + process_command_complete_response(pcpConn, buf, rsize); break; - case 'b': - if (sentMsg != 'B') + case 'w': /* watchdog info */ + if (sentMsg != 'W') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_pool_status_response(pcpConn, buf, rsize); + process_watchdog_info_response(pcpConn, buf, rsize); break; - case 't': - if (sentMsg != 'T') + case 'z': /* command complete */ + if (sentMsg != 'Z') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - setResultStatus(pcpConn, PCP_RES_COMMAND_OK); + process_command_complete_response(pcpConn, buf, rsize); break; default: @@ -599,7 +670,7 @@ pcp_disconnect(PCPConnInfo * pcpConn) * -------------------------------- */ PCPResultInfo * -pcp_terminate_pgpool(PCPConnInfo * pcpConn, char mode) +pcp_terminate_pgpool(PCPConnInfo * pcpConn, char mode, char command_scope) { int wsize; @@ -608,7 +679,10 @@ pcp_terminate_pgpool(PCPConnInfo * pcpConn, char mode) pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } - pcp_write(pcpConn->pcpConn, "T", 1); + if (command_scope == 'l') /* local only */ + pcp_write(pcpConn->pcpConn, "T", 1); + else + pcp_write(pcpConn->pcpConn, "t", 1); wsize = htonl(sizeof(int) + sizeof(char)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); pcp_write(pcpConn->pcpConn, &mode, sizeof(char)); @@ -679,12 +753,31 @@ pcp_node_count(PCPConnInfo * pcpConn) static void process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) { + char *index; BackendInfo *backend_info = NULL; - if (strcmp(buf, "CommandComplete") == 0) + if (strcmp(buf, "ArraySize") == 0) + { + int ci_size; + + index = (char *) memchr(buf, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; + index += 1; + ci_size = atoi(index); + + setResultStatus(pcpConn, PCP_RES_INCOMPLETE); + setResultSlotCount(pcpConn, ci_size); + pcpConn->pcpResInfo->nextFillSlot = 0; + return; + } + else if (strcmp(buf, "NodeInfo") == 0) { char *index = NULL; + if (PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) + goto INVALID_RESPONSE; + backend_info = (BackendInfo *) palloc(sizeof(BackendInfo)); index = (char *) memchr(buf, '\0', len); @@ -709,15 +802,40 @@ process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) if (index == NULL) goto INVALID_RESPONSE; index += 1; - backend_info->backend_weight = atof(index); + backend_info->quarantine = atoi(index); + + index = (char *) memchr(index, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; + index += 1; + strlcpy(backend_info->pg_backend_status, index, sizeof(backend_info->pg_backend_status)); index = (char *) memchr(index, '\0', len); if (index == NULL) goto INVALID_RESPONSE; + index += 1; + backend_info->backend_weight = atof(index); + index = (char *) memchr(index, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; index++; backend_info->role = atoi(index); + index = (char *) memchr(index, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; + index++; + + strlcpy(backend_info->pg_role, index, sizeof(backend_info->pg_role)); + + index = (char *) memchr(index, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; + + index++; + backend_info->standby_delay_by_time = atol(index); + index = (char *) memchr(index, '\0', len); if (index == NULL) goto INVALID_RESPONSE; @@ -725,6 +843,20 @@ process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) index++; backend_info->standby_delay = atol(index); + index = (char *) memchr(index, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; + + index++; + strlcpy(backend_info->replication_state, index, sizeof(backend_info->replication_state)); + + index = (char *) memchr(index, '\0', len); + if (index == NULL) + goto INVALID_RESPONSE; + + index++; + strlcpy(backend_info->replication_sync_state, index, sizeof(backend_info->replication_sync_state)); + index = (char *) memchr(index, '\0', len); if (index == NULL) goto INVALID_RESPONSE; @@ -739,17 +871,14 @@ process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) backend_info, sizeof(BackendInfo), NULL) < 0) goto INVALID_RESPONSE; - setCommandSuccessful(pcpConn); + return; } - else + else if (strcmp(buf, "CommandComplete") == 0) { - pcp_internal_error(pcpConn, - "command failed with reason: \"%s\"", buf); - setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + setResultStatus(pcpConn, PCP_RES_COMMAND_OK); + return; } - return; - INVALID_RESPONSE: if (backend_info) @@ -793,6 +922,174 @@ pcp_node_info(PCPConnInfo * pcpConn, int nid) return process_pcp_response(pcpConn, 'I'); } + +/* -------------------------------- + * pcp_health_check_stats - get information of health check stats pointed by given argument + * + * return structure of node information on success, -1 otherwise + * -------------------------------- + */ +PCPResultInfo * +pcp_health_check_stats(PCPConnInfo * pcpConn, int nid) +{ + int wsize; + char node_id[16]; + + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + { + pcp_internal_error(pcpConn, + "invalid PCP connection"); + return NULL; + } + + snprintf(node_id, sizeof(node_id), "%d", nid); + + pcp_write(pcpConn->pcpConn, "H", 1); + wsize = htonl(strlen(node_id) + 1 + sizeof(int)); + pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); + pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1); + if (PCPFlush(pcpConn) < 0) + return NULL; + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"L\", len=%d\n", ntohl(wsize)); + + return process_pcp_response(pcpConn, 'H'); +} + +PCPResultInfo * +pcp_reload_config(PCPConnInfo * pcpConn, char command_scope) +{ + int wsize; + +/* + * pcp packet format for pcp_reload_config + * z[size][command_scope] + */ + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + { + pcp_internal_error(pcpConn, "invalid PCP connection"); + return NULL; + } + + pcp_write(pcpConn->pcpConn, "Z", 1); + wsize = htonl(sizeof(int) + sizeof(char)); + pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); + pcp_write(pcpConn->pcpConn, &command_scope, sizeof(char)); + if (PCPFlush(pcpConn) < 0) + return NULL; + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"Z\", len=%d\n", ntohl(wsize)); + + return process_pcp_response(pcpConn, 'Z'); +} + +PCPResultInfo * +pcp_log_rotate(PCPConnInfo * pcpConn, char command_scope) +{ + int wsize; + +/* + * pcp packet format for pcp_log_rotate + * v[size][command_scope] + */ + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + { + pcp_internal_error(pcpConn, "invalid PCP connection"); + return NULL; + } + + pcp_write(pcpConn->pcpConn, "V", 1); + wsize = htonl(sizeof(int) + sizeof(char)); + pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); + pcp_write(pcpConn->pcpConn, &command_scope, sizeof(char)); + if (PCPFlush(pcpConn) < 0) + return NULL; + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"Z\", len=%d\n", ntohl(wsize)); + + return process_pcp_response(pcpConn, 'V'); +} + +PCPResultInfo * +pcp_invalidate_query_cache(PCPConnInfo * pcpConn) +{ + int wsize; + + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + { + pcp_internal_error(pcpConn, "invalid PCP connection"); + return NULL; + } + + pcp_write(pcpConn->pcpConn, "G", 1); + wsize = htonl(sizeof(int)); + pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); + if (PCPFlush(pcpConn) < 0) + return NULL; + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"G\", len=%d\n", ntohl(wsize)); + + return process_pcp_response(pcpConn, 'G'); +} + +/* + * Process health check response from PCP server. + * pcpConn: connection to the server + * buf: returned data from server + * len: length of the data + */ +static void + process_health_check_stats_response + (PCPConnInfo * pcpConn, char *buf, int len) +{ + POOL_HEALTH_CHECK_STATS *stats; + int *offsets; + int n; + int i; + char *p; + int maxstr; + char c[] = "CommandComplete"; + + if (strcmp(buf, c) != 0) + { + pcp_internal_error(pcpConn, + "command failed. invalid response"); + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + return; + } + buf += sizeof(c); + + /* Allocate health stats memory */ + stats = palloc0(sizeof(POOL_HEALTH_CHECK_STATS)); + p = (char *) stats; + + /* Calculate total packet length */ + offsets = pool_health_check_stats_offsets(&n); + + for (i = 0; i < n; i++) + { + if (i == n - 1) + maxstr = sizeof(POOL_HEALTH_CHECK_STATS) - offsets[i]; + else + maxstr = offsets[i + 1] - offsets[i]; + + StrNCpy(p + offsets[i], buf, maxstr - 1); + buf += strlen(buf) + 1; + } + + if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) stats, sizeof(POOL_HEALTH_CHECK_STATS), NULL) < 0) + { + if (stats) + pfree(stats); + pcp_internal_error(pcpConn, + "command failed. invalid response"); + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + } + else + setCommandSuccessful(pcpConn); + +} + static void process_process_count_response(PCPConnInfo * pcpConn, char *buf, int len) { @@ -824,6 +1121,7 @@ process_process_count_response(PCPConnInfo * pcpConn, char *buf, int len) pcp_internal_error(pcpConn, "command failed. invalid response"); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + pfree(process_list); return; } index += 1; @@ -878,30 +1176,18 @@ pcp_process_count(PCPConnInfo * pcpConn) return process_pcp_response(pcpConn, 'N'); } -static void -free_processInfo(struct PCPConnInfo *pcpConn, void *ptr) -{ - ProcessInfo *pi = (ProcessInfo *) ptr; - - if (pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug, "free ProcessInfo structure \n"); - - if (pi == NULL) - { - if (pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug, "ProcessInfo structure is NULL nothing to free \n"); - return; - } - if (pi->connection_info) - pfree(pi->connection_info); - pfree(pi); -} - static void process_process_info_response(PCPConnInfo * pcpConn, char *buf, int len) { char *index; - ProcessInfo *processInfo = NULL; + int *offsets; + int i, + n; + int maxstr; + char *p; + POOL_REPORT_POOLS *pools = NULL; + + offsets = pool_report_pools_offsets(&n); if (strcmp(buf, "ArraySize") == 0) { @@ -923,76 +1209,22 @@ process_process_info_response(PCPConnInfo * pcpConn, char *buf, int len) if (PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) goto INVALID_RESPONSE; - processInfo = palloc0(sizeof(ProcessInfo)); - processInfo->connection_info = palloc0(sizeof(ConnectionInfo)); - - index = (char *) memchr(buf, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->pid = atoi(index); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - strlcpy(processInfo->connection_info->database, index, SM_DATABASE); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - strlcpy(processInfo->connection_info->user, index, SM_USER); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->start_time = atol(index); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->connection_info->create_time = atol(index); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->connection_info->major = atoi(index); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->connection_info->minor = atoi(index); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->connection_info->counter = atoi(index); + pools = palloc0(sizeof(POOL_REPORT_POOLS)); + p = (char *) pools; + buf += strlen(buf) + 1; - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->connection_info->backend_id = atoi(index); - - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->connection_info->pid = atoi(index); + for (i = 0; i < n; i++) + { + if (i == n - 1) + maxstr = sizeof(POOL_REPORT_POOLS) - offsets[i]; + else + maxstr = offsets[i + 1] - offsets[i]; - index = (char *) memchr(index, '\0', len); - if (index == NULL) - goto INVALID_RESPONSE; - index += 1; - processInfo->connection_info->connected = atoi(index); + StrNCpy(p + offsets[i], buf, maxstr - 1); + buf += strlen(buf) + 1; + } - if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) processInfo, sizeof(ProcessInfo), free_processInfo) < 0) + if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) pools, sizeof(POOL_REPORT_POOLS), NULL) < 0) goto INVALID_RESPONSE; return; @@ -1006,11 +1238,9 @@ process_process_info_response(PCPConnInfo * pcpConn, char *buf, int len) INVALID_RESPONSE: - if (processInfo) + if (pools) { - if (processInfo->connection_info) - pfree(processInfo->connection_info); - pfree(processInfo); + pfree(pools); } pcp_internal_error(pcpConn, "command failed. invalid response"); @@ -1271,36 +1501,38 @@ pcp_recovery_node(PCPConnInfo * pcpConn, int nid) } /* -------------------------------- - * pcp_promote_node - promote a node given by the argument as new pgpool's master + * pcp_promote_node - promote a node given by the argument as new pgpool's main node * * return 0 on success, -1 otherwise * -------------------------------- */ PCPResultInfo * -pcp_promote_node(PCPConnInfo * pcpConn, int nid) +pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool promote) { - return _pcp_promote_node(pcpConn, nid, FALSE); + return _pcp_promote_node(pcpConn, nid, FALSE, promote); } /* -------------------------------- - * and promote a node given by the argument as new pgpool's master + * and promote a node given by the argument as new pgpool's main node * * return 0 on success, -1 otherwise * -------------------------------- */ PCPResultInfo * -pcp_promote_node_gracefully(PCPConnInfo * pcpConn, int nid) +pcp_promote_node_gracefully(PCPConnInfo * pcpConn, int nid, bool switchover) { - return _pcp_promote_node(pcpConn, nid, TRUE); + return _pcp_promote_node(pcpConn, nid, TRUE, switchover); } static PCPResultInfo * -_pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully) +_pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully, bool switchover) { int wsize; char node_id[16]; char *sendchar; + char *switchover_option; /* n: just change node status, s: + * switchover primary */ if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { @@ -1308,17 +1540,31 @@ _pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully) return NULL; } - snprintf(node_id, sizeof(node_id), "%d", nid); + snprintf(node_id, sizeof(node_id), "%d ", nid); if (gracefully) sendchar = "j"; else sendchar = "J"; + if (switchover) + switchover_option = "s"; + else + switchover_option = "n"; + pcp_write(pcpConn->pcpConn, sendchar, 1); - wsize = htonl(strlen(node_id) + 1 + sizeof(int)); + + /* calculate send buffer size */ + wsize = sizeof(char); /* protocol. 'j' or 'J' */ + wsize += strlen(node_id); /* node id + space */ + wsize += sizeof(char); /* promote option */ + wsize += sizeof(int); /* buffer length */ + wsize = htonl(wsize); + pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1); + pcp_write(pcpConn->pcpConn, switchover_option, 1); + if (PCPFlush(pcpConn) < 0) return NULL; if (pcpConn->Pfdebug) @@ -1393,6 +1639,15 @@ process_watchdog_info_response(PCPConnInfo * pcpConn, char *buf, int len) json_value_free(root); goto INVALID_RESPONSE; } + if (json_get_int_value_for_key(root, "MemberRemoteNodeCount", &wd_cluster_info->memberRemoteNodeCount)) + { + wd_cluster_info->memberRemoteNodeCount = -1; + } + if (json_get_int_value_for_key(root, "NodesRequireForQuorum", &wd_cluster_info->nodesRequiredForQuorum)) + { + wd_cluster_info->nodesRequiredForQuorum = -1; + } + if (json_get_int_value_for_key(root, "QuorumStatus", &wd_cluster_info->quorumStatus)) { json_value_free(root); @@ -1410,21 +1665,21 @@ process_watchdog_info_response(PCPConnInfo * pcpConn, char *buf, int len) } wd_cluster_info->escalated = tempVal == 0 ? false : true; - ptr = json_get_string_value_for_key(root, "MasterNodeName"); + ptr = json_get_string_value_for_key(root, "LeaderNodeName"); if (ptr == NULL) { json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wd_cluster_info->masterNodeName, ptr, sizeof(wd_cluster_info->masterNodeName) - 1); + strncpy(wd_cluster_info->leaderNodeName, ptr, sizeof(wd_cluster_info->leaderNodeName) - 1); - ptr = json_get_string_value_for_key(root, "MasterHostName"); + ptr = json_get_string_value_for_key(root, "LeaderHostName"); if (ptr == NULL) { json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wd_cluster_info->masterHostName, ptr, sizeof(wd_cluster_info->masterHostName) - 1); + strncpy(wd_cluster_info->leaderHostName, ptr, sizeof(wd_cluster_info->leaderHostName) - 1); /* Get watchdog nodes data */ for (i = 0; i < nodeCount; i++) @@ -1469,6 +1724,22 @@ process_watchdog_info_response(PCPConnInfo * pcpConn, char *buf, int len) } strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) - 1); + if (json_get_int_value_for_key(nodeInfoValue, "Membership", &wdNodeInfo->membership_status)) + { + /* would be from the older version. No need to panic */ + wdNodeInfo->membership_status = 0; + } + + ptr = json_get_string_value_for_key(nodeInfoValue, "MembershipString"); + if (ptr == NULL) + { + strncpy(wdNodeInfo->membership_status_string, "NOT-Available", + sizeof(wdNodeInfo->membership_status_string) - 1); + } + else + strncpy(wdNodeInfo->membership_status_string, ptr, + sizeof(wdNodeInfo->membership_status_string) - 1); + if (json_get_int_value_for_key(nodeInfoValue, "WdPort", &wdNodeInfo->wd_port)) { json_value_free(root); @@ -1501,6 +1772,12 @@ process_watchdog_info_response(PCPConnInfo * pcpConn, char *buf, int len) goto INVALID_RESPONSE; } + if (json_get_bool_value_for_key(nodeInfoValue, "LifecheckStarted", &wdNodeInfo->lifecheck_started)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + } json_value_free(root); @@ -1861,17 +2138,15 @@ PasswordFromFile(PCPConnInfo * pcpConn, char *hostname, char *port, char *userna if (!S_ISREG(stat_buf.st_mode)) { - if (pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug, "WARNING: password file \"%s\" is not a plain file\n", pgpassfile); + fprintf(stderr, "WARNING: password file \"%s\" is not a plain file\n", pgpassfile); return NULL; } /* If password file is insecure, alert the user and ignore it. */ if (stat_buf.st_mode & (S_IRWXG | S_IRWXO)) { - if (pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug, "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n", - pgpassfile); + fprintf(stderr, "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n", + pgpassfile); return NULL; } diff --git a/src/main/health_check.c b/src/main/health_check.c index ecf9b348b..0c72c0a72 100644 --- a/src/main/health_check.c +++ b/src/main/health_check.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2017 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -44,28 +44,38 @@ #include #include #include +#include +#include #ifdef HAVE_CRYPT_H #include #endif #include "pool.h" +#include "main/health_check.h" +#include "main/pool_internal_comms.h" #include "utils/palloc.h" #include "utils/memutils.h" #include "utils/elog.h" +#include "utils/pool_ip.h" +#include "utils/ps_status.h" +#include "utils/pool_stream.h" #include "context/pool_process_context.h" #include "context/pool_session_context.h" +#include "protocol/pool_pg_utils.h" #include "pool_config.h" -#include "utils/pool_ip.h" #include "auth/md5.h" #include "auth/pool_hba.h" -#include "utils/pool_stream.h" -char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ -static POOL_CONNECTION_POOL_SLOT * slot; +volatile POOL_HEALTH_CHECK_STATISTICS *health_check_stats; /* health check stats + * area in shared memory */ + +static POOL_CONNECTION_POOL_SLOT *slot; static volatile sig_atomic_t reload_config_request = 0; static volatile sig_atomic_t restart_request = 0; +volatile POOL_HEALTH_CHECK_STATISTICS *stats; + static bool establish_persistent_connection(int node); static void discard_persistent_connection(int node); static RETSIGTYPE my_signal_handler(int sig); @@ -73,15 +83,7 @@ static RETSIGTYPE reload_config_handler(int sig); static void reload_config(void); static RETSIGTYPE health_check_timer_handler(int sig); -#ifdef HEALTHCHECK_OPTS -#if HEALTHCHECK_OPTS > 0 -#define HEALTHCHECK_DEBUG -#endif -#endif - -#ifdef HEALTHCHECK_DEBUG -static bool check_backend_down_request(int node); -#endif +static bool check_backend_down_request(int node, bool done_requests); #undef CHECK_REQUEST #define CHECK_REQUEST \ @@ -107,18 +109,30 @@ static bool check_backend_down_request(int node); * health check child main loop */ void -do_health_check_child(int *node_id) +do_health_check_child(void *params) { sigjmp_buf local_sigjmp_buf; MemoryContext HealthCheckMemoryContext; char psbuffer[NI_MAXHOST]; + static struct timeval start_time; + static struct timeval end_time; + long diff_t; + int node_id; + + POOL_HEALTH_CHECK_STATISTICS mystat; + + node_id = *((int *) params); + stats = &health_check_stats[node_id]; + + /* Set application name */ + set_application_name_with_suffix(PT_HEALTH_CHECK, node_id); ereport(DEBUG1, - (errmsg("I am health check process pid:%d DB node id:%d", getpid(), *node_id))); + (errmsg("I am health check process pid:%d DB node id:%d", getpid(), node_id))); /* Identify myself via ps */ init_ps_display("", "", "", ""); - snprintf(psbuffer, sizeof(psbuffer), "health check process(%d)", *node_id); + snprintf(psbuffer, sizeof(psbuffer), "health check process(%d)", node_id); set_ps_display(psbuffer, false); /* set up signal handlers */ @@ -141,12 +155,17 @@ do_health_check_child(int *node_id) MemoryContextSwitchTo(TopMemoryContext); - /* Initialize my backend status */ - pool_initialize_private_backend_status(); - /* Initialize per process context */ pool_init_process_context(); + /* + * Open pool_passwd. + */ + if (strcmp("", pool_config->pool_passwd)) + { + pool_reopen_passwd_file(); + } + if (sigsetjmp(local_sigjmp_buf, 1) != 0) { pool_signal(SIGALRM, SIG_IGN); @@ -158,16 +177,27 @@ do_health_check_child(int *node_id) /* We can now handle ereport(ERROR) */ PG_exception_stack = &local_sigjmp_buf; + /* Initialize health check stats area */ + stats->min_health_check_duration = INT_MAX; for (;;) { MemoryContextSwitchTo(HealthCheckMemoryContext); MemoryContextResetAndDeleteChildren(HealthCheckMemoryContext); + /* + * Since HealthCheckMemoryContext is used for "slot", we need to clear + * it so that new slot is allocated later on. + */ + slot = NULL; + + bool skipped = false; + CHECK_REQUEST; - if (pool_config->health_check_params[*node_id].health_check_period <= 0) + if (pool_config->health_check_params[node_id].health_check_period <= 0) { + stats->min_health_check_duration = 0; sleep(30); } @@ -175,40 +205,106 @@ do_health_check_child(int *node_id) * If health checking is enabled and the node is not in down status, * do health check. */ - else if (pool_config->health_check_params[*node_id].health_check_period > 0) + else if (pool_config->health_check_params[node_id].health_check_period > 0) { bool result; + BackendInfo *bkinfo = pool_get_node_info(node_id); + + stats->total_count++; + gettimeofday(&start_time, NULL); - result = establish_persistent_connection(*node_id); + stats->last_health_check = time(NULL); + + result = establish_persistent_connection(node_id); -#ifdef HEALTHCHECK_DEBUG - if (check_backend_down_request(*node_id) || (result && slot == NULL)) -#else if (result && slot == NULL) -#endif { - if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(*node_id).flag)) + stats->last_failed_health_check = time(NULL); + + if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(node_id).flag)) { ereport(LOG, (errmsg("health check failed on node %d but failover is disallowed for the node", - *node_id))); + node_id))); } else { bool partial; - ereport(LOG, (errmsg("health check failed on node %d (timeout:%d)", - *node_id, health_check_timer_expired))); + stats->fail_count++; - /* trigger failover */ - partial = health_check_timer_expired ? false : true; - degenerate_backend_set(node_id, 1, partial ? REQ_DETAIL_SWITCHOVER : 0); + ereport(LOG, (errmsg("health check failed on node %d (timeout:%d)", + node_id, health_check_timer_expired))); + + if (bkinfo->backend_status == CON_DOWN && bkinfo->quarantine == true) + { + ereport(LOG, (errmsg("health check failed on quarantine node %d (timeout:%d)", + node_id, health_check_timer_expired), + errdetail("ignoring.."))); + } + else + { + /* trigger failover */ + partial = health_check_timer_expired ? false : true; + degenerate_backend_set(&node_id, 1, partial ? REQ_DETAIL_SWITCHOVER : 0); + } } } + else if (slot && bkinfo->backend_status == CON_DOWN && bkinfo->quarantine == true) + { + stats->success_count++; + stats->last_successful_health_check = time(NULL); + + /* + * The node has become reachable again. Reset the quarantine + * state + */ + send_failback_request(node_id, false, REQ_DETAIL_UPDATE | REQ_DETAIL_WATCHDOG); + } + else if (result && slot) + { + /* Health check succeeded */ + stats->success_count++; + stats->last_successful_health_check = time(NULL); + } + else if (!result) + { + /* Health check skipped */ + stats->skip_count++; + stats->last_skip_health_check = time(NULL); + skipped = true; + } /* Discard persistent connections */ - discard_persistent_connection(*node_id); - sleep(pool_config->health_check_params[*node_id].health_check_period); + discard_persistent_connection(node_id); + + /* + * Update health check duration only if health check was not + * skipped since the duration could be very small (probably 0) if + * health check is skipped. + */ + + if (!skipped) + { + gettimeofday(&end_time, NULL); + + if (end_time.tv_sec > start_time.tv_sec) + diff_t = end_time.tv_usec - start_time.tv_usec + 1000000 * (end_time.tv_sec - start_time.tv_sec); + else + diff_t = end_time.tv_usec - start_time.tv_usec; + + diff_t /= 1000; + stats->total_health_check_duration += diff_t; + + if (diff_t > stats->max_health_check_duration) + stats->max_health_check_duration = diff_t; + if (diff_t < stats->min_health_check_duration) + stats->min_health_check_duration = diff_t; + } + + memcpy(&mystat, (void *) stats, sizeof(mystat)); + + sleep(pool_config->health_check_params[node_id].health_check_period); } } exit(0); @@ -223,32 +319,55 @@ establish_persistent_connection(int node) { BackendInfo *bkinfo; int retry_cnt; + static time_t auto_failback_interval = 0; /* resume time of + * auto_failback */ + bool check_failback = false; + time_t now; + char *dbname; bkinfo = pool_get_node_info(node); /* - * If the node is already in down status or unused, do nothing. + * If the node is already in down status or unused, do nothing. except + * when the node state is down because of quarantine operation since we + * want to detect when the node comes back to life again to remove it from + * the quarantine state */ if (bkinfo->backend_status == CON_UNUSED || - bkinfo->backend_status == CON_DOWN) - return false; + (bkinfo->backend_status == CON_DOWN && bkinfo->quarantine == false)) + { + /* get current time to use auto_failback_interval */ + now = time(NULL); + + if (pool_config->auto_failback && auto_failback_interval < now && + STREAM && !strcmp(bkinfo->replication_state, "streaming") && !Req_info->switching) + { + ereport(DEBUG1, + (errmsg("health check DB node: %d (status:%d) for auto_failback", node, bkinfo->backend_status))); + check_failback = true; + } + else + return false; + } /* * If database is not specified, "postgres" database is assumed. */ if (*pool_config->health_check_params[node].health_check_database == '\0') - pool_config->health_check_params[node].health_check_database = "postgres"; + dbname = "postgres"; + else + dbname = pool_config->health_check_params[node].health_check_database; /* * Try to connect to the database. */ if (slot == NULL) { - retry_cnt = pool_config->health_check_params[node].health_check_max_retries; - char *password = get_pgpool_config_user_password(pool_config->health_check_params[node].health_check_user, pool_config->health_check_params[node].health_check_password); + retry_cnt = pool_config->health_check_params[node].health_check_max_retries; + do { /* @@ -266,7 +385,7 @@ establish_persistent_connection(int node) slot = make_persistent_db_connection_noerror(node, bkinfo->backend_hostname, bkinfo->backend_port, - pool_config->health_check_params[node].health_check_database, + dbname, pool_config->health_check_params[node].health_check_user, password ? password : "", false); @@ -277,6 +396,19 @@ establish_persistent_connection(int node) CLEAR_ALARM; } + /* + * If health check test is enabled, check if fake down request is + * set. If set, discard_persistent_connection will set slot to + * NULL. This simulates a connection failure. + */ + if (pool_config->health_check_test) + { + if (slot && check_backend_down_request(node, false) == true) + { + discard_persistent_connection(node); + } + } + if (slot) { if (retry_cnt != pool_config->health_check_params[node].health_check_max_retries) @@ -292,6 +424,8 @@ establish_persistent_connection(int node) if (retry_cnt >= 0) { + stats->retry_count++; + ereport(LOG, (errmsg("health check retrying on DB node: %d (round:%d)", node, @@ -301,8 +435,38 @@ establish_persistent_connection(int node) } } while (retry_cnt >= 0); + /* Check if we need to refresh max retry count */ + + if (retry_cnt != pool_config->health_check_params[node].health_check_max_retries) + { + int ret_cnt; + + retry_cnt++; + ret_cnt = pool_config->health_check_params[node].health_check_max_retries - retry_cnt; + + if (ret_cnt > stats->max_retry_count) + stats->max_retry_count = ret_cnt; + } + if (password) pfree(password); + + if (check_failback && !Req_info->switching && slot) + { + ereport(LOG, + (errmsg("request auto failback, node id:%d", node))); + /* get current time to use auto_failback_interval */ + now = time(NULL); + auto_failback_interval = now + pool_config->auto_failback_interval; + + send_failback_request(node, true, REQ_DETAIL_CONFIRMED); + } + } + + /* if check_failback is true, backend_status is DOWN or UNUSED. */ + if (check_failback) + { + return false; } return true; } @@ -370,6 +534,10 @@ reload_config(void) MemoryContextSwitchTo(oldContext); if (pool_config->enable_pool_hba) load_hba(get_hba_file_name()); + + if (strcmp("", pool_config->pool_passwd)) + pool_reopen_passwd_file(); + reload_config_request = 0; } @@ -386,7 +554,35 @@ static RETSIGTYPE health_check_timer_handler(int sig) errno = save_errno; } -#ifdef HEALTHCHECK_DEBUG +/* + * Returns the byte size of health check statistics area + */ +size_t +health_check_stats_shared_memory_size(void) +{ + size_t size; + + size = MAXALIGN(sizeof(POOL_HEALTH_CHECK_STATISTICS) * MAX_NUM_BACKENDS); + elog(DEBUG1, "health_check_stats_shared_memory_size: requested size: %lu", size); + return size; +} + +/* + * Initialize health check statistics area + */ +void +health_check_stats_init(POOL_HEALTH_CHECK_STATISTICS *addr) +{ + int i; + + health_check_stats = addr; + memset((void *) health_check_stats, 0, health_check_stats_shared_memory_size()); + + for (i = 0; i < MAX_NUM_BACKENDS; i++) + { + health_check_stats[i].min_health_check_duration = INT_MAX; + } +} /* * Node down request file. In the file, each line consists of "backend node @@ -399,11 +595,14 @@ static RETSIGTYPE health_check_timer_handler(int sig) /* * Check backend down request file with specified backend node id. If it's * down ("down"), returns true and set the status to "already_down" to - * prevent repeatable * failover. If it's other than "down", returns false. -*/ + * prevent repeating failover. If it's other than "down", returns false. + * + * When done_requests is true (second arg to function) the function returns + * true if the node has already_done status in the file. + */ static bool -check_backend_down_request(int node) +check_backend_down_request(int node, bool done_requests) { static char backend_down_request_file[POOLMAXPATHLEN]; FILE *fd; @@ -421,7 +620,7 @@ check_backend_down_request(int node) if (backend_down_request_file[0] == '\0') { snprintf(backend_down_request_file, sizeof(backend_down_request_file), - "%s/%s", pool_config->logdir, BACKEND_DOWN_REQUEST_FILE); + "%s/%s", pool_config->work_dir, BACKEND_DOWN_REQUEST_FILE); } fd = fopen(backend_down_request_file, "r"); @@ -430,7 +629,7 @@ check_backend_down_request(int node) ereport(WARNING, (errmsg("check_backend_down_request: failed to open file %s", backend_down_request_file), - errdetail("\"%s\"", strerror(errno)))); + errdetail("%m"))); return false; } @@ -442,14 +641,23 @@ check_backend_down_request(int node) if (fgets(readbuf, MAXLINE - 1, fd) == 0) break; - strncpy(buf, readbuf, sizeof(buf)); + strncpy(buf, readbuf, sizeof(buf) - 1); if (strlen(readbuf) > 0 && readbuf[strlen(readbuf) - 1] == '\n') buf[strlen(readbuf) - 1] = '\0'; + sscanf(buf, "%d\t%s", &node_id, status); + if (done_requests) + { + if (node_id == node && !strcmp(status, "already_down")) + { + fclose(fd); + return true; + } + continue; + } p = readbuf; if (found == false) { - sscanf(buf, "%d\t%s", &node_id, status); if (node_id == node && !strcmp(status, "down")) { snprintf(linebuf, sizeof(linebuf), "%d\t%s\n", node_id, "already_down"); @@ -475,30 +683,11 @@ check_backend_down_request(int node) fclose(fd); - if (!found) - return false; - - fd = fopen(backend_down_request_file, "w"); - if (!fd) - { - ereport(WARNING, - (errmsg("check_backend_down_request: failed to open file for writing %s", - backend_down_request_file), - errdetail("\"%s\"", strerror(errno)))); - return false; - } + if (writebuf) + free(writebuf); - if (fwrite(writebuf, 1, strlen(writebuf), fd) != strlen(writebuf)) - { - ereport(WARNING, - (errmsg("check_backend_down_request: failed to write %s", - backend_down_request_file), - errdetail("\"%s\"", strerror(errno)))); - fclose(fd); + if (!found) return false; - } - fclose(fd); return true; } -#endif diff --git a/src/main/main.c b/src/main/main.c index eec3c3e48..52a2b81ea 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2022 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -20,6 +20,9 @@ */ #include "pool.h" #include "pool_config.h" +#include "version.h" +#include "pool_config_variables.h" + #include #include #include @@ -35,17 +38,20 @@ #include #include #include + #include "utils/elog.h" #include "utils/palloc.h" #include "utils/memutils.h" #include "utils/pool_path.h" +#include "utils/pool_signal.h" +#include "utils/pool_ipc.h" +#include "utils/ps_status.h" +#include "utils/pool_ssl.h" -#include "version.h" #include "auth/pool_passwd.h" #include "auth/pool_hba.h" #include "query_cache/pool_memqcache.h" #include "watchdog/wd_utils.h" -#include "pool_config_variables.h" static bool get_pool_key_filename(char *poolKeyFile); @@ -71,6 +77,7 @@ int myargc; char **myargv; int assert_enabled = 0; char *pool_key = NULL; + int main(int argc, char **argv) { @@ -216,6 +223,8 @@ main(int argc, char **argv) hba_file = make_absolute_path(hba_file_path, base_dir); mypid = getpid(); + SetProcessGlobalVariables(PT_MAIN); + pool_init_config(); @@ -250,7 +259,8 @@ main(int argc, char **argv) { ereport(FATAL, (return_code(1), - errmsg("could not reload configuration file pid: %d. reason: %s", pid, strerror(errno)))); + errmsg("could not reload configuration file pid: %d", pid), + errdetail("%m"))); } exit(0); } @@ -278,12 +288,11 @@ main(int argc, char **argv) { if (kill(pid, 0) == 0) { - ereport(FATAL, - (errmsg("pid file found. is another pgpool(%d) is running?\n", pid))); + fprintf(stderr, "ERROR: pid file found. is another pgpool(%d) is running?\n", pid); + exit(EXIT_FAILURE); } else - ereport(NOTICE, - (errmsg("pid file found but it seems bogus. Trying to start pgpool anyway...\n"))); + fprintf(stderr, "NOTICE: pid file found but it seems bogus. Trying to start pgpool anyway...\n"); } } @@ -337,16 +346,23 @@ main(int argc, char **argv) char dirnamebuf[POOLMAXPATHLEN + 1]; char *dirp; - strlcpy(dirnamebuf, conf_file, sizeof(dirnamebuf)); - dirp = dirname(dirnamebuf); - snprintf(pool_passwd, sizeof(pool_passwd), "%s/%s", - dirp, pool_config->pool_passwd); + if (pool_config->pool_passwd[0] != '/') + { + strlcpy(dirnamebuf, conf_file, sizeof(dirnamebuf)); + dirp = dirname(dirnamebuf); + snprintf(pool_passwd, sizeof(pool_passwd), "%s/%s", + dirp, pool_config->pool_passwd); + } + else + strlcpy(pool_passwd, pool_config->pool_passwd, + sizeof(pool_passwd)); + pool_init_pool_passwd(pool_passwd, POOL_PASSWD_R); } pool_semaphore_create(MAX_NUM_SEMAPHORES); - PgpoolMain(discard_status, clear_memcache_oidmaps); /* this is an infinate + PgpoolMain(discard_status, clear_memcache_oidmaps); /* this is an infinite * loop */ exit(0); @@ -449,7 +465,7 @@ daemonize(void) { ereport(FATAL, (errmsg("could not daemonize the pgpool-II"), - errdetail("fork() system call failed with reason: \"%s\"", strerror(errno)))); + errdetail("fork() system call failed with reason: \"%m\""))); } else if (pid > 0) { /* parent */ @@ -461,23 +477,25 @@ daemonize(void) { ereport(FATAL, (errmsg("could not daemonize the pgpool-II"), - errdetail("setsid() system call failed with reason: \"%s\"", strerror(errno)))); + errdetail("setsid() system call failed with reason: \"%m\""))); } #endif mypid = getpid(); + SetProcessGlobalVariables(PT_MAIN); write_pid_file(); if (chdir("/")) ereport(WARNING, (errmsg("change directory failed"), - errdetail("chdir() system call failed with reason: \"%s\"", strerror(errno)))); + errdetail("chdir() system call failed with reason: \"%m\""))); /* redirect stdin, stdout and stderr to /dev/null */ i = open("/dev/null", O_RDWR); if (i < 0) { ereport(WARNING, - (errmsg("failed to open \"/dev/null\", open() failed with error \"%s\"", strerror(errno)))); + (errmsg("failed to open \"/dev/null\""), + errdetail("%m"))); } else { @@ -514,19 +532,34 @@ stop_me(void) (errmsg("could not read pid file"))); } - if (kill(pid, stop_sig) == -1) + for (;;) { - ereport(FATAL, - (errmsg("could not stop process with pid: %d", pid), - errdetail("\"%s\"", strerror(errno)))); - } - ereport(LOG, - (errmsg("stop request sent to pgpool. waiting for termination..."))); + int cnt = 5; /* sending signal retry interval */ - while (kill(pid, 0) == 0) - { - fprintf(stderr, "."); - sleep(1); + if (kill(pid, stop_sig) == -1) + { + ereport(FATAL, + (errmsg("could not stop process with pid: %d", pid), + errdetail("%m"))); + } + ereport(LOG, + (errmsg("stop request sent to pgpool (pid: %d). waiting for termination...", pid))); + + while (kill(pid, 0) == 0) + { + fprintf(stderr, "."); + sleep(1); + cnt--; + + /* + * If pgpool did not stop within 5 seconds, break the loop and try + * to send the signal again + */ + if (cnt <= 0) + break; + } + if (cnt > 0) + break; } fprintf(stderr, "done.\n"); pid_file = get_pid_file_path(); @@ -556,8 +589,9 @@ get_pid_file_path(void) if (conf_dir == NULL) { ereport(LOG, - (errmsg("failed to get the dirname of pid file:\"%s\". reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("failed to get the dirname of pid file:\"%s\"", + pool_config->pid_file_name), + errdetail("%m"))); return NULL; } path_size = strlen(conf_dir) + strlen(pool_config->pid_file_name) + 1 + 1; @@ -607,16 +641,18 @@ read_pid_file(void) close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("could not read pid file as \"%s\". reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not read pid file \"%s\"", + pool_config->pid_file_name), + errdetail("%m"))); } else if (readlen == 0) { close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("EOF detected while reading pid file \"%s\". reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("EOF detected while reading pid file \"%s\"", + pool_config->pid_file_name), + errdetail("%m"))); } pfree(pid_file); close(fd); @@ -641,12 +677,13 @@ write_pid_file(void) pool_config->pid_file_name))); } - fd = open(pid_file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); + fd = open(pid_file, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); if (fd == -1) { ereport(FATAL, - (errmsg("could not open pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not open pid file \"%s\"", + pool_config->pid_file_name), + errdetail("%m"))); } snprintf(pidbuf, sizeof(pidbuf), "%d", (int) getpid()); if (write(fd, pidbuf, strlen(pidbuf) + 1) == -1) @@ -654,23 +691,26 @@ write_pid_file(void) close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("could not write pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not write pid file \"%s\"", + pool_config->pid_file_name), + errdetail("%m"))); } if (fsync(fd) == -1) { close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("could not fsync pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not fsync pid file \"%s\"", + pool_config->pid_file_name), + errdetail("%m"))); } if (close(fd) == -1) { pfree(pid_file); ereport(FATAL, - (errmsg("could not close pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not close pid file \"%s\"", + pool_config->pid_file_name), + errdetail("%m"))); } /* register the call back to delete the pid file at system exit */ on_proc_exit(FileUnlink, (Datum) pid_file); @@ -711,5 +751,5 @@ FileUnlink(int code, Datum path) */ ereport(LOG, (errmsg("unlink failed for file at path \"%s\"", filePath), - errdetail("\"%s\"", strerror(errno)))); + errdetail("%m"))); } diff --git a/src/main/pgpool_logger.c b/src/main/pgpool_logger.c new file mode 100644 index 000000000..d57a0d000 --- /dev/null +++ b/src/main/pgpool_logger.c @@ -0,0 +1,1176 @@ +/* -*-pgpool_logger-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2023 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + */ +/*------------------------------------------------------------------------- + * + * From: PostgreSQL + * src/backend/postmaster/syslogger.c + * Copyright (c) 2004-2020, PostgreSQL Global Development Group + *------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pool.h" +#include "pool_config.h" +#include "utils/palloc.h" +#include "utils/memutils.h" +#include "utils/elog.h" +#include "parser/pg_list.h" +#include "parser/stringinfo.h" +#include "utils/ps_status.h" +#include "utils/timestamp.h" +#include "utils/pool_signal.h" +#include "main/pgpool_logger.h" + +#define DEVNULL "/dev/null" +typedef time_t pg_time_t; + +/* + * We read() into a temp buffer twice as big as a chunk, so that any fragment + * left after processing can be moved down to the front and we'll still have + * room to read a full chunk. + */ +#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 + * start, but the rest can change at SIGHUP. + */ + + +bool redirection_done = false; + +/* + * Private state + */ +static pg_time_t next_rotation_time; +static bool pipe_eof_seen = false; +static bool rotation_disabled = false; +static FILE *syslogFile = NULL; +static FILE *csvlogFile = NULL; +static pg_time_t first_syslogger_file_time = 0; +static char *last_file_name = NULL; +static char *last_csv_file_name = NULL; + +/* + * Buffers for saving partial messages from different backends. + * + * Keep NBUFFER_LISTS lists of these, with the entry for a given source pid + * being in the list numbered (pid % NBUFFER_LISTS), so as to cut down on + * the number of entries we have to examine for any one incoming message. + * There must never be more than one entry for the same source pid. + * + * An inactive buffer is not removed from its list, just held for re-use. + * An inactive buffer has pid == 0 and undefined contents of data. + */ +typedef struct +{ + int32 pid; /* PID of source process */ + StringInfoData data; /* accumulated data, as a StringInfo */ +} save_buffer; + +#define NBUFFER_LISTS 256 +static List *buffer_lists[NBUFFER_LISTS]; + +int syslogPipe[2] = {-1, -1}; + + +/* + * 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 rotation_requested = false; + + +pg_noreturn static void SysLoggerMain(int argc, char *argv[]); +static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer); +static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer); +static FILE *logfile_open(const char *filename, const char *mode, + bool allow_errors); + +static void logfile_rotate(bool time_based_rotation, int size_rotation_for); +static char *logfile_getname(pg_time_t timestamp, const char *suffix); +static void set_next_rotation_time(void); +static void sigHupHandler(int sig); +static void sigUsr1Handler(int sig); + + +/* + * Main entry point for syslogger process + * argc/argv parameters are valid only in EXEC_BACKEND case. + */ +static void +SysLoggerMain(int argc, char *argv[]) +{ + char logbuffer[READ_BUF_SIZE]; + int bytes_in_logbuffer = 0; + char *currentLogDir; + char *currentLogFilename; + int currentLogRotationAge; + pg_time_t now; + + now = time(NULL); + + + init_ps_display("", "", "", ""); + set_ps_display("PgpoolLogger", false); + + /* + * If we restarted, our stderr is already redirected into our own input + * pipe. This is of course pretty useless, not to mention that it + * interferes with detecting pipe EOF. Point stderr to /dev/null. This + * assumes that all interesting messages generated in the syslogger will + * come through elog.c and will be sent to write_syslogger_file. + */ + if (redirection_done) + { + int fd = open(DEVNULL, O_WRONLY, 0); + + /* + * The closes might look redundant, but they are not: we want to be + * darn sure the pipe gets closed even if the open failed. We can + * survive running with stderr pointing nowhere, but we can't afford + * to have extra pipe input descriptors hanging around. + * + * As we're just trying to reset these to go to DEVNULL, there's not + * much point in checking for failure from the close/dup2 calls here, + * if they fail then presumably the file descriptors are closed and + * any writes will go into the bitbucket anyway. + */ + close(fileno(stdout)); + close(fileno(stderr)); + if (fd != -1) + { + (void) dup2(fd, fileno(stdout)); + (void) dup2(fd, fileno(stderr)); + close(fd); + } + } + + + /* + * Also close our copy of the write end of the pipe. This is needed to + * ensure we can detect pipe EOF correctly. (But note that in the restart + * case, the postmaster already did this.) + */ + if (syslogPipe[1] >= 0) + close(syslogPipe[1]); + syslogPipe[1] = -1; + + /* + * Properly accept or ignore signals the postmaster might send us + * + * Note: we ignore all termination signals, and instead exit only when all + * upstream processes are gone, to ensure we don't miss any dying gasps of + * broken backends... + */ + + pool_signal(SIGHUP, sigHupHandler); + + pool_signal(SIGINT, SIG_IGN); + pool_signal(SIGTERM, SIG_IGN); + pool_signal(SIGQUIT, SIG_IGN); + pool_signal(SIGALRM, SIG_IGN); + pool_signal(SIGPIPE, SIG_IGN); + pool_signal(SIGUSR1, sigUsr1Handler); /* request log rotation */ + pool_signal(SIGUSR2, SIG_IGN); + + /* + * Reset some signals that are accepted by postmaster but not here + */ + pool_signal(SIGCHLD, SIG_DFL); + + POOL_SETMASK(&UnBlockSig); + + + /* + * 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(pool_config->log_directory); + currentLogFilename = pstrdup(pool_config->log_filename); + currentLogRotationAge = pool_config->log_rotation_age; + /* set next planned rotation time */ + set_next_rotation_time(); + + /* + * 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). + */ + + /* main worker loop */ + for (;;) + { + bool time_based_rotation = false; + int size_rotation_for = 0; + struct timeval timeout; + fd_set rfds; + int rc; + + /* + * Process any requests or signals received recently. + */ + if (got_SIGHUP) + { + got_SIGHUP = false; + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + + pool_get_config(get_config_file_name(), CFGCXT_RELOAD); + MemoryContextSwitchTo(oldContext); + + /* + * Check if the log directory or filename pattern changed in + * pgpool.conf. If so, force rotation to make sure we're writing + * the logfiles in the right place. + */ + if (strcmp(pool_config->log_directory, currentLogDir) != 0) + { + pfree(currentLogDir); + currentLogDir = pstrdup(pool_config->log_directory); + rotation_requested = true; + + /* + * Also, create new directory if not present; ignore errors + */ + if (mkdir(pool_config->log_directory, S_IREAD | S_IWRITE | S_IEXEC) == -1) + { + ereport(LOG, + (errmsg("pgpool logger, failed to create directory:\"%s\". error:\"%m\"", pool_config->log_directory))); + } + } + if (strcmp(pool_config->log_filename, currentLogFilename) != 0) + { + pfree(currentLogFilename); + currentLogFilename = pstrdup(pool_config->log_filename); + 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 (((pool_config->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. + */ + if (currentLogRotationAge != pool_config->log_rotation_age) + { + currentLogRotationAge = pool_config->log_rotation_age; + set_next_rotation_time(); + } + + /* + * If we had a rotation-disabling failure, re-enable rotation + * attempts after SIGHUP, and force one immediately. + */ + if (rotation_disabled) + { + rotation_disabled = false; + rotation_requested = true; + } + + } + + if (pool_config->log_rotation_age > 0 && !rotation_disabled) + { + /* Do a logfile rotation if it's time */ + now = (pg_time_t) time(NULL); + if (now >= next_rotation_time) + rotation_requested = time_based_rotation = true; + } + + if (!rotation_requested && pool_config->log_rotation_size > 0 && !rotation_disabled) + { + /* Do a rotation if file is too big */ + if (ftell(syslogFile) >= pool_config->log_rotation_size * 1024L) + { + rotation_requested = true; + size_rotation_for |= LOG_DESTINATION_STDERR; + } + if (csvlogFile != NULL && + ftell(csvlogFile) >= pool_config->log_rotation_size * 1024L) + { + rotation_requested = true; + size_rotation_for |= LOG_DESTINATION_CSVLOG; + } + } + + if (rotation_requested) + { + /* + * Force rotation when both values are zero. It means the request + * was sent by pcp_log_rotate. + */ + if (!time_based_rotation && size_rotation_for == 0) + size_rotation_for = LOG_DESTINATION_STDERR | LOG_DESTINATION_CSVLOG; + logfile_rotate(time_based_rotation, size_rotation_for); + } + + /* + * Calculate time till next time-based rotation, so that we don't + * sleep longer than that. We assume the value of "now" obtained + * above is still close enough. Note we can't make this calculation + * until after calling logfile_rotate(), since it will advance + * next_rotation_time. + * + * Also note that we need to beware of overflow in calculation of the + * timeout: with large settings of pool_config->log_rotation_age, + * next_rotation_time could be more than INT_MAX msec in the future. + * In that case we'll wait no more than INT_MAX msec, and try again. + */ + timeout.tv_sec = 0; + /* Reset usec everytime before calling sellect */ + timeout.tv_usec = 0; + + if (pool_config->log_rotation_age > 0 && !rotation_disabled) + { + pg_time_t delay; + + delay = next_rotation_time - now; + if (delay > 0) + { + if (delay > INT_MAX / 1000) + delay = INT_MAX / 1000; + timeout.tv_sec = delay; + } + } + + /* + * Sleep until there's something to do + */ + + FD_ZERO(&rfds); + FD_SET(syslogPipe[0], &rfds); + rc = select(syslogPipe[0] + 1, &rfds, NULL, NULL, timeout.tv_sec ? &timeout : NULL); + if (rc == 1) + { + int bytesRead; + + bytesRead = read(syslogPipe[0], + logbuffer + bytes_in_logbuffer, + sizeof(logbuffer) - bytes_in_logbuffer); + if (bytesRead < 0) + { + if (errno != EINTR) + ereport(LOG, + (errmsg("could not read from logger pipe: %m"))); + } + else if (bytesRead > 0) + { + bytes_in_logbuffer += bytesRead; + process_pipe_input(logbuffer, &bytes_in_logbuffer); + continue; + } + else + { + /* + * Zero bytes read when select() is saying read-ready means + * EOF on the pipe: that is, there are no longer any processes + * with the pipe write end open. Therefore, the postmaster + * and all backends are shut down, and we are done. + */ + pipe_eof_seen = true; + + /* if there's any data left then force it out now */ + flush_pipe_input(logbuffer, &bytes_in_logbuffer); + } + } + + if (pipe_eof_seen) + { + /* + * seeing this message on the real stderr is annoying - so we make + * it DEBUG1 to suppress in normal use. + */ + ereport(DEBUG1, + (errmsg("logger shutting down"))); + + /* + * Normal exit from the syslogger is here. Note that we + * deliberately do not close syslogFile before exiting; this is to + * allow for the possibility of elog messages being generated + * inside proc_exit. Regular exit() will take care of flushing + * and closing stdio channels. + */ + proc_exit(0); + } + } +} + +/* + * Postmaster subroutine to start a syslogger subprocess. + */ +int +SysLogger_Start(void) +{ + pid_t sysloggerPid; + char *filename; + + if (!pool_config->logging_collector) + return 0; + + /* + * If first time through, create the pipe which will receive stderr + * output. + * + * If the syslogger crashes and needs to be restarted, we continue to use + * the same pipe (indeed must do so, since extant backends will be writing + * into that pipe). + * + * This means the postmaster must continue to hold the read end of the + * pipe open, so we can pass it down to the reincarnated syslogger. This + * is a bit klugy but we have little choice. + * + * Also note that we don't bother counting the pipe FDs by calling + * Reserve/ReleaseExternalFD. There's no real need to account for them + * accurately in the postmaster or syslogger process, and both ends of the + * pipe will wind up closed in all other postmaster children. + */ + if (syslogPipe[0] < 0) + { + if (pipe(syslogPipe) < 0) + ereport(FATAL, + (errmsg("could not create pipe for syslog: %m"))); + } + + /* + * Create log directory if not present; ignore errors + */ + mkdir(pool_config->log_directory, S_IREAD | S_IWRITE | S_IEXEC); + + + /* + * The initial logfile is created right in the postmaster, to verify that + * the pool_config->log_directory is writable. We save the reference time + * so that the syslogger child process can recompute this file name. + * + * It might look a bit strange to re-do this during a syslogger restart, + * but we must do so since the postmaster closed syslogFile after the + * previous fork (and remembering that old file wouldn't be right anyway). + * Note we always append here, we won't overwrite any existing file. This + * is consistent with the normal rules, because by definition this is not + * 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 (pool_config->log_destination & LOG_DESTINATION_CSVLOG) + { + filename = logfile_getname(first_syslogger_file_time, ".csv"); + + csvlogFile = logfile_open(filename, "a", false); + + pfree(filename); + } + + switch ((sysloggerPid = fork())) + { + case -1: + ereport(LOG, + (errmsg("could not fork system logger: %m"))); + return 0; + + case 0: + on_exit_reset(); + SetProcessGlobalVariables(PT_LOGGER); + /* do the work */ + SysLoggerMain(0, NULL); + break; + + default: + /* success, in postmaster */ + + /* now we redirect stderr, if not done already */ + if (!redirection_done) + { + + /* + * Leave a breadcrumb trail when redirecting, in case the user + * forgets that redirection is active and looks only at the + * original stderr target file. + */ + ereport(LOG, + (errmsg("redirecting log output to logging collector process"), + errhint("Future log output will appear in directory \"%s\".", + pool_config->log_directory))); + +#ifndef WIN32 + fflush(stdout); + if (dup2(syslogPipe[1], fileno(stdout)) < 0) + ereport(FATAL, + (errmsg("could not redirect stdout: %m"))); + fflush(stderr); + if (dup2(syslogPipe[1], fileno(stderr)) < 0) + ereport(FATAL, + (errmsg("could not redirect stderr: %m"))); + /* Now we are done with the write end of the pipe. */ + close(syslogPipe[1]); + syslogPipe[1] = -1; +#else + + /* + * open the pipe in binary mode and make sure stderr is binary + * after it's been dup'ed into, to avoid disturbing the pipe + * chunking protocol. + */ + fflush(stderr); + fd = _open_osfhandle((intptr_t) syslogPipe[1], + _O_APPEND | _O_BINARY); + if (dup2(fd, _fileno(stderr)) < 0) + ereport(FATAL, + (errmsg("could not redirect stderr: %m"))); + close(fd); + _setmode(_fileno(stderr), _O_BINARY); + + /* + * Now we are done with the write end of the pipe. + * CloseHandle() must not be called because the preceding + * close() closes the underlying handle. + */ + syslogPipe[1] = 0; +#endif + redirection_done = true; + } + + /* postmaster will never write the file(s); close 'em */ + fclose(syslogFile); + syslogFile = NULL; + if (csvlogFile != NULL) + { + fclose(csvlogFile); + csvlogFile = NULL; + } + return (int) sysloggerPid; + } + + /* we should never reach here */ + return 0; +} + + +/* -------------------------------- + * pipe protocol handling + * -------------------------------- + */ + +/* + * Process data received through the syslogger pipe. + * + * This routine interprets the log pipe protocol which sends log messages as + * (hopefully atomic) chunks - such chunks are detected and reassembled here. + * + * The protocol has a header that starts with two nul bytes, then has a 16 bit + * length, the pid of the sending process, and a flag to indicate if it is + * the last chunk in a message. Incomplete chunks are saved until we read some + * more, and non-final chunks are accumulated until we get the final chunk. + * + * All of this is to avoid 2 problems: + * . partial messages being written to logfiles (messes rotation), and + * . messages from different backends being interleaved (messages garbled). + * + * Any non-protocol messages are written out directly. These should only come + * from non-Pgpool sources, however (e.g. third party libraries writing to + * stderr). + * + * logbuffer is the data input buffer, and *bytes_in_logbuffer is the number + * of bytes present. On exit, any not-yet-eaten data is left-justified in + * logbuffer, and *bytes_in_logbuffer is updated. + */ +static void +process_pipe_input(char *logbuffer, int *bytes_in_logbuffer) +{ + char *cursor = logbuffer; + int count = *bytes_in_logbuffer; + int dest = LOG_DESTINATION_STDERR; + + /* While we have enough for a header, process data... */ + while (count >= (int) (offsetof(PipeProtoHeader, data) + 1)) + { + PipeProtoHeader p; + int chunklen; + + /* Do we have a valid header? */ + memcpy(&p, cursor, offsetof(PipeProtoHeader, data)); + if (p.nuls[0] == '\0' && p.nuls[1] == '\0' && + p.len > 0 && p.len <= PIPE_MAX_PAYLOAD && + p.pid != 0 && + (p.is_last == 't' || p.is_last == 'f' || + p.is_last == 'T' || p.is_last == 'F')) + { + List *buffer_list; + ListCell *cell; + save_buffer *existing_slot = NULL, + *free_slot = NULL; + StringInfo str; + + chunklen = PIPE_HEADER_SIZE + p.len; + + /* Fall out of loop if we don't have the whole chunk yet */ + if (count < chunklen) + break; + + dest = (p.is_last == 'T' || p.is_last == 'F') ? + LOG_DESTINATION_CSVLOG : LOG_DESTINATION_STDERR; + + /* Locate any existing buffer for this source pid */ + buffer_list = buffer_lists[p.pid % NBUFFER_LISTS]; + foreach(cell, buffer_list) + { + save_buffer *buf = (save_buffer *) lfirst(cell); + + if (buf->pid == p.pid) + { + existing_slot = buf; + break; + } + if (buf->pid == 0 && free_slot == NULL) + free_slot = buf; + } + + if (p.is_last == 'f' || p.is_last == 'F') + { + /* + * Save a complete non-final chunk in a per-pid buffer + */ + if (existing_slot != NULL) + { + /* Add chunk to data from preceding chunks */ + str = &(existing_slot->data); + appendBinaryStringInfo(str, + cursor + PIPE_HEADER_SIZE, + p.len); + } + else + { + /* First chunk of message, save in a new buffer */ + if (free_slot == NULL) + { + /* + * Need a free slot, but there isn't one in the list, + * so create a new one and extend the list with it. + */ + free_slot = palloc(sizeof(save_buffer)); + buffer_list = lappend(buffer_list, free_slot); + buffer_lists[p.pid % NBUFFER_LISTS] = buffer_list; + } + free_slot->pid = p.pid; + str = &(free_slot->data); + initStringInfo(str); + appendBinaryStringInfo(str, + cursor + PIPE_HEADER_SIZE, + p.len); + } + } + else + { + /* + * Final chunk --- add it to anything saved for that pid, and + * either way write the whole thing out. + */ + if (existing_slot != NULL) + { + str = &(existing_slot->data); + appendBinaryStringInfo(str, + cursor + PIPE_HEADER_SIZE, + p.len); + write_syslogger_file(str->data, str->len, dest); + /* Mark the buffer unused, and reclaim string storage */ + existing_slot->pid = 0; + pfree(str->data); + } + else + { + /* The whole message was one chunk, evidently. */ + write_syslogger_file(cursor + PIPE_HEADER_SIZE, p.len, + dest); + } + } + + /* Finished processing this chunk */ + cursor += chunklen; + count -= chunklen; + } + else + { + /* Process non-protocol data */ + + /* + * Look for the start of a protocol header. If found, dump data + * up to there and repeat the loop. Otherwise, dump it all and + * fall out of the loop. (Note: we want to dump it all if at all + * possible, so as to avoid dividing non-protocol messages across + * logfiles. We expect that in many scenarios, a non-protocol + * message will arrive all in one read(), and we want to respect + * the read() boundary if possible.) + */ + for (chunklen = 1; chunklen < count; chunklen++) + { + if (cursor[chunklen] == '\0') + break; + } + /* fall back on the stderr log as the destination */ + write_syslogger_file(cursor, chunklen, LOG_DESTINATION_STDERR); + cursor += chunklen; + count -= chunklen; + } + } + + /* We don't have a full chunk, so left-align what remains in the buffer */ + if (count > 0 && cursor != logbuffer) + memmove(logbuffer, cursor, count); + *bytes_in_logbuffer = count; +} + +/* + * Force out any buffered data + * + * This is currently used only at syslogger shutdown, but could perhaps be + * useful at other times, so it is careful to leave things in a clean state. + */ +static void +flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer) +{ + int i; + + /* Dump any incomplete protocol messages */ + for (i = 0; i < NBUFFER_LISTS; i++) + { + List *list = buffer_lists[i]; + ListCell *cell; + + foreach(cell, list) + { + save_buffer *buf = (save_buffer *) lfirst(cell); + + if (buf->pid != 0) + { + StringInfo str = &(buf->data); + + write_syslogger_file(str->data, str->len, + LOG_DESTINATION_STDERR); + /* Mark the buffer unused, and reclaim string storage */ + buf->pid = 0; + pfree(str->data); + } + } + } + + /* + * Force out any remaining pipe data as-is; we don't bother trying to + * remove any protocol headers that may exist in it. + */ + if (*bytes_in_logbuffer > 0) + write_syslogger_file(logbuffer, *bytes_in_logbuffer, + LOG_DESTINATION_STDERR); + *bytes_in_logbuffer = 0; +} + + +/* -------------------------------- + * logfile routines + * -------------------------------- + */ + +/* + * Write text to the currently open logfile + * + * This is exported so that elog.c can call it when processType is PT_LOGGER; +. + * This allows the syslogger process to record elog messages of its own, + * even though its stderr does not point at the syslog pipe. + */ +void +write_syslogger_file(const char *buffer, int count, int destination) +{ + int rc; + FILE *logfile; + + /* + * 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; + + rc = fwrite(buffer, 1, count, logfile); + + /* + * 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)); +} + + +/* + * Open a new logfile with proper permissions and buffering options. + * + * If allow_errors is true, we just log any open failure and return NULL + * (with errno still correct for the fopen failure). + * Otherwise, errors are treated as fatal. + */ +static FILE * +logfile_open(const char *filename, const char *mode, bool allow_errors) +{ + FILE *fh; + mode_t oumask; + + /* + * Note we do not let pool_config->log_file_mode disable IWUSR, since we + * certainly want to be able to write the files ourselves. + */ + oumask = umask((mode_t) ((~(pool_config->log_file_mode | S_IWUSR)) & (S_IRWXU | S_IRWXG | S_IRWXO))); + fh = fopen(filename, mode); + umask(oumask); + + if (fh) + { + setvbuf(fh, NULL, _IOLBF, 0); + +#ifdef WIN32 + /* use CRLF line endings on Windows */ + _setmode(_fileno(fh), _O_TEXT); +#endif + } + else + { + int save_errno = errno; + + ereport(allow_errors ? LOG : FATAL, + (errmsg("could not open log file \"%s\": %m", + filename))); + errno = save_errno; + } + + return fh; +} + +/* + * perform logfile rotation + */ +static void +logfile_rotate(bool time_based_rotation, int size_rotation_for) +{ + char *filename; + char *csvfilename = NULL; + pg_time_t fntime; + FILE *fh; + + rotation_requested = false; + + /* + * When doing a time-based rotation, invent the new logfile name based on + * the planned rotation time, not current time, to avoid "slippage" in the + * file name when we don't do the rotation immediately. + */ + if (time_based_rotation) + fntime = next_rotation_time; + else + fntime = time(NULL); + filename = logfile_getname(fntime, NULL); + if (pool_config->log_destination & LOG_DESTINATION_CSVLOG) + csvfilename = logfile_getname(fntime, ".csv"); + + /* + * Decide whether to overwrite or append. We can overwrite if (a) + * pool_config->log_truncate_on_rotation is set, (b) the rotation was + * triggered by elapsed time and not something else, and (c) the computed + * file name is different from what we were previously logging into. + * + * Note: last_file_name should never be NULL here, but if it is, append. + */ + if (time_based_rotation || (size_rotation_for & LOG_DESTINATION_STDERR)) + { + if (pool_config->log_truncate_on_rotation && time_based_rotation && + last_file_name != NULL && + strcmp(filename, last_file_name) != 0) + fh = logfile_open(filename, "w", true); + else + fh = logfile_open(filename, "a", true); + + if (!fh) + { + /* + * ENFILE/EMFILE are not too surprising on a busy system; just + * keep using the old file till we manage to get a new one. + * Otherwise, assume something's wrong with + * pool_config->log_directory and stop trying to create files. + */ + if (errno != ENFILE && errno != EMFILE) + { + ereport(LOG, + (errmsg("disabling automatic rotation (use SIGHUP to re-enable)"))); + rotation_disabled = true; + } + + if (filename) + pfree(filename); + if (csvfilename) + pfree(csvfilename); + return; + } + + fclose(syslogFile); + syslogFile = fh; + + /* instead of pfree'ing filename, remember it for next time */ + if (last_file_name != NULL) + pfree(last_file_name); + last_file_name = filename; + filename = NULL; + } + + /* + * 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 ((pool_config->log_destination & LOG_DESTINATION_CSVLOG) && + (csvlogFile == NULL || + time_based_rotation || (size_rotation_for & LOG_DESTINATION_CSVLOG))) + { + if (pool_config->log_truncate_on_rotation && time_based_rotation && + last_csv_file_name != NULL && + strcmp(csvfilename, last_csv_file_name) != 0) + fh = logfile_open(csvfilename, "w", true); + else + fh = logfile_open(csvfilename, "a", true); + + if (!fh) + { + /* + * ENFILE/EMFILE are not too surprising on a busy system; just + * keep using the old file till we manage to get a new one. + * Otherwise, assume something's wrong with + * pool_config->log_directory and stop trying to create files. + */ + if (errno != ENFILE && errno != EMFILE) + { + ereport(LOG, + (errmsg("disabling automatic rotation (use SIGHUP to re-enable)"))); + rotation_disabled = true; + } + + if (filename) + pfree(filename); + if (csvfilename) + pfree(csvfilename); + return; + } + + if (csvlogFile != NULL) + fclose(csvlogFile); + csvlogFile = fh; + + /* instead of pfree'ing filename, remember it for next time */ + if (last_csv_file_name != NULL) + pfree(last_csv_file_name); + last_csv_file_name = csvfilename; + csvfilename = NULL; + } + else if (!(pool_config->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); + if (csvfilename) + pfree(csvfilename); + + set_next_rotation_time(); +} + + +/* + * construct logfile name using timestamp information + * + * If suffix isn't NULL, append it to the name, replacing any ".log" + * that may be in the pattern. + * + * Result is palloc'd. + */ +static char * +logfile_getname(pg_time_t timestamp, const char *suffix) +{ + char *filename; + int len; + + filename = palloc(MAXPGPATH); + + snprintf(filename, MAXPGPATH, "%s/", pool_config->log_directory); + + len = strlen(filename); + + /* treat pool_config->log_filename as a strftime pattern */ + strftime(filename + len, MAXPGPATH - len, pool_config->log_filename, + localtime(×tamp)); + + if (suffix != NULL) + { + len = strlen(filename); + if (len > 4 && (strcmp(filename + (len - 4), ".log") == 0)) + len -= 4; + strlcpy(filename + len, suffix, MAXPGPATH - len); + } + + return filename; +} + +/* + * Determine the next planned rotation time, and store in next_rotation_time. + */ +static void +set_next_rotation_time(void) +{ + pg_time_t now; + struct tm *tm; + int rotinterval; + + /* nothing to do if time-based rotation is disabled */ + if (pool_config->log_rotation_age <= 0) + return; + + /* + * The requirements here are to choose the next time > now that is a + * "multiple" of the log rotation interval. "Multiple" can be interpreted + * fairly loosely. In this version we align to log_timezone rather than + * GMT. + */ + rotinterval = pool_config->log_rotation_age * SECS_PER_MINUTE; /* convert to seconds */ + now = (pg_time_t) time(NULL); + tm = localtime(&now); + now += tm->tm_gmtoff; + now -= now % rotinterval; + now += rotinterval; + now -= tm->tm_gmtoff; + next_rotation_time = now; +} + + +/* -------------------------------- + * signal handler routines + * -------------------------------- + */ + +/* + * 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(int sig) +{ + int save_errno = errno; + + got_SIGHUP = true; + + errno = save_errno; +} + +/* SIGUSR1: set flag to rotate logfile */ +static void +sigUsr1Handler(int sig) +{ + int save_errno = errno; + + rotation_requested = true; + + errno = save_errno; +} diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index 2c04d2958..14d238003 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2018 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -19,48 +19,51 @@ * is" without express or implied warranty. */ -#include -#include -#include -#include +#include +#include +#include +#include #include #include -#include -#include +#include #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include - +#include +#include #include -#include -#include -#include -#include -#include - -#include - -#include -#include "utils/elog.h" +#ifdef __FreeBSD__ +#include +#endif #include "pool.h" +#include "version.h" +#include "pool_config.h" +#include "main/health_check.h" +#include "main/pool_internal_comms.h" +#include "main/pgpool_logger.h" +#include "utils/elog.h" #include "utils/palloc.h" #include "utils/memutils.h" -#include "pool_config.h" +#include "utils/statistics.h" +#include "utils/pool_ipc.h" #include "context/pool_process_context.h" -#include "version.h" -#include "parser/pool_string.h" +#include "protocol/pool_process_query.h" +#include "protocol/pool_pg_utils.h" #include "auth/pool_passwd.h" #include "auth/pool_hba.h" #include "query_cache/pool_memqcache.h" -#include "watchdog/wd_ipc_commands.h" +#include "utils/pool_track_table_mutation.h" +#include "watchdog/wd_internal_commands.h" #include "watchdog/wd_lifecheck.h" - #include "watchdog/watchdog.h" +#include "pcp/pcp_worker.h" +#include "utils/pool_ssl.h" +#include /* * Reasons for signalling a pgpool-II main process @@ -74,17 +77,18 @@ typedef enum * required */ SIG_WATCHDOG_QUORUM_CHANGED, /* notify main about cluster quorum change * of watchdog cluster */ - SIG_INFORM_QURANTINE_NODES, /* notify main about send degenerate requests - * for all quarantine nodes */ - MAX_INTERUPTS /* Must be last! */ -} User1SignalReason; + SIG_INFORM_QUARANTINE_NODES, /* notify main about send degenerate + * requests for all quarantine nodes */ + MAX_INTERRUPTS /* Must be last! */ +} User1SignalReason; typedef struct User1SignalSlot { - sig_atomic_t signalFlags[MAX_INTERUPTS]; -} User1SignalSlot; + sig_atomic_t signalFlags[MAX_INTERRUPTS]; +} User1SignalSlot; +#ifdef NOT_USED /* * Process pending signal actions. */ @@ -97,8 +101,10 @@ typedef struct User1SignalSlot } \ if (sigusr1_request) \ { \ - sigusr1_interupt_processor(); \ - sigusr1_request = 0; \ + do {\ + sigusr1_request = 0; \ + sigusr1_interrupt_processor(); \ + } while (sigusr1_request == 1); \ } \ if (sigchld_request) \ { \ @@ -110,18 +116,52 @@ typedef struct User1SignalSlot reload_config_request = 0; \ } \ } while (0) +#endif #define PGPOOLMAXLITSENQUEUELENGTH 10000 +#define MAX_ONE_SHOT_KILLS 8 + + +#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path) + +/* + * Context data while exectuing failover() + */ +typedef struct +{ + bool all_backend_down; /* true if all backends are down */ + bool search_primary; /* true if we need to seach primary node */ + bool need_to_restart_children; /* true if we need to restart + * child process */ + bool need_to_restart_pcp; /* true if we need to restart pc + * process */ + bool partial_restart; /* true if partial restart is needed */ + bool sync_required; /* true if watchdog synchronization is + * necessary */ + + /* followings are copy of Req_info */ + POOL_REQUEST_KIND reqkind; + int node_id_set[MAX_NUM_BACKENDS]; + int node_count; + unsigned char request_details; + + /* + * An array to hold down nodes information. Each array member corresponds + * to node id. If nodes[i] is 1, the node i is down. + */ + int nodes[MAX_NUM_BACKENDS]; +} FAILOVER_CONTEXT; static void signal_user1_to_parent_with_reason(User1SignalReason reason); static void FileUnlink(int code, Datum path); -static pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file); +static pid_t pcp_fork_a_child(int *fds, char *pcp_conf_file); static pid_t fork_a_child(int *fds, int id); -static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params); -static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp); -static int create_inet_domain_socket(const char *hostname, const int port); +static pid_t worker_fork_a_child(ProcessType type, void (*func) (void *), void *params); +static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp, const char *group, const int permissions); +static int *create_unix_domain_sockets_by_list(struct sockaddr_un *un_addrs, char *group, int permissions, int n_sockets); static int *create_inet_domain_sockets(const char *hostname, const int port); +static int *create_inet_domain_sockets_by_list(char **listen_addresses, int n_listen_addresses, int port, int *n_sockets); static void failover(void); static bool check_all_backend_down(void); static void reaper(void); @@ -129,35 +169,54 @@ static void wakeup_children(void); static void reload_config(void); static int pool_pause(struct timeval *timeout); static void kill_all_children(int sig); -static pid_t fork_follow_child(int old_master, int new_primary, int old_primary); +static pid_t fork_follow_child(int old_main_node, int new_primary, int old_primary); static int read_status_file(bool discard_status); static RETSIGTYPE exit_handler(int sig); +static void do_shutdown(int sig); static RETSIGTYPE reap_handler(int sig); static RETSIGTYPE sigusr1_handler(int sig); -static void sigusr1_interupt_processor(void); +static void sigusr1_interrupt_processor(void); static RETSIGTYPE reload_config_handler(int sig); static RETSIGTYPE wakeup_handler(int sig); static void initialize_shared_mem_objects(bool clear_memcache_oidmaps); -static int trigger_failover_command(int node, const char *command_line, - int old_master, int new_master, int old_primary); +static int trigger_failover_command(int node, const char *command_line, + int old_main_node, int new_main_node, int old_primary); static int find_primary_node(void); static int find_primary_node_repeatedly(void); -static void terminate_all_childrens(); +static void terminate_all_childrens(int sig); static void system_will_go_down(int code, Datum arg); static char *process_name_from_pid(pid_t pid); static void sync_backend_from_watchdog(void); static void update_backend_quarantine_status(void); -static void degenerate_all_quarantine_nodes(void); -static int get_server_version(POOL_CONNECTION_POOL_SLOT * *slots, int node_id); -static void get_info_from_conninfo(char *conninfo, char *host, char *port); +static int get_server_version(POOL_CONNECTION_POOL_SLOT **slots, int node_id); +static void get_info_from_conninfo(char *conninfo, char *host, int hostlen, char *port, int portlen); -static struct sockaddr_un un_addr; /* unix domain socket path */ -static struct sockaddr_un pcp_un_addr; /* unix domain socket path for PCP */ +/* + * Subroutines of failover() + */ +static int handle_failback_request(FAILOVER_CONTEXT *failover_context, int node_id); +static int handle_failover_request(FAILOVER_CONTEXT *failover_context, int node_id); +static void kill_failover_children(FAILOVER_CONTEXT *failover_context, int node_id); +static void exec_failover_command(FAILOVER_CONTEXT *failover_context, int new_main_node_id, int promote_node_id); +static int determine_new_primary_node(FAILOVER_CONTEXT *failover_context, int node_id); +static int exec_follow_primary_command(FAILOVER_CONTEXT *failover_context, int node_id, int new_primary_node_id); +static void save_node_info(FAILOVER_CONTEXT *failover_context, int new_primary_node_id, int new_main_node_id); +static void exec_child_restart(FAILOVER_CONTEXT *failover_context, int node_id); +static void exec_notice_pcp_child(FAILOVER_CONTEXT *failover_context); + +static void check_requests(void); +static void print_signal_member(sigset_t *sig); +static void service_child_processes(void); +static int select_victim_processes(int *process_info_idxs, int count); + +static struct sockaddr_un *un_addrs; /* unix domain socket path */ +static struct sockaddr_un *pcp_un_addrs; /* unix domain socket path for PCP */ ProcessInfo *process_info = NULL; /* Per child info table on shmem */ -volatile User1SignalSlot *user1SignalSlot = NULL; /* User 1 signal slot on - * shmem */ -struct timeval random_start_time; +volatile User1SignalSlot *user1SignalSlot = NULL; /* User 1 signal slot on + * shmem */ + +int current_child_process_count; /* * To track health check process ids @@ -176,17 +235,19 @@ BACKEND_STATUS private_backend_status[MAX_NUM_BACKENDS]; */ ConnectionInfo *con_info; -static int *fds; /* listening file descriptors (UNIX socket, +static int *fds = NULL; /* listening file descriptors (UNIX socket, * inet domain sockets) */ -static int pcp_unix_fd; /* unix domain socket fd for PCP (not used) */ -static int pcp_inet_fd; /* inet domain socket fd for PCP */ +static int *pcp_fds = NULL; /* listening file descriptors for pcp (UNIX + * socket, inet domain sockets) */ + extern char *pcp_conf_file; /* path for pcp.conf */ extern char *conf_file; extern char *hba_file; -static int exiting = 0; /* non 0 if I'm exiting */ -static int switching = 0; /* non 0 if I'm failing over or degenerating */ +static volatile sig_atomic_t exiting = 0; /* non 0 if I'm exiting */ +static volatile sig_atomic_t switching = 0; /* non 0 if I'm failing over or + * degenerating */ POOL_REQUEST_INFO *Req_info; /* request info area in shared memory */ volatile sig_atomic_t *InRecovery; /* non 0 if recovery is started */ @@ -194,6 +255,12 @@ volatile sig_atomic_t reload_config_request = 0; static volatile sig_atomic_t sigusr1_request = 0; static volatile sig_atomic_t sigchld_request = 0; static volatile sig_atomic_t wakeup_request = 0; +static volatile sig_atomic_t main_exit_request = 0; /* set by exit_handler; + * carries the captured signal + * number (SIGTERM/INT/QUIT) + * so the main loop can + * perform the (non-async-safe) + * shutdown work itself. */ static int pipe_fds[2]; /* for delivering signals */ @@ -206,11 +273,25 @@ static pid_t follow_pid = 0; /* pid for child process handling follow * command */ static pid_t pcp_pid = 0; /* pid for child process handling PCP */ static pid_t watchdog_pid = 0; /* pid for watchdog child process */ +static pid_t pgpool_logger_pid = 0; /* pid for pgpool_logger process */ static pid_t wd_lifecheck_pid = 0; /* pid for child process handling watchdog * lifecheck */ -BACKEND_STATUS *my_backend_status[MAX_NUM_BACKENDS]; /* Backend status buffer */ -int my_master_node_id; /* Master node id buffer */ +/* Backend status buffer */ +volatile BACKEND_STATUS *my_backend_status[MAX_NUM_BACKENDS]; + +int my_main_node_id; /* Main node id buffer */ + +/* + * Dummy variable to suppress compiler warnings by discarding return values + * from write(2) in signal handlers + */ +static int dummy_status; + +/* + * Snapshot Isolation manage area + */ +volatile SI_ManageInfo *si_manage_info; /* * pgpool main program @@ -219,7 +300,15 @@ int my_master_node_id; /* Master node id buffer */ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) { + int num_inet_fds = 0; + int num_unix_fds = 0; + int num_pcp_fds = 0; + int *unix_fds; + int *inet_fds; + int *pcp_unix_fds; + int *pcp_inet_fds; int i; + char unix_domain_socket_path[UNIXSOCK_PATH_BUFLEN + 1024]; sigjmp_buf local_sigjmp_buf; @@ -229,11 +318,12 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) */ volatile bool first = true; - /* For PostmasterRandom */ - gettimeofday(&random_start_time, NULL); + /* + * Query cache lock file path. This should be declared as "static" because + * the path is passed to be registered using on_proc_exit(). + */ + static char query_cache_lock_path[MAXPGPATH]; - /* Set the process type variable */ - processType = PT_MAIN; processState = INITIALIZING; /* @@ -241,30 +331,97 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) */ read_status_file(discard_status); - /* - * install the call back for preparation of system exit - */ - on_system_exit(system_will_go_down, (Datum) NULL); - /* set unix domain socket path for connections to pgpool */ - snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/.s.PGSQL.%d", - pool_config->socket_dir, - pool_config->port); + for (i = 0; i < pool_config->num_unix_socket_directories; i++) + { + memset(unix_domain_socket_path, 0, sizeof(unix_domain_socket_path)); + snprintf(unix_domain_socket_path, sizeof(unix_domain_socket_path), "%s/.s.PGSQL.%d", + pool_config->unix_socket_directories[i], pool_config->port); + + if (strlen(unix_domain_socket_path) >= UNIXSOCK_PATH_BUFLEN) + { + ereport(WARNING, + (errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)", + unix_domain_socket_path, + (int) (UNIXSOCK_PATH_BUFLEN - 1)))); + continue; + } + un_addrs = realloc(un_addrs, sizeof(struct sockaddr_un) * (num_unix_fds + 1)); + if (un_addrs == NULL) + ereport(FATAL, + (errmsg("failed to allocate memory in startup process"))); + + snprintf(un_addrs[i].sun_path, sizeof(un_addrs[i].sun_path), "%s", unix_domain_socket_path); + num_unix_fds++; + } + + if (num_unix_fds == 0) + { + ereport(FATAL, + (errmsg("could not create any Unix-domain sockets"))); + } + /* set unix domain socket path for pgpool PCP communication */ - snprintf(pcp_un_addr.sun_path, sizeof(pcp_un_addr.sun_path), "%s/.s.PGSQL.%d", - pool_config->pcp_socket_dir, - pool_config->pcp_port); + for (i = 0; i < pool_config->num_pcp_socket_directories; i++) + { + memset(unix_domain_socket_path, 0, sizeof(unix_domain_socket_path)); + snprintf(unix_domain_socket_path, sizeof(unix_domain_socket_path), "%s/.s.PGSQL.%d", + pool_config->pcp_socket_dir[i], + pool_config->pcp_port); + + if (strlen(unix_domain_socket_path) >= UNIXSOCK_PATH_BUFLEN) + { + ereport(WARNING, + (errmsg("PCP Unix-domain socket path \"%s\" is too long (maximum %d bytes)", + unix_domain_socket_path, + (int) (UNIXSOCK_PATH_BUFLEN - 1)))); + continue; + } + pcp_un_addrs = realloc(pcp_un_addrs, sizeof(struct sockaddr_un) * (num_pcp_fds + 1)); + if (pcp_un_addrs == NULL) + ereport(FATAL, + (errmsg("failed to allocate memory in startup process"))); + + snprintf(pcp_un_addrs[i].sun_path, sizeof(pcp_un_addrs[i].sun_path), "%s", unix_domain_socket_path); + num_pcp_fds++; + } + + if (num_pcp_fds == 0) + { + ereport(FATAL, + (errmsg("could not create any PCP Unix-domain sockets"))); + } /* set up signal handlers */ pool_signal(SIGPIPE, SIG_IGN); - /* create unix domain socket */ - fds = malloc(sizeof(int) * 2); - if (fds == NULL) - ereport(FATAL, - (errmsg("failed to allocate memory in startup process"))); + /* start the log collector if enabled */ + pgpool_logger_pid = SysLogger_Start(); + + /* + * If using syslogger, close the read side of the pipe. We don't bother + * tracking this in fd.c, either. + */ + if (syslogPipe[0] >= 0) + close(syslogPipe[0]); + syslogPipe[0] = -1; initialize_shared_mem_objects(clear_memcache_oidmaps); + + /* + * install the callback for preparation of system exit + */ + on_system_exit(system_will_go_down, (Datum) NULL); + + /* setup signal handlers */ + pool_signal(SIGCHLD, reap_handler); + pool_signal(SIGUSR1, sigusr1_handler); + pool_signal(SIGUSR2, wakeup_handler); + pool_signal(SIGTERM, exit_handler); + pool_signal(SIGINT, exit_handler); + pool_signal(SIGQUIT, exit_handler); + pool_signal(SIGHUP, reload_config_handler); + if (pool_config->use_watchdog) { sigset_t mask; @@ -272,23 +429,18 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) wakeup_request = 0; /* - * Watchdog process fires SIGUSR2 once in stable state, so install the - * SIGUSR2 handler first up. In addition, when wathcodg fails to start - * with FATAL, the process exits and SIGCHLD is fired, so SIGCHLD - * handelr is also needed. Finally, we also need to set the SIGUSR1 - * handler for the failover requests from other watchdog nodes. In - * case a request arrives at the same time when the watchdog has just - * been initialized. - */ - pool_signal(SIGUSR2, wakeup_handler); - pool_signal(SIGCHLD, reap_handler); - pool_signal(SIGUSR1, sigusr1_handler); - - /* - * okay as we need to wait until watchdog is in stable state so only - * wait for SIGUSR1, SIGCHLD, and signals those are necessary to make - * sure we respond to user requests of shutdown if it arrives while we - * are in waiting state. + * Watchdog process fires SIGUSR2 once in stable state In addition, + * when watchdog fails to start with FATAL, the process exits and + * SIGCHLD is fired, so we can also expect SIGCHLD from watchdog + * process. Finally, we also need to look for the SIGUSR1 signal for + * the failover requests from other watchdog nodes. In case a request + * arrives at the same time when the watchdog has just been + * initialized. + * + * So we need to wait until watchdog is in stable state so only wait + * for SIGUSR1, SIGCHLD, and signals those are necessary to make sure + * we respond to user requests of shutdown if it arrives while we are + * in waiting state. * * Note that SIGUSR1 does not need to be in the wait signal list, * although it's signal handler is already installed, but even if the @@ -303,6 +455,8 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) sigdelset(&mask, SIGTERM); sigdelset(&mask, SIGINT); sigdelset(&mask, SIGQUIT); + sigdelset(&mask, SIGHUP); + watchdog_pid = initialize_watchdog(); ereport(LOG, (errmsg("waiting for watchdog to initialize"))); @@ -319,7 +473,8 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) } ereport(LOG, - (errmsg("watchdog process is initialized"))); + (errmsg("watchdog process is initialized"), + errdetail("watchdog messaging data version: %s", WD_MESSAGE_DATA_VERSION))); /* * initialize the lifecheck process @@ -328,42 +483,71 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) if (sigusr1_request) { - sigusr1_interupt_processor(); - sigusr1_request = 0; + do + { + sigusr1_request = 0; + sigusr1_interrupt_processor(); + } while (sigusr1_request == 1); } } - fds[0] = create_unix_domain_socket(un_addr); - fds[1] = -1; - on_proc_exit(FileUnlink, (Datum) un_addr.sun_path); + /* create unix domain socket(s) */ + fds = malloc(sizeof(int) * (num_unix_fds + 1)); + if (fds == NULL) + ereport(FATAL, + (errmsg("failed to allocate memory in startup process"))); - /* create inet domain socket if any */ - if (pool_config->listen_addresses[0]) + unix_fds = create_unix_domain_sockets_by_list(un_addrs, + pool_config->unix_socket_group, + pool_config->unix_socket_permissions, + num_unix_fds); + + for (i = 0; i < num_unix_fds; i++) { - int *inet_fds, - *walk; - int n = 1; + on_proc_exit(FileUnlink, (Datum) un_addrs[i].sun_path); + } - inet_fds = create_inet_domain_sockets(pool_config->listen_addresses, pool_config->port); + /* copy unix domain sockets */ + memcpy(fds, unix_fds, sizeof(int) * num_unix_fds); + fds[num_unix_fds] = -1; + free(unix_fds); - for (walk = inet_fds; *walk != -1; walk++) - n++; + /* create inet domain socket if any */ + inet_fds = create_inet_domain_sockets_by_list(pool_config->listen_addresses, pool_config->num_listen_addresses, + pool_config->port, &num_inet_fds); - fds = realloc(fds, sizeof(int) * (n + 1)); + /* copy inet domain sockets if any */ + if (num_inet_fds > 0) + { + fds = realloc(fds, sizeof(int) * (num_inet_fds + num_unix_fds + 1)); if (fds == NULL) ereport(FATAL, - (errmsg("failed to allocate memory in startup process"))); + (errmsg("failed to expand memory for fds"))); - n = 1; - for (walk = inet_fds; *walk != -1; walk++) - { - fds[n] = inet_fds[n - 1]; - n++; - } - fds[n] = -1; + memcpy(&fds[num_unix_fds], inet_fds, sizeof(int) * num_inet_fds); + fds[num_unix_fds + num_inet_fds] = -1; free(inet_fds); } + /* For query cache concurrency control */ + if (pool_config->memory_cache_enabled || pool_config->enable_shared_relcache) + { + int lfd; + + snprintf(query_cache_lock_path, sizeof(query_cache_lock_path), + "%s/%s", pool_config->work_dir, QUERY_CACHE_LOCK_FILE); + lfd = open(query_cache_lock_path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); + if (lfd == -1) + { + ereport(FATAL, + (errmsg("Failed to open lock file for query cache \"%s\"", query_cache_lock_path), + errdetail("%m"))); + } + close(lfd); + + /* Register file unlink at exit */ + on_proc_exit(FileUnlink, (Datum) query_cache_lock_path); + } /* * We need to block signal here. Otherwise child might send some signals, @@ -372,23 +556,31 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) * is harmless. */ POOL_SETMASK(&BlockSig); - /* fork the children */ - for (i = 0; i < pool_config->num_init_children; i++) + + if (pool_config->process_management == PM_DYNAMIC) + { + if (pool_config->process_management_strategy == PM_STRATEGY_AGGRESSIVE) + current_child_process_count = pool_config->max_spare_children; + else + current_child_process_count = pool_config->min_spare_children; + } + else + current_child_process_count = pool_config->num_init_children; + ereport(DEBUG1, + (errmsg("Spawning %d child processes", current_child_process_count))); + for (i = 0; i < current_child_process_count; i++) { - process_info[i].pid = fork_a_child(fds, i); process_info[i].start_time = time(NULL); + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; + process_info[i].connected = 0; + process_info[i].wait_for_connect = 0; + process_info[i].pooled_connections = 0; + process_info[i].need_to_restart = false; + process_info[i].exit_if_idle = false; + process_info[i].pid = fork_a_child(fds, i); } - /* set up signal handlers */ - - pool_signal(SIGTERM, exit_handler); - pool_signal(SIGINT, exit_handler); - pool_signal(SIGQUIT, exit_handler); - pool_signal(SIGCHLD, reap_handler); - pool_signal(SIGUSR1, sigusr1_handler); - pool_signal(SIGUSR2, wakeup_handler); - pool_signal(SIGHUP, reload_config_handler); - /* create pipe for delivering event */ if (pipe(pipe_fds) < 0) { @@ -407,26 +599,49 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) Req_info->primary_node_id = find_primary_node_repeatedly(); } - /* fork a child for PCP handling */ - pcp_unix_fd = create_unix_domain_socket(pcp_un_addr); - /* Add onproc exit to clean up the unix domain socket at exit */ - on_proc_exit(FileUnlink, (Datum) pcp_un_addr.sun_path); + /* create pcp unix domain socket */ + num_inet_fds = 0; + + pcp_unix_fds = create_unix_domain_sockets_by_list(pcp_un_addrs, "", 0777, num_pcp_fds); + for (i = 0; i < num_pcp_fds; i++) + { + on_proc_exit(FileUnlink, (Datum) pcp_un_addrs[i].sun_path); + } + pcp_fds = malloc(sizeof(int) * (num_pcp_fds + 1)); + if (pcp_fds == NULL) + ereport(FATAL, + (errmsg("failed to allocate memory in startup process"))); + + memcpy(pcp_fds, pcp_unix_fds, sizeof(int) * num_pcp_fds); + pcp_fds[num_pcp_fds] = -1; + free(pcp_unix_fds); + + /* create inet domain socket if any */ + pcp_inet_fds = create_inet_domain_sockets_by_list(pool_config->pcp_listen_addresses, + pool_config->num_pcp_listen_addresses, + pool_config->pcp_port, &num_inet_fds); - if (pool_config->pcp_listen_addresses[0]) + if (num_inet_fds > 0) { - pcp_inet_fd = create_inet_domain_socket(pool_config->pcp_listen_addresses, pool_config->pcp_port); + pcp_fds = realloc(pcp_fds, sizeof(int) * (num_inet_fds + num_pcp_fds + 1)); + if (pcp_fds == NULL) + ereport(FATAL, + (errmsg("failed to expand memory for pcp_fds"))); + + memcpy(&pcp_fds[num_pcp_fds], pcp_inet_fds, sizeof(int) * num_inet_fds); + pcp_fds[num_inet_fds + num_pcp_fds] = -1; + free(pcp_inet_fds); } - pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file); + + pcp_pid = pcp_fork_a_child(pcp_fds, pcp_conf_file); /* Fork worker process */ worker_pid = worker_fork_a_child(PT_WORKER, do_worker_child, NULL); /* Fork health check process */ for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - health_check_pids[i] = worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); - } + health_check_pids[i] = + worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); if (sigsetjmp(local_sigjmp_buf, 1) != 0) { @@ -448,11 +663,15 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) /* This is the main loop */ for (;;) { + /* Check pending requests */ + check_requests(); +#ifdef NOT_USED CHECK_REQUEST; +#endif /* * check for child signals to ensure child startup before reporting - * successfull start. + * successful start. */ if (first) { @@ -493,11 +712,22 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) for (;;) { int r; - struct timeval t = {3, 0}; + struct timeval t = {2, 0}; POOL_SETMASK(&UnBlockSig); r = pool_pause(&t); POOL_SETMASK(&BlockSig); + + /* + * If a SIGTERM/SIGINT/SIGQUIT was queued by exit_handler, + * service it immediately rather than waiting another tick. + */ + if (main_exit_request) + do_shutdown(main_exit_request); + + if (pool_config->process_management == PM_DYNAMIC) + service_child_processes(); + if (r > 0) break; } @@ -530,6 +760,7 @@ register_node_operation_request(POOL_REQUEST_KIND kind, int *node_id_set, int co if ((Req_info->request_queue_tail - MAX_REQUEST_QUEUE_SIZE) == Req_info->request_queue_head) { pool_semaphore_unlock(REQUEST_INFO_SEM); + POOL_SETMASK(&oldmask); return false; } Req_info->request_queue_tail++; @@ -557,30 +788,33 @@ register_node_operation_request(POOL_REQUEST_KIND kind, int *node_id_set, int co } void -register_watchdog_quorum_change_interupt(void) +register_watchdog_quorum_change_interrupt(void) { signal_user1_to_parent_with_reason(SIG_WATCHDOG_QUORUM_CHANGED); } void -register_watchdog_state_change_interupt(void) +register_watchdog_state_change_interrupt(void) { signal_user1_to_parent_with_reason(SIG_WATCHDOG_STATE_CHANGED); } void -register_backend_state_sync_req_interupt(void) +register_backend_state_sync_req_interrupt(void) { signal_user1_to_parent_with_reason(SIG_BACKEND_SYNC_REQUIRED); } void register_inform_quarantine_nodes_req(void) { - signal_user1_to_parent_with_reason(SIG_INFORM_QURANTINE_NODES); + signal_user1_to_parent_with_reason(SIG_INFORM_QUARANTINE_NODES); } static void signal_user1_to_parent_with_reason(User1SignalReason reason) { + ereport(LOG, + (errmsg("signal_user1_to_parent_with_reason(%d)", reason))); + user1SignalSlot->signalFlags[reason] = true; pool_signal_parent(SIGUSR1); } @@ -589,7 +823,7 @@ signal_user1_to_parent_with_reason(User1SignalReason reason) * fork a child for PCP */ static pid_t -pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file) +pcp_fork_a_child(int *fds, char *pcp_conf_file) { pid_t pid; @@ -598,23 +832,23 @@ pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file) if (pid == 0) { on_exit_reset(); + SetProcessGlobalVariables(PT_PCP); + + /* close pgpool listening sockets */ + close_listening_sockets(POOL_CLOSE_PGPOOL_LISTENING_SOCKS); close(pipe_fds[0]); close(pipe_fds[1]); - /* Set the process type variable */ - processType = PT_PCP; - /* call PCP child main */ - POOL_SETMASK(&UnBlockSig); health_check_timer_expired = 0; reload_config_request = 0; - pcp_main(unix_fd, inet_fd); + pcp_main(fds); } else if (pid == -1) { ereport(FATAL, - (errmsg("fork() failed. reason: %s", strerror(errno)))); + (errmsg("fork() failed. reason: %m"))); } return pid; @@ -648,8 +882,10 @@ fork_a_child(int *fds, int id) close(pipe_fds[1]); } - /* Set the process type variable */ - processType = PT_CHILD; + SetProcessGlobalVariables(PT_CHILD); + + /* close pcp listening sockets */ + close_listening_sockets(POOL_CLOSE_PCP_LISTENING_SOCKS); /* call child main */ POOL_SETMASK(&UnBlockSig); @@ -662,7 +898,7 @@ fork_a_child(int *fds, int id) { ereport(FATAL, (errmsg("failed to fork a child"), - errdetail("system call fork() failed with reason: %s", strerror(errno)))); + errdetail("system call fork() failed with reason: %m"))); } return pid; @@ -671,7 +907,8 @@ fork_a_child(int *fds, int id) /* * fork worker child process */ -static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params) +static pid_t +worker_fork_a_child(ProcessType type, void (*func) (void *), void *params) { pid_t pid; @@ -695,8 +932,18 @@ static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params close(pipe_fds[1]); } - /* Set the process type variable */ - processType = type; + SetProcessGlobalVariables(type); + + /* + * Close pgpool listening sockets and pcp listening sockets if they + * are already setup. They are not ncessary for woker process (health + * check and streaming replication check process). + */ + close_listening_sockets(POOL_CLOSE_PGPOOL_LISTENING_SOCKS | + POOL_CLOSE_PCP_LISTENING_SOCKS); + + ereport(LOG, + (errmsg("process started"))); /* call child main */ POOL_SETMASK(&UnBlockSig); @@ -708,12 +955,19 @@ static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params { ereport(FATAL, (errmsg("failed to fork a child"), - errdetail("system call fork() failed with reason: %s", strerror(errno)))); + errdetail("system call fork() failed with reason: %m"))); } return pid; } +/* + * Create a socket list by "hostname" and return it. "hostname" can be either + * single host name, IP or "*" which means all available UP interface. If + * fails with getaddrinfo, socket, setsockopt, bind or listen, return NULL and + * pgpool will ignore the hostname. This could happen if wrong hostname or + * duplicated hostname is specified in listen_addresses parameter. + */ static int * create_inet_domain_sockets(const char *hostname, const int port) { @@ -742,14 +996,17 @@ create_inet_domain_sockets(const char *hostname, const int port) { ereport(FATAL, (errmsg("failed to create INET domain socket"), - errdetail("asprintf() failed: %s", strerror(errno)))); + errdetail("asprintf() failed: %m"))); } if ((ret = getaddrinfo((!hostname || strcmp(hostname, "*") == 0) ? NULL : hostname, portstr, &hints, &res)) != 0) { - ereport(FATAL, + /* Perhaps wrong hostname or IP */ + ereport(WARNING, (errmsg("failed to create INET domain socket"), errdetail("getaddrinfo() failed: %s", gai_strerror(ret)))); + free(portstr); + return NULL; } free(portstr); @@ -758,6 +1015,9 @@ create_inet_domain_sockets(const char *hostname, const int port) n++; sockfds = malloc(sizeof(int) * (n + 1)); + if (sockfds == NULL) + ereport(FATAL, + (errmsg("failed to allocate memory for socket fds"))); n = 0; for (walk = res; walk != NULL; walk = walk->ai_next) sockfds[n++] = -1; @@ -791,16 +1051,18 @@ create_inet_domain_sockets(const char *hostname, const int port) */ ereport(LOG, (errmsg("perhaps failed to create INET domain socket"), - errdetail("socket(%s) failed: \"%s\"", buf, strerror(errno)))); + errdetail("socket(%s) failed: \"%m\"", buf))); continue; } if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one))) == -1) { - ereport(FATAL, + ereport(WARNING, (errmsg("failed to create INET domain socket"), - errdetail("socket error \"%s\"", strerror(errno)))); + errdetail("socket error \"%m\""))); + close(fd); + continue; } if (walk->ai_family == AF_INET6) @@ -816,15 +1078,17 @@ create_inet_domain_sockets(const char *hostname, const int port) { ereport(LOG, (errmsg("perhaps failed to create INET domain socket"), - errdetail("setsockopt(%s, IPV6_V6ONLY) failed: \"%s\"", buf, strerror(errno)))); + errdetail("setsockopt(%s, IPV6_V6ONLY) failed: \"%m\"", buf))); } } if (bind(fd, walk->ai_addr, walk->ai_addrlen) != 0) { - ereport(FATAL, + ereport(WARNING, (errmsg("failed to create INET domain socket"), - errdetail("bind on socket failed with error \"%s\"", strerror(errno)))); + errdetail("bind on socket failed with error \"%m\""))); + close(fd); + continue; } backlog = pool_config->num_init_children * pool_config->listen_backlog_multiplier; @@ -834,9 +1098,13 @@ create_inet_domain_sockets(const char *hostname, const int port) status = listen(fd, backlog); if (status < 0) - ereport(FATAL, + { + ereport(WARNING, (errmsg("failed to create INET domain socket"), - errdetail("listen on socket failed with error \"%s\"", strerror(errno)))); + errdetail("listen on socket failed with error \"%m\""))); + close(fd); + continue; + } sockfds[n++] = fd; } @@ -845,639 +1113,373 @@ create_inet_domain_sockets(const char *hostname, const int port) if (n == 0) { - ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("Failed to create any sockets. See the earlier LOG messages."))); + /* No sockets created. Perhaps duplicated listen address. */ + free(sockfds); + return NULL; } return sockfds; } /* -* create inet domain socket +* create UNIX domain socket */ static int -create_inet_domain_socket(const char *hostname, const int port) +create_unix_domain_socket(struct sockaddr_un un_addr_tmp, const char *group, const int permissions) { - struct sockaddr_in addr; + struct sockaddr_un addr; int fd; int status; - int one = 1; int len; - int backlog; - fd = socket(AF_INET, SOCK_STREAM, 0); + /* Delete any pre-existing socket file to avoid failure at bind() time */ + unlink(un_addr_tmp.sun_path); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("socket error \"%s\"", strerror(errno)))); + (errmsg("failed to create a socket"), + errdetail("Failed to create UNIX domain socket. error: \"%m\""))); } - if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, - sizeof(one))) == -1) + memset((char *) &addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", un_addr_tmp.sun_path); + len = sizeof(struct sockaddr_un); + status = bind(fd, (struct sockaddr *) &addr, len); + if (status == -1) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("socket error \"%s\"", strerror(errno)))); + (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), + errdetail("bind socket failed with error: \"%m\""))); } - memset((char *) &addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - - if (strcmp(hostname, "*") == 0) - { - addr.sin_addr.s_addr = htonl(INADDR_ANY); - } - else + if (*group != '\0') { - struct hostent *hostinfo; + char *endptr; + gid_t gid; + unsigned long val; - hostinfo = gethostbyname(hostname); - if (!hostinfo) + /* check group */ + val = strtoul(group, &endptr, 10); + if (*endptr == '\0') { - ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("could not resolve hostname \"%s\": error \"%s\"", hostname, hstrerror(h_errno)))); - + gid = val; } - addr.sin_addr = *(struct in_addr *) hostinfo->h_addr; - } - - addr.sin_port = htons(port); - len = sizeof(struct sockaddr_in); + else + { + struct group *gr; - status = bind(fd, (struct sockaddr *) &addr, len); - if (status == -1) - { - int saved_errno = errno; - char host[NI_MAXHOST], - servname[NI_MAXSERV]; + gr = getgrnam(group); + if (!gr) + { + ereport(FATAL, + (errmsg("unix_socket_group \"%s\" does not exist", group))); + } + gid = gr->gr_gid; + } - if ((status = getnameinfo((struct sockaddr *) &addr, len, host, sizeof(host), servname, sizeof(servname), 0))) + if (chown(un_addr_tmp.sun_path, -1, gid) == -1) { - ereport(NOTICE, - (errmsg("getnameinfo failed while creating INET domain socket"), - errdetail("getnameinfo failed with reason: \"%s\"", gai_strerror(status)))); - - snprintf(servname, sizeof(servname), "%d", port); - snprintf(host, sizeof(host), "%s", hostname); + ereport(FATAL, + (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), + errdetail("system call chown failed with error: \"%m\""))); } - ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("bind on host:\"%s\" server:\"%s\" failed with error \"%s\"", host, servname, strerror(saved_errno)))); } - backlog = pool_config->num_init_children * pool_config->listen_backlog_multiplier; - - if (backlog > PGPOOLMAXLITSENQUEUELENGTH) - backlog = PGPOOLMAXLITSENQUEUELENGTH; + if (chmod(un_addr_tmp.sun_path, permissions) == -1) + { + ereport(FATAL, + (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), + errdetail("system call chmod failed with error: \"%m\""))); + } - status = listen(fd, backlog); + status = listen(fd, PGPOOLMAXLITSENQUEUELENGTH); if (status < 0) + { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("listen on socket failed with error \"%s\"", strerror(errno)))); - + (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), + errdetail("system call listen() failed with error: \"%m\""))); + } return fd; } /* -* create UNIX domain socket -*/ -static int -create_unix_domain_socket(struct sockaddr_un un_addr_tmp) -{ - struct sockaddr_un addr; - int fd; - int status; - int len; - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - ereport(FATAL, - (errmsg("failed to create a socket"), - errdetail("Failed to create UNIX domain socket. error: \"%s\"", strerror(errno)))); - } - memset((char *) &addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", un_addr_tmp.sun_path); - len = sizeof(struct sockaddr_un); - status = bind(fd, (struct sockaddr *) &addr, len); - if (status == -1) - { - ereport(FATAL, - (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), - errdetail("bind socket failed with error: \"%s\"", strerror(errno)))); - } - - if (chmod(un_addr_tmp.sun_path, 0777) == -1) - { - ereport(FATAL, - (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), - errdetail("system call chmod failed with error: \"%s\"", strerror(errno)))); - } - - status = listen(fd, PGPOOLMAXLITSENQUEUELENGTH); - if (status < 0) - { - ereport(FATAL, - (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), - errdetail("system call listen() failed with error: \"%s\"", strerror(errno)))); - } - return fd; -} - -/* - * function called as shared memory exit call back to kill all childrens + * sends the kill signal to all Pgpool children except to + * the pgpool_logger child + * wait for the termination of all killed children before returning. */ static void -terminate_all_childrens() +terminate_all_childrens(int sig) { pid_t wpid; + int i; + int killed_count = 0; + int terminated_count = 0; /* * This is supposed to be called from main process */ if (processType != PT_MAIN) return; - POOL_SETMASK(&BlockSig); - kill_all_children(SIGINT); - if (pcp_pid > 0) - kill(pcp_pid, SIGINT); + if (sig != SIGTERM && sig != SIGINT && sig != SIGQUIT) + { + ereport(LOG, + (errmsg("invalid terminate signal: \"%d\"", sig), + errdetail("ignoring"))); + + return; + } + + for (i = 0; i < pool_config->num_init_children; i++) + { + pid_t pid = process_info[i].pid; + + if (pid != 0) + { + kill(pid, sig); + process_info[i].pid = 0; + killed_count++; + } + } + + if (pcp_pid != 0) + { + kill(pcp_pid, sig); + killed_count++; + } pcp_pid = 0; - if (worker_pid > 0) - kill(worker_pid, SIGINT); + + if (worker_pid != 0) + { + kill(worker_pid, sig); + killed_count++; + } worker_pid = 0; + if (pool_config->use_watchdog) { if (pool_config->use_watchdog) { if (watchdog_pid) - kill(watchdog_pid, SIGINT); + { + kill(watchdog_pid, sig); + killed_count++; + } watchdog_pid = 0; if (wd_lifecheck_pid) - kill(wd_lifecheck_pid, SIGINT); + { + kill(wd_lifecheck_pid, sig); + killed_count++; + } wd_lifecheck_pid = 0; } } - /* wait for all children to exit */ + for (i = 0; i < MAX_NUM_BACKENDS; i++) + { + if (health_check_pids[i] != 0) + { + kill(health_check_pids[i], sig); + health_check_pids[i] = 0; + killed_count++; + } + } + /* wait for all killed children to exit */ do { int ret_pid; wpid = waitpid(-1, &ret_pid, 0); - } while (wpid > 0 || (wpid == -1 && errno == EINTR)); + if (wpid > 0) + terminated_count++; + } while (terminated_count < killed_count && + (wpid > 0 || (wpid == -1 && errno == EINTR))); if (wpid == -1 && errno != ECHILD) ereport(LOG, - (errmsg("wait() failed. reason:%s", strerror(errno)))); + (errmsg("wait() failed"), + errdetail("%m"))); - POOL_SETMASK(&UnBlockSig); } -/* - * Reuest failover. If "switch_over" is false, request all existing sessions - * restarting. - */ -void -notice_backend_error(int node_id, unsigned char flags) -{ - int n = node_id; - - if (getpid() == mypid) - { - ereport(LOG, - (errmsg("notice_backend_error: called from pgpool main. ignored."))); - } - else - { - degenerate_backend_set(&n, 1, flags); - } -} /* - * degenerate_backend_set_ex: + * Pgpool main process exit handler. * - * The function registers/verifies the node down operation request. - * The request is then processed by failover function. + * This handler runs in async-signal context: it MUST only call + * async-signal-safe primitives (POSIX 2024 2.4.3). ereport(), + * pool_semaphore_lock(), MemoryContext operations, blocking waitpid() + * and exit(3) (atexit chain + stdio flush) are all unsafe here. In a + * previous version this body did the full shutdown inline, which could + * deadlock or corrupt heap state when SIGTERM/SIGINT/SIGQUIT arrived + * while PT_MAIN was inside ereport(), palloc(), or another semop. * - * node_id_set: array of node ids to be registered for NODE DOWN operation - * count: number of elements in node_id_set array - * error: if set error is thrown as soon as any node id is found in - * node_id_set on which operation could not be performed. - * test_only: When set, function only checks if NODE DOWN operation can be - * executed on provided node ids and never registers the operation - * request. - * For test_only case function returs false or throws an error as - * soon as first non complient node in node_id_set is found - * switch_over: if set, the request is originated by switch over, not errors. + * The handler now only records the requested signal number into a + * sig_atomic_t flag and writes one byte to the self-pipe so the main + * loop's select() returns. The actual shutdown is performed + * synchronously by do_shutdown() from the main loop, where calling + * non-async-safe code is permitted. * - * wd_failover_id: The watchdog internal ID for this failover + * If the same signal is delivered to a forked child that has not yet + * reset this handler, fall through to proc_exit() unchanged. */ -bool -degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, bool error, bool test_only) +static RETSIGTYPE exit_handler(int sig) { - int i; - int node_id[MAX_NUM_BACKENDS]; - int node_count = 0; - int elevel = LOG; - - if (error) - elevel = ERROR; + int save_errno = errno; - for (i = 0; i < count; i++) + /* + * this could happen in a child process if a signal has been sent before + * resetting signal handler. proc_exit() ultimately reduces to _exit() + * for non-PT_MAIN processes; calling it from a handler in a child that + * hasn't yet rewired its own handlers is the historical behaviour. + */ + if (getpid() != mypid) { - if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS || - (!VALID_BACKEND(node_id_set[i]) && BACKEND_INFO(node_id_set[i]).quarantine == false)) - { - if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS) - ereport(elevel, - (errmsg("invalid degenerate backend request, node id: %d is out of range. node id must be between [0 and %d]" - ,node_id_set[i], MAX_NUM_BACKENDS))); - else - ereport(elevel, - (errmsg("invalid degenerate backend request, node id : %d status: [%d] is not valid for failover" - ,node_id_set[i], BACKEND_INFO(node_id_set[i]).backend_status))); - if (test_only) - return false; - - continue; - } - - if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(node_id_set[i]).flag)) - { - ereport(elevel, - (errmsg("degenerate backend request for node_id: %d from pid [%d] is canceled because failover is disallowed on the node", - node_id_set[i], getpid()))); - if (test_only) - return false; - } - else - { - if (!test_only) /* do not produce this log if we are in - * testing mode */ - ereport(LOG, - (errmsg("received degenerate backend request for node_id: %d from pid [%d]", - node_id_set[i], getpid()))); - - node_id[node_count++] = node_id_set[i]; - } + proc_exit(0); + errno = save_errno; + return; } - if (node_count) + if (sig != SIGTERM && sig != SIGINT && sig != SIGQUIT) { - WDFailoverCMDResults res = FAILOVER_RES_PROCEED; - - /* If this was only a test. Inform the caller without doing anything */ - if (test_only) - return true; + errno = save_errno; + return; + } - if (!(flags & REQ_DETAIL_WATCHDOG)) - { - int x; + /* + * Record the signal for the main loop. Repeated signals coalesce; the + * first one wins, which matches the previous "exiting" guard. + */ + if (main_exit_request == 0) + main_exit_request = sig; - for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) - { - res = wd_degenerate_backend_set(node_id_set, count, flags); - if (res != FAILOVER_RES_TRANSITION) - break; - sleep(1); - } - } - if (res == FAILOVER_RES_TRANSITION) - { - /* - * What to do when cluster is still not stable Is proceeding to - * failover is the right choice ??? - */ - ereport(NOTICE, - (errmsg("received degenerate backend request for %d node(s) from pid [%d], But cluster is not in stable state" - ,node_count, getpid()))); - } - if (res == FAILOVER_RES_PROCEED) - { - register_node_operation_request(NODE_DOWN_REQUEST, node_id, node_count, flags); - } - else if (res == FAILOVER_RES_NO_QUORUM) - { - ereport(LOG, - (errmsg("degenerate backend request for %d node(s) from pid [%d], is changed to quarantine node request by watchdog" - ,node_count, getpid()), - errdetail("watchdog does not holds the quorum"))); + /* Wake up the main loop if the self-pipe is set up. */ + if (pipe_fds[1]) + { + /* + * write() is async-signal-safe. We deliberately ignore the + * return value: if the pipe is full the main loop will pick the + * flag up on its next select() wake-up anyway. + * + * We do not use "(void) write()" here because it warns "warning: + * ignoring return value of write declared with attribute + * warn_unused_result [-Wunused-result] on gcc -O2 -Wall and some + * platforms enabling _FORTIFY_SOURCE. + */ + ssize_t w = write(pipe_fds[1], "\0", 1); - register_node_operation_request(NODE_QUARANTINE_REQUEST, node_id, node_count, flags); - } - else if (res == FAILOVER_RES_CONSENSUS_MAY_FAIL) - { - ereport(LOG, - (errmsg("degenerate backend request for %d node(s) from pid [%d], is changed to quarantine node request by watchdog" - ,node_count, getpid()), - errdetail("watchdog is taking time to build consensus"))); - register_node_operation_request(NODE_QUARANTINE_REQUEST, node_id, node_count, flags); - } - else if (res == FAILOVER_RES_BUILDING_CONSENSUS) - { - ereport(LOG, - (errmsg("degenerate backend request for node_id: %d from pid [%d], will be handled by watchdog, which is building consensus for request" - ,*node_id, getpid()))); - } - else if (res == FAILOVER_RES_WILL_BE_DONE) - { - /* we will receive a sync request from master watchdog node */ - ereport(LOG, - (errmsg("degenerate backend request for %d node(s) from pid [%d], will be handled by watchdog" - ,node_count, getpid()))); - } - else - { - ereport(elevel, - (errmsg("degenerate backend request for %d node(s) from pid [%d] is canceled by other pgpool" - ,node_count, getpid()))); - return false; - } + (void) w; } - return true; + + errno = save_errno; } /* - * wrapper over degenerate_backend_set_ex function to register - * NODE down operation request + * Synchronous shutdown body, invoked from the PT_MAIN main loop when + * main_exit_request has been set by exit_handler(). All the work that used + * to live inside the signal handler (ereport, pool_semaphore_lock, + * waitpid, kill of child group, exit(3)) lives here, in normal context + * where it is safe. */ -bool -degenerate_backend_set(int *node_id_set, int count, unsigned char flags) -{ - return degenerate_backend_set_ex(node_id_set, count, flags, false, false); -} - -/* send promote node request using SIGUSR1 */ -bool -promote_backend(int node_id, unsigned char flags) +static void +do_shutdown(int sig) { - WDFailoverCMDResults res = FAILOVER_RES_PROCEED; - bool ret = false; - - if (!SL_MODE) - { - return false; - } + int *walk; - if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || !VALID_BACKEND(node_id)) - { - if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) - ereport(LOG, - (errmsg("invalid promote backend request, node id: %d is out of range. node id must be between [0 and %d]" - ,node_id, MAX_NUM_BACKENDS))); - else - ereport(LOG, - (errmsg("invalid promote backend request, node id : %d status: [%d] not valid" - ,node_id, BACKEND_INFO(node_id).backend_status))); - return false; - } ereport(LOG, - (errmsg("received promote backend request for node_id: %d from pid [%d]", - node_id, getpid()))); + (errmsg("exit handler called (signal: %d)", sig))); - /* If this was only a test. Inform the caller without doing anything */ - if (!(flags & REQ_DETAIL_WATCHDOG)) - { - int x; + POOL_SETMASK(&AuthBlockSig); - for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) - { - res = wd_promote_backend(node_id, flags); - if (res != FAILOVER_RES_TRANSITION) - break; - sleep(1); - } - } - if (res == FAILOVER_RES_TRANSITION) + /* + * Check if another exit handler instance is already running. Since the + * shutdown now runs serially from the main loop this is mostly a + * belt-and-braces guard, but cheap and harmless to keep. + */ + if (exiting) { - /* - * What to do when cluster is still not stable Is proceeding to - * failover is the right choice ??? - */ - ereport(NOTICE, - (errmsg("promote backend request for node_id: %d from pid [%d], But cluster is not in stable state" - ,node_id, getpid()))); + POOL_SETMASK(&UnBlockSig); + return; } - if (res == FAILOVER_RES_PROCEED) - { - ret = register_node_operation_request(PROMOTE_NODE_REQUEST, &node_id, 1, flags); - } - else if (res == FAILOVER_RES_WILL_BE_DONE) - { - ereport(LOG, - (errmsg("promote backend request for node_id: %d from pid [%d], will be handled by watchdog" - ,node_id, getpid()))); - } - else if (res == FAILOVER_RES_NO_QUORUM) - { - ereport(LOG, - (errmsg("promote backend request for node_id: %d from pid [%d], is canceled because watchdog does not hold quorum" - ,node_id, getpid()))); - } - else if (res == FAILOVER_RES_BUILDING_CONSENSUS) + pool_semaphore_lock(MAIN_EXIT_HANDLER_SEM); + if (exiting == 0) { - ereport(LOG, - (errmsg("promote backend request for node_id: %d from pid [%d], will be handled by watchdog, which is building consensus for request" - ,node_id, getpid()))); + exiting = 1; + pool_semaphore_unlock(MAIN_EXIT_HANDLER_SEM); } else { + pool_semaphore_unlock(MAIN_EXIT_HANDLER_SEM); ereport(LOG, - (errmsg("promote backend request for node_id: %d from pid [%d] is canceled by other pgpool" - ,node_id, getpid()))); + (errmsg("exit handler (signal: %d) called. but exit handler is already in progress", sig))); + POOL_SETMASK(&UnBlockSig); + return; } - return ret; -} -/* send failback request using SIGUSR1 */ -bool -send_failback_request(int node_id, bool throw_error, unsigned char flags) -{ - WDFailoverCMDResults res = FAILOVER_RES_PROCEED; - bool ret = false; + processState = EXITING; + ereport(LOG, + (errmsg("shutting down by signal %d", sig))); - if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || - (RAW_MODE && BACKEND_INFO(node_id).backend_status != CON_DOWN && VALID_BACKEND(node_id))) + /* Close listen socket if they are already initialized */ + if (fds) { - if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) - ereport(throw_error ? ERROR : LOG, - (errmsg("invalid failback request, node id: %d is out of range. node id must be between [0 and %d]" - ,node_id, MAX_NUM_BACKENDS))); - else - ereport(throw_error ? ERROR : LOG, - (errmsg("invalid failback request, node id : %d status: [%d] not valid for failback" - ,node_id, BACKEND_INFO(node_id).backend_status))); - return false; + for (walk = fds; *walk != -1; walk++) + close(*walk); } ereport(LOG, - (errmsg("received failback request for node_id: %d from pid [%d]", - node_id, getpid()))); + (errmsg("terminating all child processes"))); + terminate_all_childrens(sig); - /* check we are trying to failback the quarantine node */ - if (BACKEND_INFO(node_id).quarantine) + /* + * Send signal to follow child process and it's children. + */ + if (follow_pid > 0) { - /* set the update flags */ ereport(LOG, - (errmsg("failback request from pid [%d] is changed to update status request because node_id: %d was quarantined", - getpid(), node_id))); - flags |= REQ_DETAIL_UPDATE; - } - else - { - /* - * no need to go to watchdog if it's an update or already initiated - * from watchdog - */ - if (!(flags & REQ_DETAIL_WATCHDOG)) + (errmsg("terminating all child processes of follow child"))); + kill(follow_pid, sig); + switch (sig) { - int x; - - for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) - { - res = wd_send_failback_request(node_id, flags); - if (res != FAILOVER_RES_TRANSITION) - break; - sleep(1); - } + case SIGINT: + case SIGTERM: + case SIGQUIT: + case SIGSTOP: + case SIGKILL: + if (kill(-follow_pid, sig) < 0) + elog(LOG, "kill(%ld,%d) failed: %m", (long) (-follow_pid), sig); + break; + default: + break; } } - if (res == FAILOVER_RES_TRANSITION) - { - /* - * What to do when cluster is still not stable Is proceeding to - * failover is the right choice ??? - */ - ereport(NOTICE, - (errmsg("failback request for node_id: %d from pid [%d], But cluster is not in stable state" - ,node_id, getpid()))); - } - - if (res == FAILOVER_RES_PROCEED) - { - ret = register_node_operation_request(NODE_UP_REQUEST, &node_id, 1, flags); - } - else if (res == FAILOVER_RES_WILL_BE_DONE) - { - ereport(LOG, - (errmsg("failback request for node_id: %d from pid [%d], will be handled by watchdog" - ,node_id, getpid()))); - } - else - { - ereport(throw_error ? ERROR : LOG, - (errmsg("failback request for node_id: %d from pid [%d] is canceled by other pgpool" - ,node_id, getpid()))); - } - return ret; + POOL_SETMASK(&UnBlockSig); + ereport(LOG, + (errmsg("Pgpool-II system is shutdown"))); + process_info = NULL; + exit(0); } -static RETSIGTYPE exit_handler(int sig) +/* + * Calculate next valid main node id. + * If no valid node found, returns -1. + */ +int +get_next_main_node(void) { int i; - pid_t wpid; - int *walk; - - int save_errno = errno; - POOL_SETMASK(&AuthBlockSig); - - /* - * this could happen in a child process if a signal has been sent before - * resetting signal handler - */ - if (getpid() != mypid) - { - POOL_SETMASK(&UnBlockSig); - proc_exit(0); - } - - if (sig != SIGTERM && sig != SIGINT && sig != SIGQUIT) - { - POOL_SETMASK(&UnBlockSig); - errno = save_errno; - return; - } - exiting = 1; - processState = EXITING; - - /* Close listen socket */ - for (walk = fds; *walk != -1; walk++) - close(*walk); - - for (i = 0; i < pool_config->num_init_children; i++) - { - pid_t pid = process_info[i].pid; - - if (pid) - { - kill(pid, sig); - process_info[i].pid = 0; - } - } - - for (i = 0; i < MAX_NUM_BACKENDS; i++) - { - if (health_check_pids[i] > 0) - { - kill(health_check_pids[i], sig); - } - } - - if (pcp_pid > 0) - kill(pcp_pid, sig); - pcp_pid = 0; - - if (worker_pid > 0) - kill(worker_pid, sig); - worker_pid = 0; - - if (pool_config->use_watchdog) - { - if (watchdog_pid) - kill(watchdog_pid, sig); - watchdog_pid = 0; - - if (wd_lifecheck_pid) - kill(wd_lifecheck_pid, sig); - wd_lifecheck_pid = 0; - } - - POOL_SETMASK(&UnBlockSig); - do - { - int ret_pid; - - wpid = waitpid(-1, &ret_pid, 0); - } while (wpid > 0 || (wpid == -1 && errno == EINTR)); - - process_info = NULL; - exit(0); -} - -/* - * Calculate next valid master node id. - * If no valid node found, returns -1. - */ -int -get_next_master_node(void) -{ - int i; - - for (i = 0; i < pool_config->backend_desc->num_backends; i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { /* * Do not use VALID_BACKEND macro in raw mode. VALID_BACKEND return - * true only if the argument is master node id. In other words, - * standby nodes are false. So need to check backend status with + * true only if the argument is main node id. In other words, standby + * nodes are false. So need to check backend status with * VALID_BACKEND_RAW. */ if (RAW_MODE) @@ -1509,12 +1511,13 @@ static RETSIGTYPE sigusr1_handler(int sig) POOL_SETMASK(&BlockSig); sigusr1_request = 1; - write(pipe_fds[1], "\0", 1); + dummy_status = write(pipe_fds[1], "\0", 1); #ifdef NOT_USED if (write(pipe_fds[1], "\0", 1) < 0) ereport(WARNING, - (errmsg("SIGUSR1 handler: write to pipe failed with error \"%s\"", strerror(errno)))); + (errmsg("SIGUSR1 handler: write to pipe failed"), + errdetail("%m"))); #endif POOL_SETMASK(&UnBlockSig); @@ -1524,9 +1527,9 @@ static RETSIGTYPE sigusr1_handler(int sig) static void -sigusr1_interupt_processor(void) +sigusr1_interrupt_processor(void) { - ereport(DEBUG1, + ereport(LOG, (errmsg("Pgpool-II parent process received SIGUSR1"))); if (user1SignalSlot->signalFlags[SIG_WATCHDOG_QUORUM_CHANGED]) @@ -1535,7 +1538,7 @@ sigusr1_interupt_processor(void) (errmsg("Pgpool-II parent process received watchdog quorum change signal from watchdog"))); user1SignalSlot->signalFlags[SIG_WATCHDOG_QUORUM_CHANGED] = false; - if (get_watchdog_quorum_state() >= 0) + if (wd_internal_get_watchdog_quorum_state() >= 0) { ereport(LOG, (errmsg("watchdog cluster now holds the quorum"), @@ -1544,12 +1547,12 @@ sigusr1_interupt_processor(void) } } - if (user1SignalSlot->signalFlags[SIG_INFORM_QURANTINE_NODES]) + if (user1SignalSlot->signalFlags[SIG_INFORM_QUARANTINE_NODES]) { ereport(LOG, (errmsg("Pgpool-II parent process received inform quarantine nodes signal from watchdog"))); - user1SignalSlot->signalFlags[SIG_INFORM_QURANTINE_NODES] = false; + user1SignalSlot->signalFlags[SIG_INFORM_QUARANTINE_NODES] = false; degenerate_all_quarantine_nodes(); } @@ -1559,27 +1562,43 @@ sigusr1_interupt_processor(void) (errmsg("Pgpool-II parent process received sync backend signal from watchdog"))); user1SignalSlot->signalFlags[SIG_BACKEND_SYNC_REQUIRED] = false; - if (get_watchdog_local_node_state() == WD_STANDBY) + if (wd_internal_get_watchdog_local_node_state() == WD_STANDBY) { ereport(LOG, - (errmsg("master watchdog has performed failover"), - errdetail("syncing the backend states from the MASTER watchdog node"))); + (errmsg("leader watchdog has performed failover"), + errdetail("syncing the backend states from the LEADER watchdog node"))); sync_backend_from_watchdog(); } } if (user1SignalSlot->signalFlags[SIG_WATCHDOG_STATE_CHANGED]) { - ereport(DEBUG1, + WD_STATES wd_state; + + ereport(LOG, (errmsg("Pgpool-II parent process received watchdog state change signal from watchdog"))); user1SignalSlot->signalFlags[SIG_WATCHDOG_STATE_CHANGED] = false; - if (get_watchdog_local_node_state() == WD_STANDBY) + wd_state = wd_internal_get_watchdog_local_node_state(); + if (wd_state == WD_STANDBY) { ereport(LOG, (errmsg("we have joined the watchdog cluster as STANDBY node"), - errdetail("syncing the backend states from the MASTER watchdog node"))); + errdetail("syncing the backend states from the LEADER watchdog node"))); sync_backend_from_watchdog(); + + /* + * we also want to release the follow_primary lock if it was held + * by the remote node. because the change of watchdog coordinator + * would lead to forever stuck in the the locked state + */ + pool_release_follow_primary_lock(true); + } + else if (wd_state == WD_COORDINATOR && + pool_config->disable_load_balance_on_write == + DLBOW_DML_ADAPTIVE_GLOBAL) + { + pool_track_table_mutation_trigger_global_cold_start(); } } if (user1SignalSlot->signalFlags[SIG_FAILOVER_INTERRUPT]) @@ -1621,32 +1640,22 @@ check_all_backend_down(void) } /* - * backend connection error, failover/failback request, if possible - * failover() must be called under protecting signals. + * The workhorse of failover processing. Directly called with pgpool main + * process or called from sigusr1_interrupt_processor() after SIGUSR1 signal + * is received. */ static void failover(void) { - int i, - j, - k; + FAILOVER_CONTEXT failover_context; int node_id; - int new_master; + int new_main_node; int new_primary = -1; - int nodes[MAX_NUM_BACKENDS]; - bool need_to_restart_children = true; - bool partial_restart = false; - int status; - int sts; - bool need_to_restart_pcp = false; - bool all_backend_down = true; - bool sync_required = false; + int i; ereport(DEBUG1, (errmsg("failover handler called"))); - memset(nodes, 0, sizeof(int) * MAX_NUM_BACKENDS); - /* * this could happen in a child process if a signal has been sent before * resetting signal handler @@ -1682,16 +1691,21 @@ failover(void) return; } + /* initialize failover context */ + memset(&failover_context, 0, sizeof(failover_context)); + failover_context.search_primary = true; + Req_info->switching = true; switching = 1; + + /* + * This loop processes each failover/failback request until the queue is + * empty. + */ for (;;) { - POOL_REQUEST_KIND reqkind; int queue_index; - int node_id_set[MAX_NUM_BACKENDS]; - int node_count; - unsigned char request_details; - bool search_primary = true; + int promote_node = 0; pool_semaphore_lock(REQUEST_INFO_SEM); @@ -1707,17 +1721,17 @@ failover(void) /* make a local copy of request */ Req_info->request_queue_head++; queue_index = Req_info->request_queue_head % MAX_REQUEST_QUEUE_SIZE; - memcpy(node_id_set, Req_info->request[queue_index].node_id, (sizeof(int) * Req_info->request[queue_index].count)); - reqkind = Req_info->request[queue_index].kind; - request_details = Req_info->request[queue_index].request_details; - node_count = Req_info->request[queue_index].count; + memcpy(failover_context.node_id_set, Req_info->request[queue_index].node_id, (sizeof(int) * Req_info->request[queue_index].count)); + failover_context.reqkind = Req_info->request[queue_index].kind; + failover_context.request_details = Req_info->request[queue_index].request_details; + failover_context.node_count = Req_info->request[queue_index].count; pool_semaphore_unlock(REQUEST_INFO_SEM); ereport(DEBUG1, (errmsg("failover handler"), - errdetail("kind: %d flags: %x node_count: %d index:%d", reqkind, request_details, node_count, queue_index))); + errdetail("kind: %d flags: %x node_count: %d index:%d", failover_context.reqkind, failover_context.request_details, failover_context.node_count, queue_index))); - if (reqkind == CLOSE_IDLE_REQUEST) + if (failover_context.reqkind == CLOSE_IDLE_REQUEST) { kill_all_children(SIGUSR1); continue; @@ -1727,113 +1741,37 @@ failover(void) wd_failover_start(); /* - * if not in replication mode/master slave mode, we treat this a - * restart request. otherwise we need to check if we have already - * failovered. + * If not in streaming replication mode/native replication mode, we + * treat this as a restart request. Otherwise we need to check if we + * have already performed the failover. */ ereport(DEBUG1, (errmsg("failover handler"), - errdetail("starting to select new master node"))); - node_id = node_id_set[0]; + errdetail("starting to select new main node"))); - /* failback request? */ - if (reqkind == NODE_UP_REQUEST) + /* + * If this is promoting specified node, new_main_node should be + * replaced by the requested node. The requested node should be + * REAL_PRIMARY_NODE_ID. + */ + if (failover_context.request_details & REQ_DETAIL_PROMOTE) { - if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || - (reqkind == NODE_UP_REQUEST && !(RAW_MODE && - BACKEND_INFO(node_id).backend_status == CON_DOWN) && VALID_BACKEND(node_id)) || - (reqkind == NODE_DOWN_REQUEST && !VALID_BACKEND(node_id))) - { - if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) - ereport(LOG, - (errmsg("invalid failback request, node id: %d is invalid. node id must be between [0 and %d]", node_id, MAX_NUM_BACKENDS))); - else - ereport(LOG, - (errmsg("invalid failback request, status: [%d] of node id : %d is invalid for failback", BACKEND_INFO(node_id).backend_status, node_id))); - - continue; - } - - ereport(LOG, - (errmsg("starting fail back. reconnect host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); - - /* Check to see if all backends are down */ - all_backend_down = check_all_backend_down(); - - BACKEND_INFO(node_id).backend_status = CON_CONNECT_WAIT; /* unset down status */ - pool_set_backend_status_changed_time(node_id); - - if ((request_details & REQ_DETAIL_UPDATE)) + promote_node = failover_context.node_id_set[0]; /* requested node */ + for (i = 0; i < failover_context.node_count; i++) { - /* remove the quarantine flag */ - BACKEND_INFO(node_id).quarantine = false; - - /* - * do not search for primary node when handling the quarantine - * nodes - */ - search_primary = false; - - /* - * recalculate the master node id after setting the backend - * status of quarantined node, this will bring us to the old - * master_node_id that was beofre the quarantine state - */ - Req_info->master_node_id = get_next_master_node(); - if (Req_info->primary_node_id == -1 && - BACKEND_INFO(node_id).role == ROLE_PRIMARY) - { - /* - * if the failback request is for the quarantined node and - * that node had a primary role before it was quarantined, - * restore the primary node status for that node. this is - * important for the failover script to get the proper - * value of old primary - */ - ereport(LOG, - (errmsg("failover: failing back the quarantine node that was primary before it was quarantined"), - errdetail("all children needs a restart"))); - Req_info->primary_node_id = node_id; - - /* - * since we changed the primary node so restart of all - * children is required - */ - need_to_restart_children = true; - partial_restart = false; - } - else if (all_backend_down == false) - { - ereport(LOG, - (errmsg("Do not restart children because we are failing back node id %d host: %s port: %d and we are in streaming replication mode and not all backends were down", node_id, - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); - need_to_restart_children = false; - partial_restart = false; - } - else - { - need_to_restart_children = true; - partial_restart = false; - } + failover_context.node_id_set[i] = REAL_PRIMARY_NODE_ID; } - else - { - /* - * The request is a proper failbak request and not because of - * the update status of quarantined node - */ - (void) write_status_file(); + } - trigger_failover_command(node_id, pool_config->failback_command, - MASTER_NODE_ID, get_next_master_node(), PRIMARY_NODE_ID); - } + node_id = failover_context.node_id_set[0]; /* set target node id */ - sync_required = true; + /* failback request? */ + if (failover_context.reqkind == NODE_UP_REQUEST) + { + if (handle_failback_request(&failover_context, node_id) < 0) + continue; } - else if (reqkind == PROMOTE_NODE_REQUEST) + else if (failover_context.reqkind == PROMOTE_NODE_REQUEST) { if (node_id != -1 && VALID_BACKEND(node_id)) { @@ -1852,66 +1790,18 @@ failover(void) else /* NODE_DOWN_REQUEST && * NODE_QUARANTINE_REQUEST */ { - int cnt = 0; - - for (i = 0; i < node_count; i++) - { - if (node_id_set[i] != -1 && (BACKEND_INFO(node_id_set[i]).quarantine == true || - ((RAW_MODE && VALID_BACKEND_RAW(node_id_set[i])) || - VALID_BACKEND(node_id_set[i])))) - { - ereport(LOG, - (errmsg("starting %s. shutdown host %s(%d)", - (reqkind == NODE_QUARANTINE_REQUEST) ? "quarantine" : "degeneration", - BACKEND_INFO(node_id_set[i]).backend_hostname, - BACKEND_INFO(node_id_set[i]).backend_port))); - - BACKEND_INFO(node_id_set[i]).backend_status = CON_DOWN; /* set down status */ - pool_set_backend_status_changed_time(node_id_set[i]); - if (reqkind == NODE_QUARANTINE_REQUEST) - { - BACKEND_INFO(node_id_set[i]).quarantine = true; - } - else - { - /* - * if the degeneration request is for the quarantined - * node and that node had a primary role before it was - * quarantined, Restore the primary node status for - * that node before degenerating it. This is important - * for the failover script to get the proper valueo of - * old primary - */ - if (Req_info->primary_node_id == -1 && - BACKEND_INFO(node_id_set[i]).quarantine == true && - BACKEND_INFO(node_id_set[i]).role == ROLE_PRIMARY) - { - ereport(DEBUG2, - (errmsg("failover: degenerating the node that was primary node before it was quarantined"))); - Req_info->primary_node_id = node_id_set[i]; - search_primary = false; - } - BACKEND_INFO(node_id_set[i]).quarantine = false; - (void) write_status_file(); - } - - /* save down node */ - nodes[node_id_set[i]] = 1; - cnt++; - } - } - if (cnt == 0) - { - ereport(LOG, - (errmsg("failover: no backends are degenerated"))); + /* process single failover request */ + if (handle_failover_request(&failover_context, node_id) < 0) continue; - } } - new_master = get_next_master_node(); + /* + * Determin new main node. + */ + new_main_node = get_next_main_node(); - if (new_master < 0) + if (new_main_node < 0) { ereport(LOG, (errmsg("failover: no valid backend node found"))); @@ -1919,569 +1809,487 @@ failover(void) ereport(DEBUG1, (errmsg("failover/failback request details: STREAM: %d reqkind: %d detail: %x node_id: %d", - STREAM, reqkind, request_details & REQ_DETAIL_SWITCHOVER, + STREAM, failover_context.reqkind, failover_context.request_details & REQ_DETAIL_SWITCHOVER, node_id))); /* - * On 2011/5/2 Tatsuo Ishii says: if mode is streaming replication and - * request is NODE_UP_REQUEST (failback case) we don't need to restart - * all children. Existing session will not use newly attached node, - * but load balanced node is not changed until this session ends, so - * it's harmless anyway. + * Kill child process to prepare failover/failback. */ + kill_failover_children(&failover_context, node_id); /* - * On 2015/9/21 Tatsuo Ishii says: this judgment is not sufficient if - * all backends were down. Child process has local status in which all - * backends are down. In this case even if new connection arrives from - * frontend, the child will not accept it because the local status - * shows all backends are down. For this purpose we refer to - * "all_backend_down" variable, which was set before updating backend - * status. - * - * See bug 248 for more details. + * Exec failover_command if needed. We do not execute failover when + * request is quarantine type. Also if the request is to promote + * specified node, execute failover command. */ + exec_failover_command(&failover_context, new_main_node, promote_node); - if (STREAM && reqkind == NODE_UP_REQUEST && all_backend_down == false) - { - /* - * The decision to restart/no-restart children for update status - * request has already been made - */ - if (!(request_details & REQ_DETAIL_UPDATE)) - { - ereport(LOG, - (errmsg("Do not restart children because we are failing back node id %d host: %s port: %d and we are in streaming replication mode and not all backends were down", node_id, - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); - - need_to_restart_children = false; - partial_restart = false; - } - } + /* + * Determine new primary node id. Possibly call + * find_primary_node_repeatedly(). + */ + new_primary = determine_new_primary_node(&failover_context, node_id); /* - * If the mode is streaming replication and the request is - * NODE_DOWN_REQUEST and it's actually a switch over request, we don't - * need to restart all children, except the node is primary. + * If follow_primary_command is provided and in streaming replication + * mode, we start degenerating all backends as they are not replicated + * anymore. */ - else if (STREAM && (reqkind == NODE_DOWN_REQUEST || reqkind == NODE_QUARANTINE_REQUEST) && - request_details & REQ_DETAIL_SWITCHOVER && node_id != PRIMARY_NODE_ID) - { - ereport(LOG, - (errmsg("Do not restart children because we are switching over node id %d host: %s port: %d and we are in streaming replication mode", node_id, - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + i = exec_follow_primary_command(&failover_context, node_id, new_primary); - need_to_restart_children = true; - partial_restart = true; + /* if follow primary command was executed, main node can be changed */ + if (i >= 0) + new_main_node = i; - for (i = 0; i < pool_config->num_init_children; i++) - { - bool restart = false; + /* + * Now new primary node and new main node are established. Save them + * into shared memory. Also update status changed time. + */ + save_node_info(&failover_context, new_primary, new_main_node); - for (j = 0; j < pool_config->max_pool; j++) - { - for (k = 0; k < NUM_BACKENDS; k++) - { - ConnectionInfo *con = pool_coninfo(i, j, k); + /* Kill children and restart them if needed */ + exec_child_restart(&failover_context, node_id); + } - if (con->connected && con->load_balancing_node == node_id) - { - ereport(LOG, - (errmsg("child pid %d needs to restart because pool %d uses backend %d", - process_info[i].pid, j, node_id))); - restart = true; - break; - } - } - } + /* + * We are almost done. Unlock flags. + */ + pool_semaphore_lock(REQUEST_INFO_SEM); + switching = 0; + Req_info->switching = false; + pool_semaphore_unlock(REQUEST_INFO_SEM); - if (restart) - { - pid_t pid = process_info[i].pid; + /* + * kick wakeup_handler in pcp_child to notice that failover/failback done. + */ + exec_notice_pcp_child(&failover_context); +} - if (pid) - { - kill(pid, SIGQUIT); - ereport(DEBUG1, - (errmsg("failover handler"), - errdetail("kill process with PID:%d", pid))); - } - } - } - } - else - { - ereport(LOG, - (errmsg("Restart all children"))); +/* + * handle SIGCHLD + */ +static RETSIGTYPE reap_handler(int sig) +{ + int save_errno = errno; - /* kill all children */ - for (i = 0; i < pool_config->num_init_children; i++) - { - pid_t pid = process_info[i].pid; + POOL_SETMASK(&BlockSig); + sigchld_request = 1; - if (pid) - { - kill(pid, SIGQUIT); - ereport(DEBUG1, - (errmsg("failover handler"), - errdetail("kill process with PID:%d", pid))); - } - } + if (pipe_fds[1]) + { + dummy_status = write(pipe_fds[1], "\0", 1); + } - need_to_restart_children = true; - partial_restart = false; - } +#ifdef NOT_USED + if (pipe_fds[1] && write(pipe_fds[1], "\0", 1) < 0) + ereport(WARNING, + (errmsg("reap_handler: write to pipe failed"), + errdetail("%m"))); +#endif - /* - * Exec failover_command if needed We do not execute failover when - * request is quarantine type - */ - if (reqkind == NODE_DOWN_REQUEST) - { - for (i = 0; i < pool_config->backend_desc->num_backends; i++) - { - if (nodes[i]) - { - trigger_failover_command(i, pool_config->failover_command, - MASTER_NODE_ID, new_master, REAL_PRIMARY_NODE_ID); - sync_required = true; - } - } - } + POOL_SETMASK(&UnBlockSig); - if (reqkind == PROMOTE_NODE_REQUEST && VALID_BACKEND(node_id)) - { - new_primary = node_id; - } - else if (reqkind == NODE_QUARANTINE_REQUEST) - { - /* - * if the quarantine node was the primary node set the newprimary - * to -1 (invalid) - */ - if (Req_info->primary_node_id == node_id) - { - /* - * set the role of the node, This will help us restore the - * primary node id when the node will come out from quarantine - * state - */ - BACKEND_INFO(node_id).role = ROLE_PRIMARY; - new_primary = -1; - } - else if (SL_MODE) - { - new_primary = Req_info->primary_node_id; - } - } + errno = save_errno; +} + +/* + * pool_waitpid: + * nothing more than a wrapper function over NOHANG mode waitpid() or wait3() + * depending on the existence of waitpid in the system + */ +pid_t +pool_waitpid(int *status) +{ +#ifdef HAVE_WAITPID + return waitpid(-1, status, WNOHANG); +#else + return wait3(status, WNOHANG, NULL); +#endif +} + +/* + * process_name_from_pid() + * helper function for reaper() to report the terminating child process type name + */ +static char * +process_name_from_pid(pid_t pid) +{ + if (pid == pcp_pid) + return "PCP child"; + if (pid == worker_pid) + return "worker child"; + if (pool_config->use_watchdog) + { + if (pid == watchdog_pid) + return "watchdog child"; + else if (pid == wd_lifecheck_pid) + return "watchdog lifecheck"; + } + if (pid == pgpool_logger_pid) + return "pgpool log collector"; + return "child"; +} + +/* + * Attach zombie processes and restart child processes. + * reaper() must be called protected from signals. + * Note: + * In pgpool child can exit in two ways, either by some signal or by + * calling exit() system function. + * For the case of child terminating due to a signal the reaper() function + * always forks a new respective type of child process. But for the case when + * child got terminated by exit() system call than the function checks the exit + * code and if the child was exited by POOL_EXIT_FATAL than we do not restarts the + * terminating child but shutdowns the pgpool-II. This allow + * the child process to inform parent process of fatal failures which needs + * to be rectified (e.g startup failure) by user for smooth running of system. + * Also the child exits with success status POOL_EXIT_NO_RESTART does not gets + * restarted. + */ +static void +reaper(void) +{ + pid_t pid; + int status; + int i; + + ereport(DEBUG1, + (errmsg("reaper handler"))); + + if (exiting) + { + ereport(DEBUG1, + (errmsg("reaper handler: exited because already in exiting mode"))); + return; + } + + if (switching) + { + ereport(DEBUG1, + (errmsg("reaper handler: exited due to switching"))); + return; + } + + /* clear SIGCHLD request */ + sigchld_request = 0; + + while ((pid = pool_waitpid(&status)) > 0) + { + pid_t new_pid = 0; + bool shutdown_system = false; + bool restart_child = true; + bool found = false; + char *exiting_process_name = process_name_from_pid(pid); + bool process_health_check = false; /* - * If the down node was a standby node in streaming replication mode, - * we can avoid calling find_primary_node_repeatedly() and recognize - * the former primary as the new primary node, which will reduce the - * time to process standby down. + * Check if the terminating child wants pgpool main to go down with it */ - else if (SL_MODE && - reqkind == NODE_DOWN_REQUEST) + if (WIFEXITED(status)) { - if (Req_info->primary_node_id != node_id) + if (WEXITSTATUS(status) == POOL_EXIT_FATAL) { - new_primary = Req_info->primary_node_id; + ereport(DEBUG1, + (errmsg("%s process with pid: %d exit with FATAL ERROR. pgpool-II will be shutdown", exiting_process_name, pid))); + shutdown_system = true; } - else + else if (WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) { - if (Req_info->primary_node_id >= 0) - BACKEND_INFO(Req_info->primary_node_id).role = ROLE_STANDBY; - new_primary = find_primary_node_repeatedly(); + ereport(DEBUG1, + (errmsg("%s process with pid: %d exit with SUCCESS. child will not be restarted", exiting_process_name, pid))); + + restart_child = false; } } - else if (search_primary == false) - { - ereport(DEBUG1, - (errmsg("faliover was called on quarantined node. No need to search for primary node"))); - new_primary = Req_info->primary_node_id; - } - else + if (WIFSIGNALED(status)) { - new_primary = find_primary_node_repeatedly(); - } - - /* - * If follow_master_command is provided and in master/slave streaming - * replication mode, we start degenerating all backends as they are - * not replicated anymore. - */ - int follow_cnt = 0; + /* Child terminated by segmentation fault or sigkill. Report it */ + if (WTERMSIG(status) == SIGSEGV) + ereport(WARNING, + (errmsg("%s process with pid: %d was terminated by segmentation fault", exiting_process_name, pid))); + else if (WTERMSIG(status) == SIGKILL) + ereport(WARNING, + (errmsg("%s process with pid: %d was terminated by sigkill", exiting_process_name, pid))); + else + ereport(DEBUG1, + (errmsg("%s process with pid: %d exits with status %d by signal %d", exiting_process_name, pid, status, WTERMSIG(status)))); - if (STREAM) - { - if (*pool_config->follow_master_command != '\0' || - reqkind == PROMOTE_NODE_REQUEST) + /* + * If the watchdog process was terminated abnormally. we need to + * set the cleanup flag so that the new watchdog process can start + * without problems + */ + if (pool_config->use_watchdog && pid == watchdog_pid) { - /* only if the failover is against the current primary */ - if (((reqkind == NODE_DOWN_REQUEST) && - (nodes[Req_info->primary_node_id])) || - ((reqkind == PROMOTE_NODE_REQUEST) && - (VALID_BACKEND(node_id)))) - { - - for (i = 0; i < pool_config->backend_desc->num_backends; i++) - { - /* do not degenerate the new primary */ - if ((new_primary >= 0) && (i != new_primary)) - { - BackendInfo *bkinfo; - - bkinfo = pool_get_node_info(i); - ereport(LOG, - (errmsg("starting follow degeneration. shutdown host %s(%d)", - bkinfo->backend_hostname, - bkinfo->backend_port))); - bkinfo->backend_status = CON_DOWN; /* set down status */ - pool_set_backend_status_changed_time(i); - (void) write_status_file(); - - follow_cnt++; - } - } - - if (follow_cnt == 0) - { - ereport(LOG, - (errmsg("failover: no follow backends are degenerated"))); - } - else - { - /* update new master node */ - new_master = get_next_master_node(); - ereport(LOG, - (errmsg("failover: %d follow backends have been degenerated", follow_cnt))); - } - } + set_watchdog_process_needs_cleanup(); } } + else + ereport(DEBUG1, + (errmsg("%s process with pid: %d exits with status %d", exiting_process_name, pid, status))); - if ((follow_cnt > 0) && (*pool_config->follow_master_command != '\0')) + /* if exiting child process was PCP handler */ + if (pid == pcp_pid) { - follow_pid = fork_follow_child(Req_info->master_node_id, new_primary, - Req_info->primary_node_id); + found = true; + if (restart_child) + { + pcp_pid = pcp_fork_a_child(pcp_fds, pcp_conf_file); + new_pid = pcp_pid; + } + else + pcp_pid = 0; } - /* Save primary node id */ - if (Req_info->primary_node_id != new_primary) + /* exiting process was worker process */ + else if (pid == worker_pid) { - if (Req_info->primary_node_id >= 0) + found = true; + if (restart_child) { - pool_set_backend_status_changed_time(Req_info->primary_node_id); + worker_pid = worker_fork_a_child(PT_WORKER, do_worker_child, NULL); + new_pid = worker_pid; } - if (new_primary >= 0) + else + worker_pid = 0; + } + else if (pid == pgpool_logger_pid) + { + if (restart_child) { - BACKEND_INFO(new_primary).role = ROLE_PRIMARY; - pool_set_backend_status_changed_time(new_primary); + pgpool_logger_pid = SysLogger_Start(); } + else + pgpool_logger_pid = 0; } - Req_info->primary_node_id = new_primary; - ereport(LOG, - (errmsg("failover: set new primary node: %d", Req_info->primary_node_id))); - if (new_master >= 0) + /* exiting process was follow child process */ + else if (pid == follow_pid) { - Req_info->master_node_id = new_master; - sync_required = true; - ereport(LOG, - (errmsg("failover: set new master node: %d", Req_info->master_node_id))); + follow_pid = 0; } - - /* Kill children and restart them if needed */ - if (need_to_restart_children) + /* exiting process was watchdog process */ + else if (pool_config->use_watchdog) { - for (i = 0; i < pool_config->num_init_children; i++) + if (watchdog_pid == pid) { - /* - * Try to kill pgpool child because previous kill signal may - * not be received by pgpool child. This could happen if - * multiple PostgreSQL are going down (or even starting - * pgpool, without starting PostgreSQL can trigger this). - * Child calls degenerate_backend() and it tries to aquire - * semaphore to write a failover request. In this case the - * signal mask is set as well, thus signals are never - * received. - */ - - bool restart = false; - - if (partial_restart) + found = true; + if (restart_child) { - for (j = 0; j < pool_config->max_pool; j++) - { - for (k = 0; k < NUM_BACKENDS; k++) - { - ConnectionInfo *con = pool_coninfo(i, j, k); - - if (con->connected && con->load_balancing_node == node_id) - { - - ereport(LOG, - (errmsg("child pid %d needs to restart because pool %d uses backend %d", - process_info[i].pid, j, node_id))); - restart = true; - break; - } - } - } + watchdog_pid = initialize_watchdog(); + new_pid = watchdog_pid; } else - restart = true; - - if (restart) + watchdog_pid = 0; + } + else if (wd_lifecheck_pid == pid) + { + found = true; + if (restart_child) { - if (process_info[i].pid) - { - kill(process_info[i].pid, SIGQUIT); - - process_info[i].pid = fork_a_child(fds, i); - process_info[i].start_time = time(NULL); - } + wd_lifecheck_pid = initialize_watchdog_lifecheck(); + new_pid = wd_lifecheck_pid; } else - process_info[i].need_to_restart = 1; + wd_lifecheck_pid = 0; } } - else + /* + * we are not able to identify the exiting process yet. check if the + * exiting process was child process (handling PG clients) + */ + if (found == false) { - /* - * Set restart request to each child. Children will exit(1) - * whenever they are convenient. - */ + /* look for exiting child's pid */ for (i = 0; i < pool_config->num_init_children; i++) { - process_info[i].need_to_restart = 1; + if (pid == process_info[i].pid) + { + found = true; + /* if found, fork a new child */ + if (!switching && !exiting && restart_child && + pool_config->process_management != PM_DYNAMIC) + { + process_info[i].pid = fork_a_child(fds, i); + process_info[i].start_time = time(NULL); + new_pid = process_info[i].pid; + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; + process_info[i].connected = 0; + process_info[i].wait_for_connect = 0; + } + else + { + current_child_process_count--; + process_info[i].pid = 0; + } + break; + } } } - /* - * Send restart request to worker child. - */ - kill(worker_pid, SIGUSR1); - - if (sync_required) - wd_failover_end(); - - if (reqkind == NODE_UP_REQUEST) + /* Check health check process */ + if (found == false) { - ereport(LOG, - (errmsg("failback done. reconnect host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + process_health_check = true; - /* Fork health check process if needed */ for (i = 0; i < NUM_BACKENDS; i++) { - if (health_check_pids[i] == 0) + if (pid == health_check_pids[i]) { - ereport(LOG, - (errmsg("start health check process for host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + found = true; - health_check_pids[i] = worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); + /* Fork new health check worker */ + if (!switching && !exiting && VALID_BACKEND(i)) + { + health_check_pids[i] = worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); + } + else + health_check_pids[i] = 0; } } } - else if (reqkind == PROMOTE_NODE_REQUEST) + + if (shutdown_system) + ereport(FATAL, + (errmsg("%s process exit with fatal error. exiting pgpool-II", exiting_process_name))); + + else if (restart_child && new_pid) { - ereport(LOG, - (errmsg("promotion done. promoted host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + /* Report if the child was restarted */ + ereport(DEBUG1, + (errmsg("fork a new %s process with pid: %d", exiting_process_name, new_pid))); } else { - /* - * Temporary black magic. Without this regression 055 does not - * finish - */ - fprintf(stderr, "%s done. shutdown host %s(%d)", - (reqkind == NODE_DOWN_REQUEST) ? "failover" : "quarantine", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port); - - ereport(LOG, - (errmsg("%s done. shutdown host %s(%d)", - (reqkind == NODE_DOWN_REQUEST) ? "failover" : "quarantine", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); - } - need_to_restart_pcp = true; - } - switching = 0; - Req_info->switching = false; - - /* - * kick wakeup_handler in pcp_child to notice that failover/failback done - */ - kill(pcp_pid, SIGUSR2); - - if (need_to_restart_pcp) - { - sleep(1); - - /* - * Send restart request to pcp child. - */ - kill(pcp_pid, SIGUSR1); - for (;;) - { - sts = waitpid(pcp_pid, &status, 0); - if (sts != -1) - break; - if (sts == -1) + if (process_health_check == false) { - if (errno == EINTR) - continue; - else - { - ereport(WARNING, - (errmsg("failover: waitpid failed. reason: %s", strerror(errno)))); - continue; - } + /* And the child was not restarted */ + ereport(LOG, + (errmsg("%s process with pid: %d exited with success and will not be restarted", exiting_process_name, pid))); } } - if (WIFSIGNALED(status)) - ereport(LOG, - (errmsg("PCP child %d exits with status %d by signal %d in failover()", pcp_pid, status, WTERMSIG(status)))); - else - ereport(LOG, - (errmsg("PCP child %d exits with status %d in failover()", pcp_pid, status))); - pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file); - ereport(LOG, - (errmsg("fork a new PCP child pid %d in failover()", pcp_pid))); } + ereport(DEBUG1, + (errmsg("reaper handler: exiting normally"))); } -#ifdef NOT_USED /* - * health check timer handler + * get node information specified by node_number */ -static RETSIGTYPE health_check_timer_handler(int sig) +BackendInfo * +pool_get_node_info(int node_number) { - int save_errno = errno; + if (node_number < 0 || node_number >= NUM_BACKENDS) + return NULL; - POOL_SETMASK(&BlockSig); - health_check_timer_expired = 1; - POOL_SETMASK(&UnBlockSig); - errno = save_errno; + return &BACKEND_INFO(node_number); } /* - * do_health_check() performs the health check on all backend nodes. - * The inout parameter health_check_node_id is the starting backend - * node number for health check and when the function returns or - * exits with an error health_check_node_id contains the value - * of last backend node number on which health check was performed. - * - * Function returns false if all backend nodes are down and true if all - * backend nodes are in healthy state + * get number of nodes */ -static bool -do_health_check(bool use_template_db, volatile int *health_check_node_id) +int +pool_get_node_count(void) { - POOL_CONNECTION_POOL_SLOT *slot; - BackendInfo *bkinfo; - static char *dbname; - int i; - bool all_nodes_healthy = false; - char *password = get_pgpool_config_user_password(pool_config->health_check_user, - pool_config->health_check_password); - - /* Do not execute health check during recovery */ - if (*InRecovery) - return false; - - if (!strcmp(pool_config->health_check_database, "")) - dbname = use_template_db ? "template1" : "postgres"; - else - dbname = pool_config->health_check_database; + return NUM_BACKENDS; +} - ereport(DEBUG1, - (errmsg("doing health check against database:%s user:%s", - dbname, pool_config->health_check_user))); +/* + * get process ids + */ +int * +pool_get_process_list(int *array_size) +{ + int *array; + int cnt = 0; + int i; - /* - * Start checking the backed nodes starting from the previously failed - * node - */ - for (i = *health_check_node_id; i < pool_config->backend_desc->num_backends; i++) + for (i = 0; i < pool_config->num_init_children; i++) { - *health_check_node_id = i; - - /* - * Make sure that health check timer has not been expired. Before - * called health_check(), health_check_timer_expired is set to 0. - * However it is possible that while processing DB nodes health check - * timer expired. - */ - if (health_check_timer_expired) + if (process_info[i].pid != 0) + cnt++; + } + *array_size = cnt; + cnt = 0; + array = palloc0(*array_size * sizeof(int)); + for (i = 0; i < pool_config->num_init_children || cnt < *array_size; i++) + { + if (process_info[i].pid != 0) { - ereport(ERROR, - (errmsg("health check timer has been already expired before attempting to connect backend node %d", i))); + array[cnt] = process_info[i].pid; + cnt++; } + } - bkinfo = pool_get_node_info(i); + return array; +} - ereport(DEBUG1, - (errmsg("Backend DB node %d status is %d", i, bkinfo->backend_status))); +/* + * get process information specified by pid + */ +ProcessInfo * +pool_get_process_info(pid_t pid) +{ + int i; + for (i = 0; i < pool_config->num_init_children; i++) + if (process_info[i].pid == pid) + return &process_info[i]; - if (bkinfo->backend_status == CON_UNUSED || - bkinfo->backend_status == CON_DOWN) - continue; + return NULL; +} - all_nodes_healthy = true; - ereport(DEBUG1, - (errmsg("Trying to make persistent DB connection to backend node %d having status %d", i, bkinfo->backend_status))); +/* + * handle SIGUSR2 + * Wakeup all processes + */ +static void +wakeup_children(void) +{ + kill_all_children(SIGUSR2); +} - slot = make_persistent_db_connection(i, bkinfo->backend_hostname, - bkinfo->backend_port, - dbname, - pool_config->health_check_user, - password ? password : "", false); - ereport(DEBUG1, - (errmsg("persistent DB connection to backend node %d having status %d is successful", i, bkinfo->backend_status))); +static RETSIGTYPE wakeup_handler(int sig) +{ + int save_errno = errno; - discard_persistent_db_connection(slot); + wakeup_request = 1; + if (processState != INITIALIZING) + { + POOL_SETMASK(&BlockSig); + dummy_status = write(pipe_fds[1], "\0", 1); +#ifdef NOT_USED + if (write(pipe_fds[1], "\0", 1) < 0) + ereport(WARNING, + (errmsg("wakeup_handler: write to pipe failed"), + errdetail("%m"))); +#endif + POOL_SETMASK(&UnBlockSig); } - if (password) - pfree(password); - return all_nodes_healthy; + errno = save_errno; } -#endif /* - * handle SIGCHLD + * handle SIGHUP + * */ -static RETSIGTYPE reap_handler(int sig) +static RETSIGTYPE reload_config_handler(int sig) { int save_errno = errno; POOL_SETMASK(&BlockSig); - sigchld_request = 1; - - if (pipe_fds[1]) - { - write(pipe_fds[1], "\0", 1); - } - + reload_config_request = 1; + dummy_status = write(pipe_fds[1], "\0", 1); #ifdef NOT_USED - if (pipe_fds[1] && write(pipe_fds[1], "\0", 1) < 0) + if (write(pipe_fds[1], "\0", 1) < 0) ereport(WARNING, - (errmsg("reap_handler: write to pipe failed with error \"%s\"", strerror(errno)))); + (errmsg("reload_config_handler: write to pipe failed"), + errdetail("%m"))); #endif POOL_SETMASK(&UnBlockSig); @@ -2489,1880 +2297,3122 @@ static RETSIGTYPE reap_handler(int sig) errno = save_errno; } -/* - * pool_waitpid: - * nothing more than a wrapper function over NOHANG mode waitpid() or wait3() - * depending on the existance of waitpid in the system - */ -pid_t -pool_waitpid(int *status) -{ -#ifdef HAVE_WAITPID - return waitpid(-1, status, WNOHANG); -#else - return wait3(status, WNOHANG, NULL); -#endif -} - -/* - * process_name_from_pid() - * helper function for reaper() to report the terminating child process type name - */ -static char * -process_name_from_pid(pid_t pid) -{ - if (pid == pcp_pid) - return "PCP child"; - if (pid == worker_pid) - return "worker child"; - if (pool_config->use_watchdog) - { - if (pid == watchdog_pid) - return "watchdog child"; - else if (pid == wd_lifecheck_pid) - return "watchdog lifecheck"; - } - return "child"; -} - -/* - * Attach zombie processes and restart child processes. - * reaper() must be called protected from signals. - * Note: - * In pgpool child can exit in two ways, either by some signal or by - * calling exit() system function. - * For the case of child terminating due to a signal the reaper() function - * always forks a new respective type of child process. But for the case when - * child got terminated by exit() system call than the function checks the exit - * code and if the child was exited by POOL_EXIT_FATAL than we do not restarts the - * terminating child but shutdowns the pgpool-II. This allow - * the child process to inform parent process of fatal failures which needs - * to be rectified (e.g startup failure) by user for smooth running of system. - * Also the child exits with success status POOL_EXIT_NO_RESTART does not gets - * restarted. - */ static void -reaper(void) +kill_all_children(int sig) { - pid_t pid; - int status; int i; - ereport(DEBUG1, - (errmsg("reaper handler"))); - - if (exiting) + if (process_info) { - ereport(DEBUG1, - (errmsg("reaper handler: exited because already in exiting mode"))); - return; - } + /* kill all children */ + for (i = 0; i < pool_config->num_init_children; i++) + { + pid_t pid = process_info[i].pid; - if (switching) - { - ereport(DEBUG1, - (errmsg("reaper handler: exited due to switching"))); - return; + if (pid) + { + kill(pid, sig); + } + } } - /* clear SIGCHLD request */ - sigchld_request = 0; - - while ((pid = pool_waitpid(&status)) > 0) + if (sig == SIGHUP) { - pid_t new_pid = 0; - bool shutdown_system = false; - bool restart_child = true; - bool found = false; - char *exiting_process_name = process_name_from_pid(pid); + /* make PCP process reload as well */ + if (pcp_pid > 0) + kill(pcp_pid, sig); - /* - * Check if the terminating child wants pgpool main to go down with it - */ - if (WIFEXITED(status)) + /* make health check process reload as well */ + for (i = 0; i < NUM_BACKENDS; i++) { - if (WEXITSTATUS(status) == POOL_EXIT_FATAL) + if (health_check_pids[i] > 0) + kill(health_check_pids[i], sig); + } + + /* make worker process reload as well */ + if (worker_pid > 0) + kill(worker_pid, sig); + + /* make watchdog process reload as well */ + if (watchdog_pid > 0) + kill(watchdog_pid, sig); + + /* make logger process reload as well */ + if (pgpool_logger_pid > 0) + kill(pgpool_logger_pid, sig); + } +} + +/* + * pause in a period specified by timeout. If any data is coming + * through pipe_fds[0], that means one of: failover request(SIGUSR1), + * SIGCHLD received, children wake up request(SIGUSR2 used in on line + * recovery processing) or config file reload request(SIGHUP) has been + * occurred. In this case this function returns 1. + * otherwise 0: (no signal event occurred), -1: (error) + * XXX: is it OK that select(2) error is ignored here? + */ +static int +pool_pause(struct timeval *timeout) +{ + fd_set rfds; + int n; + char dummy; + + FD_ZERO(&rfds); + FD_SET(pipe_fds[0], &rfds); + n = select(pipe_fds[0] + 1, &rfds, NULL, NULL, timeout); + if (n == 1) + { + if (read(pipe_fds[0], &dummy, 1) < 0) + ereport(WARNING, + (errmsg("pool_pause: read on pipe failed"), + errdetail("%m"))); + } + return n; +} + +/* + * sleep for seconds specified by "second". Unlike pool_pause(), this + * function guarantees that it will sleep for specified seconds. This + * function uses pool_pause() internally. If it informs that there is + * a pending signal event, they are processed using CHECK_REQUEST + * macro. Note that most of these processes are done while all signals + * are blocked. + */ +void +pool_sleep(unsigned int second) +{ + struct timeval current_time, + sleep_time; + + gettimeofday(¤t_time, NULL); + sleep_time.tv_sec = second + current_time.tv_sec; + sleep_time.tv_usec = current_time.tv_usec; + + POOL_SETMASK(&UnBlockSig); + while (sleep_time.tv_sec > current_time.tv_sec) + { + struct timeval timeout; + int r; + + timeout.tv_sec = sleep_time.tv_sec - current_time.tv_sec; + timeout.tv_usec = sleep_time.tv_usec - current_time.tv_usec; + if (timeout.tv_usec < 0) + { + timeout.tv_sec--; + timeout.tv_usec += 1000000; + } + + r = pool_pause(&timeout); + POOL_SETMASK(&BlockSig); + if (r > 0) + check_requests(); + POOL_SETMASK(&UnBlockSig); + gettimeofday(¤t_time, NULL); + } + POOL_SETMASK(&BlockSig); +} + +/* + * trigger_failover_command: execute specified command at failover. + * command_line is null-terminated string. + */ +static int +trigger_failover_command(int node, const char *command_line, + int old_main_node, int new_main_node, int old_primary) +{ + int r = 0; + StringInfoData exec_cmd_data; + StringInfo exec_cmd = &exec_cmd_data; + BackendInfo *info; + BackendInfo *newmain; + BackendInfo *oldprimary; + + if (command_line == NULL || (strlen(command_line) == 0)) + return 0; + + /* check failed nodeID */ + if (node < 0 || node >= NUM_BACKENDS) + return -1; + + info = pool_get_node_info(node); + if (!info) + return -1; + + initStringInfo(exec_cmd); + + while (*command_line) + { + if (*command_line == '%') + { + if (*(command_line + 1)) { - ereport(DEBUG1, - (errmsg("%s process with pid: %d exit with FATAL ERROR. pgpool-II will be shutdown", exiting_process_name, pid))); - shutdown_system = true; + char val = *(command_line + 1); + + switch (val) + { + case 'p': /* failed node port */ + appendStringInfo(exec_cmd, " %d", info->backend_port); + break; + + case 'D': /* failed node database directory */ + appendStringInfoString(exec_cmd, info->backend_data_directory); + break; + + case 'd': /* failed node id */ + appendStringInfo(exec_cmd, " %d", node); + break; + + case 'h': /* failed host name */ + appendStringInfoString(exec_cmd, info->backend_hostname); + break; + + case 'H': /* new main host name */ + newmain = pool_get_node_info(new_main_node); + if (newmain) + appendStringInfoString(exec_cmd, newmain->backend_hostname); + else + /* no valid new main */ + appendStringInfoString(exec_cmd, "\"\""); + break; + + case 'm': /* new main node id */ + appendStringInfo(exec_cmd, " %d", new_main_node); + break; + + case 'r': /* new main node port */ + newmain = pool_get_node_info(new_main_node); + if (newmain) + appendStringInfo(exec_cmd, "%d", newmain->backend_port); + else + /* no valid new main node */ + appendStringInfoString(exec_cmd, "\"\""); + break; + + case 'R': /* new main database directory */ + newmain = pool_get_node_info(new_main_node); + if (newmain) + appendStringInfoString(exec_cmd, newmain->backend_data_directory); + else + /* no valid new main */ + appendStringInfoString(exec_cmd, "\"\""); + break; + + case 'M': /* old main node id */ + appendStringInfo(exec_cmd, "%d", old_main_node); + break; + + case 'P': /* old primary node id */ + appendStringInfo(exec_cmd, "%d", old_primary); + break; + + case 'N': /* old primary host name */ + oldprimary = pool_get_node_info(old_primary); + if (oldprimary) + appendStringInfoString(exec_cmd, oldprimary->backend_hostname); + else + /* no valid old primary */ + appendStringInfoString(exec_cmd, "\"\""); + break; + + case 'S': /* old primary port */ + oldprimary = pool_get_node_info(old_primary); + if (oldprimary) + appendStringInfo(exec_cmd, "%d", oldprimary->backend_port); + else + /* no valid old primary */ + appendStringInfoString(exec_cmd, "\"\""); + break; + + case '%': /* escape */ + appendStringInfoString(exec_cmd, "%"); + break; + + default: /* ignore */ + break; + } + command_line++; } - else if (WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) + } + else + appendStringInfoChar(exec_cmd, *command_line); + + command_line++; + } + + if (strlen(exec_cmd->data) != 0) + { + ereport(LOG, + (errmsg("execute command: %s", exec_cmd->data))); + r = system(exec_cmd->data); + } + + pfree(exec_cmd->data); + + return r; +} + +/* + * This function is used by find_primary_node(). Find primary node/standby + * node and returns static array of status for each backend node. This + * function must not throw ERROR or FATAL. + */ +static POOL_NODE_STATUS pool_node_status[MAX_NUM_BACKENDS]; + +POOL_NODE_STATUS * +verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) +{ + POOL_SELECT_RESULT *res; + int num_primaries = 0; + int num_standbys = 0; + int i, + j; + BackendInfo *backend_info; + + for (i = 0; i < NUM_BACKENDS; i++) + { + pool_node_status[i] = POOL_NODE_STATUS_UNUSED; + + if (!VALID_BACKEND(i)) + continue; + + if (!slots[i]) + continue; + + if (get_query_result(slots, i, "SELECT pg_catalog.pg_is_in_recovery()", &res)) + { + continue; + } + + get_server_version(slots, i); + + if (res->data[0] && !strcmp(res->data[0], "t")) + { + /* Possibly standby */ + pool_node_status[i] = POOL_NODE_STATUS_STANDBY; + num_standbys++; + } + else if (res->data[0] && !strcmp(res->data[0], "f")) + { + /* Possibly primary */ + pool_node_status[i] = POOL_NODE_STATUS_PRIMARY; + num_primaries++; + } + free_select_result(res); + } + + /* + * If there's no primary node, there's no point to run additional + * testings. + */ + if (num_primaries == 0) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: there's no primary node"))); + return pool_node_status; + } + + /* + * There's no standby node. + */ + if (num_standbys == 0) + { + if (num_primaries == 1) + { + /* + * If there's only one primary node and there's no standby, + * there's no point to run additional testings. + */ + ereport(DEBUG1, + (errmsg("verify_backend_node_status: there's no standby node"))); + return pool_node_status; + } + else + { + /* + * There are multiple primaries and there's no standby node. + * There's no way to decide which one is correct. We just leave + * the youngest primary node and detach rests if allowed. + */ + for (i = 0; i < NUM_BACKENDS; i++) { - ereport(DEBUG1, - (errmsg("%s process with pid: %d exit with SUCCESS. child will not be restarted", exiting_process_name, pid))); + if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: decided node %d is the true primary", i))); + i++; + for (; i < NUM_BACKENDS; i++) + { + if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) + { + if (pool_config->detach_false_primary) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: node %d is a false primary", i))); + pool_node_status[i] = POOL_NODE_STATUS_INVALID; + } + else + pool_node_status[i] = POOL_NODE_STATUS_UNUSED; + } + } + } + } + } + return pool_node_status; + } + + /* + * There are multiple standbys + */ + else + { + bool check_connectivity = false; + int wal_receiver_status = 0; + int wal_receiver_conninfo = 1; + char host[MAX_DB_HOST_NAMELEN]; + char port[1024]; + int primary[MAX_NUM_BACKENDS]; + int true_primary = -1; + + ereport(DEBUG1, + (errmsg("verify_backend_node_status: multiple standbys: %d", num_standbys))); + + if (!pool_config->detach_false_primary) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: detach_false_primary is off and no additional checking is performed"))); + return pool_node_status; + } + + /* + * Check connectivity between primary and standby by using + * pg_stat_wal_receiver (only >= 9.6.0) if there's more than or equal + * to 1 primary. + */ + for (i = 0; i < NUM_BACKENDS; i++) + { + if (!VALID_BACKEND(i)) + continue; + + if (!slots[i]) + continue; + + if (get_server_version(slots, i) >= 90600) + { + check_connectivity = true; + break; + } + } + if (!check_connectivity) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: server version is lower than 9.6.0. Skipping connectivity checks"))); + return pool_node_status; + } + + ereport(DEBUG1, + (errmsg("verify_backend_node_status: checking connectivity"))); + + for (i = 0; i < NUM_BACKENDS; i++) + { + primary[i] = 0; + + if (!VALID_BACKEND(i)) + continue; + + if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: %d is primary", i))); + + for (j = 0; j < NUM_BACKENDS; j++) + { + if (pool_node_status[j] == POOL_NODE_STATUS_STANDBY && slots[j]) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: %d is standby", j))); + + if (get_query_result(slots, j, "SELECT status, conninfo FROM pg_catalog.pg_stat_wal_receiver", &res)) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: call pg_stat_wal_receiver to standby %d failed", j))); + continue; + } + if (res->numrows <= 0) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: pg_stat_wal_receiver returned no row. standby %d", j))); + free_select_result(res); + continue; + } + if (res->nullflags[wal_receiver_status] == -1) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: pg_stat_wal_receiver status for standby %d is NULL", j))); + free_select_result(res); + continue; + } + if (strcmp(res->data[wal_receiver_status], "streaming")) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: pg_stat_wal_receiver status is not \"streaming\" for standby %d (%s)", j, res->data[wal_receiver_status]))); + free_select_result(res); + continue; + + } + if (res->nullflags[wal_receiver_conninfo] == -1) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: pg_stat_wal_receiver conninfo for standby %d is NULL", j))); + continue; + } + get_info_from_conninfo(res->data[wal_receiver_conninfo], host, sizeof(host), port, sizeof(port)); + ereport(DEBUG1, + (errmsg("verify_backend_node_status: conninfo for standby %d is === %s ===. host:%s port:%s", j, res->data[wal_receiver_conninfo], host, port))); + free_select_result(res); + + /* get primary backend info */ + backend_info = pool_get_node_info(i); + + /* verify host and port */ + if (((*backend_info->backend_hostname == '/' && *host == '\0') || + + /* + * It is possible that backend_hostname is Unix domain + * socket but wal_receiver connects via TCP/IP + * localhost. + */ + (*backend_info->backend_hostname == '/' && !strcmp("localhost", host)) || + !strcmp(backend_info->backend_hostname, host)) && + backend_info->backend_port == atoi(port)) + { + /* the standby connects to the primary */ + primary[i]++; + if (primary[i] == num_standbys) + true_primary = i; + } + else + { + /* the standby does not connect to the primary */ + ereport(LOG, + (errmsg("verify_backend_node_status: primary %d does not connect to standby %d", i, j), + errdetail("pgpool.conf backend: (host=\"%s\" port=%d) does not match PostgreSQL primary_conninfo: (host=\"%s\" port=%s)", + backend_info->backend_hostname, backend_info->backend_port, host, port))); + } + } + } + } + } + + /* + * Check if each primary connected standbys. If all standbys connect + * to one of primaries, then the primary is good. Other primaries are + * false. If none of primaries does not own all connected standbys, + * we cannot judge which primary is good. + */ + for (i = 0; i < NUM_BACKENDS; i++) + { + ereport(DEBUG1, + (errmsg("verify_backend_node_status: primary %d owns %d standbys out of %d", i, primary[i], num_standbys))); + ereport(DEBUG1, + (errmsg("verify_backend_node_status: true_primary %d", true_primary))); + + if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY && primary[i] >= 0) + { + if (primary[i] < num_standbys) + { + ereport(LOG, + (errmsg("verify_backend_node_status: primary %d owns only %d standbys out of %d", i, primary[i], num_standbys))); + + /* + * If the good primary exists and detach_false_primary is + * true, then ask to detach the false primary + */ + if (true_primary >= 0 && pool_config->detach_false_primary) + pool_node_status[i] = POOL_NODE_STATUS_INVALID; + } + } + } + + } + + return pool_node_status; +} + +POOL_NODE_STATUS * +pool_get_node_status(void) +{ + return pool_node_status; +} + +/* + * Find the primary node (i.e. not standby node) and returns its node + * id. If no primary node is found, returns -1. + */ +static int +find_primary_node(void) +{ + BackendInfo *bkinfo; + POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; + int i; + POOL_NODE_STATUS *status; + int primary = -1; + char *password = NULL; + + /* Streaming replication mode? */ + if (!SL_MODE) + { + /* + * No point to look for primary node if not in streaming replication + * mode. + */ + ereport(DEBUG1, + (errmsg("find_primary_node: not in streaming replication mode"))); + return -1; + } + + /* + * First check for "ALWAYS_PRIMARY" flags exists. If so, do not perform + * actual primary node check and just returns the node id. + */ + for (i = 0; i < NUM_BACKENDS; i++) + { + if (POOL_ALWAYS_PRIMARY & BACKEND_INFO(i).flag) + { + ereport(DEBUG1, + (errmsg("find_primary_node: ALWAYS_PRIMARY flag found. Returns node id: %d", i))); + return i; + } + } + + password = get_pgpool_config_user_password(pool_config->sr_check_user, + pool_config->sr_check_password); + + /* + * Establish connections to backend + */ + for (i = 0; i < NUM_BACKENDS; i++) + { + slots[i] = NULL; + + if (!VALID_BACKEND(i)) + continue; + + bkinfo = pool_get_node_info(i); + + slots[i] = make_persistent_db_connection_noerror(i, bkinfo->backend_hostname, + bkinfo->backend_port, + pool_config->sr_check_database, + pool_config->sr_check_user, + password ? password : "", false); + if (!slots[i]) + { + ereport(LOG, + (errmsg("find_primary_node: make_persistent_db_connection_noerror failed on node %d", i))); + } + } + + if (password) + pfree(password); + + /* Verify backend status */ + pool_acquire_follow_primary_lock(true, false); + status = verify_backend_node_status(slots); + pool_release_follow_primary_lock(false); + + for (i = 0; i < NUM_BACKENDS; i++) + { + if (status[i] == POOL_NODE_STATUS_PRIMARY) + { + /* This is the primary */ + ereport(LOG, + (errmsg("find_primary_node: primary node is %d", i))); + primary = i; + } + else if (status[i] == POOL_NODE_STATUS_STANDBY) + { + ereport(LOG, + (errmsg("find_primary_node: standby node is %d", i))); + } + else if (status[i] == POOL_NODE_STATUS_INVALID) + { + /* Split brain or invalid node */ + ereport(LOG, + (errmsg("find_primary_node: invalid node %d", i))); + } + } + + for (i = 0; i < NUM_BACKENDS; i++) + { + if (slots[i]) + discard_persistent_db_connection(slots[i]); + } + + return primary; +} + +static int +find_primary_node_repeatedly(void) +{ + time_t search_primary_expiration; + time_t now; + int node_id = -1; + int i; + + /* Streaming replication mode? */ + if (!SL_MODE) + { + /* + * No point to look for primary node if not in streaming replication + * mode. + */ + ereport(DEBUG1, + (errmsg("find_primary_node_repeatedly: not in streaming replication mode"))); + return -1; + } + + /* + * If follow primary command is ongoing, skip primary node check. Just + * return current primary node to avoid deadlock between pgpool main + * failover() and follow primary process. + */ + if (Req_info->follow_primary_ongoing) + { + ereport(LOG, + (errmsg("find_primary_node_repeatedly: follow primary is ongoing. return current primary: %d", + Req_info->primary_node_id))); + + return Req_info->primary_node_id; + } + + /* + * If all of the backends are down, there's no point to keep on searching + * primary node. + */ + for (i = 0; i < NUM_BACKENDS; i++) + { + if (VALID_BACKEND(i)) + break; + } + if (i == NUM_BACKENDS) + { + ereport(LOG, + (errmsg("find_primary_node_repeatedly: all of the backends are down. Giving up finding primary node"))); + return -1; + } + + /* + * Try to find the new primary node and keep trying for + * search_primary_node_timeout seconds. search_primary_node_timeout = 0 + * means never timeout and keep searching indefinitely + */ + ereport(LOG, + (errmsg("find_primary_node_repeatedly: waiting for finding a primary node"))); + + /* set expiration time for searching the primary node */ + search_primary_expiration = time(NULL) + pool_config->search_primary_node_timeout; + + for (;;) + { + now = time(NULL); + + if (pool_config->search_primary_node_timeout == 0 || search_primary_expiration > now) + { + node_id = find_primary_node(); + if (node_id != -1) + break; + pool_sleep(1); + } + else + { + ereport(LOG, + (errmsg("failed to find primary node"), + errdetail("find_primary_node_repeatedly: expired after %d seconds", + pool_config->search_primary_node_timeout))); + break; + } + } + return node_id; +} + +/* +* fork a follow child +*/ +static pid_t +fork_follow_child(int old_main_node, int new_primary, int old_primary) +{ + pid_t pid; + int i; + + pid = fork(); + + if (pid == 0) + { + POOL_SETMASK(&UnBlockSig); + + pool_signal(SIGCHLD, SIG_DFL); + pool_signal(SIGUSR1, SIG_DFL); + pool_signal(SIGUSR2, SIG_DFL); + pool_signal(SIGTERM, SIG_DFL); + pool_signal(SIGINT, SIG_DFL); + pool_signal(SIGQUIT, SIG_DFL); + pool_signal(SIGHUP, SIG_DFL); + + on_exit_reset(); + + /* + * Set session id if possible + */ +#ifdef HAVE_SETSID + if (setsid() < 0) + { + ereport(FATAL, + (errmsg("could not set session id in the fork_follow_child"), + errdetail("setsid() system call failed with reason: \"%m\""))); + } +#endif + + SetProcessGlobalVariables(PT_FOLLOWCHILD); + + /* + * when the watchdog is enabled, we would come here only on the + * coordinator node. so before acquiring the local lock, Lock all the + * standby nodes so that they should stop false primary detection + * until we are finished with the follow primary command. + */ + wd_lock_standby(WD_FOLLOW_PRIMARY_LOCK); + pool_acquire_follow_primary_lock(true, false); + Req_info->follow_primary_ongoing = true; + for (i = 0; i < pool_config->backend_desc->num_backends; i++) + { + BackendInfo *bkinfo; + + bkinfo = pool_get_node_info(i); + if (bkinfo->backend_status == CON_DOWN) + { + ereport(LOG, + (errmsg("=== Starting follow primary command for node %d ===", i))); + trigger_failover_command(i, pool_config->follow_primary_command, + old_main_node, new_primary, old_primary); + ereport(LOG, + (errmsg("=== Follow primary command for node %d ended ===", i))); + } + } + Req_info->follow_primary_ongoing = false; + pool_release_follow_primary_lock(false); + /* inform standby watchdog nodes to release the lock as well */ + wd_unlock_standby(WD_FOLLOW_PRIMARY_LOCK); + exit(0); + } + else if (pid == -1) + { + ereport(WARNING, + (errmsg("follow fork() failed"), + errdetail("%m"))); + exit(1); + } + return pid; +} + +static void +initialize_shared_mem_objects(bool clear_memcache_oidmaps) +{ + BackendDesc *backend_desc; + Size size; + int i; + + /* + * Calculate the size of required shared memory and try to allocate + * everything in single memory segment + */ + size = 256; /* let us have some extra space */ + size += MAXALIGN(sizeof(BackendDesc)); + elog(DEBUG1, "BackendDesc: %zu bytes requested for shared memory", MAXALIGN(sizeof(BackendDesc))); + size += MAXALIGN(pool_coninfo_size()); + size += MAXALIGN(pool_config->num_init_children * (sizeof(ProcessInfo))); + elog(DEBUG1, "ProcessInfo: num_init_children (%d) * sizeof(ProcessInfo) (%zu) = %zu bytes requested for shared memory", + pool_config->num_init_children, sizeof(ProcessInfo), pool_config->num_init_children * sizeof(ProcessInfo)); + size += MAXALIGN(sizeof(User1SignalSlot)); + elog(DEBUG1, "UserSignalSlot: %zu bytes requested for shared memory", MAXALIGN(sizeof(User1SignalSlot))); + size += MAXALIGN(sizeof(POOL_REQUEST_INFO)); + elog(DEBUG1, "POOL_REQUEST_INFO: %zu bytes requested for shared memory", MAXALIGN(sizeof(POOL_REQUEST_INFO))); + size += MAXALIGN(sizeof(int)); /* for InRecovery */ + size += MAXALIGN(stat_shared_memory_size()); + elog(DEBUG1, "stat_shared_memory_size: %zu bytes requested for shared memory", MAXALIGN(stat_shared_memory_size())); + size += MAXALIGN(health_check_stats_shared_memory_size()); + /* Snapshot Isolation manage area */ + size += MAXALIGN(sizeof(SI_ManageInfo)); + elog(DEBUG1, "SI_ManageInfo: %zu bytes requested for shared memory", MAXALIGN(sizeof(SI_ManageInfo))); + size += MAXALIGN(pool_config->num_init_children * sizeof(pid_t)); + size += MAXALIGN(pool_config->num_init_children * sizeof(pid_t)); + + if (pool_is_shmem_cache()) + { + size += MAXALIGN(pool_shared_memory_cache_size()); + size += MAXALIGN(pool_shared_memory_fsmm_size()); + size += MAXALIGN(pool_hash_size(pool_config->memqcache_max_num_cache)); + } + if (pool_config->memory_cache_enabled || pool_config->enable_shared_relcache) + { + size += MAXALIGN(sizeof(POOL_QUERY_CACHE_STATS)); + elog(DEBUG1, "POOL_QUERY_CACHE_STATS: %zu bytes requested for shared memory", MAXALIGN(sizeof(POOL_QUERY_CACHE_STATS))); + } + + if (pool_config->use_watchdog) + { + size += MAXALIGN(wd_ipc_get_shared_mem_size()); + elog(DEBUG1, "watchdog: %zu bytes requested for shared memory", MAXALIGN(wd_ipc_get_shared_mem_size())); + } + + if (pool_config->disable_load_balance_on_write == + DLBOW_DML_ADAPTIVE_GLOBAL) + { + size += MAXALIGN(pool_track_table_mutation_shmem_size()); + elog(DEBUG1, + "track_table_mutation: %zu bytes requested" + " for shared memory", + MAXALIGN(pool_track_table_mutation_shmem_size())); + } + + initialize_shared_memory_main_segment(size); + + /* Move the backend descriptors to shared memory */ + backend_desc = pool_shared_memory_segment_get_chunk(sizeof(BackendDesc)); + memcpy(backend_desc, pool_config->backend_desc, sizeof(BackendDesc)); + pfree(pool_config->backend_desc); + pool_config->backend_desc = backend_desc; + + /* get the shared memory from main segment */ + con_info = (ConnectionInfo *) pool_shared_memory_segment_get_chunk(pool_coninfo_size()); + + process_info = (ProcessInfo *) pool_shared_memory_segment_get_chunk(pool_config->num_init_children * (sizeof(ProcessInfo))); + for (i = 0; i < pool_config->num_init_children; i++) + { + process_info[i].connection_info = pool_coninfo(i, 0, 0); + process_info[i].pid = 0; + } + + user1SignalSlot = (User1SignalSlot *) pool_shared_memory_segment_get_chunk(sizeof(User1SignalSlot)); + + Req_info = (POOL_REQUEST_INFO *) pool_shared_memory_segment_get_chunk(sizeof(POOL_REQUEST_INFO)); + + InRecovery = (int *) pool_shared_memory_segment_get_chunk(sizeof(int)); + + /* Initialize statistics area */ + stat_set_stat_area(pool_shared_memory_segment_get_chunk(stat_shared_memory_size())); + stat_init_stat_area(); - restart_child = false; - } - } - if (WIFSIGNALED(status)) + /* Initialize health check statistics area */ + health_check_stats_init(pool_shared_memory_segment_get_chunk(health_check_stats_shared_memory_size())); + + /* Initialize Snapshot Isolation manage area */ + si_manage_info = (SI_ManageInfo *) pool_shared_memory_segment_get_chunk(sizeof(SI_ManageInfo)); + + si_manage_info->snapshot_waiting_children = + (pid_t *) pool_shared_memory_segment_get_chunk(pool_config->num_init_children * sizeof(pid_t)); + + si_manage_info->commit_waiting_children = + (pid_t *) pool_shared_memory_segment_get_chunk(pool_config->num_init_children * sizeof(pid_t)); + + /* + * Initialize backend status area. From now on, VALID_BACKEND macro can be + * used. (get_next_main_node() uses VALID_BACKEND) + */ + + for (i = 0; i < MAX_NUM_BACKENDS; i++) + { + my_backend_status[i] = + (volatile BACKEND_STATUS *) &(BACKEND_INFO(i).backend_status); + } + + /* initialize Req_info */ + Req_info->main_node_id = get_next_main_node(); + Req_info->conn_counter = 0; + Req_info->switching = false; + Req_info->request_queue_head = Req_info->request_queue_tail = -1; + Req_info->primary_node_id = -2; + *InRecovery = RECOVERY_INIT; + + /* + * Initialize shared memory cache + */ + if (pool_config->memory_cache_enabled || pool_config->enable_shared_relcache) + { + if (pool_is_shmem_cache()) { - /* Child terminated by segmentation fault. Report it */ - if (WTERMSIG(status) == SIGSEGV) - ereport(WARNING, - (errmsg("%s process with pid: %d was terminated by segmentation fault", exiting_process_name, pid))); - else - ereport(LOG, - (errmsg("%s process with pid: %d exits with status %d by signal %d", exiting_process_name, pid, status, WTERMSIG(status)))); + size_t size; + + size = pool_shared_memory_cache_size(); + pool_init_memory_cache(size); + + size = pool_shared_memory_fsmm_size(); + if (size == 0) + ereport(FATAL, + (errmsg("invalid shared memory size"), + errdetail("pool_shared_memory_fsmm_size error"))); + + pool_init_fsmm(size); + + pool_allocate_fsmm_clock_hand(); + + pool_discard_oid_maps(); - /* - * If the watchdog process was terminated abonormally. we need to - * set the cleanup flag so that the new watchdog process can start - * without problems - */ - if (pool_config->use_watchdog && pid == watchdog_pid) - { - set_watchdog_process_needs_cleanup(); - } - } - else ereport(LOG, - (errmsg("%s process with pid: %d exits with status %d", exiting_process_name, pid, status))); + (errmsg("pool_discard_oid_maps: discarded memqcache oid maps"))); - /* if exiting child process was PCP handler */ - if (pid == pcp_pid) - { - found = true; - if (restart_child) - { - pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file); - new_pid = pcp_pid; - } - else - pcp_pid = 0; + pool_hash_init(pool_config->memqcache_max_num_cache); + + pool_init_whole_cache_blocks(); } - /* exiting process was worker process */ - else if (pid == worker_pid) +#ifdef USE_MEMCACHED + else { - found = true; - if (restart_child) + if (clear_memcache_oidmaps) { - worker_pid = worker_fork_a_child(PT_WORKER, do_worker_child, NULL); - new_pid = worker_pid; + pool_discard_oid_maps(); + ereport(LOG, + (errmsg("discarded memqcache oid maps"))); } else - worker_pid = 0; + { + ereport(DEBUG1, + (errmsg("skipped discarding memqcache oid maps"))); + } } +#endif - /* exiting process was watchdog process */ - else if (pool_config->use_watchdog) + pool_init_memqcache_stats(); + } + + /* initialize watchdog IPC unix domain socket address */ + if (pool_config->use_watchdog) + { + wd_ipc_initialize_data(); + } + + /* initialize pcp worker child pids */ + memset(Req_info->pcp_worker_pids, 0, sizeof(Req_info->pcp_worker_pids)); + + /* Initialize track table mutation for recently written tables */ + if (pool_config->disable_load_balance_on_write == + DLBOW_DML_ADAPTIVE_GLOBAL) + { + pool_track_table_mutation_init(); + } +} + +/* +* Read the status file +*/ +static int +read_status_file(bool discard_status) +{ + FILE *fd; + char fnamebuf[POOLMAXPATHLEN]; + int i; + bool someone_wakeup = false; + bool is_old_format; + + /* + * Set backend status changed timestamp so that it is set even if there's + * no status file or discard status option is specified. + */ + for (i = 0; i < MAX_NUM_BACKENDS; i++) + { + pool_set_backend_status_changed_time(i); + } + + snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->work_dir, STATUS_FILE_NAME); + fd = fopen(fnamebuf, "r"); + if (!fd) + { + ereport(LOG, + (errmsg("Backend status file %s does not exist", fnamebuf))); + return -1; + } + + /* + * If discard_status is true, unlink pgpool_status and do not restore + * previous status. + */ + if (discard_status) + { + fclose(fd); + if (unlink(fnamebuf) == 0) + ereport(LOG, + (errmsg("Backend status file %s discarded", fnamebuf))); + else + ereport(WARNING, + (errmsg("failed to discard backend status file: \"%s\"", fnamebuf), + errdetail("%m"))); + return 0; + } + + /* + * First try out with old format file. + */ + is_old_format = true; + + if (fread(&backend_rec, 1, sizeof(backend_rec), fd) == sizeof(backend_rec)) + { + /* It's likely old binary format status file */ + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { - if (watchdog_pid == pid) + if (backend_rec.status[i] == CON_DOWN) { - found = true; - if (restart_child) - { - watchdog_pid = initialize_watchdog(); - new_pid = watchdog_pid; - } - else - watchdog_pid = 0; + BACKEND_INFO(i).backend_status = CON_DOWN; + pool_set_backend_status_changed_time(i); + (void) write_status_file(); + ereport(LOG, + (errmsg("read_status_file: %d th backend is set to down status", i))); } - else if (wd_lifecheck_pid == pid) + else if (backend_rec.status[i] == CON_CONNECT_WAIT || + backend_rec.status[i] == CON_UP) { - found = true; - if (restart_child) - { - wd_lifecheck_pid = initialize_watchdog_lifecheck(); - new_pid = wd_lifecheck_pid; - } - else - wd_lifecheck_pid = 0; + BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; + pool_set_backend_status_changed_time(i); + (void) write_status_file(); + someone_wakeup = true; + } + else + { + /* It seems it's not an old binary format status file */ + is_old_format = false; + break; } } + } + else + is_old_format = false; + + fclose(fd); + if (!is_old_format) + { /* - * we are not able to identify the exiting process yet. check if the - * exiting process was child process (handling PG clients) + * Fall back to new ascii format file. the format looks like(case is + * ignored): + * + * up|down|unused UP|down|unused : : */ - if (found == false) +#define MAXLINE 10 + char readbuf[MAXLINE]; + + fd = fopen(fnamebuf, "r"); + if (!fd) { - /* look for exiting child's pid */ - for (i = 0; i < pool_config->num_init_children; i++) + ereport(LOG, + (errmsg("Backend status file %s does not exist", fnamebuf))); + return -1; + } + + for (i = 0; i < MAX_NUM_BACKENDS; i++) + { + BACKEND_INFO(i).backend_status = CON_UNUSED; + pool_set_backend_status_changed_time(i); + } + + for (i = 0;; i++) + { + readbuf[MAXLINE - 1] = '\0'; + if (fgets(readbuf, MAXLINE - 1, fd) == 0) + break; + + if (!strncasecmp("up", readbuf, 2)) { - if (pid == process_info[i].pid) - { - found = true; - /* if found, fork a new child */ - if (!switching && !exiting && restart_child) - { - process_info[i].pid = fork_a_child(fds, i); - process_info[i].start_time = time(NULL); - new_pid = process_info[i].pid; - } - else - process_info[i].pid = 0; - break; - } + BACKEND_INFO(i).backend_status = CON_UP; + someone_wakeup = true; + ereport(LOG, + (errmsg("reading status file: %d th backend is set to up status", i))); + } + else if (!strncasecmp("down", readbuf, 4)) + { + BACKEND_INFO(i).backend_status = CON_DOWN; + pool_set_backend_status_changed_time(i); + ereport(LOG, + (errmsg("reading status file: %d th backend is set to down status", i))); + } + else if (!strncasecmp("unused", readbuf, 6)) + { + BACKEND_INFO(i).backend_status = CON_UNUSED; + pool_set_backend_status_changed_time(i); + ereport(LOG, + (errmsg("reading status file: %d th backend is set to unused status", i))); } - } - - /* Check health check process */ - if (found == false) - { - for (i = 0; i < NUM_BACKENDS; i++) + else { - if (pid == health_check_pids[i]) - { - found = true; - - /* Fork new health check worker */ - if (!switching && !exiting && VALID_BACKEND(i)) - { - health_check_pids[i] = worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); - } - else - health_check_pids[i] = 0; - } + ereport(WARNING, + (errmsg("invalid data in status file, ignoring..."), + errdetail("backend:%d status is invalid: \"%s\"", i, readbuf))); } } + fclose(fd); + } - if (shutdown_system) - ereport(FATAL, - (errmsg("%s process exit with fatal error. exiting pgpool-II", exiting_process_name))); - - else if (restart_child && new_pid) + /* + * If no one woke up, we regard the status file bogus + */ + if (someone_wakeup == false) + { + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { - /* Report if the child was restarted */ - ereport(LOG, - (errmsg("fork a new %s process with pid: %d", exiting_process_name, new_pid))); + BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; + pool_set_backend_status_changed_time(i); } + (void) write_status_file(); + } + + return 0; +} + +/* +* Write the status file +*/ +int +write_status_file(void) +{ + FILE *fd; + int fdnum; + char fnamebuf[POOLMAXPATHLEN]; + char buf[10]; + int i; + + if (!pool_config) + { + ereport(WARNING, + (errmsg("pool_config is not set"))); + return 0; + } + + /* + * Check to see if all nodes are down status. If so, skip writing status + * file. So pgpool_status will always reflect the last set of nodes to + * which any data was written. Upon restart, if the up-to-date (previously + * "up") node is in fact down (regardless of whether the stale ("down") + * node is back up), pgpool will detect this in its health check and will + * fail; if the up-to-date (previously "up") node is back up, then pgpool + * will commence using it. + * + * See [pgpool-general: 4721] for more discussion. + */ + for (i = 0; i < pool_config->backend_desc->num_backends; i++) + { + if (BACKEND_INFO(i).backend_status != CON_DOWN) + break; + } + + if (i && i == pool_config->backend_desc->num_backends) + { + ereport(WARNING, + (errmsg("All the DB nodes are in down status and skip writing status file."))); + + return 0; + } + + snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->work_dir, STATUS_FILE_NAME); + fd = fopen(fnamebuf, "w"); + if (!fd) + { + ereport(WARNING, + (errmsg("failed to open status file at: \"%s\"", fnamebuf), + errdetail("%m"))); + return -1; + } + + for (i = 0; i < pool_config->backend_desc->num_backends; i++) + { + char *status; + + if (BACKEND_INFO(i).backend_status == CON_UP || + BACKEND_INFO(i).backend_status == CON_CONNECT_WAIT) + status = "up"; + else if (BACKEND_INFO(i).backend_status == CON_DOWN) + status = "down"; else + status = "unused"; + + sprintf(buf, "%s\n", status); + if (fwrite(buf, 1, strlen(buf), fd) != strlen(buf)) { - /* And the child was not restarted */ - ereport(LOG, - (errmsg("%s process with pid: %d exited with success and will not be restarted", exiting_process_name, pid))); + ereport(WARNING, + (errmsg("failed to write status file at: \"%s\"", fnamebuf), + errdetail("%m"))); + fclose(fd); + return -1; } + } + if (fflush(fd) != 0) + { + ereport(WARNING, + (errmsg("failed to write status file at: \"%s\"", fnamebuf), + errdetail("%m"))); + fclose(fd); + return -1; + } + fdnum = fileno(fd); + if (fdnum < 0) + { + ereport(WARNING, + (errmsg("failed to get file number. fsync() will not be performed: \"%s\"", fnamebuf), + errdetail("%m"))); + fclose(fd); + return -1; + } + if (fsync(fdnum) != 0) + { + ereport(WARNING, + (errmsg("failed to fsync(): \"%s\"", fnamebuf), + errdetail("%m"))); + fclose(fd); + return -1; } - ereport(DEBUG1, - (errmsg("reaper handler: exiting normally"))); -} -/* - * get node information specified by node_number - */ -BackendInfo * -pool_get_node_info(int node_number) -{ - if (node_number < 0 || node_number >= NUM_BACKENDS) - return NULL; + fclose(fd); - return &BACKEND_INFO(node_number); + return 0; } -/* - * get number of nodes - */ -int -pool_get_node_count(void) +static void +reload_config(void) { - return NUM_BACKENDS; + ereport(LOG, + (errmsg("reload config files."))); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + + pool_get_config(conf_file, CFGCXT_RELOAD); + + /* Reloading config file could change backend status */ + (void) write_status_file(); + + MemoryContextSwitchTo(oldContext); + if (pool_config->enable_pool_hba) + load_hba(hba_file); + +#ifdef USE_SSL + + /* + * If SSL is enabled, re-initialize the SSL context so that new + * connections pick up rotated certificates without requiring a restart. + * SSL_ServerSide_init() is safe to call repeatedly: it frees and replaces + * the existing SSL_CTX only on success, leaving the old context intact on + * failure. + */ + if (pool_config->ssl) + { + ereport(LOG, + (errmsg("reload SSL certificates."))); + SSL_ServerSide_init(); + } +#endif /* USE_SSL */ + + kill_all_children(SIGHUP); } -/* - * get process ids - */ -int * -pool_get_process_list(int *array_size) +/* Call back function to unlink the file */ +static void +FileUnlink(int code, Datum path) { - int *array; - int i; + char *filePath = (char *) path; - *array_size = pool_config->num_init_children; - array = palloc0(*array_size * sizeof(int)); - for (i = 0; i < *array_size; i++) - array[i] = process_info[i].pid; + if (unlink(filePath) == 0) + return; - return array; + /* + * We are already exiting the system just produce a log entry to report an + * error + */ + ereport(LOG, + (errmsg("unlink failed for file at path \"%s\"", filePath), + errdetail("%m"))); } -/* - * get process information specified by pid - */ -ProcessInfo * -pool_get_process_info(pid_t pid) +static void +system_will_go_down(int code, Datum arg) { - int i; + if (mypid != getpid()) + { + /* should never happen */ + ereport(LOG, (errmsg("system_will_go_down called from invalid process"))); + return; + } + POOL_SETMASK(&AuthBlockSig); + /* Write status file */ + (void) write_status_file(); - for (i = 0; i < pool_config->num_init_children; i++) - if (process_info[i].pid == pid) - return &process_info[i]; + /* + * Terminate all childrens. But we may already have killed all the + * childrens if we come to this function because of shutdown signal. + */ - return NULL; + if (processState != EXITING) + { + ereport(LOG, + (errmsg("shutting down"))); + terminate_all_childrens(SIGINT); + } + + /* + * Send signal to follow child process and it's children. + */ + if (follow_pid > 0) + { + ereport(LOG, + (errmsg("terminating all child processes of follow child"))); + kill(follow_pid, SIGTERM); + kill(-follow_pid, SIGTERM); + } + + processState = EXITING; + POOL_SETMASK(&UnBlockSig); } -/* - * handle SIGUSR2 - * Wakeup all processes - */ -static void -wakeup_children(void) +int +pool_send_to_frontend(char *data, int len, bool flush) +{ + if (processType == PT_PCP_WORKER) + return send_to_pcp_frontend(data, len, flush); + else if (processType == PT_CHILD) + return send_to_pg_frontend(data, len, flush); + return -1; +} + +int +pool_frontend_exists(void) { - kill_all_children(SIGUSR2); + if (processType == PT_PCP_WORKER) + return pcp_frontend_exists(); + else if (processType == PT_CHILD) + return pg_frontend_exists(); + return -1; } -static RETSIGTYPE wakeup_handler(int sig) +static void +update_backend_quarantine_status(void) { - int save_errno = errno; + /* + * Reset the quarantine flag from each backend and set it to con_wait + */ + int i; + WD_STATES wd_state = wd_internal_get_watchdog_local_node_state(); - wakeup_request = 1; - if (processState != INITIALIZING) + for (i = 0; i < NUM_BACKENDS; i++) { - POOL_SETMASK(&BlockSig); - write(pipe_fds[1], "\0", 1); -#ifdef NOT_USED - if (write(pipe_fds[1], "\0", 1) < 0) - ereport(WARNING, - (errmsg("wakeup_handler: write to pipe failed with error \"%s\"", strerror(errno)))); -#endif - POOL_SETMASK(&UnBlockSig); + if (BACKEND_INFO(i).quarantine && BACKEND_INFO(i).backend_status == CON_DOWN) + { + /* + * Send the failback request for the node we also set the watchdog + * flag, so that the failover should only be executed locally + * because, we will eventually send the sync backend message to + * all standby nodes + */ + if (wd_state == WD_COORDINATOR) + send_failback_request(i, false, REQ_DETAIL_UPDATE | REQ_DETAIL_WATCHDOG); + } } - errno = save_errno; } /* - * handle SIGHUP + * The function fetch the current status of all configured backend + * nodes from the LEADER/COORDINATOR watchdog Pgpool-II and synchronize the + * local backend states with the cluster wide status of each node. + * + * Latter in the function after syncing the backend node status the function + * do a partial or full restart of Pgpool-II children depending upon the + * Pgpool-II mode and type of node status change * */ -static RETSIGTYPE reload_config_handler(int sig) +static void +sync_backend_from_watchdog(void) { - int save_errno = errno; + bool primary_changed = false; + bool node_status_was_changed_to_down = false; + bool node_status_was_changed_to_up = false; + bool need_to_restart_children = false; + bool partial_restart = false; + bool reload_master_node_id = false; - POOL_SETMASK(&BlockSig); - reload_config_request = 1; - write(pipe_fds[1], "\0", 1); -#ifdef NOT_USED - if (write(pipe_fds[1], "\0", 1) < 0) + int down_node_ids[MAX_NUM_BACKENDS]; + int down_node_ids_index = 0; + int i; + WDPGBackendStatus *backendStatus; + + /* + * Ask the watchdog to get all the backend states from the + * Leader/Coordinator Pgpool-II node + */ + backendStatus = get_pg_backend_status_from_leader_wd_node(); + + if (!backendStatus) + { ereport(WARNING, - (errmsg("reload_config_handler: write to pipe failed with error \"%s\"", strerror(errno)))); -#endif + (errmsg("failed to get the backend status from the leader watchdog node"), + errdetail("using the local backend node status"))); + return; + } + if (backendStatus->node_count <= 0) + { + /* + * -ve node count is returned by watchdog when the node itself is a + * leader and in that case we need to use the local backend node + * status + */ + ereport(LOG, + (errmsg("I am the leader watchdog node"), + errdetail("using the local backend node status"))); + pfree(backendStatus); + return; + } - POOL_SETMASK(&UnBlockSig); + ereport(LOG, + (errmsg("leader watchdog node \"%s\" returned status for %d backend nodes", backendStatus->nodeName, backendStatus->node_count))); - errno = save_errno; -} + ereport(DEBUG1, + (errmsg("primary node on leader watchdog node \"%s\" is %d", backendStatus->nodeName, backendStatus->primary_node_id))); -static void -kill_all_children(int sig) -{ - int i; - if (process_info) + /* + * update the local backend status Also remove quarantine flags + */ + for (i = 0; i < backendStatus->node_count; i++) { - /* kill all children */ - for (i = 0; i < pool_config->num_init_children; i++) + BACKEND_INFO(i).quarantine = false; + if (backendStatus->backend_status[i] == CON_DOWN) { - pid_t pid = process_info[i].pid; - - if (pid) + if (BACKEND_INFO(i).backend_status != CON_DOWN) { - kill(pid, sig); + BACKEND_INFO(i).backend_status = CON_DOWN; + pool_set_backend_status_changed_time(i); + my_backend_status[i] = + (volatile BACKEND_STATUS *) &(BACKEND_INFO(i).backend_status); + reload_master_node_id = true; + node_status_was_changed_to_down = true; + ereport(LOG, + (errmsg("backend:%d is set to down status", i), + errdetail("backend:%d is DOWN on cluster leader \"%s\"", i, backendStatus->nodeName))); + down_node_ids[down_node_ids_index++] = i; } } - } - /* make PCP process reload as well */ - if (sig == SIGHUP && pcp_pid > 0) - kill(pcp_pid, sig); -} - -/* - * pause in a period specified by timeout. If any data is coming - * through pipe_fds[0], that means one of: failover request(SIGUSR1), - * SIGCHLD received, children wake up request(SIGUSR2 used in on line - * recovery processing) or config file reload request(SIGHUP) has been - * occurred. In this case this function returns 1. - * otherwise 0: (no signal event occurred), -1: (error) - * XXX: is it OK that select(2) error is ignored here? - */ -static int -pool_pause(struct timeval *timeout) -{ - fd_set rfds; - int n; - char dummy; + else if (backendStatus->backend_status[i] == CON_CONNECT_WAIT || + backendStatus->backend_status[i] == CON_UP) + { + if (BACKEND_INFO(i).backend_status != CON_CONNECT_WAIT) + { + if (BACKEND_INFO(i).backend_status == CON_DOWN) + node_status_was_changed_to_up = true; - FD_ZERO(&rfds); - FD_SET(pipe_fds[0], &rfds); - n = select(pipe_fds[0] + 1, &rfds, NULL, NULL, timeout); - if (n == 1) - { - if (read(pipe_fds[0], &dummy, 1) < 0) - ereport(WARNING, - (errmsg("pool_pause: read on pipe failed with error \"%s\"", strerror(errno)))); - } - return n; -} + BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; + pool_set_backend_status_changed_time(i); + my_backend_status[i] = + (volatile BACKEND_STATUS *) &(BACKEND_INFO(i).backend_status); + reload_master_node_id = true; -/* - * sleep for seconds specified by "second". Unlike pool_pause(), this - * function guarantees that it will sleep for specified seconds. This - * function uses pool_pause() internally. If it informs that there is - * a pending signal event, they are processed using CHECK_REQUEST - * macro. Note that most of these processes are done while all signals - * are blocked. - */ -void -pool_sleep(unsigned int second) -{ - struct timeval current_time, - sleep_time; + ereport(LOG, + (errmsg("backend:%d is set to UP status", i), + errdetail("backend:%d is UP on cluster leader \"%s\"", i, backendStatus->nodeName))); - gettimeofday(¤t_time, NULL); - sleep_time.tv_sec = second + current_time.tv_sec; - sleep_time.tv_usec = current_time.tv_usec; + } + } + } - POOL_SETMASK(&UnBlockSig); - while (sleep_time.tv_sec > current_time.tv_sec) + /* + * Update primary node id info on the shared memory area if it's different + * from the one on leader watchdog node. This should be done only in + * streaming or logical replication mode. + */ + if (SL_MODE && Req_info->primary_node_id != backendStatus->primary_node_id) { - struct timeval timeout; - int r; + /* Do not produce this log message if we are starting up the Pgpool-II */ + if (processState != INITIALIZING) + ereport(LOG, + (errmsg("primary node:%d on leader watchdog node \"%s\" is different from local primary node:%d", + backendStatus->primary_node_id, backendStatus->nodeName, Req_info->primary_node_id))); - timeout.tv_sec = sleep_time.tv_sec - current_time.tv_sec; - timeout.tv_usec = sleep_time.tv_usec - current_time.tv_usec; - if (timeout.tv_usec < 0) + /* + * leader node returns primary_node_id = -1 when the primary node is + * in quarantine state on the leader. So we will not update our + * primary node id when the status of current primary node is not + * CON_DOWN while primary_node_id sent by leader watchdog node is -1 + * + * Note that Req_info->primary_node_id could be -2, which is the + * initial value. So we need to avoid crash by checking the value is + * not lower than 0. Otherwise we will get crash while looking up + * BACKEND_INFO array. See Mantis bug id 614 for more details. + */ + if (Req_info->primary_node_id >= 0 && + backendStatus->primary_node_id == -1 && BACKEND_INFO(Req_info->primary_node_id).backend_status != CON_DOWN) { - timeout.tv_sec--; - timeout.tv_usec += 1000000; + ereport(LOG, + (errmsg("primary node:%d on leader watchdog node \"%s\" seems to be quarantined", + Req_info->primary_node_id, backendStatus->nodeName), + errdetail("keeping the current primary"))); + } + else if (Req_info->primary_node_id >= 0 && + backendStatus->primary_node_id == -2) + { + /* + * Leader watchdog is still initialising and has not yet run + * find_primary_node_repeatedly(); its primary_node_id is still + * the initial sentinel -2. Do not overwrite our locally-determined + * primary with the leader's stale initial state. + * + * Without this guard, a simultaneous restart of all pgpool nodes + * leaves every STANDBY watchdog with primary_node_id = -2 forever: + * sync_backend_from_watchdog() is only re-invoked on + * SIG_BACKEND_SYNC_REQUIRED (raised from WD_FAILOVER_END), so + * there is no normal path that resyncs once the leader's own + * find_primary_node_repeatedly() completes. + */ + ereport(LOG, + (errmsg("primary node on leader watchdog node \"%s\" is still in the initial state", + backendStatus->nodeName), + errdetail("keeping the locally-detected primary node:%d", Req_info->primary_node_id))); + } + else + { + Req_info->primary_node_id = backendStatus->primary_node_id; + primary_changed = true; } - - r = pool_pause(&timeout); - POOL_SETMASK(&BlockSig); - if (r > 0) - CHECK_REQUEST; - POOL_SETMASK(&UnBlockSig); - gettimeofday(¤t_time, NULL); } - POOL_SETMASK(&BlockSig); -} -/* - * trigger_failover_command: execute specified command at failover. - * command_line is null-terminated string. - */ -static int -trigger_failover_command(int node, const char *command_line, - int old_master, int new_master, int old_primary) -{ - int r = 0; - String *exec_cmd; - char port_buf[6]; - char buf[2]; - BackendInfo *info; - BackendInfo *newmaster; + pfree(backendStatus); - if (command_line == NULL || (strlen(command_line) == 0)) - return 0; + if (reload_master_node_id) + { + Req_info->main_node_id = get_next_main_node(); + } - /* check failed nodeID */ - if (node < 0 || node >= NUM_BACKENDS) - return -1; + /* We don't need to do anything else if the Pgpool-II is starting up */ + if (processState == INITIALIZING) + return; + + /* + * Decide if All or subset of the Pgpool-II children needs immediate + * restart or we can do that after finishing the current session + * + * Check if there was no change at all + */ + if (node_status_was_changed_to_up == false && + node_status_was_changed_to_down == false && + primary_changed == false) + { + ereport(LOG, + (errmsg("backend nodes status remains same after the sync from \"%s\"", backendStatus->nodeName))); + return; + } + if (!STREAM) + { + /* + * If we are not in streaming replication mode restart all child + * processes + */ + ereport(LOG, + (errmsg("node status was changed after the sync from \"%s\"", backendStatus->nodeName), + errdetail("all children needs to be restarted as we are not in streaming replication mode"))); + need_to_restart_children = true; + partial_restart = false; + } + else if (primary_changed) + { + /* + * if Primary node was changed, We should restart all children + */ + need_to_restart_children = true; + partial_restart = false; + ereport(LOG, + (errmsg("primary node was changed after the sync from \"%s\"", backendStatus->nodeName), + errdetail("all children needs to be restarted"))); - info = pool_get_node_info(node); - if (!info) - return -1; + } + else + { + if (node_status_was_changed_to_down == false) + { + /* + * no node was detached, So no need to restart any child process + */ + need_to_restart_children = false; + partial_restart = false; + ereport(LOG, + (errmsg("No backend node was detached because of backend status sync from \"%s\"", backendStatus->nodeName), + errdetail("no need to restart children"))); + } + else + { + ereport(LOG, + (errmsg("%d backend node(s) were detached because of backend status sync from \"%s\"", down_node_ids_index, backendStatus->nodeName), + errdetail("restarting the children processes"))); - buf[1] = '\0'; - exec_cmd = init_string(""); + need_to_restart_children = true; + partial_restart = !check_all_backend_down(); + } + } - while (*command_line) + /* Kill children and restart them if needed */ + if (need_to_restart_children) { - if (*command_line == '%') + for (i = 0; i < pool_config->num_init_children; i++) { - if (*(command_line + 1)) + bool restart = false; + + if (partial_restart) { - char val = *(command_line + 1); + int j, + k; - switch (val) + for (j = 0; j < pool_config->max_pool; j++) { - case 'p': /* failed node port */ - snprintf(port_buf, sizeof(port_buf), "%d", info->backend_port); - string_append_char(exec_cmd, port_buf); - break; - - case 'D': /* failed node database directory */ - string_append_char(exec_cmd, info->backend_data_directory); - break; - - case 'd': /* failed node id */ - snprintf(port_buf, sizeof(port_buf), "%d", node); - string_append_char(exec_cmd, port_buf); - break; - - case 'h': /* failed host name */ - string_append_char(exec_cmd, info->backend_hostname); - break; - - case 'H': /* new master host name */ - newmaster = pool_get_node_info(new_master); - if (newmaster) - string_append_char(exec_cmd, newmaster->backend_hostname); - else - /* no valid new master */ - string_append_char(exec_cmd, "\"\""); - break; - - case 'm': /* new master node id */ - snprintf(port_buf, sizeof(port_buf), "%d", new_master); - string_append_char(exec_cmd, port_buf); - break; + for (k = 0; k < NUM_BACKENDS; k++) + { + int idx; + ConnectionInfo *con = pool_coninfo(i, j, k); - case 'r': /* new master port */ - newmaster = pool_get_node_info(get_next_master_node()); - if (newmaster) + for (idx = 0; idx < down_node_ids_index; idx++) { - snprintf(port_buf, sizeof(port_buf), "%d", newmaster->backend_port); - string_append_char(exec_cmd, port_buf); - } - else - /* no valid new master */ - string_append_char(exec_cmd, "\"\""); - break; - - case 'R': /* new master database directory */ - newmaster = pool_get_node_info(get_next_master_node()); - if (newmaster) - string_append_char(exec_cmd, newmaster->backend_data_directory); - else - /* no valid new master */ - string_append_char(exec_cmd, "\"\""); - break; - - case 'M': /* old master node id */ - snprintf(port_buf, sizeof(port_buf), "%d", old_master); - string_append_char(exec_cmd, port_buf); - break; + int node_id = down_node_ids[idx]; - case 'P': /* old primary node id */ - snprintf(port_buf, sizeof(port_buf), "%d", old_primary); - string_append_char(exec_cmd, port_buf); - break; + if (con->connected && con->load_balancing_node == node_id) + { + ereport(LOG, + (errmsg("child process with PID:%d needs restart, because pool %d uses backend %d", + process_info[i].pid, j, node_id))); + restart = true; + break; + } + if (restart) + break; + } + } + } + } + else + { + restart = true; + } - case '%': /* escape */ - string_append_char(exec_cmd, "%"); - break; + if (restart) + { + if (process_info[i].pid) + { + kill(process_info[i].pid, SIGQUIT); - default: /* ignore */ - break; + process_info[i].pid = fork_a_child(fds, i); + process_info[i].start_time = time(NULL); + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; + process_info[i].connected = 0; + process_info[i].wait_for_connect = 0; + process_info[i].pooled_connections = 0; } - command_line++; } + else + process_info[i].need_to_restart = 1; } - else - { - buf[0] = *command_line; - string_append_char(exec_cmd, buf); - } - command_line++; } - if (strlen(exec_cmd->data) != 0) + else { - ereport(LOG, - (errmsg("execute command: %s", exec_cmd->data))); - r = system(exec_cmd->data); + /* + * Set restart request to each child. Children will exit(1) whenever + * they are convenient. + */ + for (i = 0; i < pool_config->num_init_children; i++) + { + if (process_info[i].pid) + process_info[i].need_to_restart = 1; + } } - free_string(exec_cmd); + /* + * Send restart request to worker child. + */ + kill(worker_pid, SIGUSR1); + + /* Fork health check process if needed */ + for (i = 0; i < NUM_BACKENDS; i++) + { + if (health_check_pids[i] == 0) + { + ereport(LOG, + (errmsg("start health check process for host %s(%d)", + BACKEND_INFO(i).backend_hostname, + BACKEND_INFO(i).backend_port))); - return r; + health_check_pids[i] = worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); + } + } } /* - * This function is used by find_primary_node(). Find primary node/standby - * node and returns static array of status for each backend node. This - * function must not throw ERROR or FATAL. + * Obtain backend server version number and cache it. Note that returned + * version number is in the static memory area. */ -static POOL_NODE_STATUS pool_node_status[MAX_NUM_BACKENDS]; - -POOL_NODE_STATUS * -verify_backend_node_status(POOL_CONNECTION_POOL_SLOT * *slots) +static int +get_server_version(POOL_CONNECTION_POOL_SLOT **slots, int node_id) { + static int server_versions[MAX_NUM_BACKENDS]; + + char *query; POOL_SELECT_RESULT *res; - int num_primaries = 0; - int num_standbys = 0; - int i, - j; - BackendInfo *backend_info; - for (i = 0; i < NUM_BACKENDS; i++) + if (server_versions[node_id] == 0) { - pool_node_status[i] = POOL_NODE_STATUS_UNUSED; - - if (!VALID_BACKEND(i)) - continue; + query = "SELECT pg_catalog.current_setting('server_version_num')"; - if (!slots[i]) - continue; - - if (get_query_result(slots, i, "SELECT pg_is_in_recovery()", &res)) - { - continue; - } - - get_server_version(slots, i); - - if (res->data[0] && !strcmp(res->data[0], "t")) - { - /* Possibly standby */ - pool_node_status[i] = POOL_NODE_STATUS_STANDBY; - num_standbys++; - } - else if (res->data[0] && !strcmp(res->data[0], "f")) + /* Get backend server version. If the query fails, keep previous info. */ + if (get_query_result(slots, node_id, query, &res) == 0) { - /* Possibly primary */ - pool_node_status[i] = POOL_NODE_STATUS_PRIMARY; - num_primaries++; + server_versions[node_id] = atoi(res->data[0]); + ereport(DEBUG1, + (errmsg("get_server_version: backend %d server version: %d", node_id, server_versions[node_id]))); + free_select_result(res); } - free_select_result(res); } + return server_versions[node_id]; +} - /* - * If there's no primary node, there's no point to run additional - * testings. - */ - if (num_primaries == 0) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: there's no primary node"))); - return pool_node_status; - } +/* + * Get info from conninfo string. + */ +static void +get_info_from_conninfo(char *conninfo, char *host, int hostlen, char *port, int portlen) +{ + char *p; - /* - * There's no standby node. - */ - if (num_standbys == 0) + *host = '\0'; + *port = '\0'; + + p = strstr(conninfo, "host"); + if (p) { - if (num_primaries == 1) - { - /* - * If there's only one primary node and there's no standby, - * there's no point to run additional testings. - */ - ereport(DEBUG1, - (errmsg("verify_backend_node_status: there's no standby node"))); - return pool_node_status; - } - else - { - /* - * There are multiple primaries and there's no standby node. - * There's no way to decide which one is correct. We just leave - * the youngest primary node and detach rests if allowed. - */ - for (i = 0; i < NUM_BACKENDS; i++) - { - if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: decided node %d is the true primary", i))); - i++; - for (; i < NUM_BACKENDS; i++) - { - if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) - { - if (pool_config->detach_false_primary) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: node %d is a false primary", i))); - pool_node_status[i] = POOL_NODE_STATUS_INVALID; - } - else - pool_node_status[i] = POOL_NODE_STATUS_UNUSED; - } - } - } - } - } - return pool_node_status; + /* skip "host=" */ + while (*p && *p++ != '=') + ; + + while (*p && hostlen-- && *p != ' ') + *host++ = *p++; + *host = '\0'; } - /* - * There are multiple standbys - */ - else + p = strstr(conninfo, "port"); + if (p) { - bool check_connectivity = false; - int wal_receiver_status = 0; - int wal_receiver_conninfo = 1; - char host[1024]; - char port[1024]; - int primary[MAX_NUM_BACKENDS]; - int true_primary = -1; + /* skip "port=" */ + while (*p && *p++ != '=') + ; - ereport(DEBUG1, - (errmsg("verify_backend_node_status: multiple standbys: %d", num_standbys))); + while (*p && portlen-- && *p != ' ') + *port++ = *p++; + *port = '\0'; + } +} - if (!pool_config->detach_false_primary) +/* + * Set backend status changed time for specified backend id. + */ +void +pool_set_backend_status_changed_time(int backend_id) +{ + time_t tval; + + tval = time(NULL); + BACKEND_INFO(backend_id).status_changed_time = tval; +} + +/* + * Acquire lock on follow primary command execution. Follow primary command + * and detach_false_primary must acquire this lock before execution because + * they are conflicting each other. If argument "block" is true, this + * function will not return until it succeeds in acquiring the lock. This + * function returns true if succeeded in acquiring the lock. + * + * first arg:block is ignored when remote_request is set + */ +bool +pool_acquire_follow_primary_lock(bool block, bool remote_request) +{ + pool_sigset_t oldmask; + volatile int follow_primary_count; + + for (;;) + { + POOL_SETMASK2(&BlockSig, &oldmask); + pool_semaphore_lock(FOLLOW_PRIMARY_SEM); + follow_primary_count = Req_info->follow_primary_count; + + if (follow_primary_count <= 0) { + /* the lock is not held by anyone */ ereport(DEBUG1, - (errmsg("verify_backend_node_status: detach_false_primary is off and no additional checking is performed"))); - return pool_node_status; + (errmsg("pool_acquire_follow_primary_lock: lock was not held by anyone"))); + break; } - - /* - * Check connectivity between primary and standby by using - * pg_stat_wal_receiver (only >= 9.6.0) if there's more than or equal - * to 1 primary. - */ - for (i = 0; i < NUM_BACKENDS; i++) + else if (follow_primary_count > 0 && remote_request) { - if (!VALID_BACKEND(i)) - continue; + if (Req_info->follow_primary_lock_held_remotely) + { + /* + * The lock was already held by remote node and we only + * support one remote lock + */ + ereport(LOG, + (errmsg("pool_acquire_follow_primary_lock: received remote locking request while lock is already held by the remote node"))); - if (get_server_version(slots, i) >= 90600) + } + else { - check_connectivity = true; - break; + /* set the flag that watchdog has requested the lock */ + Req_info->follow_primary_lock_pending = true; } + pool_semaphore_unlock(FOLLOW_PRIMARY_SEM); + POOL_SETMASK(&oldmask); + /* return and inform that the lock was held by someone */ + ereport(DEBUG1, + (errmsg("pool_acquire_follow_primary_lock: lock was held by someone %d", follow_primary_count))); + return false; } - if (!check_connectivity) + + else if (follow_primary_count > 0 && !block) { + pool_semaphore_unlock(FOLLOW_PRIMARY_SEM); + POOL_SETMASK(&oldmask); + /* return and inform that the lock was held by someone */ ereport(DEBUG1, - (errmsg("verify_backend_node_status: server verion is lower than 9.6.0. Skipping connectivity checks"))); - return pool_node_status; + (errmsg("pool_acquire_follow_primary_lock: lock was held by someone %d", follow_primary_count))); + return false; } + pool_semaphore_unlock(FOLLOW_PRIMARY_SEM); + POOL_SETMASK(&oldmask); ereport(DEBUG1, - (errmsg("verify_backend_node_status: checking connectivity"))); - - for (i = 0; i < NUM_BACKENDS; i++) - { - primary[i] = 0; - - if (!VALID_BACKEND(i)) - continue; + (errmsg("pool_acquire_follow_primary_lock: lock was held by someone %d sleeping...", follow_primary_count))); + sleep(1); + } - if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: %d is primary", i))); + /* acquire lock */ + Req_info->follow_primary_lock_held_remotely = remote_request; - for (j = 0; j < NUM_BACKENDS; j++) - { - if (pool_node_status[j] == POOL_NODE_STATUS_STANDBY) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: %d is standby", j))); + Req_info->follow_primary_count = 1; + pool_semaphore_unlock(FOLLOW_PRIMARY_SEM); + POOL_SETMASK(&oldmask); - if (get_query_result(slots, j, "SELECT status, conninfo FROM pg_stat_wal_receiver", &res)) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: call pg_stat_wal_receiver to standby %d failed", j))); - continue; - } - if (res->numrows <= 0) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: pg_stat_wal_receiver returned no row. standby %d", j))); - free_select_result(res); - continue; - } - if (res->nullflags[wal_receiver_status] == -1) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: pg_stat_wal_receiver status for standby %d is NULL", j))); - free_select_result(res); - continue; - } - if (strcmp(res->data[wal_receiver_status], "streaming")) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: pg_stat_wal_receiver status is not \"streaming\" for standby %d (%s)", j, res->data[wal_receiver_status]))); - free_select_result(res); - continue; + ereport(DEBUG1, + (errmsg("pool_acquire_follow_primary_lock: succeeded in acquiring lock"))); - } - if (res->nullflags[wal_receiver_conninfo] == -1) - { - ereport(DEBUG1, - (errmsg("verify_backend_node_status: pg_stat_wal_receiver conninfo for standby %d is NULL", j))); - continue; - } - get_info_from_conninfo(res->data[wal_receiver_conninfo], host, port); - ereport(DEBUG1, - (errmsg("verify_backend_node_status: conninfo for standby %d is === %s ===. host:%s port:%s", j, res->data[wal_receiver_conninfo], host, port))); - free_select_result(res); + return true; +} - /* get primary backend info */ - backend_info = pool_get_node_info(i); +/* + * Release lock on follow primary command execution. + */ +void +pool_release_follow_primary_lock(bool remote_request) +{ + pool_sigset_t oldmask; - /* verify host and port */ - if (((*backend_info->backend_hostname == '/' && *host == '\0') || - !strcmp(backend_info->backend_hostname, host)) && - backend_info->backend_port == atoi(port)) - { - /* the standby connects to the primary */ - primary[i]++; - if (primary[i] == num_standbys) - true_primary = i; - } - else - { - /* the standby does not connect to the primary */ - ereport(LOG, - (errmsg("verify_backend_node_status: primary %d does not connect to standby %d", i, j))); - } - } - } - } + POOL_SETMASK2(&BlockSig, &oldmask); + pool_semaphore_lock(FOLLOW_PRIMARY_SEM); + if (remote_request) + { + if (Req_info->follow_primary_lock_held_remotely) + { + /* remote request can only release locks held by remote nodes */ + Req_info->follow_primary_count = 0; + Req_info->follow_primary_lock_held_remotely = false; + ereport(DEBUG1, + (errmsg("pool_release_follow_primary_lock relased the remote lock"))); + } + else if (Req_info->follow_primary_count) + { + /* + * we have received the release lock request from remote but the + * lock is not held by remote node. Just ignore the request + */ + ereport(DEBUG1, + (errmsg("pool_release_follow_primary_lock is not relasing the lock since it was not held by remote node"))); } /* - * Check if each primary connected standbys. If all standbys connect - * to one of primaries, then the primary is good. Other primaries are - * false. If none of primaries does not own all connected standbys, - * we cannot judge which primary is good. + * Silently ignore, if we received the release request from remote + * while no lock was held. Also clear the pending lock request, As we + * only support single remote lock */ - for (i = 0; i < NUM_BACKENDS; i++) + Req_info->follow_primary_lock_pending = false; + + } + else /* local request */ + { + /* + * if we have a pending lock request from watchdog do not remove the + * actual lock, Just clear the pending flag + */ + if (Req_info->follow_primary_lock_pending) { + Req_info->follow_primary_lock_held_remotely = true; + Req_info->follow_primary_count = 1; + /* also clear the pending lock flag */ + Req_info->follow_primary_lock_pending = false; ereport(DEBUG1, - (errmsg("verify_backend_node_status: primary %d owns %d standbys out of %d", i, primary[i], num_standbys))); - ereport(DEBUG1, - (errmsg("verify_backend_node_status: true_primary %d", true_primary))); - - if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY && primary[i] >= 0) + (errmsg("pool_release_follow_primary_lock is not relasing the lock and shifting it to coordinator watchdog node"))); + } + else + { + if (Req_info->follow_primary_lock_held_remotely) { - if (primary[i] < num_standbys) - { - ereport(LOG, - (errmsg("verify_backend_node_status: primary %d owns only %d standbys out of %d", i, primary[i], num_standbys))); - - /* - * If the good primary exists and detach_false_primary is - * true, then ask to detach the false primary - */ - if (true_primary >= 0 && pool_config->detach_false_primary) - pool_node_status[i] = POOL_NODE_STATUS_INVALID; - } + /* + * Ideally this should not happen. yet if for some reason our + * local node is trying to release a lock that is held by + * remote node. Just produce a LOG message and release the + * lock + */ + ereport(LOG, + (errmsg("pool_release_follow_primary_lock is relasing the remote lock by local request"))); } + Req_info->follow_primary_count = 0; + Req_info->follow_primary_lock_held_remotely = false; } } + pool_semaphore_unlock(FOLLOW_PRIMARY_SEM); + POOL_SETMASK(&oldmask); - return pool_node_status; -} + ereport(DEBUG1, + (errmsg("pool_release_follow_primary_lock called"))); -POOL_NODE_STATUS * -pool_get_node_status(void) -{ - return pool_node_status; } /* - * Find the primary node (i.e. not standby node) and returns its node - * id. If no primary node is found, returns -1. + * Sending log rotation signal to logger process. */ -static int -find_primary_node(void) +void +pool_signal_logrotate(void) { - BackendInfo *bkinfo; - POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; - int i; - POOL_NODE_STATUS *status; - int primary = -1; - char *password = NULL; - - /* Streaming replication mode? */ - if (!SL_MODE) + if (!pool_config->logging_collector) { - /* - * No point to look for primary node if not in streaming replication - * mode. - */ - ereport(DEBUG1, - (errmsg("find_primary_node: not in streaming replication mode"))); - return -1; + ereport(ERROR, + (errmsg("process log rotation request failed"), + errdetail("logging_collector is disabled"))); } - /* - * First check for "ALWAYS_MASTER" flags exists. If so, do not perform - * actual primary node check and just returns the node id. - */ - for (i = 0; i < NUM_BACKENDS; i++) + if (pgpool_logger_pid != 0) { - if (POOL_ALWAYS_MASTER & BACKEND_INFO(i).flag) - { - ereport(DEBUG1, - (errmsg("find_primary_node: ALWAYS_MASTER flag found. Returns node id: %d", i))); - return i; - } - } - - password = get_pgpool_config_user_password(pool_config->sr_check_user, - pool_config->sr_check_password); + ereport(DEBUG1, + (errmsg("sending SIGUSR1 to logger process with PID:%d to rotate log file", pgpool_logger_pid))); - /* - * Establish connections to backend - */ - for (i = 0; i < NUM_BACKENDS; i++) + if (kill(pgpool_logger_pid, SIGUSR1) != 0) + ereport(ERROR, + (errmsg("process log rotation request failed"), + errdetail("failed to send SIGUSR1 to logger process with PID:%d", pgpool_logger_pid))); + } + else { - slots[i] = NULL; - - if (!VALID_BACKEND(i)) - continue; + ereport(ERROR, + (errmsg("process log rotation request failed"), + errdetail("logger process PID:%d is not valid", pgpool_logger_pid))); + } +} - bkinfo = pool_get_node_info(i); +/* + * ------------------------------------------------------------------------- + * Subroutines for failover() begin + * ------------------------------------------------------------------------- + */ - slots[i] = make_persistent_db_connection_noerror(i, bkinfo->backend_hostname, - bkinfo->backend_port, - pool_config->sr_check_database, - pool_config->sr_check_user, - password ? password : "", true); - if (!slots[i]) - { +/* + * Handle failback request. Called from failover(). + */ +static int +handle_failback_request(FAILOVER_CONTEXT *failover_context, int node_id) +{ + if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || + (failover_context->reqkind == NODE_UP_REQUEST && !(RAW_MODE && + BACKEND_INFO(node_id).backend_status == CON_DOWN) && VALID_BACKEND(node_id)) || + (failover_context->reqkind == NODE_DOWN_REQUEST && !VALID_BACKEND(node_id))) + { + if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) ereport(LOG, - (errmsg("find_primary_node: make_persistent_db_connection_noerror failed on node %d", i))); - } + (errmsg("invalid failback request, node id: %d is invalid. node id must be between [0 and %d]", node_id, MAX_NUM_BACKENDS))); + else + ereport(LOG, + (errmsg("invalid failback request, status: [%d] of node id : %d is invalid for failback", BACKEND_INFO(node_id).backend_status, node_id))); + + return -1; } - if (password) - pfree(password); + ereport(LOG, + (errmsg("=== Starting fail back. reconnect host %s(%d) ===", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); - /* Verify backend status */ - status = verify_backend_node_status(slots); + /* Check to see if all backends are down */ + failover_context->all_backend_down = check_all_backend_down(); - for (i = 0; i < NUM_BACKENDS; i++) + BACKEND_INFO(node_id).backend_status = CON_CONNECT_WAIT; /* unset down status */ + pool_set_backend_status_changed_time(node_id); + + if ((failover_context->request_details & REQ_DETAIL_UPDATE)) { - if (status[i] == POOL_NODE_STATUS_PRIMARY) + /* remove the quarantine flag */ + BACKEND_INFO(node_id).quarantine = false; + + /* + * do not search for primary node when handling the quarantine nodes + */ + failover_context->search_primary = false; + + /* + * recalculate the main node id after setting the backend status of + * quarantined node, this will bring us to the old main_node_id that + * was before the quarantine state + */ + Req_info->main_node_id = get_next_main_node(); + if (Req_info->primary_node_id == -1 && + BACKEND_INFO(node_id).role == ROLE_PRIMARY) { - /* This is the primary */ + /* + * if the failback request is for the quarantined node and that + * node had a primary role before it was quarantined, restore the + * primary node status for that node. this is important for the + * failover script to get the proper value of old primary + */ ereport(LOG, - (errmsg("find_primary_node: primary node is %d", i))); - primary = i; + (errmsg("failover: failing back the quarantine node that was primary before it was quarantined"), + errdetail("all children needs a restart"))); + Req_info->primary_node_id = node_id; + + /* + * since we changed the primary node so restart of all children is + * required + */ + failover_context->need_to_restart_children = true; + failover_context->partial_restart = false; } - else if (status[i] == POOL_NODE_STATUS_STANDBY) + else if (failover_context->all_backend_down == false) { ereport(LOG, - (errmsg("find_primary_node: standby node is %d", i))); + (errmsg("Do not restart children because we are failing back node id %d host: %s port: %d and we are in streaming replication mode and not all backends were down", node_id, + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); + failover_context->need_to_restart_children = false; + failover_context->partial_restart = false; } - else if (status[i] == POOL_NODE_STATUS_INVALID) + else { - /* Split brain or invalid node */ - ereport(LOG, - (errmsg("find_primary_node: invalid node %d", i))); + failover_context->need_to_restart_children = true; + failover_context->partial_restart = false; } } - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (slots[i]) - discard_persistent_db_connection(slots[i]); - } - - return primary; -} - -static int -find_primary_node_repeatedly(void) -{ - int sec; - int node_id = -1; - - /* Streaming replication mode? */ - if (!SL_MODE) + else { /* - * No point to look for primary node if not in streaming replication - * mode. + * The request is a proper failback request and not because of the + * update status of quarantined node */ - ereport(DEBUG1, - (errmsg("find_primary_node: not in streaming replication mode"))); - return -1; - } + (void) write_status_file(); - /* - * Try to find the new primary node and keep trying for - * search_primary_node_timeout seconds. search_primary_node_timeout = 0 - * means never timeout and keep searching indefinitely - */ - ereport(LOG, - (errmsg("find_primary_node_repeatedly: waiting for finding a primary node"))); - for (sec = 0; (pool_config->search_primary_node_timeout == 0 || - sec < pool_config->search_primary_node_timeout); sec++) - { - node_id = find_primary_node(); - if (node_id != -1) - break; - pool_sleep(1); + trigger_failover_command(node_id, pool_config->failback_command, + MAIN_NODE_ID, get_next_main_node(), PRIMARY_NODE_ID); } - return node_id; + + failover_context->sync_required = true; + + return 0; } /* -* fork a follow child -*/ -pid_t -fork_follow_child(int old_master, int new_primary, int old_primary) + * Handle failover request. Called from failover(). + * return -1 if no node is requested failover. + */ +static int +handle_failover_request(FAILOVER_CONTEXT *failover_context, int node_id) { - pid_t pid; + int cnt = 0; /* number of down node ids */ int i; - pid = fork(); - - if (pid == 0) + for (i = 0; i < failover_context->node_count; i++) { - on_exit_reset(); - processType = PT_FOLLOWCHILD; - - ereport(LOG, - (errmsg("start triggering follow command."))); - for (i = 0; i < pool_config->backend_desc->num_backends; i++) + if (failover_context->node_id_set[i] != -1 && (BACKEND_INFO(failover_context->node_id_set[i]).quarantine == true || + ((RAW_MODE && VALID_BACKEND_RAW(failover_context->node_id_set[i])) || + VALID_BACKEND(failover_context->node_id_set[i])))) { - BackendInfo *bkinfo; + ereport(LOG, + (errmsg("=== Starting %s. shutdown host %s(%d) ===", + (failover_context->reqkind == NODE_QUARANTINE_REQUEST) ? "quarantine" : "degeneration", + BACKEND_INFO(failover_context->node_id_set[i]).backend_hostname, + BACKEND_INFO(failover_context->node_id_set[i]).backend_port))); + + BACKEND_INFO(failover_context->node_id_set[i]).backend_status = CON_DOWN; /* set down status */ + pool_set_backend_status_changed_time(failover_context->node_id_set[i]); + if (failover_context->reqkind == NODE_QUARANTINE_REQUEST) + { + BACKEND_INFO(failover_context->node_id_set[i]).quarantine = true; + } + else + { + /* + * if the degeneration request is for the quarantined node and + * that node had a primary role before it was quarantined, + * Restore the primary node status for that node before + * degenerating it. This is important for the failover script + * to get the proper value of old primary + */ + if (Req_info->primary_node_id == -1 && + BACKEND_INFO(failover_context->node_id_set[i]).quarantine == true && + BACKEND_INFO(failover_context->node_id_set[i]).role == ROLE_PRIMARY) + { + ereport(DEBUG2, + (errmsg("failover: degenerating the node that was primary node before it was quarantined"))); + Req_info->primary_node_id = failover_context->node_id_set[i]; + failover_context->search_primary = false; + } + BACKEND_INFO(failover_context->node_id_set[i]).quarantine = false; + (void) write_status_file(); + } - bkinfo = pool_get_node_info(i); - if (bkinfo->backend_status == CON_DOWN) - trigger_failover_command(i, pool_config->follow_master_command, - old_master, new_primary, old_primary); + /* save down node */ + failover_context->nodes[failover_context->node_id_set[i]] = 1; + cnt++; } - exit(0); } - else if (pid == -1) + + if (cnt == 0) { - ereport(WARNING, - (errmsg("follow fork() failed with reason: \"%s\"", strerror(errno)))); - exit(1); + ereport(LOG, + (errmsg("failover: no backends are degenerated"))); + return -1; } - return pid; + return 0; } - +/* + * Kill child process to prepare failover/failback. + */ static void -initialize_shared_mem_objects(bool clear_memcache_oidmaps) +kill_failover_children(FAILOVER_CONTEXT *failover_context, int node_id) { - int size, - i; + int i, + j, + k; /* - * con_info is a 3 dimension array: i corresponds to pgpool child process, - * j corresponds to connection pool in each process and k corresponds to - * backends in each connection pool. - * - * XXX: Before 2010/4/12 this was a 2 dimension array: i corresponds to - * pgpool child process, j corresponds to connection pool in each process. - * Of course this was wrong. + * On 2011/5/2 Tatsuo Ishii says: if mode is streaming replication and + * request is NODE_UP_REQUEST (failback case) we don't need to restart all + * children. Existing session will not use newly attached node, but load + * balanced node is not changed until this session ends, so it's harmless + * anyway. */ - size = pool_coninfo_size(); - con_info = pool_shared_memory_create(size); - memset(con_info, 0, size); - - size = pool_config->num_init_children * (sizeof(ProcessInfo)); - - ereport(DEBUG1, - (errmsg("ProcessInfo: num_init_children (%d) * sizeof(ProcessInfo) (%zu) = %d bytes requested for shared memory", - pool_config->num_init_children, - sizeof(ProcessInfo), - size))); - - process_info = pool_shared_memory_create(size); - memset(process_info, 0, size); - - for (i = 0; i < pool_config->num_init_children; i++) - { - process_info[i].connection_info = pool_coninfo(i, 0, 0); - } - - user1SignalSlot = pool_shared_memory_create(sizeof(User1SignalSlot)); - /* create fail over/switch over event area */ - Req_info = pool_shared_memory_create(sizeof(POOL_REQUEST_INFO)); - - ereport(DEBUG1, - (errmsg("Request info are: sizeof(POOL_REQUEST_INFO) %zu bytes requested for shared memory", - sizeof(POOL_REQUEST_INFO)))); /* - * Initialize backend status area. From now on, VALID_BACKEND macro can be - * used. (get_next_master_node() uses VALID_BACKEND) + * On 2015/9/21 Tatsuo Ishii says: this judgment is not sufficient if all + * backends were down. Child process has local status in which all + * backends are down. In this case even if new connection arrives from + * frontend, the child will not accept it because the local status shows + * all backends are down. For this purpose we refer to "all_backend_down" + * variable, which was set before updating backend status. + * + * See bug 248 for more details. */ - for (i = 0; i < MAX_NUM_BACKENDS; i++) + /* + * We also need to think about a case when the former primary node did not + * exist. In the case we need to restart all children as well. For + * example when previous primary node id is 0 and then it went down, + * restarted, re-attached without promotion. Then existing child process + * loses connection slot to node 0 and keeps on using it when node 0 comes + * back. This could result in segfault later on in the child process + * because there's no connection to node id 0. + * + * Actually we need to think about when ALWAYS_PRIMARY flag is set *but* + * DISALLOW_TO_FAILOVER flag is not set case. In the case after primary + * failover Req_info->primary_node_id is set, but connection to the + * primary node does not exist. So we should do full restart if requested + * node id is the former primary node. + * + * See bug 672 for more details. + */ + if (STREAM && failover_context->reqkind == NODE_UP_REQUEST && failover_context->all_backend_down == false && + Req_info->primary_node_id >= 0 && Req_info->primary_node_id != node_id) { - my_backend_status[i] = &(BACKEND_INFO(i).backend_status); - } - - /* initialize Req_info */ - Req_info->master_node_id = get_next_master_node(); - Req_info->conn_counter = 0; - Req_info->switching = false; - Req_info->request_queue_head = Req_info->request_queue_tail = -1; - Req_info->primary_node_id = -2; - InRecovery = pool_shared_memory_create(sizeof(int)); - *InRecovery = RECOVERY_INIT; + /* + * The decision to restart/no-restart children for update status + * request has already been made + */ + if (!(failover_context->request_details & REQ_DETAIL_UPDATE)) + { + ereport(LOG, + (errmsg("Do not restart children because we are failing back node id %d host: %s port: %d and we are in streaming replication mode and not all backends were down", node_id, + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); - ereport(DEBUG1, - (errmsg("Recovery management area: sizeof(int) %zu bytes requested for shared memory", - sizeof(int)))); + failover_context->need_to_restart_children = false; + failover_context->partial_restart = false; + } + } /* - * Initialize shared memory cache + * If the mode is streaming replication and the request is + * NODE_DOWN_REQUEST and it's actually a switch over request, we don't + * need to restart all children, except the node is primary. */ - if (pool_config->memory_cache_enabled) + else if (STREAM && (failover_context->reqkind == NODE_DOWN_REQUEST || failover_context->reqkind == NODE_QUARANTINE_REQUEST) && + failover_context->request_details & REQ_DETAIL_SWITCHOVER && node_id != PRIMARY_NODE_ID) { - if (pool_is_shmem_cache()) - { - size_t size; - - size = pool_shared_memory_cache_size(); - pool_init_memory_cache(size); + ereport(LOG, + (errmsg("Do not restart children because we are switching over node id %d host: %s port: %d and we are in streaming replication mode", node_id, + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); - size = pool_shared_memory_fsmm_size(); - if (size == 0) - ereport(FATAL, - (errmsg("invalid shared memory size"), - errdetail("pool_shared_memory_fsmm_size error"))); + failover_context->need_to_restart_children = true; + failover_context->partial_restart = true; - pool_init_fsmm(size); + for (i = 0; i < pool_config->num_init_children; i++) + { + bool restart = false; - pool_allocate_fsmm_clock_hand(); + for (j = 0; j < pool_config->max_pool; j++) + { + for (k = 0; k < NUM_BACKENDS; k++) + { + ConnectionInfo *con = pool_coninfo(i, j, k); - pool_discard_oid_maps(); + if (con->connected && con->load_balancing_node == node_id) + { + ereport(LOG, + (errmsg("child pid %d needs to restart because pool %d uses backend %d", + process_info[i].pid, j, node_id))); + restart = true; + break; + } + } + } - ereport(LOG, - (errmsg("pool_discard_oid_maps: discarded memqcache oid maps"))); + if (restart) + { + pid_t pid = process_info[i].pid; - pool_hash_init(pool_config->memqcache_max_num_cache); + if (pid) + { + kill(pid, SIGQUIT); + ereport(DEBUG1, + (errmsg("failover handler"), + errdetail("kill process with PID:%d", pid))); + } + } } + } + else + { + ereport(LOG, + (errmsg("Restart all children"))); -#ifdef USE_MEMCACHED - else + /* kill all children */ + for (i = 0; i < pool_config->num_init_children; i++) { - if (clear_memcache_oidmaps) + pid_t pid = process_info[i].pid; + + if (pid) { - pool_discard_oid_maps(); - ereport(LOG, - (errmsg("discarded memqcache oid maps"))); + kill(pid, SIGQUIT); + ereport(DEBUG1, + (errmsg("failover handler"), + errdetail("kill process with PID:%d", pid))); } - else + } + + failover_context->need_to_restart_children = true; + failover_context->partial_restart = false; + } +} + +/* + * Exec failover_command if needed. We do not execute failover when request is + * quarantine type. Also if the request is to promote specified node, execute + * failover command. + */ +static void +exec_failover_command(FAILOVER_CONTEXT *failover_context, int new_main_node_id, int promote_node_id) +{ + int i; + + if (failover_context->reqkind == NODE_DOWN_REQUEST) + { + for (i = 0; i < pool_config->backend_desc->num_backends; i++) + { + if (failover_context->nodes[i]) { - ereport(DEBUG1, - (errmsg("skipped discarding memqcache oid maps"))); + /* + * If this is promoting specified node, new_main_node should + * be replaced by the requested node. The requested node + * should be REAL_PRIMARY_NODE_ID. + */ + if (failover_context->request_details & REQ_DETAIL_PROMOTE) + { + trigger_failover_command(i, pool_config->failover_command, + MAIN_NODE_ID, promote_node_id, REAL_PRIMARY_NODE_ID); + } + else + { + trigger_failover_command(i, pool_config->failover_command, + MAIN_NODE_ID, new_main_node_id, REAL_PRIMARY_NODE_ID); + } + failover_context->sync_required = true; } } -#endif - - pool_init_memqcache_stats(); - } - - /* Initialize statistics area */ - stat_set_stat_area(pool_shared_memory_create(stat_shared_memory_size())); - stat_init_stat_area(); - /* initialize watchdog IPC unix domain socket address */ - if (pool_config->use_watchdog) - { - wd_ipc_initialize_data(); } } /* -* Read the status file -*/ + * Determine new primary node id. Possibly call find_primary_node_repeatedly(). + */ static int -read_status_file(bool discard_status) +determine_new_primary_node(FAILOVER_CONTEXT *failover_context, int node_id) { - FILE *fd; - char fnamebuf[POOLMAXPATHLEN]; - int i; - bool someone_wakeup = false; - bool is_old_format; + int new_primary; - snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->logdir, STATUS_FILE_NAME); - fd = fopen(fnamebuf, "r"); - if (!fd) + if (failover_context->reqkind == PROMOTE_NODE_REQUEST && VALID_BACKEND(node_id)) { - ereport(LOG, - (errmsg("Backend status file %s does not exist", fnamebuf))); - return -1; + new_primary = node_id; } - - /* - * If discard_status is true, unlink pgpool_status and do not restore - * previous status. - */ - if (discard_status) + else if (failover_context->reqkind == NODE_QUARANTINE_REQUEST) { - fclose(fd); - if (unlink(fnamebuf) == 0) - ereport(LOG, - (errmsg("Backend status file %s discarded", fnamebuf))); + /* + * If the quarantine node was the primary node, set the new primary to + * -1 (invalid). + */ + if (Req_info->primary_node_id == node_id) + { + /* + * set the role of the node, This will help us restore the primary + * node id when the node will come out from quarantine state + */ + BACKEND_INFO(node_id).role = ROLE_PRIMARY; + new_primary = -1; + } else - ereport(WARNING, - (errmsg("failed to discard backend status file: \"%s\" with reason: \"%s\"", fnamebuf, strerror(errno)))); - return 0; + { + new_primary = Req_info->primary_node_id; + } } /* - * Frist try out with old format file. + * If the down node was a standby node in streaming replication mode, we + * can avoid calling find_primary_node_repeatedly() and recognize the + * former primary as the new primary node, which will reduce the time to + * process standby down. This does not apply to the case when no primary + * node existed (Req_info->primary_node_id < 0). In this case + * find_primary_node_repeatedly() should be called. */ - is_old_format = true; - - if (fread(&backend_rec, 1, sizeof(backend_rec), fd) == sizeof(backend_rec)) + else if (SL_MODE && + failover_context->reqkind == NODE_DOWN_REQUEST) { - /* It's likely old binary format status file */ - for (i = 0; i < pool_config->backend_desc->num_backends; i++) + if (Req_info->primary_node_id >= 0 && Req_info->primary_node_id != node_id) { - if (backend_rec.status[i] == CON_DOWN) - { - BACKEND_INFO(i).backend_status = CON_DOWN; - pool_set_backend_status_changed_time(i); - (void) write_status_file(); - ereport(LOG, - (errmsg("read_status_file: %d th backend is set to down status", i))); - } - else if (BACKEND_INFO(i).backend_status == CON_CONNECT_WAIT || - BACKEND_INFO(i).backend_status == CON_UP) - { - BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; - pool_set_backend_status_changed_time(i); - (void) write_status_file(); - someone_wakeup = true; - } - else - { - /* It seems it's not an old binary format status file */ - is_old_format = false; - break; - } + new_primary = Req_info->primary_node_id; } + else + { + if (Req_info->primary_node_id >= 0) + BACKEND_INFO(Req_info->primary_node_id).role = ROLE_STANDBY; + new_primary = find_primary_node_repeatedly(); + } + } + else if (failover_context->search_primary == false) + { + ereport(DEBUG1, + (errmsg("failover was called on quarantined node. No need to search for primary node"))); + new_primary = Req_info->primary_node_id; } else - is_old_format = false; + { + new_primary = find_primary_node_repeatedly(); + } - fclose(fd); + return new_primary; +} - if (!is_old_format) +/* + * Execute follow primary command if necessary. + * return new main node id if it needs to be changed. + * If not changed, -1 will be returned. + */ +static int +exec_follow_primary_command(FAILOVER_CONTEXT *failover_context, int node_id, int new_primary_node_id) +{ + int follow_cnt = 0; + int new_main_node_id = -1; + int i; + + if (!STREAM) + return -1; + + if (*pool_config->follow_primary_command != '\0' || + failover_context->reqkind == PROMOTE_NODE_REQUEST) { /* - * Fall back to new ascii format file. the format looks like(case is - * ignored): - * - * up|down|unused UP|down|unused : : + * follow primary command is executed in following cases: - failover + * against the current primary - no primary exists and new primary is + * created by failover - promote node request */ -#define MAXLINE 10 - char readbuf[MAXLINE]; - - fd = fopen(fnamebuf, "r"); - if (!fd) - { - ereport(LOG, - (errmsg("Backend status file %s does not exist", fnamebuf))); - return -1; - } - - for (i = 0; i < MAX_NUM_BACKENDS; i++) - { - BACKEND_INFO(i).backend_status = CON_UNUSED; - pool_set_backend_status_changed_time(i); - } - - for (i = 0;; i++) + if (((failover_context->reqkind == NODE_DOWN_REQUEST) && + Req_info->primary_node_id >= 0 && + (failover_context->nodes[Req_info->primary_node_id])) || + (failover_context->reqkind == NODE_DOWN_REQUEST && Req_info->primary_node_id < 0 && new_primary_node_id >= 0) || + (node_id >= 0 && (failover_context->reqkind == PROMOTE_NODE_REQUEST) && + (VALID_BACKEND(node_id)))) { - readbuf[MAXLINE - 1] = '\0'; - if (fgets(readbuf, MAXLINE - 1, fd) == 0) - break; - if (!strncasecmp("up", readbuf, 2)) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { - BACKEND_INFO(i).backend_status = CON_UP; - someone_wakeup = true; + /* do not degenerate the new primary */ + if ((new_primary_node_id >= 0) && (i != new_primary_node_id)) + { + BackendInfo *bkinfo; + + bkinfo = pool_get_node_info(i); + ereport(LOG, + (errmsg("starting follow degeneration. shutdown host %s(%d)", + bkinfo->backend_hostname, + bkinfo->backend_port))); + bkinfo->backend_status = CON_DOWN; /* set down status */ + pool_set_backend_status_changed_time(i); + (void) write_status_file(); + + follow_cnt++; + } } - else if (!strncasecmp("down", readbuf, 4)) + + if (follow_cnt == 0) { - BACKEND_INFO(i).backend_status = CON_DOWN; - pool_set_backend_status_changed_time(i); ereport(LOG, - (errmsg("reading status file: %d th backend is set to down status", i))); - } - else if (!strncasecmp("unused", readbuf, 6)) - { - BACKEND_INFO(i).backend_status = CON_UNUSED; - pool_set_backend_status_changed_time(i); + (errmsg("failover: no follow backends are degenerated"))); } else { - ereport(WARNING, - (errmsg("invalid data in status file, ignoring..."), - errdetail("backend:%d status is invalid: \"%s\"", i, readbuf))); + /* update new primary node */ + new_main_node_id = get_next_main_node(); + ereport(LOG, + (errmsg("failover: %d follow backends have been degenerated", follow_cnt))); } } - fclose(fd); } - /* - * If no one woke up, we regard the status file bogus - */ - if (someone_wakeup == false) + if ((follow_cnt > 0) && (*pool_config->follow_primary_command != '\0')) { - for (i = 0; i < pool_config->backend_desc->num_backends; i++) - { - BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; - pool_set_backend_status_changed_time(i); - } - (void) write_status_file(); + /* exec follow child */ + follow_pid = fork_follow_child(Req_info->primary_node_id, new_primary_node_id, + Req_info->primary_node_id); } - return 0; + return new_main_node_id; } /* -* Write the status file -*/ -int -write_status_file() + * Now new primary node and new main node are established. + * Save them into shared memory. Also update status changed time. + */ +static void +save_node_info(FAILOVER_CONTEXT *failover_context, int new_primary_node_id, int new_main_node_id) { - FILE *fd; - int fdnum; - char fnamebuf[POOLMAXPATHLEN]; - char buf[10]; - int i; - - if (!pool_config) + /* Save primary node id */ + if (Req_info->primary_node_id != new_primary_node_id) { - ereport(WARNING, - (errmsg("pool_config is not set"))); - return 0; + if (Req_info->primary_node_id >= 0) + { + pool_set_backend_status_changed_time(Req_info->primary_node_id); + } + if (new_primary_node_id >= 0) + { + BACKEND_INFO(new_primary_node_id).role = ROLE_PRIMARY; + pool_set_backend_status_changed_time(new_primary_node_id); + } } + Req_info->primary_node_id = new_primary_node_id; + ereport(LOG, + (errmsg("failover: set new primary node: %d", Req_info->primary_node_id))); - /* - * Check to see if all nodes are down status. If so, skip writing status - * file. So pgpool_status will always reflect the last set of nodes to - * which any data was written. Upon restart, if the up-to-date (previously - * "up") node is in fact down (regardless of whether the stale ("down") - * node is back up), pgpool will detect this in its health check and will - * fail; if the up-to-date (previously "up") node is back up, then pgpool - * will commence using it. - * - * See [pgpool-general: 4721] for more discussion. - */ - for (i = 0; i < pool_config->backend_desc->num_backends; i++) + if (new_main_node_id >= 0) { - if (BACKEND_INFO(i).backend_status != CON_DOWN) - break; + Req_info->main_node_id = new_main_node_id; + failover_context->sync_required = true; + ereport(LOG, + (errmsg("failover: set new main node: %d", Req_info->main_node_id))); } +} - if (i && i == pool_config->backend_desc->num_backends) +/* + * Rstart child process if needed. + */ +static void +exec_child_restart(FAILOVER_CONTEXT *failover_context, int node_id) +{ + int i, + j, + k; + + if (failover_context->need_to_restart_children) { - ereport(WARNING, - (errmsg("All the DB nodes are in down status and skip writing status file."))); + for (i = 0; i < pool_config->num_init_children; i++) + { + /* + * Try to kill pgpool child because previous kill signal may not + * be received by pgpool child. This could happen if multiple + * PostgreSQL are going down (or even starting pgpool, without + * starting PostgreSQL can trigger this). Child calls + * degenerate_backend() and it tries to acquire semaphore to write + * a failover request. In this case the signal mask is set as + * well, thus signals are never received. + */ - return 0; + bool restart = false; + + if (failover_context->partial_restart) + { + for (j = 0; j < pool_config->max_pool; j++) + { + for (k = 0; k < NUM_BACKENDS; k++) + { + ConnectionInfo *con = pool_coninfo(i, j, k); + + if (con->connected && con->load_balancing_node == node_id) + { + + ereport(LOG, + (errmsg("child pid %d needs to restart because pool %d uses backend %d", + process_info[i].pid, j, node_id))); + restart = true; + break; + } + } + } + } + else + restart = true; + + if (restart) + { + if (process_info[i].pid) + { + kill(process_info[i].pid, SIGQUIT); + + process_info[i].pid = fork_a_child(fds, i); + process_info[i].start_time = time(NULL); + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; + process_info[i].connected = 0; + process_info[i].wait_for_connect = 0; + process_info[i].pooled_connections = 0; + + } + } + else + process_info[i].need_to_restart = 1; + } + } + + else + { + /* + * Set restart request to each child. Children will exit(1) whenever + * they are convenient. + */ + for (i = 0; i < pool_config->num_init_children; i++) + { + process_info[i].need_to_restart = 1; + } } - snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->logdir, STATUS_FILE_NAME); - fd = fopen(fnamebuf, "w"); - if (!fd) - { - ereport(WARNING, - (errmsg("failed to open status file at: \"%s\"", fnamebuf), - errdetail("\"%s\"", strerror(errno)))); - return -1; - } + /* + * Send restart request to worker child. + */ + kill(worker_pid, SIGUSR1); - for (i = 0; i < pool_config->backend_desc->num_backends; i++) - { - char *status; + if (failover_context->sync_required) + wd_failover_end(); - if (BACKEND_INFO(i).backend_status == CON_UP || - BACKEND_INFO(i).backend_status == CON_CONNECT_WAIT) - status = "up"; - else if (BACKEND_INFO(i).backend_status == CON_DOWN) - status = "down"; - else - status = "unused"; + if (failover_context->reqkind == NODE_UP_REQUEST) + { + ereport(LOG, + (errmsg("=== Failback done. reconnect host %s(%d) ===", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); - sprintf(buf, "%s\n", status); - if (fwrite(buf, 1, strlen(buf), fd) != strlen(buf)) + /* Fork health check process if needed */ + for (i = 0; i < NUM_BACKENDS; i++) { - ereport(WARNING, - (errmsg("failed to write status file at: \"%s\"", fnamebuf), - errdetail("\"%s\"", strerror(errno)))); - fclose(fd); - return -1; - } - } + if (health_check_pids[i] == 0) + { + ereport(LOG, + (errmsg("start health check process for host %s(%d)", + BACKEND_INFO(i).backend_hostname, + BACKEND_INFO(i).backend_port))); - if (fflush(fd) != 0) - { - ereport(WARNING, - (errmsg("failed to write status file at: \"%s\"", fnamebuf), - errdetail("\"%s\"", strerror(errno)))); - fclose(fd); - return -1; + health_check_pids[i] = worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); + } + } } - fdnum = fileno(fd); - if (fdnum < 0) + else if (failover_context->reqkind == PROMOTE_NODE_REQUEST) { - ereport(WARNING, - (errmsg("failed to get file number. fsync() will not be performed: \"%s\"", fnamebuf), - errdetail("\"%s\"", strerror(errno)))); - fclose(fd); - return -1; + ereport(LOG, + (errmsg("=== Promotion done. promoted host %s(%d) ===", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); } - if (fsync(fdnum) != 0) + else { - ereport(WARNING, - (errmsg("failed to fsync(): \"%s\"", fnamebuf), - errdetail("\"%s\"", strerror(errno)))); - fclose(fd); - return -1; - } - - fclose(fd); +#ifdef NOT_USED + /* + * Temporary black magic. Without this regression 055 does not finish + */ + fprintf(stderr, "=== %s done. shutdown host %s(%d) ===", + (failover_context->reqkind == NODE_DOWN_REQUEST) ? "Failover" : "Quarantine", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port); +#endif - return 0; + ereport(LOG, + (errmsg("=== %s done. shutdown host %s(%d) ===", + (failover_context->reqkind == NODE_DOWN_REQUEST) ? "Failover" : "Quarantine", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); + } + failover_context->need_to_restart_pcp = true; } +/* + * kick wakeup_handler in pcp_child to notice that failover/failback done. + */ static void -reload_config(void) +exec_notice_pcp_child(FAILOVER_CONTEXT *failover_context) { - ereport(LOG, - (errmsg("reload config files."))); - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + int status; + int sts; - pool_get_config(conf_file, CFGCXT_RELOAD); + kill(pcp_pid, SIGUSR2); - /* Realoading config file could change backend status */ - (void) write_status_file(); + if (failover_context->need_to_restart_pcp) + { + sleep(1); - MemoryContextSwitchTo(oldContext); - if (pool_config->enable_pool_hba) - load_hba(hba_file); - kill_all_children(SIGHUP); + /* + * Send restart request to pcp child. + */ + kill(pcp_pid, SIGUSR1); + for (;;) + { + sts = waitpid(pcp_pid, &status, 0); + if (sts != -1) + break; + + if (errno == EINTR) + continue; + else + { + ereport(WARNING, + (errmsg("failover: waitpid failed"), + errdetail("%m"))); + continue; + } + } + if (WIFSIGNALED(status)) + ereport(LOG, + (errmsg("PCP child %d exits with status %d by signal %d in failover()", pcp_pid, status, WTERMSIG(status)))); + else + ereport(LOG, + (errmsg("PCP child %d exits with status %d in failover()", pcp_pid, status))); - if (worker_pid) - kill(worker_pid, SIGHUP); + pcp_pid = pcp_fork_a_child(pcp_fds, pcp_conf_file); + ereport(LOG, + (errmsg("fork a new PCP child pid %d in failover()", pcp_pid))); + } } -/* Call back function to unlink the file */ -static void -FileUnlink(int code, Datum path) +/* + * ------------------------------------------------------------------------- + * Subroutines for failover() end + * ------------------------------------------------------------------------- + */ + + +/* + * Create UNIX domain sockets by unix_socket_directories/pcp_socket_dir, + * which is an array of string. The number of elements is + * "n_listen_addresses". "port" is the port number. A socket array is returned. + * The number of elements in the socket array is "n_sockets". + */ +static int * +create_unix_domain_sockets_by_list(struct sockaddr_un *un_addrs, + char *group, int permissions, int n_sockets) { - char *filePath = (char *) path; + int i; + int *sockets = NULL; - if (unlink(filePath) == 0) - return; + if (un_addrs == NULL) + return NULL; - /* - * We are already exiting the system just produce a log entry to report an - * error - */ - ereport(LOG, - (errmsg("unlink failed for file at path \"%s\"", filePath), - errdetail("%s", strerror(errno)))); -} + sockets = malloc(sizeof(int) * n_sockets); + if (sockets == NULL) + ereport(FATAL, + (errmsg("failed to allocate memory in startup process"))); -static void -system_will_go_down(int code, Datum arg) -{ - if (mypid != getpid()) + for (i = 0; i < n_sockets; i++) { - /* should never happen */ - ereport(LOG, (errmsg("system_will_go_down called from invalid process"))); - return; - } - POOL_SETMASK(&AuthBlockSig); - /* Write status file */ - (void) write_status_file(); + ereport(LOG, + (errmsg("create socket files[%d]: %s", i, un_addrs[i].sun_path))); - /* - * Terminate all childrens. But we may already have killed all the - * childrens if we come to this function because of shutdown signal. - */ - if (processState != EXITING) - terminate_all_childrens(); - processState = EXITING; - POOL_SETMASK(&UnBlockSig); + sockets[i] = create_unix_domain_socket(un_addrs[i], group, permissions); + } + return sockets; } -int -pool_send_to_frontend(char *data, int len, bool flush) +/* + * Create INET domain sockets by specified listen address list + * "listen_addresses", which is an array of string. The number of elements is + * "n_listen_addresses". "port" is the port number. A socket array is returned. + * The number of elements in the socket array is "n_sockets". + */ +static int * +create_inet_domain_sockets_by_list(char **listen_addresses, int n_listen_addresses, int port, int *n_sockets) { - if (processType == PT_PCP_WORKER) - return send_to_pcp_frontend(data, len, flush); - else if (processType == PT_CHILD) - return send_to_pg_frontend(data, len, flush); - return -1; -} + int *sockets = NULL; + int i; -int -pool_frontend_exists(void) -{ - if (processType == PT_PCP_WORKER) - return pcp_frontend_exists(); - else if (processType == PT_CHILD) - return pg_frontend_exists(); - return -1; -} + *n_sockets = 0; -static void -degenerate_all_quarantine_nodes(void) -{ - int i; + if (listen_addresses == NULL || listen_addresses[0] == NULL) + return NULL; - for (i = 0; i < NUM_BACKENDS; i++) + for (i = 0; i < n_listen_addresses; i++) { - if (BACKEND_INFO(i).quarantine && BACKEND_INFO(i).backend_status == CON_DOWN) - { - /* just send the request to watchdog */ - if (wd_degenerate_backend_set(&i, 1, REQ_DETAIL_UPDATE) == FAILOVER_RES_PROCEED) - register_node_operation_request(NODE_DOWN_REQUEST, &i, 1, REQ_DETAIL_WATCHDOG | REQ_DETAIL_SWITCHOVER); - } - } -} + int *inet_fds, + *walk; + int n = 0; /* number of fds returned from + * create_inet_domain_sockets(). */ -static void -update_backend_quarantine_status(void) -{ - /* - * Reset the quarantine flag from each backend and set it to con_wait - */ - int i; - WD_STATES wd_state = get_watchdog_local_node_state(); + ereport(LOG, + (errmsg("listen address[%d]: %s", i, listen_addresses[i]))); - for (i = 0; i < NUM_BACKENDS; i++) - { - if (BACKEND_INFO(i).quarantine && BACKEND_INFO(i).backend_status == CON_DOWN) + inet_fds = create_inet_domain_sockets(listen_addresses[i], port); + + if (!inet_fds) + continue; + + for (walk = inet_fds; *walk != -1; walk++) + n++; + + sockets = realloc(sockets, sizeof(int) * (n + 1 + *n_sockets)); + if (sockets == NULL) + ereport(FATAL, + (errmsg("failed to allocate memory in startup process"))); + + n = 0; + for (walk = inet_fds; *walk != -1; walk++) { - /* - * Send the failback request for the node we also set the watchdog - * flag, so that the failover should only be executed locally - * because, we will eventually send the sync backend message to - * all standby nodes - */ - if (wd_state == WD_COORDINATOR) - send_failback_request(i, false, REQ_DETAIL_UPDATE | REQ_DETAIL_WATCHDOG); + ereport(DEBUG5, + (errmsg("set inet socket: %d to sockets[%d]", inet_fds[n], *n_sockets))); + + sockets[*n_sockets] = inet_fds[n++]; + (*n_sockets)++; } + sockets[*n_sockets] = -1; + free(inet_fds); } + + return sockets; } /* - * The function fetch the current status of all configured backend - * nodes from the MASTER/COORDINATOR watchdog Pgpool-II and synchronize the - * local backend states with the cluster wide status of each node. - * - * Latter in the funcrtion after syncing the backend node status the function - * do a partial or full restart of Pgpool-II children depending upon the - * Pgpool-II mode and type of node status change - * + * Check and execute pending requests set by signal interrupts. */ -static void -sync_backend_from_watchdog(void) +static +void +check_requests(void) { - bool primary_changed = false; - bool node_status_was_changed_to_down = false; - bool node_status_was_changed_to_up = false; - bool need_to_restart_children = false; - bool partial_restart = false; - bool reload_maste_node_id = false; - - int down_node_ids[MAX_NUM_BACKENDS]; - int down_node_ids_index = 0; - int i; + sigset_t sig; /* - * Ask the watchdog to get all the backend states from the - * Master/Coordinator Pgpool-II node + * Shutdown request? exit_handler() set main_exit_request to the captured + * signal number; perform the actual (non-async-safe) shutdown here, in + * normal context. do_shutdown() does not return. */ - WDPGBackendStatus *backendStatus = get_pg_backend_status_from_master_wd_node(); - - if (!backendStatus) - { - ereport(WARNING, - (errmsg("failed to get the backend status from the master watchdog node"), - errdetail("using the local backend node status"))); - return; - } - if (backendStatus->node_count <= 0) + if (main_exit_request) { - /* - * -ve node count is returned by watchdog when the node itself is a - * master and in that case we need to use the loacl backend node - * status - */ - ereport(LOG, - (errmsg("I am the master watchdog node"), - errdetail("using the local backend node status"))); - pfree(backendStatus); - return; + do_shutdown(main_exit_request); } - ereport(LOG, - (errmsg("master watchdog node \"%s\" returned status for %d backend nodes", backendStatus->nodeName, backendStatus->node_count))); - - ereport(DEBUG1, - (errmsg("primary node on master watchdog node \"%s\" is %d", backendStatus->nodeName, backendStatus->primary_node_id))); - - if (Req_info->primary_node_id != backendStatus->primary_node_id) + /* + * Waking child request? + */ + if (wakeup_request) { - /* Do not produce this log message if we are starting up the Pgpool-II */ - if (processState != INITIALIZING) - ereport(LOG, - (errmsg("primary node:%d on master watchdog node \"%s\" is different from local primary node:%d", - backendStatus->primary_node_id, backendStatus->nodeName, Req_info->primary_node_id))); - - Req_info->primary_node_id = backendStatus->primary_node_id; - primary_changed = true; + wakeup_children(); + wakeup_request = 0; } /* - * update the local backend status Also remove quarantine flags + * Failover or failback request? */ - for (i = 0; i < backendStatus->node_count; i++) + if (sigusr1_request) { - BACKEND_INFO(i).quarantine = false; - if (backendStatus->backend_status[i] == CON_DOWN) - { - if (BACKEND_INFO(i).backend_status != CON_DOWN) - { - BACKEND_INFO(i).backend_status = CON_DOWN; - pool_set_backend_status_changed_time(i); - my_backend_status[i] = &(BACKEND_INFO(i).backend_status); - reload_maste_node_id = true; - node_status_was_changed_to_down = true; - ereport(LOG, - (errmsg("backend:%d is set to down status", i), - errdetail("backend:%d is DOWN on cluster master \"%s\"", i, backendStatus->nodeName))); - down_node_ids[down_node_ids_index++] = i; - } - } - else if (backendStatus->backend_status[i] == CON_CONNECT_WAIT || - backendStatus->backend_status[i] == CON_UP) + do { - if (BACKEND_INFO(i).backend_status != CON_CONNECT_WAIT) - { - if (BACKEND_INFO(i).backend_status == CON_DOWN) - node_status_was_changed_to_up = true; + sigusr1_request = 0; + sigusr1_interrupt_processor(); + } while (sigusr1_request == 1); + } - BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; - pool_set_backend_status_changed_time(i); - my_backend_status[i] = &(BACKEND_INFO(i).backend_status); - reload_maste_node_id = true; + /* Check pending signals (SIGQUIT/SIGTERRM/SIGINT) */ + sigpending(&sig); + print_signal_member(&sig); - ereport(LOG, - (errmsg("backend:%d is set to UP status", i), - errdetail("backend:%d is UP on cluster master \"%s\"", i, backendStatus->nodeName))); + /* + * Unblock signals so that SIGQUIT/SIGTERRM/SIGINT can be accepted. They + * are all shutdown requests. + */ + POOL_SETMASK(&UnBlockSig); - } - } + /* + * Reap child request? + */ + if (sigchld_request) + { + reaper(); } - pfree(backendStatus); - if (reload_maste_node_id) + /* + * Configuration file reloading request? + */ + if (reload_config_request) { - Req_info->master_node_id = get_next_master_node(); + reload_config(); + reload_config_request = 0; } - /* We don't need to do anything else if the Pgpool-II is starting up */ - if (processState == INITIALIZING) - return; - /* - * Decide if All or subset of the Pgpool-II children needs immidiate - * restart or we can do that after finishing the current session - * - * Check if there was no change at all + * Block signals again */ - if (node_status_was_changed_to_up == false && - node_status_was_changed_to_down == false && - primary_changed == false) - { + POOL_SETMASK(&BlockSig); +} + +static +void +print_signal_member(sigset_t *sig) +{ + if (sigismember(sig, SIGQUIT)) ereport(LOG, - (errmsg("backend nodes status remains same after the sync from \"%s\"", backendStatus->nodeName))); - return; - } - if (!STREAM) - { - /* - * If we are not in streaming replication mode restart all child - * processes - */ + (errmsg("SIGQUIT is member"))); + if (sigismember(sig, SIGINT)) ereport(LOG, - (errmsg("node status was chenged after the sync from \"%s\"", backendStatus->nodeName), - errdetail("all children needs to be restarted as we are not in streaming replication mode"))); - need_to_restart_children = true; - partial_restart = false; - } - else if (primary_changed) - { - /* - * if Primary node was changed, We should restart all children - */ - need_to_restart_children = true; - partial_restart = false; + (errmsg("SIGINT is member"))); + if (sigismember(sig, SIGTERM)) ereport(LOG, - (errmsg("primary node was chenged after the sync from \"%s\"", backendStatus->nodeName), - errdetail("all children needs to be restarted"))); + (errmsg("SIGTERM is member"))); +} - } - else - { - if (node_status_was_changed_to_down == false) - { - /* - * no node was detached, So no need to restart any child process - */ - need_to_restart_children = false; - partial_restart = false; - ereport(LOG, - (errmsg("No backend node was detached because of backend status sync from \"%s\"", backendStatus->nodeName), - errdetail("no need to restart children"))); - } - else +/* +* Function does the house keeping of spare child processes +*/ +static void +service_child_processes(void) +{ + int connected_children = Req_info->conn_counter; + int idle_children = current_child_process_count - connected_children; + static int high_load_counter = 0; + + ereport(DEBUG2, + (errmsg("current_children_count = %d idle_children = %d connected_children = %d high_load_counter = %d", + current_child_process_count, idle_children, connected_children, high_load_counter))); + if (idle_children > pool_config->max_spare_children) + { + int ki; + int victim_count; + int kill_process_info_idxs[MAX_ONE_SHOT_KILLS]; + int kill_count = idle_children - pool_config->max_spare_children; + int cycle_skip_count_before_scale_down; + int cycle_skip_between_scale_down; + int one_shot_kill_count; + + switch (pool_config->process_management_strategy) { - ereport(LOG, - (errmsg("%d backend node(s) were detached because of backend status sync from \"%s\"", down_node_ids_index, backendStatus->nodeName), - errdetail("restarting the children processes"))); + case PM_STRATEGY_AGGRESSIVE: + cycle_skip_count_before_scale_down = 25; /* roughly 50 seconds */ + cycle_skip_between_scale_down = 2; + one_shot_kill_count = MAX_ONE_SHOT_KILLS; + break; - need_to_restart_children = true; - partial_restart = !check_all_backend_down(); + case PM_STRATEGY_LAZY: + cycle_skip_count_before_scale_down = 150; /* roughly 300 seconds */ + cycle_skip_between_scale_down = 10; + one_shot_kill_count = 3; + break; + + case PM_STRATEGY_GENTLE: + cycle_skip_count_before_scale_down = 60; /* roughly 120 seconds */ + cycle_skip_between_scale_down = 5; + one_shot_kill_count = 3; + break; + + default: + /* should never come here, but if we do use gentle counts */ + cycle_skip_count_before_scale_down = 60; /* roughly 120 seconds */ + cycle_skip_between_scale_down = 5; + one_shot_kill_count = 3; + break; } - } - /* Kill children and restart them if needed */ - if (need_to_restart_children) - { - for (i = 0; i < pool_config->num_init_children; i++) - { - bool restart = false; + /* Do not scale down too quickly */ + if (++high_load_counter < cycle_skip_count_before_scale_down || high_load_counter % cycle_skip_between_scale_down) + return; - if (partial_restart) - { - int j, - k; + memset(kill_process_info_idxs, -1, sizeof(kill_process_info_idxs)); - for (j = 0; j < pool_config->max_pool; j++) - { - for (k = 0; k < NUM_BACKENDS; k++) - { - int idx; - ConnectionInfo *con = pool_coninfo(i, j, k); + if (kill_count > one_shot_kill_count) + kill_count = one_shot_kill_count; - for (idx = 0; idx < down_node_ids_index; idx++) - { - int node_id = down_node_ids[idx]; + victim_count = select_victim_processes(kill_process_info_idxs, kill_count); - if (con->connected && con->load_balancing_node == node_id) - { - ereport(LOG, - (errmsg("child process with PID:%d needs restart, because pool %d uses backend %d", - process_info[i].pid, j, node_id))); - restart = true; - break; - } - if (restart) - break; - } - } - } - } - else - { - restart = true; - } + for (ki = 0; ki < victim_count; ki++) + { + int index = kill_process_info_idxs[ki]; - if (restart) + if (index >= 0) { - if (process_info[i].pid) + if (process_info[index].pid && process_info[index].status == WAIT_FOR_CONNECT) { - kill(process_info[i].pid, SIGQUIT); - - process_info[i].pid = fork_a_child(fds, i); - process_info[i].start_time = time(NULL); + ereport(DEBUG1, + (errmsg("asking child process with pid:%d to kill itself to satisfy max_spare_children", + process_info[index].pid), + errdetail("child process has %d pooled connections", process_info[index].pooled_connections))); + process_info[index].exit_if_idle = true; + kill(process_info[index].pid, SIGUSR2); } } - else - process_info[i].need_to_restart = 1; } } - else { - /* - * Set restart request to each child. Children will exit(1) whenever - * they are convenient. - */ - for (i = 0; i < pool_config->num_init_children; i++) + /* Reset the high load counter */ + high_load_counter = 0; + /* See if we need to spawn new children */ + if (idle_children < pool_config->min_spare_children) { - process_info[i].need_to_restart = 1; + int i; + int spawned = 0; + int new_spawn_no = pool_config->min_spare_children - idle_children; + + /* Add 25% of max_spare_children */ + new_spawn_no += pool_config->max_spare_children / 4; + if (new_spawn_no + current_child_process_count > pool_config->num_init_children) + { + ereport(DEBUG5, + (errmsg("we have hit the ceiling, spawning %d child(ren)", + pool_config->num_init_children - current_child_process_count))); + new_spawn_no = pool_config->num_init_children - current_child_process_count; + } + if (new_spawn_no <= 0) + return; + for (i = 0; i < pool_config->num_init_children; i++) + { + if (process_info[i].pid == 0) + { + process_info[i].start_time = time(NULL); + process_info[i].client_connection_count = 0; + process_info[i].status = WAIT_FOR_CONNECT; + process_info[i].connected = 0; + process_info[i].wait_for_connect = 0; + process_info[i].pooled_connections = 0; + process_info[i].need_to_restart = 0; + process_info[i].exit_if_idle = false; + process_info[i].pid = fork_a_child(fds, i); + + current_child_process_count++; + if (++spawned >= new_spawn_no) + break; + } + } } } - - /* - * Send restart request to worker child. - */ - kill(worker_pid, SIGUSR1); } /* - * Obtain backend server version number and cache it. Note that returned - * version number is in the static memory area. + * Function selects the child processes that can be killed based. + * selection criteria is to select the processes with minimum number of + * pooled connections. + * Returns the total number of identified process and fills the proc_info_arr + * with the victim children process_info index */ static int -get_server_version(POOL_CONNECTION_POOL_SLOT * *slots, int node_id) +select_victim_processes(int *process_info_idxs, int count) { - static int server_versions[MAX_NUM_BACKENDS]; + int i, + ki; + bool found_enough = false; + int selected_count = 0; - char *query; - POOL_SELECT_RESULT *res; + if (count <= 0) + return 0; - if (server_versions[node_id] == 0) + for (i = 0; i < pool_config->num_init_children; i++) { - query = "SELECT current_setting('server_version_num')"; - - /* Get backend server version. If the query fails, keep previous info. */ - if (get_query_result(slots, node_id, query, &res) == 0) + /* Only the child process in waiting for connect can be terminated */ + if (process_info[i].pid && process_info[i].status == WAIT_FOR_CONNECT) { - server_versions[node_id] = atoi(res->data[0]); - ereport(DEBUG1, - (errmsg("get_server_version: backend %d server version: %d", node_id, server_versions[node_id]))); - free_select_result(res); + if (selected_count < count) + { + process_info_idxs[selected_count++] = i; + } + else + { + found_enough = true; + + /* + * we don't bother selecting the child having least pooled + * connection with aggressive strategy + */ + if (pool_config->process_management_strategy != PM_STRATEGY_AGGRESSIVE) + { + for (ki = 0; ki < count; ki++) + { + int old_index = process_info_idxs[ki]; + + if (old_index < 0 || process_info[old_index].pooled_connections > process_info[i].pooled_connections) + { + process_info_idxs[ki] = i; + found_enough = false; + break; + } + if (process_info[old_index].pooled_connections) + found_enough = false; + } + } + } } + if (found_enough) + break; } - return server_versions[node_id]; + return selected_count; } /* - * Get info from conninfo string. + * Close all listening sockets + * + * kind bitmap specifies which listening sockets to be closed. */ -static void -get_info_from_conninfo(char *conninfo, char *host, char *port) +void +close_listening_sockets(int kind) { - char *p; - - *host = '\0'; - *port = '\0'; + int i; - p = strstr(conninfo, "host"); - if (p) + if (kind & POOL_CLOSE_PGPOOL_LISTENING_SOCKS && fds != NULL) { - while (*p && *p != ' ') - *host++ = *p++; - *host = '\0'; + for (i = 0; fds[i] > 0; i++) + close(fds[i]); } - - p = strstr(conninfo, "port"); - if (p) + if (kind & POOL_CLOSE_PCP_LISTENING_SOCKS && pcp_fds != NULL) { - /* skip "port=" */ - while (*p && *p++ != '=') - ; - - while (*p && *p != ' ') - *port++ = *p++; - *port = '\0'; + for (i = 0; pcp_fds[i] > 0; i++) + close(pcp_fds[i]); } } - -/* - * Set backend status changed time for specified backend id. - */ -void -pool_set_backend_status_changed_time(int backend_id) -{ - time_t tval; - - tval = time(NULL); - BACKEND_INFO(backend_id).status_changed_time = tval; -} diff --git a/src/main/pool_globals.c b/src/main/pool_globals.c index 517701bd3..84680fc8d 100644 --- a/src/main/pool_globals.c +++ b/src/main/pool_globals.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2010 PgPool Global Development Group + * Copyright (c) 2003-2023 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -20,8 +20,96 @@ * * Global variables. Should be eventually removed. */ +#include /* For getpid */ #include "pool.h" +#include "utils/elog.h" + pid_t mypid; /* pgpool parent process id */ +pid_t myProcPid; /* process pid */ ProcessType processType; ProcessState processState; +bool reset_query_error; /* true if error returned from backend while + * processing reset queries */ + +/* + * Application name + */ +static char *process_application_name = "main"; + +/* + * Fixed application names. ordered by ProcessType. + */ +char *application_names[] = {"main", + "child", + "sr_check_worker", + "heart_beat_sender", + "heart_beat_receiver", + "watchdog", + "life_check", + "follow_child", + "watchdog_utility", + "pcp_main", + "pcp_child", + "health_check", + "logger" +}; + +char * +get_application_name_for_process(ProcessType ptype) +{ + if (ptype < 0 || ptype >= PT_LAST_PTYPE) + { + ereport(ERROR, + (errmsg("failed to set application name. process type: %d", ptype))); + } + return application_names[ptype]; +} + +/* + * Set application name by ProcessType + */ +void +set_application_name(ProcessType ptype) +{ + process_application_name = get_application_name_for_process(ptype); +} + +/* + * Set application name with arbitrary string. The storage for the string must + * be persistent at least in the session. + */ +void +set_application_name_with_string(char *string) +{ + process_application_name = string; +} + +/* + * Set application name with suffix + */ +void +set_application_name_with_suffix(ProcessType ptype, int suffix) +{ + static char appname_buf[POOLCONFIG_MAXNAMELEN + 1]; + + snprintf(appname_buf, POOLCONFIG_MAXNAMELEN, "%s%d", get_application_name_for_process(ptype), suffix); + set_application_name_with_string(appname_buf); +} + +/* + * Get current application name + */ +char * +get_application_name(void) +{ + return process_application_name; +} + +void +SetProcessGlobalVariables(ProcessType pType) +{ + processType = pType; + myProcPid = getpid(); + set_application_name(pType); +} diff --git a/src/main/pool_internal_comms.c b/src/main/pool_internal_comms.c new file mode 100644 index 000000000..35efd0465 --- /dev/null +++ b/src/main/pool_internal_comms.c @@ -0,0 +1,447 @@ +/* -*-pgpool_main-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2020 PgPool Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + */ + +/* + * pool_internal_comms consists of functions that can be called + * from any pgpool-II process to instruct pgpool-II main process to + * perform a particular function + */ +#include +#include +#include + +#include "utils/elog.h" +#include "utils/pool_signal.h" + +#include "pool.h" +#include "main/pool_internal_comms.h" +#include "watchdog/wd_internal_commands.h" +#include "utils/palloc.h" +#include "utils/memutils.h" +#include "pool_config.h" + +/* + * sends the signal to pgpool-II main process to terminate Pgpool-II + * process. + */ +bool +terminate_pgpool(char mode, bool error) +{ + + pid_t ppid = getppid(); + int sig; + + if (mode == 's') + { + ereport(DEBUG1, + (errmsg("processing shutdown request"), + errdetail("sending SIGTERM to the parent process with PID:%d", ppid))); + sig = SIGTERM; + } + else if (mode == 'f') + { + ereport(DEBUG1, + (errmsg("processing shutdown request"), + errdetail("sending SIGINT to the parent process with PID:%d", ppid))); + sig = SIGINT; + } + else if (mode == 'i') + { + ereport(DEBUG1, + (errmsg("processing shutdown request"), + errdetail("sending SIGQUIT to the parent process with PID:%d", ppid))); + sig = SIGQUIT; + } + else + { + ereport(error ? ERROR : WARNING, + (errmsg("error while processing shutdown request"), + errdetail("invalid shutdown mode \"%c\"", mode))); + return false; + } + + pool_signal_parent(sig); + return true; +} + +/* + * degenerate_backend_set_ex: + * + * The function registers/verifies the node down operation request. + * The request is then processed by failover function. + * + * node_id_set: array of node ids to be registered for NODE DOWN operation + * count: number of elements in node_id_set array + * error: if set error is thrown as soon as any node id is found in + * node_id_set on which operation could not be performed. + * test_only: When set, function only checks if NODE DOWN operation can be + * executed on provided node ids and never registers the operation + * request. + * For test_only case function returns false or throws an error as + * soon as first non compliant node in node_id_set is found + * switch_over: if set, the request is originated by switch over, not errors. + * + * wd_failover_id: The watchdog internal ID for this failover + */ +bool +degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, bool error, bool test_only) +{ + int i; + int node_id[MAX_NUM_BACKENDS]; + int node_count = 0; + int elevel = LOG; + + if (error) + elevel = ERROR; + + for (i = 0; i < count; i++) + { + if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS || + (!VALID_BACKEND(node_id_set[i]) && BACKEND_INFO(node_id_set[i]).quarantine == false)) + { + if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS) + ereport(elevel, + (errmsg("invalid degenerate backend request, node id: %d is out of range. node id must be between [0 and %d]" + ,node_id_set[i], MAX_NUM_BACKENDS))); + else + ereport(elevel, + (errmsg("invalid degenerate backend request, node id : %d status: [%d] is not valid for failover" + ,node_id_set[i], BACKEND_INFO(node_id_set[i]).backend_status))); + if (test_only) + return false; + + continue; + } + + if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(node_id_set[i]).flag)) + { + ereport(elevel, + (errmsg("degenerate backend request for node_id: %d from pid [%d] is canceled because failover is disallowed on the node", + node_id_set[i], getpid()))); + if (test_only) + return false; + } + else + { + if (!test_only) /* do not produce this log if we are in + * testing mode */ + ereport(LOG, + (errmsg("received degenerate backend request for node_id: %d from pid [%d]", + node_id_set[i], getpid()))); + + node_id[node_count++] = node_id_set[i]; + } + } + + if (node_count) + { + WDFailoverCMDResults res = FAILOVER_RES_PROCEED; + + /* If this was only a test. Inform the caller without doing anything */ + if (test_only) + return true; + + if (!(flags & REQ_DETAIL_WATCHDOG)) + { + int x; + + for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSACTION; x++) + { + res = wd_degenerate_backend_set(node_id_set, count, flags); + if (res != FAILOVER_RES_TRANSITION) + break; + sleep(1); + } + } + if (res == FAILOVER_RES_TRANSITION) + { + /* + * What to do when cluster is still not stable Is proceeding to + * failover is the right choice ??? + */ + ereport(NOTICE, + (errmsg("received degenerate backend request for %d node(s) from pid [%d], But cluster is not in stable state" + ,node_count, getpid()))); + } + if (res == FAILOVER_RES_PROCEED) + { + register_node_operation_request(NODE_DOWN_REQUEST, node_id, node_count, flags); + } + else if (res == FAILOVER_RES_NO_QUORUM) + { + ereport(LOG, + (errmsg("degenerate backend request for %d node(s) from pid [%d], is changed to quarantine node request by watchdog" + ,node_count, getpid()), + errdetail("watchdog does not holds the quorum"))); + + register_node_operation_request(NODE_QUARANTINE_REQUEST, node_id, node_count, flags); + } + else if (res == FAILOVER_RES_CONSENSUS_MAY_FAIL) + { + ereport(LOG, + (errmsg("degenerate backend request for %d node(s) from pid [%d], is changed to quarantine node request by watchdog" + ,node_count, getpid()), + errdetail("watchdog is taking time to build consensus"))); + register_node_operation_request(NODE_QUARANTINE_REQUEST, node_id, node_count, flags); + } + else if (res == FAILOVER_RES_BUILDING_CONSENSUS) + { + ereport(LOG, + (errmsg("degenerate backend request for node_id: %d from pid [%d], will be handled by watchdog, which is building consensus for request" + ,*node_id, getpid()))); + } + else if (res == FAILOVER_RES_WILL_BE_DONE) + { + /* we will receive a sync request from leader watchdog node */ + ereport(LOG, + (errmsg("degenerate backend request for %d node(s) from pid [%d], will be handled by watchdog" + ,node_count, getpid()))); + } + else + { + ereport(elevel, + (errmsg("degenerate backend request for %d node(s) from pid [%d] is canceled by other pgpool" + ,node_count, getpid()))); + return false; + } + } + return true; +} + +/* + * wrapper over degenerate_backend_set_ex function to register + * NODE down operation request + */ +bool +degenerate_backend_set(int *node_id_set, int count, unsigned char flags) +{ + return degenerate_backend_set_ex(node_id_set, count, flags, false, false); +} + +/* send promote node request using SIGUSR1 */ +bool +promote_backend(int node_id, unsigned char flags) +{ + WDFailoverCMDResults res = FAILOVER_RES_PROCEED; + bool ret = false; + + if (!SL_MODE) + { + return false; + } + + if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || !VALID_BACKEND(node_id)) + { + if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) + ereport(LOG, + (errmsg("invalid promote backend request, node id: %d is out of range. node id must be between [0 and %d]" + ,node_id, MAX_NUM_BACKENDS))); + else + ereport(LOG, + (errmsg("invalid promote backend request, node id : %d status: [%d] not valid" + ,node_id, BACKEND_INFO(node_id).backend_status))); + return false; + } + ereport(LOG, + (errmsg("received promote backend request for node_id: %d from pid [%d]", + node_id, getpid()))); + + /* If this was only a test. Inform the caller without doing anything */ + if (!(flags & REQ_DETAIL_WATCHDOG)) + { + int x; + + for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSACTION; x++) + { + res = wd_promote_backend(node_id, flags); + if (res != FAILOVER_RES_TRANSITION) + break; + sleep(1); + } + } + if (res == FAILOVER_RES_TRANSITION) + { + /* + * What to do when cluster is still not stable Is proceeding to + * failover is the right choice ??? + */ + ereport(NOTICE, + (errmsg("promote backend request for node_id: %d from pid [%d], But cluster is not in stable state" + ,node_id, getpid()))); + } + + if (res == FAILOVER_RES_PROCEED) + { + ret = register_node_operation_request(PROMOTE_NODE_REQUEST, &node_id, 1, flags); + } + else if (res == FAILOVER_RES_WILL_BE_DONE) + { + ereport(LOG, + (errmsg("promote backend request for node_id: %d from pid [%d], will be handled by watchdog" + ,node_id, getpid()))); + } + else if (res == FAILOVER_RES_NO_QUORUM) + { + ereport(LOG, + (errmsg("promote backend request for node_id: %d from pid [%d], is canceled because watchdog does not hold quorum" + ,node_id, getpid()))); + } + else if (res == FAILOVER_RES_BUILDING_CONSENSUS) + { + ereport(LOG, + (errmsg("promote backend request for node_id: %d from pid [%d], will be handled by watchdog, which is building consensus for request" + ,node_id, getpid()))); + } + else + { + ereport(LOG, + (errmsg("promote backend request for node_id: %d from pid [%d] is canceled by other pgpool" + ,node_id, getpid()))); + } + return ret; +} + +/* send failback request using SIGUSR1 */ +bool +send_failback_request(int node_id, bool throw_error, unsigned char flags) +{ + WDFailoverCMDResults res = FAILOVER_RES_PROCEED; + bool ret = false; + + if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || + (RAW_MODE && BACKEND_INFO(node_id).backend_status != CON_DOWN && VALID_BACKEND(node_id))) + { + if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) + ereport(throw_error ? ERROR : LOG, + (errmsg("invalid failback request, node id: %d is out of range. node id must be between [0 and %d]" + ,node_id, MAX_NUM_BACKENDS))); + else + ereport(throw_error ? ERROR : LOG, + (errmsg("invalid failback request, node id : %d status: [%d] not valid for failback" + ,node_id, BACKEND_INFO(node_id).backend_status))); + return false; + } + + ereport(LOG, + (errmsg("received failback request for node_id: %d from pid [%d]", + node_id, getpid()))); + + /* check we are trying to failback the quarantine node */ + if (BACKEND_INFO(node_id).quarantine) + { + /* set the update flags */ + ereport(LOG, + (errmsg("failback request from pid [%d] is changed to update status request because node_id: %d was quarantined", + getpid(), node_id))); + flags |= REQ_DETAIL_UPDATE; + } + else + { + /* + * no need to go to watchdog if it's an update or already initiated + * from watchdog + */ + if (!(flags & REQ_DETAIL_WATCHDOG)) + { + int x; + + for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSACTION; x++) + { + res = wd_send_failback_request(node_id, flags); + if (res != FAILOVER_RES_TRANSITION) + break; + sleep(1); + } + } + } + + if (res == FAILOVER_RES_TRANSITION) + { + /* + * What to do when cluster is still not stable Is proceeding to + * failover is the right choice ??? + */ + ereport(NOTICE, + (errmsg("failback request for node_id: %d from pid [%d], But cluster is not in stable state" + ,node_id, getpid()))); + } + + if (res == FAILOVER_RES_PROCEED) + { + ret = register_node_operation_request(NODE_UP_REQUEST, &node_id, 1, flags); + } + else if (res == FAILOVER_RES_WILL_BE_DONE) + { + ereport(LOG, + (errmsg("failback request for node_id: %d from pid [%d], will be handled by watchdog" + ,node_id, getpid()))); + } + else + { + ereport(throw_error ? ERROR : LOG, + (errmsg("failback request for node_id: %d from pid [%d] is canceled by other pgpool" + ,node_id, getpid()))); + } + return ret; +} + +/* + * Request failover. If "switch_over" is false, request all existing sessions + * restarting. + */ +void +notice_backend_error(int node_id, unsigned char flags) +{ + int n = node_id; + + if (getpid() == mypid) + { + ereport(LOG, + (errmsg("notice_backend_error: called from pgpool main. ignored."))); + } + else + { + degenerate_backend_set(&n, 1, flags); + } +} + +void +degenerate_all_quarantine_nodes(void) +{ + int i; + + for (i = 0; i < NUM_BACKENDS; i++) + { + if (BACKEND_INFO(i).quarantine && BACKEND_INFO(i).backend_status == CON_DOWN) + { + /* just send the request to watchdog */ + if (wd_degenerate_backend_set(&i, 1, REQ_DETAIL_UPDATE) == FAILOVER_RES_PROCEED) + register_node_operation_request(NODE_DOWN_REQUEST, &i, 1, REQ_DETAIL_WATCHDOG | REQ_DETAIL_SWITCHOVER); + } + } +} + + +bool +close_idle_connections(void) +{ + return register_node_operation_request(CLOSE_IDLE_REQUEST, NULL, 0, 0); +} diff --git a/src/parser/.gitignore b/src/parser/.gitignore new file mode 100644 index 000000000..7906cbb89 --- /dev/null +++ b/src/parser/.gitignore @@ -0,0 +1,5 @@ +/gram.c +/gram.h +/gram_minimal.c +/gram_minimal.h +/scan.c diff --git a/src/parser/Makefile.am b/src/parser/Makefile.am index fc4935def..6d79dadb6 100644 --- a/src/parser/Makefile.am +++ b/src/parser/Makefile.am @@ -5,13 +5,14 @@ noinst_LIBRARIES = libsql-parser.a libsql_parser_a_SOURCES = \ copyfuncs.c \ gram.y \ + gram_minimal.y \ keywords.c \ + kwlookup.c \ list.c \ makefuncs.c \ nodes.c \ outfuncs.c \ parser.c \ - pool_string.c \ scansup.c \ stringinfo.c \ value.c \ @@ -24,11 +25,26 @@ if use_repl_snprintf libsql_parser_a_SOURCES += snprintf.c endif -EXTRA_DIST = scan.c scan.l +EXTRA_DIST = scan.l +ARFLAGS = cr +AM_YFLAGS = -d -Wno-yacc -AM_YFLAGS = -d +BUILT_SOURCES = \ + gram.c \ + gram.h \ + gram_minimal.c \ + gram_minimal.h \ + scan.c + +gram.c gram.h: gram.y scan.c +gram_minimal.c gram_minimal.h: gram_minimal.y scan.c -gram.c: gram.y scan.c scan.c: scan.l $(LEX) -o'scan.c' $< + +generate_parsers: gram_template.y + $(SUNIFDEF) --undef pgpool_minimal_parser gram_template.y > gram.y||: + $(SUNIFDEF) --define pgpool_minimal_parser gram_template.y > gram_minimal.y||: + +.PHONY: generate_parsers diff --git a/src/parser/Makefile.in b/src/parser/Makefile.in deleted file mode 100644 index 1176b3c35..000000000 --- a/src/parser/Makefile.in +++ /dev/null @@ -1,643 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@use_repl_snprintf_TRUE@am__append_1 = snprintf.c -subdir = src/parser -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs gram.h gram.c $(top_srcdir)/ylwrap -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/docbook.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/c-compiler.m4 \ - $(top_srcdir)/c-library.m4 $(top_srcdir)/general.m4 \ - $(top_srcdir)/ac_func_accept_argtypes.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/src/include/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -AM_V_AR = $(am__v_AR_@AM_V@) -am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) -am__v_AR_0 = @echo " AR " $@; -am__v_AR_1 = -libsql_parser_a_AR = $(AR) $(ARFLAGS) -libsql_parser_a_LIBADD = -am__libsql_parser_a_SOURCES_DIST = copyfuncs.c gram.y keywords.c \ - list.c makefuncs.c nodes.c outfuncs.c parser.c pool_string.c \ - scansup.c stringinfo.c value.c \ - $(top_srcdir)/src/utils/mmgr/mcxt.c \ - $(top_srcdir)/src/utils/mmgr/aset.c \ - $(top_srcdir)/src/utils/error/elog.c wchar.c scan.c snprintf.c -am__dirstamp = $(am__leading_dot)dirstamp -@use_repl_snprintf_TRUE@am__objects_1 = snprintf.$(OBJEXT) -am_libsql_parser_a_OBJECTS = copyfuncs.$(OBJEXT) gram.$(OBJEXT) \ - keywords.$(OBJEXT) list.$(OBJEXT) makefuncs.$(OBJEXT) \ - nodes.$(OBJEXT) outfuncs.$(OBJEXT) parser.$(OBJEXT) \ - pool_string.$(OBJEXT) scansup.$(OBJEXT) stringinfo.$(OBJEXT) \ - value.$(OBJEXT) $(top_srcdir)/src/utils/mmgr/mcxt.$(OBJEXT) \ - $(top_srcdir)/src/utils/mmgr/aset.$(OBJEXT) \ - $(top_srcdir)/src/utils/error/elog.$(OBJEXT) wchar.$(OBJEXT) \ - scan.$(OBJEXT) $(am__objects_1) -libsql_parser_a_OBJECTS = $(am_libsql_parser_a_OBJECTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/include -depcomp = -am__depfiles_maybe = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || -am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ - -e s/c++$$/h++/ -e s/c$$/h/ -YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) -LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) -AM_V_YACC = $(am__v_YACC_@AM_V@) -am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) -am__v_YACC_0 = @echo " YACC " $@; -am__v_YACC_1 = -YLWRAP = $(top_srcdir)/ylwrap -SOURCES = $(libsql_parser_a_SOURCES) -DIST_SOURCES = $(am__libsql_parser_a_SOURCES_DIST) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOG = @CATALOG@ -CC = @CC@ -CFLAGS = @CFLAGS@ -COLLATEINDEX = @COLLATEINDEX@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DLLTOOL = @DLLTOOL@ -DOCBOOKSTYLE = @DOCBOOKSTYLE@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JADE = @JADE@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LEXLIB = @LEXLIB@ -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LYNX = @LYNX@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MEMCACHED_DIR = @MEMCACHED_DIR@ -MEMCACHED_INCLUDE_OPT = @MEMCACHED_INCLUDE_OPT@ -MEMCACHED_LINK_OPT = @MEMCACHED_LINK_OPT@ -MEMCACHED_RPATH_OPT = @MEMCACHED_RPATH_OPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSGMLS = @NSGMLS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OSX = @OSX@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PGCONFIG = @PGCONFIG@ -PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ -PGSQL_LIB_DIR = @PGSQL_LIB_DIR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -STYLE = @STYLE@ -VERSION = @VERSION@ -XMLLINT = @XMLLINT@ -XSLTPROC = @XSLTPROC@ -XSLTPROC_HTML_FLAGS = @XSLTPROC_HTML_FLAGS@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -parser_incdir = $(top_srcdir)/src/include/parser -AM_CPPFLAGS = -D_GNU_SOURCE -I $(parser_incdir) -I @PGSQL_INCLUDE_DIR@ -noinst_LIBRARIES = libsql-parser.a -libsql_parser_a_SOURCES = copyfuncs.c gram.y keywords.c list.c \ - makefuncs.c nodes.c outfuncs.c parser.c pool_string.c \ - scansup.c stringinfo.c value.c \ - $(top_srcdir)/src/utils/mmgr/mcxt.c \ - $(top_srcdir)/src/utils/mmgr/aset.c \ - $(top_srcdir)/src/utils/error/elog.c wchar.c scan.c \ - $(am__append_1) -EXTRA_DIST = scan.c scan.l -AM_YFLAGS = -d -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj .y -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps src/parser/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps src/parser/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -gram.h: gram.c - @if test ! -f $@; then rm -f gram.c; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) gram.c; else :; fi -$(top_srcdir)/src/utils/mmgr/$(am__dirstamp): - @$(MKDIR_P) $(top_srcdir)/src/utils/mmgr - @: > $(top_srcdir)/src/utils/mmgr/$(am__dirstamp) -$(top_srcdir)/src/utils/mmgr/mcxt.$(OBJEXT): \ - $(top_srcdir)/src/utils/mmgr/$(am__dirstamp) -$(top_srcdir)/src/utils/mmgr/aset.$(OBJEXT): \ - $(top_srcdir)/src/utils/mmgr/$(am__dirstamp) -$(top_srcdir)/src/utils/error/$(am__dirstamp): - @$(MKDIR_P) $(top_srcdir)/src/utils/error - @: > $(top_srcdir)/src/utils/error/$(am__dirstamp) -$(top_srcdir)/src/utils/error/elog.$(OBJEXT): \ - $(top_srcdir)/src/utils/error/$(am__dirstamp) - -libsql-parser.a: $(libsql_parser_a_OBJECTS) $(libsql_parser_a_DEPENDENCIES) $(EXTRA_libsql_parser_a_DEPENDENCIES) - $(AM_V_at)-rm -f libsql-parser.a - $(AM_V_AR)$(libsql_parser_a_AR) libsql-parser.a $(libsql_parser_a_OBJECTS) $(libsql_parser_a_LIBADD) - $(AM_V_at)$(RANLIB) libsql-parser.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f $(top_srcdir)/src/utils/error/*.$(OBJEXT) - -rm -f $(top_srcdir)/src/utils/mmgr/*.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -.c.o: - $(AM_V_CC)$(COMPILE) -c -o $@ $< - -.c.obj: - $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: - $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< - -.y.c: - $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(top_srcdir)/src/utils/error/$(am__dirstamp)" || rm -f $(top_srcdir)/src/utils/error/$(am__dirstamp) - -test -z "$(top_srcdir)/src/utils/mmgr/$(am__dirstamp)" || rm -f $(top_srcdir)/src/utils/mmgr/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -rm -f gram.c - -rm -f gram.h -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - - -gram.c: gram.y scan.c -scan.c: scan.l - $(LEX) -o'scan.c' $< - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/parser/README b/src/parser/README new file mode 100644 index 000000000..74e7d15a6 --- /dev/null +++ b/src/parser/README @@ -0,0 +1,49 @@ +Generating minimal and standard parser files +-------------------------------------------- +To generate minimal and standard grammar files issue 'make generate_parsers' +from Pgpool-II/src/parser directory. This will use gram_template.y file and +will generate two grammar files. gram_minimal.y (for the minimal parser) and +gram.y (for the standard parser). + +'make generate_parsers' uses sunifdef (http://www.linuxcertif.com/man/1/sunifdef/) +utility to generate the parsers. And If the 'sunifdef' utility is present on the +the system in the standard path then the configure will automatically pick it up +by itself. But in the case when the sunifdef is not present in the default path +then you can use "--with-sunifdef=sunifdef_dir' configure switch to provide the +'sunifdef' path. + +Notes on importing the PostgreSQL parser +---------------------------------------- +To import the PostgreSQL parser, merge all the changes in gram_template.y file +from PostgreSQL's gram.y, and then run 'make generate_parsers' to generate +updated minimal and standard grammar files for Pgpool-II + +Controlling minimal and standard parser output +----------------------------------------------- +All the code in gram_template.y file inside #ifdef pgpool_minimal_parser section +will only gets included in the gram_minimal.y file while the code inside +#ifndef pgpool_minimal_parser section will only be included in the standard parser +file. +Similarly, the unconditional code which is not in either +#ifndef pgpool_minimal_parser or #ifdef pgpool_minimal_parser will become part of +both the parser. + +Example:1 +--------- +#ifdef pgpool_minimal_parser +code only for the minimal parser +#else +code only for the standard parser +#endif +code for both parsers +.. + +Example:2 +--------- +#ifndef pgpool_minimal_parser +code only for the standard parser +#else +code only for the minimal parser +#endif +code for both parsers + diff --git a/src/parser/copyfuncs.c b/src/parser/copyfuncs.c index da43fa64e..9cbbbe4f0 100644 --- a/src/parser/copyfuncs.c +++ b/src/parser/copyfuncs.c @@ -11,8 +11,8 @@ * be handled easily in a simple depth-first traversal. * * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -52,14 +52,21 @@ /* Copy a field that is a pointer to a C string, or perhaps NULL */ #define COPY_STRING_FIELD(fldname) \ - (newnode->fldname = from->fldname ? pstrdup(from->fldname) : (char *) NULL) + (newnode->fldname = from->fldname ? pstrdup(from->fldname) : NULL) + +/* Copy a field that is an inline array */ +#define COPY_ARRAY_FIELD(fldname) \ + memcpy(newnode->fldname, from->fldname, sizeof(newnode->fldname)) /* Copy a field that is a pointer to a simple palloc'd object of size sz */ #define COPY_POINTER_FIELD(fldname, sz) \ do { \ Size _size = (sz); \ - newnode->fldname = palloc(_size); \ - memcpy(newnode->fldname, from->fldname, _size); \ + if (_size > 0) \ + { \ + newnode->fldname = palloc(_size); \ + memcpy(newnode->fldname, from->fldname, _size); \ + } \ } while (0) /* Copy a parse location field (for Copy, this is same as scalar case) */ @@ -77,12 +84,13 @@ * _copyPlannedStmt */ static PlannedStmt * -_copyPlannedStmt(const PlannedStmt *from) +_copyPlannedStmt(const PlannedStmt * from) { PlannedStmt *newnode = makeNode(PlannedStmt); COPY_SCALAR_FIELD(commandType); COPY_SCALAR_FIELD(queryId); + COPY_SCALAR_FIELD(planId); COPY_SCALAR_FIELD(hasReturning); COPY_SCALAR_FIELD(hasModifyingCTE); COPY_SCALAR_FIELD(canSetTag); @@ -91,10 +99,12 @@ _copyPlannedStmt(const PlannedStmt *from) COPY_SCALAR_FIELD(parallelModeNeeded); COPY_SCALAR_FIELD(jitFlags); COPY_NODE_FIELD(planTree); + COPY_NODE_FIELD(partPruneInfos); COPY_NODE_FIELD(rtable); + COPY_BITMAPSET_FIELD(unprunableRelids); + COPY_NODE_FIELD(permInfos); COPY_NODE_FIELD(resultRelations); - COPY_NODE_FIELD(nonleafResultRelations); - COPY_NODE_FIELD(rootResultRelations); + COPY_NODE_FIELD(appendRelations); COPY_NODE_FIELD(subplans); COPY_BITMAPSET_FIELD(rewindPlanIDs); COPY_NODE_FIELD(rowMarks); @@ -115,14 +125,16 @@ _copyPlannedStmt(const PlannedStmt *from) * all the copy functions for classes which inherit from Plan. */ static void -CopyPlanFields(const Plan *from, Plan *newnode) +CopyPlanFields(const Plan * from, Plan * newnode) { + COPY_SCALAR_FIELD(plan.disabled_nodes); COPY_SCALAR_FIELD(startup_cost); COPY_SCALAR_FIELD(total_cost); COPY_SCALAR_FIELD(plan_rows); COPY_SCALAR_FIELD(plan_width); COPY_SCALAR_FIELD(parallel_aware); COPY_SCALAR_FIELD(parallel_safe); + COPY_SCALAR_FIELD(async_capable); COPY_SCALAR_FIELD(plan_node_id); COPY_NODE_FIELD(targetlist); COPY_NODE_FIELD(qual); @@ -137,7 +149,7 @@ CopyPlanFields(const Plan *from, Plan *newnode) * _copyPlan */ static Plan * -_copyPlan(const Plan *from) +_copyPlan(const Plan * from) { Plan *newnode = makeNode(Plan); @@ -154,7 +166,7 @@ _copyPlan(const Plan *from) * _copyResult */ static Result * -_copyResult(const Result *from) +_copyResult(const Result * from) { Result *newnode = makeNode(Result); @@ -175,7 +187,7 @@ _copyResult(const Result *from) * _copyProjectSet */ static ProjectSet * -_copyProjectSet(const ProjectSet *from) +_copyProjectSet(const ProjectSet * from) { ProjectSet *newnode = makeNode(ProjectSet); @@ -191,7 +203,7 @@ _copyProjectSet(const ProjectSet *from) * _copyModifyTable */ static ModifyTable * -_copyModifyTable(const ModifyTable *from) +_copyModifyTable(const ModifyTable * from) { ModifyTable *newnode = makeNode(ModifyTable); @@ -206,13 +218,13 @@ _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(resultRelIndex); - COPY_SCALAR_FIELD(rootResultRelIndex); - COPY_NODE_FIELD(plans); + COPY_NODE_FIELD(updateColnosLists); COPY_NODE_FIELD(withCheckOptionLists); + COPY_STRING_FIELD(returningOldAlias); + COPY_STRING_FIELD(returningNewAlias); COPY_NODE_FIELD(returningLists); COPY_NODE_FIELD(fdwPrivLists); COPY_BITMAPSET_FIELD(fdwDirectModifyPlans); @@ -221,9 +233,12 @@ _copyModifyTable(const ModifyTable *from) COPY_SCALAR_FIELD(onConflictAction); COPY_NODE_FIELD(arbiterIndexes); COPY_NODE_FIELD(onConflictSet); + COPY_NODE_FIELD(onConflictCols); COPY_NODE_FIELD(onConflictWhere); COPY_SCALAR_FIELD(exclRelRTI); COPY_NODE_FIELD(exclRelTlist); + COPY_NODE_FIELD(mergeActionLists); + COPY_NODE_FIELD(mergeJoinConditions); return newnode; } @@ -232,7 +247,7 @@ _copyModifyTable(const ModifyTable *from) * _copyAppend */ static Append * -_copyAppend(const Append *from) +_copyAppend(const Append * from) { Append *newnode = makeNode(Append); @@ -244,10 +259,11 @@ _copyAppend(const Append *from) /* * copy remainder of node */ + COPY_BITMAPSET_FIELD(apprelids); COPY_NODE_FIELD(appendplans); + COPY_SCALAR_FIELD(nasyncplans); COPY_SCALAR_FIELD(first_partial_plan); - COPY_NODE_FIELD(partitioned_rels); - COPY_NODE_FIELD(part_prune_info); + COPY_SCALAR_FIELD(part_prune_index); return newnode; } @@ -256,7 +272,7 @@ _copyAppend(const Append *from) * _copyMergeAppend */ static MergeAppend * -_copyMergeAppend(const MergeAppend *from) +_copyMergeAppend(const MergeAppend * from) { MergeAppend *newnode = makeNode(MergeAppend); @@ -268,13 +284,14 @@ _copyMergeAppend(const MergeAppend *from) /* * copy remainder of node */ - COPY_NODE_FIELD(partitioned_rels); + COPY_BITMAPSET_FIELD(apprelids); 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_SCALAR_FIELD(part_prune_index); return newnode; } @@ -283,7 +300,7 @@ _copyMergeAppend(const MergeAppend *from) * _copyRecursiveUnion */ static RecursiveUnion * -_copyRecursiveUnion(const RecursiveUnion *from) +_copyRecursiveUnion(const RecursiveUnion * from) { RecursiveUnion *newnode = makeNode(RecursiveUnion); @@ -297,11 +314,9 @@ _copyRecursiveUnion(const RecursiveUnion *from) */ COPY_SCALAR_FIELD(wtParam); COPY_SCALAR_FIELD(numCols); - if (from->numCols > 0) - { - COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); - } + 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); return newnode; @@ -311,7 +326,7 @@ _copyRecursiveUnion(const RecursiveUnion *from) * _copyBitmapAnd */ static BitmapAnd * -_copyBitmapAnd(const BitmapAnd *from) +_copyBitmapAnd(const BitmapAnd * from) { BitmapAnd *newnode = makeNode(BitmapAnd); @@ -332,7 +347,7 @@ _copyBitmapAnd(const BitmapAnd *from) * _copyBitmapOr */ static BitmapOr * -_copyBitmapOr(const BitmapOr *from) +_copyBitmapOr(const BitmapOr * from) { BitmapOr *newnode = makeNode(BitmapOr); @@ -354,7 +369,7 @@ _copyBitmapOr(const BitmapOr *from) * _copyGather */ static Gather * -_copyGather(const Gather *from) +_copyGather(const Gather * from) { Gather *newnode = makeNode(Gather); @@ -382,7 +397,7 @@ _copyGather(const Gather *from) * all the copy functions for classes which inherit from Scan. */ static void -CopyScanFields(const Scan *from, Scan *newnode) +CopyScanFields(const Scan * from, Scan * newnode) { CopyPlanFields((const Plan *) from, (Plan *) newnode); @@ -393,7 +408,7 @@ CopyScanFields(const Scan *from, Scan *newnode) * _copyScan */ static Scan * -_copyScan(const Scan *from) +_copyScan(const Scan * from) { Scan *newnode = makeNode(Scan); @@ -409,7 +424,7 @@ _copyScan(const Scan *from) * _copySeqScan */ static SeqScan * -_copySeqScan(const SeqScan *from) +_copySeqScan(const SeqScan * from) { SeqScan *newnode = makeNode(SeqScan); @@ -425,7 +440,7 @@ _copySeqScan(const SeqScan *from) * _copySampleScan */ static SampleScan * -_copySampleScan(const SampleScan *from) +_copySampleScan(const SampleScan * from) { SampleScan *newnode = makeNode(SampleScan); @@ -446,7 +461,7 @@ _copySampleScan(const SampleScan *from) * _copyIndexScan */ static IndexScan * -_copyIndexScan(const IndexScan *from) +_copyIndexScan(const IndexScan * from) { IndexScan *newnode = makeNode(IndexScan); @@ -473,7 +488,7 @@ _copyIndexScan(const IndexScan *from) * _copyIndexOnlyScan */ static IndexOnlyScan * -_copyIndexOnlyScan(const IndexOnlyScan *from) +_copyIndexOnlyScan(const IndexOnlyScan * from) { IndexOnlyScan *newnode = makeNode(IndexOnlyScan); @@ -487,6 +502,7 @@ _copyIndexOnlyScan(const IndexOnlyScan *from) */ COPY_SCALAR_FIELD(indexid); COPY_NODE_FIELD(indexqual); + COPY_NODE_FIELD(recheckqual); COPY_NODE_FIELD(indexorderby); COPY_NODE_FIELD(indextlist); COPY_SCALAR_FIELD(indexorderdir); @@ -498,7 +514,7 @@ _copyIndexOnlyScan(const IndexOnlyScan *from) * _copyBitmapIndexScan */ static BitmapIndexScan * -_copyBitmapIndexScan(const BitmapIndexScan *from) +_copyBitmapIndexScan(const BitmapIndexScan * from) { BitmapIndexScan *newnode = makeNode(BitmapIndexScan); @@ -521,7 +537,7 @@ _copyBitmapIndexScan(const BitmapIndexScan *from) * _copyBitmapHeapScan */ static BitmapHeapScan * -_copyBitmapHeapScan(const BitmapHeapScan *from) +_copyBitmapHeapScan(const BitmapHeapScan * from) { BitmapHeapScan *newnode = makeNode(BitmapHeapScan); @@ -542,7 +558,7 @@ _copyBitmapHeapScan(const BitmapHeapScan *from) * _copyTidScan */ static TidScan * -_copyTidScan(const TidScan *from) +_copyTidScan(const TidScan * from) { TidScan *newnode = makeNode(TidScan); @@ -559,11 +575,32 @@ _copyTidScan(const TidScan *from) return newnode; } +/* + * _copyTidRangeScan + */ +static TidRangeScan * +_copyTidRangeScan(const TidRangeScan * from) +{ + TidRangeScan *newnode = makeNode(TidRangeScan); + + /* + * copy node superclass fields + */ + CopyScanFields((const Scan *) from, (Scan *) newnode); + + /* + * copy remainder of node + */ + COPY_NODE_FIELD(tidrangequals); + + return newnode; +} + /* * _copySubqueryScan */ static SubqueryScan * -_copySubqueryScan(const SubqueryScan *from) +_copySubqueryScan(const SubqueryScan * from) { SubqueryScan *newnode = makeNode(SubqueryScan); @@ -576,6 +613,7 @@ _copySubqueryScan(const SubqueryScan *from) * copy remainder of node */ COPY_NODE_FIELD(subplan); + COPY_SCALAR_FIELD(scanstatus); return newnode; } @@ -584,7 +622,7 @@ _copySubqueryScan(const SubqueryScan *from) * _copyFunctionScan */ static FunctionScan * -_copyFunctionScan(const FunctionScan *from) +_copyFunctionScan(const FunctionScan * from) { FunctionScan *newnode = makeNode(FunctionScan); @@ -606,7 +644,7 @@ _copyFunctionScan(const FunctionScan *from) * _copyTableFuncScan */ static TableFuncScan * -_copyTableFuncScan(const TableFuncScan *from) +_copyTableFuncScan(const TableFuncScan * from) { TableFuncScan *newnode = makeNode(TableFuncScan); @@ -627,7 +665,7 @@ _copyTableFuncScan(const TableFuncScan *from) * _copyValuesScan */ static ValuesScan * -_copyValuesScan(const ValuesScan *from) +_copyValuesScan(const ValuesScan * from) { ValuesScan *newnode = makeNode(ValuesScan); @@ -648,7 +686,7 @@ _copyValuesScan(const ValuesScan *from) * _copyCteScan */ static CteScan * -_copyCteScan(const CteScan *from) +_copyCteScan(const CteScan * from) { CteScan *newnode = makeNode(CteScan); @@ -670,7 +708,7 @@ _copyCteScan(const CteScan *from) * _copyNamedTuplestoreScan */ static NamedTuplestoreScan * -_copyNamedTuplestoreScan(const NamedTuplestoreScan *from) +_copyNamedTuplestoreScan(const NamedTuplestoreScan * from) { NamedTuplestoreScan *newnode = makeNode(NamedTuplestoreScan); @@ -691,7 +729,7 @@ _copyNamedTuplestoreScan(const NamedTuplestoreScan *from) * _copyWorkTableScan */ static WorkTableScan * -_copyWorkTableScan(const WorkTableScan *from) +_copyWorkTableScan(const WorkTableScan * from) { WorkTableScan *newnode = makeNode(WorkTableScan); @@ -712,7 +750,7 @@ _copyWorkTableScan(const WorkTableScan *from) * _copyForeignScan */ static ForeignScan * -_copyForeignScan(const ForeignScan *from) +_copyForeignScan(const ForeignScan * from) { ForeignScan *newnode = makeNode(ForeignScan); @@ -725,6 +763,7 @@ _copyForeignScan(const ForeignScan *from) * copy remainder of node */ COPY_SCALAR_FIELD(operation); + COPY_SCALAR_FIELD(resultRelation); COPY_SCALAR_FIELD(fs_server); COPY_NODE_FIELD(fdw_exprs); COPY_NODE_FIELD(fdw_private); @@ -740,7 +779,7 @@ _copyForeignScan(const ForeignScan *from) * _copyCustomScan */ static CustomScan * -_copyCustomScan(const CustomScan *from) +_copyCustomScan(const CustomScan * from) { CustomScan *newnode = makeNode(CustomScan); @@ -776,7 +815,7 @@ _copyCustomScan(const CustomScan *from) * all the copy functions for classes which inherit from Join. */ static void -CopyJoinFields(const Join *from, Join *newnode) +CopyJoinFields(const Join * from, Join * newnode) { CopyPlanFields((const Plan *) from, (Plan *) newnode); @@ -789,7 +828,7 @@ CopyJoinFields(const Join *from, Join *newnode) * _copyGatherMerge */ static GatherMerge * -_copyGatherMerge(const GatherMerge *from) +_copyGatherMerge(const GatherMerge * from) { GatherMerge *newnode = makeNode(GatherMerge); @@ -808,7 +847,7 @@ _copyGatherMerge(const GatherMerge *from) 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_BITMAPSET_FIELD(initParam); + COPY_BITMAPSET_FIELD(initParam); return newnode; } @@ -817,7 +856,7 @@ _copyGatherMerge(const GatherMerge *from) * _copyJoin */ static Join * -_copyJoin(const Join *from) +_copyJoin(const Join * from) { Join *newnode = makeNode(Join); @@ -834,7 +873,7 @@ _copyJoin(const Join *from) * _copyNestLoop */ static NestLoop * -_copyNestLoop(const NestLoop *from) +_copyNestLoop(const NestLoop * from) { NestLoop *newnode = makeNode(NestLoop); @@ -856,7 +895,7 @@ _copyNestLoop(const NestLoop *from) * _copyMergeJoin */ static MergeJoin * -_copyMergeJoin(const MergeJoin *from) +_copyMergeJoin(const MergeJoin * from) { MergeJoin *newnode = makeNode(MergeJoin); int numCols; @@ -871,14 +910,11 @@ _copyMergeJoin(const MergeJoin *from) */ COPY_SCALAR_FIELD(skip_mark_restore); COPY_NODE_FIELD(mergeclauses); - numCols = list_length(from->mergeclauses); - if (numCols > 0) - { - COPY_POINTER_FIELD(mergeFamilies, numCols * sizeof(Oid)); - COPY_POINTER_FIELD(mergeCollations, numCols * sizeof(Oid)); - COPY_POINTER_FIELD(mergeStrategies, numCols * sizeof(int)); - COPY_POINTER_FIELD(mergeNullsFirst, numCols * sizeof(bool)); - } + COPY_POINTER_FIELD(mergeFamilies, list_length(from->mergeclauses) * sizeof(Oid)); + COPY_POINTER_FIELD(mergeCollations, list_length(from->mergeclauses) * sizeof(Oid)); + COPY_POINTER_FIELD(mergeStrategies, list_length(from->mergeclauses) * sizeof(int)); + COPY_POINTER_FIELD(mergeReversals, list_length(from->mergeclauses) * sizeof(bool)); + COPY_POINTER_FIELD(mergeNullsFirst, list_length(from->mergeclauses) * sizeof(bool)); return newnode; } @@ -887,7 +923,7 @@ _copyMergeJoin(const MergeJoin *from) * _copyHashJoin */ static HashJoin * -_copyHashJoin(const HashJoin *from) +_copyHashJoin(const HashJoin * from) { HashJoin *newnode = makeNode(HashJoin); @@ -900,6 +936,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; } @@ -909,7 +948,7 @@ _copyHashJoin(const HashJoin *from) * _copyMaterial */ static Material * -_copyMaterial(const Material *from) +_copyMaterial(const Material * from) { Material *newnode = makeNode(Material); @@ -923,23 +962,86 @@ _copyMaterial(const Material *from) /* - * _copySort + * _copyMemoize */ -static Sort * -_copySort(const Sort *from) +static Memoize * +_copyMemoize(const Memoize * from) { - Sort *newnode = makeNode(Sort); + Memoize *newnode = makeNode(Memoize); /* * copy node superclass fields */ CopyPlanFields((const Plan *) from, (Plan *) newnode); + /* + * copy remainder of node + */ + COPY_SCALAR_FIELD(numKeys); + COPY_POINTER_FIELD(hashOperators, sizeof(Oid) * from->numKeys); + COPY_POINTER_FIELD(collations, sizeof(Oid) * from->numKeys); + COPY_NODE_FIELD(param_exprs); + COPY_SCALAR_FIELD(singlerow); + COPY_SCALAR_FIELD(binary_mode); + COPY_SCALAR_FIELD(est_entries); + COPY_BITMAPSET_FIELD(keyparamids); + + return newnode; +} + + +/* + * CopySortFields + * + * This function copies the fields of the Sort node. It is used by + * all the copy functions for classes which inherit from Sort. + */ +static void +CopySortFields(const Sort * from, Sort * newnode) +{ + CopyPlanFields((const Plan *) from, (Plan *) newnode); + 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)); +} + +/* + * _copySort + */ +static Sort * +_copySort(const Sort * from) +{ + Sort *newnode = makeNode(Sort); + + /* + * copy node superclass fields + */ + CopySortFields(from, newnode); + + return newnode; +} + + +/* + * _copyIncrementalSort + */ +static IncrementalSort * +_copyIncrementalSort(const IncrementalSort * from) +{ + IncrementalSort *newnode = makeNode(IncrementalSort); + + /* + * copy node superclass fields + */ + CopySortFields((const Sort *) from, (Sort *) newnode); + + /* + * copy remainder of node + */ + COPY_SCALAR_FIELD(nPresortedCols); return newnode; } @@ -949,7 +1051,7 @@ _copySort(const Sort *from) * _copyGroup */ static Group * -_copyGroup(const Group *from) +_copyGroup(const Group * from) { Group *newnode = makeNode(Group); @@ -958,6 +1060,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; } @@ -966,7 +1069,7 @@ _copyGroup(const Group *from) * _copyAgg */ static Agg * -_copyAgg(const Agg *from) +_copyAgg(const Agg * from) { Agg *newnode = makeNode(Agg); @@ -975,12 +1078,11 @@ _copyAgg(const Agg *from) COPY_SCALAR_FIELD(aggstrategy); COPY_SCALAR_FIELD(aggsplit); COPY_SCALAR_FIELD(numCols); - if (from->numCols > 0) - { - COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); - } + 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_SCALAR_FIELD(transitionSpace); COPY_BITMAPSET_FIELD(aggParams); COPY_NODE_FIELD(groupingSets); COPY_NODE_FIELD(chain); @@ -992,33 +1094,33 @@ _copyAgg(const Agg *from) * _copyWindowAgg */ static WindowAgg * -_copyWindowAgg(const WindowAgg *from) +_copyWindowAgg(const WindowAgg * from) { WindowAgg *newnode = makeNode(WindowAgg); CopyPlanFields((const Plan *) from, (Plan *) newnode); + COPY_STRING_FIELD(winname); COPY_SCALAR_FIELD(winref); COPY_SCALAR_FIELD(partNumCols); - if (from->partNumCols > 0) - { - COPY_POINTER_FIELD(partColIdx, from->partNumCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid)); - } + 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(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); COPY_NODE_FIELD(endOffset); + COPY_NODE_FIELD(runCondition); + COPY_NODE_FIELD(runConditionOrig); COPY_SCALAR_FIELD(startInRangeFunc); COPY_SCALAR_FIELD(endInRangeFunc); COPY_SCALAR_FIELD(inRangeColl); COPY_SCALAR_FIELD(inRangeAsc); COPY_SCALAR_FIELD(inRangeNullsFirst); + COPY_SCALAR_FIELD(topWindow); return newnode; } @@ -1027,7 +1129,7 @@ _copyWindowAgg(const WindowAgg *from) * _copyUnique */ static Unique * -_copyUnique(const Unique *from) +_copyUnique(const Unique * from) { Unique *newnode = makeNode(Unique); @@ -1042,6 +1144,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; } @@ -1050,7 +1153,7 @@ _copyUnique(const Unique *from) * _copyHash */ static Hash * -_copyHash(const Hash *from) +_copyHash(const Hash * from) { Hash *newnode = makeNode(Hash); @@ -1062,6 +1165,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); @@ -1074,7 +1178,7 @@ _copyHash(const Hash *from) * _copySetOp */ static SetOp * -_copySetOp(const SetOp *from) +_copySetOp(const SetOp * from) { SetOp *newnode = makeNode(SetOp); @@ -1089,10 +1193,10 @@ _copySetOp(const SetOp *from) COPY_SCALAR_FIELD(cmd); COPY_SCALAR_FIELD(strategy); COPY_SCALAR_FIELD(numCols); - COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); - COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); - COPY_SCALAR_FIELD(flagColIdx); - COPY_SCALAR_FIELD(firstFlag); + COPY_POINTER_FIELD(cmpColIdx, from->numCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(cmpOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(cmpCollations, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(cmpNullsFirst, from->numCols * sizeof(bool)); COPY_SCALAR_FIELD(numGroups); return newnode; @@ -1102,7 +1206,7 @@ _copySetOp(const SetOp *from) * _copyLockRows */ static LockRows * -_copyLockRows(const LockRows *from) +_copyLockRows(const LockRows * from) { LockRows *newnode = makeNode(LockRows); @@ -1124,7 +1228,7 @@ _copyLockRows(const LockRows *from) * _copyLimit */ static Limit * -_copyLimit(const Limit *from) +_copyLimit(const Limit * from) { Limit *newnode = makeNode(Limit); @@ -1138,6 +1242,11 @@ _copyLimit(const Limit *from) */ COPY_NODE_FIELD(limitOffset); COPY_NODE_FIELD(limitCount); + COPY_SCALAR_FIELD(limitOption); + COPY_SCALAR_FIELD(uniqNumCols); + COPY_POINTER_FIELD(uniqColIdx, from->uniqNumCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(uniqOperators, from->uniqNumCols * sizeof(Oid)); + COPY_POINTER_FIELD(uniqCollations, from->uniqNumCols * sizeof(Oid)); return newnode; } @@ -1146,7 +1255,7 @@ _copyLimit(const Limit *from) * _copyNestLoopParam */ static NestLoopParam * -_copyNestLoopParam(const NestLoopParam *from) +_copyNestLoopParam(const NestLoopParam * from) { NestLoopParam *newnode = makeNode(NestLoopParam); @@ -1160,7 +1269,7 @@ _copyNestLoopParam(const NestLoopParam *from) * _copyPlanRowMark */ static PlanRowMark * -_copyPlanRowMark(const PlanRowMark *from) +_copyPlanRowMark(const PlanRowMark * from) { PlanRowMark *newnode = makeNode(PlanRowMark); @@ -1177,10 +1286,11 @@ _copyPlanRowMark(const PlanRowMark *from) } static PartitionPruneInfo * -_copyPartitionPruneInfo(const PartitionPruneInfo *from) +_copyPartitionPruneInfo(const PartitionPruneInfo * from) { PartitionPruneInfo *newnode = makeNode(PartitionPruneInfo); + COPY_BITMAPSET_FIELD(relids); COPY_NODE_FIELD(prune_infos); COPY_BITMAPSET_FIELD(other_subplans); @@ -1188,20 +1298,19 @@ _copyPartitionPruneInfo(const PartitionPruneInfo *from) } static PartitionedRelPruneInfo * -_copyPartitionedRelPruneInfo(const PartitionedRelPruneInfo *from) +_copyPartitionedRelPruneInfo(const PartitionedRelPruneInfo * from) { PartitionedRelPruneInfo *newnode = makeNode(PartitionedRelPruneInfo); - COPY_SCALAR_FIELD(reloid); - COPY_NODE_FIELD(pruning_steps); + COPY_SCALAR_FIELD(rtindex); COPY_BITMAPSET_FIELD(present_parts); COPY_SCALAR_FIELD(nparts); - COPY_SCALAR_FIELD(nexprs); COPY_POINTER_FIELD(subplan_map, from->nparts * sizeof(int)); COPY_POINTER_FIELD(subpart_map, from->nparts * sizeof(int)); - COPY_POINTER_FIELD(hasexecparam, from->nexprs * sizeof(bool)); - COPY_SCALAR_FIELD(do_initial_prune); - COPY_SCALAR_FIELD(do_exec_prune); + COPY_POINTER_FIELD(leafpart_rti_map, from->nparts * sizeof(int)); + COPY_POINTER_FIELD(relid_map, from->nparts * sizeof(Oid)); + COPY_NODE_FIELD(initial_prunning_steps); + COPY_NODE_FIELD(exec_prunning_steps); COPY_BITMAPSET_FIELD(execparamids); return newnode; @@ -1211,7 +1320,7 @@ _copyPartitionedRelPruneInfo(const PartitionedRelPruneInfo *from) * _copyPartitionPruneStepOp */ static PartitionPruneStepOp * -_copyPartitionPruneStepOp(const PartitionPruneStepOp *from) +_copyPartitionPruneStepOp(const PartitionPruneStepOp * from) { PartitionPruneStepOp *newnode = makeNode(PartitionPruneStepOp); @@ -1228,7 +1337,7 @@ _copyPartitionPruneStepOp(const PartitionPruneStepOp *from) * _copyPartitionPruneStepCombine */ static PartitionPruneStepCombine * -_copyPartitionPruneStepCombine(const PartitionPruneStepCombine *from) +_copyPartitionPruneStepCombine(const PartitionPruneStepCombine * from) { PartitionPruneStepCombine *newnode = makeNode(PartitionPruneStepCombine); @@ -1243,7 +1352,7 @@ _copyPartitionPruneStepCombine(const PartitionPruneStepCombine *from) * _copyPlanInvalItem */ static PlanInvalItem * -_copyPlanInvalItem(const PlanInvalItem *from) +_copyPlanInvalItem(const PlanInvalItem * from) { PlanInvalItem *newnode = makeNode(PlanInvalItem); @@ -1300,6 +1409,7 @@ _copyTableFunc(const TableFunc *from) { TableFunc *newnode = makeNode(TableFunc); + COPY_SCALAR_FIELD(functype); COPY_NODE_FIELD(ns_uris); COPY_NODE_FIELD(ns_names); COPY_NODE_FIELD(docexpr); @@ -1310,7 +1420,10 @@ _copyTableFunc(const TableFunc *from) COPY_NODE_FIELD(colcollations); COPY_NODE_FIELD(colexprs); COPY_NODE_FIELD(coldefexprs); + COPY_NODE_FIELD(colvalexprs); + COPY_NODE_FIELD(passingvalexprs); COPY_BITMAPSET_FIELD(notnulls); + COPY_NODE_FIELD(plan); COPY_SCALAR_FIELD(ordinalitycol); COPY_LOCATION_FIELD(location); @@ -1327,6 +1440,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); @@ -1356,9 +1470,11 @@ _copyVar(const Var *from) COPY_SCALAR_FIELD(vartype); COPY_SCALAR_FIELD(vartypmod); COPY_SCALAR_FIELD(varcollid); + COPY_BITMAPSET_FIELD(varnullingrels); COPY_SCALAR_FIELD(varlevelsup); - COPY_SCALAR_FIELD(varnoold); - COPY_SCALAR_FIELD(varoattno); + COPY_SCALAR_FIELD(varreturningtype); + COPY_SCALAR_FIELD(varnosyn); + COPY_SCALAR_FIELD(varattnosyn); COPY_LOCATION_FIELD(location); return newnode; @@ -1446,6 +1562,8 @@ _copyAggref(const Aggref *from) COPY_SCALAR_FIELD(aggkind); COPY_SCALAR_FIELD(agglevelsup); COPY_SCALAR_FIELD(aggsplit); + COPY_SCALAR_FIELD(aggno); + COPY_SCALAR_FIELD(aggtransno); COPY_LOCATION_FIELD(location); return newnode; @@ -1482,6 +1600,7 @@ _copyWindowFunc(const WindowFunc *from) COPY_SCALAR_FIELD(inputcollid); COPY_NODE_FIELD(args); COPY_NODE_FIELD(aggfilter); + COPY_NODE_FIELD(runCondition); COPY_SCALAR_FIELD(winref); COPY_SCALAR_FIELD(winstar); COPY_SCALAR_FIELD(winagg); @@ -1490,16 +1609,42 @@ _copyWindowFunc(const WindowFunc *from) return newnode; } +static WindowFuncRunCondition * +_copyWindowFuncRunCondition(const WindowFuncRunCondition *from) +{ + WindowFuncRunCondition *newnode = makeNode(WindowFuncRunCondition); + + COPY_SCALAR_FIELD(opno); + COPY_SCALAR_FIELD(inputcollid); + COPY_SCALAR_FIELD(wfunc_left); + COPY_NODE_FIELD(arg); + + return newnode; +} + +static MergeSupportFunc * +_copyMergeSupportFunc(const MergeSupportFunc *from) +{ + MergeSupportFunc *newnode = makeNode(MergeSupportFunc); + + COPY_SCALAR_FIELD(msftype); + COPY_SCALAR_FIELD(msfcollid); + COPY_LOCATION_FIELD(location); + + return newnode; +} + /* - * _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(refrestype); COPY_SCALAR_FIELD(reftypmod); COPY_SCALAR_FIELD(refcollid); COPY_NODE_FIELD(refupperindexpr); @@ -1617,6 +1762,8 @@ _copyScalarArrayOpExpr(const ScalarArrayOpExpr *from) COPY_SCALAR_FIELD(opno); COPY_SCALAR_FIELD(opfuncid); + COPY_SCALAR_FIELD(hashfuncid); + COPY_SCALAR_FIELD(negfuncid); COPY_SCALAR_FIELD(useOr); COPY_SCALAR_FIELD(inputcollid); COPY_NODE_FIELD(args); @@ -1878,6 +2025,8 @@ _copyArrayExpr(const ArrayExpr *from) COPY_SCALAR_FIELD(element_typeid); COPY_NODE_FIELD(elements); COPY_SCALAR_FIELD(multidims); + COPY_LOCATION_FIELD(list_start); + COPY_LOCATION_FIELD(list_end); COPY_LOCATION_FIELD(location); return newnode; @@ -1908,7 +2057,7 @@ _copyRowCompareExpr(const RowCompareExpr *from) { RowCompareExpr *newnode = makeNode(RowCompareExpr); - COPY_SCALAR_FIELD(rctype); + COPY_SCALAR_FIELD(cmptype); COPY_NODE_FIELD(opnos); COPY_NODE_FIELD(opfamilies); COPY_NODE_FIELD(inputcollids); @@ -1989,6 +2138,147 @@ _copyXmlExpr(const XmlExpr *from) return newnode; } +static JsonFormat * +_copyJsonFormat(const JsonFormat *from) +{ + JsonFormat *newnode = makeNode(JsonFormat); + + COPY_SCALAR_FIELD(format_type); + COPY_SCALAR_FIELD(encoding); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonReturning * +_copyJsonReturning(const JsonReturning *from) +{ + JsonReturning *newnode = makeNode(JsonReturning); + + COPY_NODE_FIELD(format); + COPY_SCALAR_FIELD(typid); + COPY_SCALAR_FIELD(typmod); + + return newnode; +} + +static JsonValueExpr * +_copyJsonValueExpr(const JsonValueExpr *from) +{ + JsonValueExpr *newnode = makeNode(JsonValueExpr); + + COPY_NODE_FIELD(raw_expr); + COPY_NODE_FIELD(formatted_expr); + COPY_NODE_FIELD(format); + + return newnode; +} + +static JsonConstructorExpr * +_copyJsonConstructorExpr(const JsonConstructorExpr *from) +{ + JsonConstructorExpr *newnode = makeNode(JsonConstructorExpr); + + COPY_SCALAR_FIELD(type); + COPY_NODE_FIELD(args); + COPY_NODE_FIELD(func); + COPY_NODE_FIELD(coercion); + COPY_NODE_FIELD(returning); + COPY_SCALAR_FIELD(absent_on_null); + COPY_SCALAR_FIELD(unique); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonIsPredicate * +_copyJsonIsPredicate(const JsonIsPredicate *from) +{ + JsonIsPredicate *newnode = makeNode(JsonIsPredicate); + + COPY_NODE_FIELD(expr); + COPY_NODE_FIELD(format); + COPY_SCALAR_FIELD(item_type); + COPY_SCALAR_FIELD(unique_keys); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonBehavior * +_copyJsonBehavior(const JsonBehavior *from) +{ + JsonBehavior *newnode = makeNode(JsonBehavior); + + COPY_SCALAR_FIELD(btype); + COPY_NODE_FIELD(expr); + COPY_SCALAR_FIELD(coerce); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonExpr * +_copyJsonExpr(const JsonExpr *from) +{ + JsonExpr *newnode = makeNode(JsonExpr); + + COPY_SCALAR_FIELD(op); + COPY_STRING_FIELD(column_name); + COPY_NODE_FIELD(formatted_expr); + COPY_NODE_FIELD(format); + COPY_NODE_FIELD(path_spec); + COPY_NODE_FIELD(returning); + COPY_NODE_FIELD(passing_names); + COPY_NODE_FIELD(passing_values); + COPY_NODE_FIELD(on_empty); + COPY_NODE_FIELD(on_error); + COPY_SCALAR_FIELD(use_io_coercion); + COPY_SCALAR_FIELD(use_json_coercion); + COPY_SCALAR_FIELD(wrapper); + COPY_SCALAR_FIELD(omit_quotes); + COPY_SCALAR_FIELD(collation); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonTablePath * +_copyJsonTablePath(const JsonTablePath *from) +{ + JsonTablePath *newnode = makeNode(JsonTablePath); + + COPY_NODE_FIELD(value); + COPY_STRING_FIELD(name); + + return newnode; +} + +static JsonTablePathScan * +_copyJsonTablePathScan(const JsonTablePathScan *from) +{ + JsonTablePathScan *newnode = makeNode(JsonTablePathScan); + + COPY_NODE_FIELD(path); + COPY_SCALAR_FIELD(errorOnError); + COPY_NODE_FIELD(child); + COPY_SCALAR_FIELD(colMin); + COPY_SCALAR_FIELD(colMax); + + return newnode; +} + +static JsonTableSiblingJoin * +_copyJsonTableSiblingJoin(const JsonTableSiblingJoin *from) +{ + JsonTableSiblingJoin *newnode = makeNode(JsonTableSiblingJoin); + + COPY_NODE_FIELD(lplan); + COPY_NODE_FIELD(rplan); + + return newnode; +} + /* * _copyNullTest */ @@ -2020,6 +2310,21 @@ _copyBooleanTest(const BooleanTest *from) return newnode; } +static MergeAction * +_copyMergeAction(const MergeAction *from) +{ + MergeAction *newnode = makeNode(MergeAction); + + COPY_SCALAR_FIELD(matchKind); + COPY_SCALAR_FIELD(commandType); + COPY_SCALAR_FIELD(override); + COPY_NODE_FIELD(qual); + COPY_NODE_FIELD(targetList); + COPY_NODE_FIELD(updateColnos); + + return newnode; +} + /* * _copyCoerceToDomain */ @@ -2114,6 +2419,18 @@ _copyInferenceElem(const InferenceElem *from) return newnode; } +static ReturningExpr * +_copyReturningExpr(const ReturningExpr *from) +{ + ReturningExpr *newnode = makeNode(ReturningExpr); + + COPY_SCALAR_FIELD(retlevelsup); + COPY_SCALAR_FIELD(retold); + COPY_NODE_FIELD(retexpr); + + return newnode; +} + /* * _copyTargetEntry */ @@ -2159,6 +2476,7 @@ _copyJoinExpr(const JoinExpr *from) COPY_NODE_FIELD(larg); COPY_NODE_FIELD(rarg); COPY_NODE_FIELD(usingClause); + COPY_NODE_FIELD(join_using_alias); COPY_NODE_FIELD(quals); COPY_NODE_FIELD(alias); COPY_SCALAR_FIELD(rtindex); @@ -2201,7 +2519,7 @@ _copyOnConflictExpr(const OnConflictExpr *from) } /* **************************************************************** - * 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. @@ -2213,24 +2531,35 @@ _copyOnConflictExpr(const OnConflictExpr *from) * _copyPathKey */ static PathKey * -_copyPathKey(const PathKey *from) +_copyPathKey(const PathKey * from) { PathKey *newnode = makeNode(PathKey); /* EquivalenceClasses are never moved, so just shallow-copy the pointer */ COPY_SCALAR_FIELD(pk_eclass); COPY_SCALAR_FIELD(pk_opfamily); - COPY_SCALAR_FIELD(pk_strategy); + COPY_SCALAR_FIELD(pk_cmptype); COPY_SCALAR_FIELD(pk_nulls_first); return newnode; } +static GroupByOrdering * +_copyGroupByOrdering(const GroupByOrdering * from) +{ + GroupByOrdering *newnode = makeNode(GroupByOrdering); + + COPY_NODE_FIELD(pathkeys); + COPY_NODE_FIELD(clauses); + + return newnode; +} + /* * _copyRestrictInfo */ static RestrictInfo * -_copyRestrictInfo(const RestrictInfo *from) +_copyRestrictInfo(const RestrictInfo * from) { RestrictInfo *newnode = makeNode(RestrictInfo); @@ -2240,6 +2569,7 @@ _copyRestrictInfo(const RestrictInfo *from) COPY_SCALAR_FIELD(can_join); COPY_SCALAR_FIELD(pseudoconstant); COPY_SCALAR_FIELD(leakproof); + COPY_SCALAR_FIELD(has_volatile); COPY_SCALAR_FIELD(security_level); COPY_BITMAPSET_FIELD(clause_relids); COPY_BITMAPSET_FIELD(required_relids); @@ -2267,6 +2597,8 @@ _copyRestrictInfo(const RestrictInfo *from) COPY_SCALAR_FIELD(right_bucketsize); COPY_SCALAR_FIELD(left_mcvfreq); COPY_SCALAR_FIELD(right_mcvfreq); + COPY_SCALAR_FIELD(left_hasheqoperator); + COPY_SCALAR_FIELD(right_hasheqoperator); return newnode; } @@ -2275,7 +2607,7 @@ _copyRestrictInfo(const RestrictInfo *from) * _copyPlaceHolderVar */ static PlaceHolderVar * -_copyPlaceHolderVar(const PlaceHolderVar *from) +_copyPlaceHolderVar(const PlaceHolderVar * from) { PlaceHolderVar *newnode = makeNode(PlaceHolderVar); @@ -2291,7 +2623,7 @@ _copyPlaceHolderVar(const PlaceHolderVar *from) * _copySpecialJoinInfo */ static SpecialJoinInfo * -_copySpecialJoinInfo(const SpecialJoinInfo *from) +_copySpecialJoinInfo(const SpecialJoinInfo * from) { SpecialJoinInfo *newnode = makeNode(SpecialJoinInfo); @@ -2314,7 +2646,7 @@ _copySpecialJoinInfo(const SpecialJoinInfo *from) * _copyAppendRelInfo */ static AppendRelInfo * -_copyAppendRelInfo(const AppendRelInfo *from) +_copyAppendRelInfo(const AppendRelInfo * from) { AppendRelInfo *newnode = makeNode(AppendRelInfo); @@ -2323,6 +2655,8 @@ _copyAppendRelInfo(const AppendRelInfo *from) COPY_SCALAR_FIELD(parent_reltype); COPY_SCALAR_FIELD(child_reltype); COPY_NODE_FIELD(translated_vars); + COPY_SCALAR_FIELD(num_child_cols); + COPY_POINTER_FIELD(parent_colnos, from->num_child_cols * sizeof(AttrNumber)); COPY_SCALAR_FIELD(parent_reloid); return newnode; @@ -2332,7 +2666,7 @@ _copyAppendRelInfo(const AppendRelInfo *from) * _copyPlaceHolderInfo */ static PlaceHolderInfo * -_copyPlaceHolderInfo(const PlaceHolderInfo *from) +_copyPlaceHolderInfo(const PlaceHolderInfo * from) { PlaceHolderInfo *newnode = makeNode(PlaceHolderInfo); @@ -2357,14 +2691,23 @@ _copyRangeTblEntry(const RangeTblEntry *from) { RangeTblEntry *newnode = makeNode(RangeTblEntry); + COPY_NODE_FIELD(alias); + COPY_NODE_FIELD(eref); COPY_SCALAR_FIELD(rtekind); COPY_SCALAR_FIELD(relid); + COPY_SCALAR_FIELD(inh); COPY_SCALAR_FIELD(relkind); + COPY_SCALAR_FIELD(rellockmode); + COPY_SCALAR_FIELD(perminfoindex); COPY_NODE_FIELD(tablesample); COPY_NODE_FIELD(subquery); COPY_SCALAR_FIELD(security_barrier); COPY_SCALAR_FIELD(jointype); + COPY_SCALAR_FIELD(joinmergedcols); COPY_NODE_FIELD(joinaliasvars); + COPY_NODE_FIELD(joinleftcols); + COPY_NODE_FIELD(joinrightcols); + COPY_NODE_FIELD(join_using_alias); COPY_NODE_FIELD(functions); COPY_SCALAR_FIELD(funcordinality); COPY_NODE_FIELD(tablefunc); @@ -2377,16 +2720,9 @@ _copyRangeTblEntry(const RangeTblEntry *from) COPY_NODE_FIELD(colcollations); COPY_STRING_FIELD(enrname); COPY_SCALAR_FIELD(enrtuples); - COPY_NODE_FIELD(alias); - COPY_NODE_FIELD(eref); + COPY_NODE_FIELD(groupexprs); COPY_SCALAR_FIELD(lateral); - COPY_SCALAR_FIELD(inh); COPY_SCALAR_FIELD(inFromCl); - COPY_SCALAR_FIELD(requiredPerms); - COPY_SCALAR_FIELD(checkAsUser); - COPY_BITMAPSET_FIELD(selectedCols); - COPY_BITMAPSET_FIELD(insertedCols); - COPY_BITMAPSET_FIELD(updatedCols); COPY_NODE_FIELD(securityQuals); return newnode; @@ -2442,6 +2778,7 @@ _copySortGroupClause(const SortGroupClause *from) COPY_SCALAR_FIELD(tleSortGroupRef); COPY_SCALAR_FIELD(eqop); COPY_SCALAR_FIELD(sortop); + COPY_SCALAR_FIELD(reverse_sort); COPY_SCALAR_FIELD(nulls_first); COPY_SCALAR_FIELD(hashable); @@ -2535,6 +2872,38 @@ _copyOnConflictClause(const OnConflictClause *from) return newnode; } +static CTESearchClause * +_copyCTESearchClause(const CTESearchClause *from) +{ + CTESearchClause *newnode = makeNode(CTESearchClause); + + COPY_NODE_FIELD(search_col_list); + COPY_SCALAR_FIELD(search_breadth_first); + COPY_STRING_FIELD(search_seq_column); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static CTECycleClause * +_copyCTECycleClause(const CTECycleClause *from) +{ + CTECycleClause *newnode = makeNode(CTECycleClause); + + COPY_NODE_FIELD(cycle_col_list); + COPY_STRING_FIELD(cycle_mark_column); + COPY_NODE_FIELD(cycle_mark_value); + COPY_NODE_FIELD(cycle_mark_default); + COPY_STRING_FIELD(cycle_path_column); + COPY_LOCATION_FIELD(location); + COPY_SCALAR_FIELD(cycle_mark_type); + COPY_SCALAR_FIELD(cycle_mark_typmod); + COPY_SCALAR_FIELD(cycle_mark_collation); + COPY_SCALAR_FIELD(cycle_mark_neop); + + return newnode; +} + static CommonTableExpr * _copyCommonTableExpr(const CommonTableExpr *from) { @@ -2542,7 +2911,10 @@ _copyCommonTableExpr(const CommonTableExpr *from) COPY_STRING_FIELD(ctename); COPY_NODE_FIELD(aliascolnames); + COPY_SCALAR_FIELD(ctematerialized); COPY_NODE_FIELD(ctequery); + COPY_NODE_FIELD(search_clause); + COPY_NODE_FIELD(cycle_clause); COPY_LOCATION_FIELD(location); COPY_SCALAR_FIELD(cterecursive); COPY_SCALAR_FIELD(cterefcount); @@ -2554,8 +2926,22 @@ _copyCommonTableExpr(const CommonTableExpr *from) return newnode; } +static MergeWhenClause * +_copyMergeWhenClause(const MergeWhenClause *from) +{ + MergeWhenClause *newnode = makeNode(MergeWhenClause); + + COPY_SCALAR_FIELD(matchKind); + COPY_SCALAR_FIELD(commandType); + COPY_SCALAR_FIELD(override); + COPY_NODE_FIELD(condition); + COPY_NODE_FIELD(targetList); + COPY_NODE_FIELD(values); + return newnode; +} + static A_Expr * -_copyAExpr(const A_Expr *from) +_copyA_Expr(const A_Expr *from) { A_Expr *newnode = makeNode(A_Expr); @@ -2563,6 +2949,8 @@ _copyAExpr(const A_Expr *from) COPY_NODE_FIELD(name); COPY_NODE_FIELD(lexpr); COPY_NODE_FIELD(rexpr); + COPY_LOCATION_FIELD(rexpr_list_start); + COPY_LOCATION_FIELD(rexpr_list_end); COPY_LOCATION_FIELD(location); return newnode; @@ -2591,29 +2979,37 @@ _copyParamRef(const ParamRef *from) } static A_Const * -_copyAConst(const A_Const *from) +_copyA_Const(const A_Const *from) { A_Const *newnode = makeNode(A_Const); - /* This part must duplicate _copyValue */ - COPY_SCALAR_FIELD(val.type); - switch (from->val.type) + COPY_SCALAR_FIELD(isnull); + if (!from->isnull) { - case T_Integer: - COPY_SCALAR_FIELD(val.val.ival); - break; - case T_Float: - case T_String: - case T_BitString: - COPY_STRING_FIELD(val.val.str); - break; - case T_Null: - /* nothing to do */ - break; - default: - elog(ERROR, "unrecognized node type: %d", - (int) from->val.type); - break; + /* This part must duplicate other _copy*() functions. */ + COPY_SCALAR_FIELD(val.node.type); + switch (nodeTag(&from->val)) + { + case T_Integer: + COPY_SCALAR_FIELD(val.ival.ival); + break; + case T_Float: + COPY_STRING_FIELD(val.fval.fval); + break; + case T_Boolean: + COPY_SCALAR_FIELD(val.boolval.boolval); + break; + case T_String: + COPY_STRING_FIELD(val.sval.sval); + break; + case T_BitString: + COPY_STRING_FIELD(val.bsval.bsval); + break; + default: + elog(ERROR, "unrecognized node type: %d", + (int) nodeTag(&from->val)); + break; + } } COPY_LOCATION_FIELD(location); @@ -2630,18 +3026,19 @@ _copyFuncCall(const FuncCall *from) COPY_NODE_FIELD(args); COPY_NODE_FIELD(agg_order); COPY_NODE_FIELD(agg_filter); + COPY_NODE_FIELD(over); COPY_SCALAR_FIELD(agg_within_group); COPY_SCALAR_FIELD(agg_star); COPY_SCALAR_FIELD(agg_distinct); COPY_SCALAR_FIELD(func_variadic); - COPY_NODE_FIELD(over); + COPY_SCALAR_FIELD(funcformat); COPY_LOCATION_FIELD(location); return newnode; } static A_Star * -_copyAStar(const A_Star *from) +_copyA_Star(const A_Star *from) { A_Star *newnode = makeNode(A_Star); @@ -2649,7 +3046,7 @@ _copyAStar(const A_Star *from) } static A_Indices * -_copyAIndices(const A_Indices *from) +_copyA_Indices(const A_Indices *from) { A_Indices *newnode = makeNode(A_Indices); @@ -2677,6 +3074,8 @@ _copyA_ArrayExpr(const A_ArrayExpr *from) A_ArrayExpr *newnode = makeNode(A_ArrayExpr); COPY_NODE_FIELD(elements); + COPY_LOCATION_FIELD(list_start); + COPY_LOCATION_FIELD(list_end); COPY_LOCATION_FIELD(location); return newnode; @@ -2862,12 +3261,24 @@ _copyIndexElem(const IndexElem *from) COPY_STRING_FIELD(indexcolname); COPY_NODE_FIELD(collation); COPY_NODE_FIELD(opclass); + COPY_NODE_FIELD(opclassopts); COPY_SCALAR_FIELD(ordering); COPY_SCALAR_FIELD(nulls_ordering); return newnode; } +static StatsElem * +_copyStatsElem(const StatsElem *from) +{ + StatsElem *newnode = makeNode(StatsElem); + + COPY_STRING_FIELD(name); + COPY_NODE_FIELD(expr); + + return newnode; +} + static ColumnDef * _copyColumnDef(const ColumnDef *from) { @@ -2875,16 +3286,17 @@ _copyColumnDef(const ColumnDef *from) COPY_STRING_FIELD(colname); COPY_NODE_FIELD(typeName); + COPY_STRING_FIELD(compression); COPY_SCALAR_FIELD(inhcount); 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); @@ -2903,29 +3315,37 @@ _copyConstraint(const Constraint *from) COPY_STRING_FIELD(conname); COPY_SCALAR_FIELD(deferrable); COPY_SCALAR_FIELD(initdeferred); - COPY_LOCATION_FIELD(location); + COPY_SCALAR_FIELD(is_enforced); + COPY_SCALAR_FIELD(skip_validation); + COPY_SCALAR_FIELD(initially_valid); COPY_SCALAR_FIELD(is_no_inherit); COPY_NODE_FIELD(raw_expr); COPY_STRING_FIELD(cooked_expr); COPY_SCALAR_FIELD(generated_when); + COPY_SCALAR_FIELD(generated_kind); + COPY_SCALAR_FIELD(nulls_not_distinct); COPY_NODE_FIELD(keys); + COPY_SCALAR_FIELD(without_overlaps); COPY_NODE_FIELD(including); COPY_NODE_FIELD(exclusions); 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); COPY_NODE_FIELD(fk_attrs); COPY_NODE_FIELD(pk_attrs); + COPY_SCALAR_FIELD(fk_with_period); + COPY_SCALAR_FIELD(pk_with_period); COPY_SCALAR_FIELD(fk_matchtype); COPY_SCALAR_FIELD(fk_upd_action); COPY_SCALAR_FIELD(fk_del_action); + COPY_NODE_FIELD(fk_del_set_cols); COPY_NODE_FIELD(old_conpfeqop); COPY_SCALAR_FIELD(old_pktable_oid); - COPY_SCALAR_FIELD(skip_validation); - COPY_SCALAR_FIELD(initially_valid); + COPY_LOCATION_FIELD(location); return newnode; } @@ -2981,18 +3401,261 @@ _copyRoleSpec(const RoleSpec *from) return newnode; } -static TriggerTransition * -_copyTriggerTransition(const TriggerTransition *from) +static ReturningOption * +_copyReturningOption(const ReturningOption *from) { - TriggerTransition *newnode = makeNode(TriggerTransition); + ReturningOption *newnode = makeNode(ReturningOption); - COPY_STRING_FIELD(name); + COPY_SCALAR_FIELD(option); + COPY_STRING_FIELD(value); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static ReturningClause * +_copyReturningClause(const ReturningClause *from) +{ + ReturningClause *newnode = makeNode(ReturningClause); + + COPY_NODE_FIELD(options); + COPY_NODE_FIELD(exprs); + + return newnode; +} + +static TriggerTransition * +_copyTriggerTransition(const TriggerTransition *from) +{ + TriggerTransition *newnode = makeNode(TriggerTransition); + + COPY_STRING_FIELD(name); COPY_SCALAR_FIELD(isNew); COPY_SCALAR_FIELD(isTable); return newnode; } +static JsonOutput * +_copyJsonOutput(const JsonOutput *from) +{ + JsonOutput *newnode = makeNode(JsonOutput); + + COPY_NODE_FIELD(typeName); + COPY_NODE_FIELD(returning); + + return newnode; +} + +static JsonArgument * +_copyJsonArgument(const JsonArgument *from) +{ + JsonArgument *newnode = makeNode(JsonArgument); + + COPY_NODE_FIELD(val); + COPY_STRING_FIELD(name); + + return newnode; +} + +static JsonFuncExpr * +_copyJsonFuncExpr(const JsonFuncExpr *from) +{ + JsonFuncExpr *newnode = makeNode(JsonFuncExpr); + + COPY_SCALAR_FIELD(op); + COPY_STRING_FIELD(column_name); + COPY_NODE_FIELD(context_item); + COPY_NODE_FIELD(pathspec); + COPY_NODE_FIELD(passing); + COPY_NODE_FIELD(output); + COPY_NODE_FIELD(on_empty); + COPY_NODE_FIELD(on_error); + COPY_SCALAR_FIELD(wrapper); + COPY_SCALAR_FIELD(quotes); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonTablePathSpec * +_copyJsonTablePathSpec(const JsonTablePathSpec *from) +{ + JsonTablePathSpec *newnode = makeNode(JsonTablePathSpec); + + COPY_NODE_FIELD(string); + COPY_STRING_FIELD(name); + COPY_LOCATION_FIELD(name_location); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonTable * +_copyJsonTable(const JsonTable *from) +{ + JsonTable *newnode = makeNode(JsonTable); + + COPY_NODE_FIELD(context_item); + COPY_NODE_FIELD(pathspec); + COPY_NODE_FIELD(passing); + COPY_NODE_FIELD(columns); + COPY_NODE_FIELD(on_error); + COPY_NODE_FIELD(alias); + COPY_SCALAR_FIELD(lateral); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonTableColumn * +_copyJsonTableColumn(const JsonTableColumn *from) +{ + JsonTableColumn *newnode = makeNode(JsonTableColumn); + + COPY_SCALAR_FIELD(coltype); + COPY_STRING_FIELD(name); + COPY_NODE_FIELD(typeName); + COPY_NODE_FIELD(pathspec); + COPY_NODE_FIELD(format); + COPY_SCALAR_FIELD(wrapper); + COPY_SCALAR_FIELD(quotes); + COPY_NODE_FIELD(columns); + COPY_NODE_FIELD(on_empty); + COPY_NODE_FIELD(on_error); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonKeyValue * +_copyJsonKeyValue(const JsonKeyValue *from) +{ + JsonKeyValue *newnode = makeNode(JsonKeyValue); + + COPY_NODE_FIELD(key); + COPY_NODE_FIELD(value); + + return newnode; +} + +static JsonParseExpr * +_copyJsonParseExpr(const JsonParseExpr *from) +{ + JsonParseExpr *newnode = makeNode(JsonParseExpr); + + COPY_NODE_FIELD(expr); + COPY_NODE_FIELD(output); + COPY_SCALAR_FIELD(unique_keys); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonScalarExpr * +_copyJsonScalarExpr(const JsonScalarExpr *from) +{ + JsonScalarExpr *newnode = makeNode(JsonScalarExpr); + + COPY_NODE_FIELD(expr); + COPY_NODE_FIELD(output); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonSerializeExpr * +_copyJsonSerializeExpr(const JsonSerializeExpr *from) +{ + JsonSerializeExpr *newnode = makeNode(JsonSerializeExpr); + + COPY_NODE_FIELD(expr); + COPY_NODE_FIELD(output); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonObjectConstructor * +_copyJsonObjectConstructor(const JsonObjectConstructor *from) +{ + JsonObjectConstructor *newnode = makeNode(JsonObjectConstructor); + + COPY_NODE_FIELD(exprs); + COPY_NODE_FIELD(output); + COPY_SCALAR_FIELD(absent_on_null); + COPY_SCALAR_FIELD(unique); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonArrayConstructor * +_copyJsonArrayConstructor(const JsonArrayConstructor *from) +{ + JsonArrayConstructor *newnode = makeNode(JsonArrayConstructor); + + COPY_NODE_FIELD(exprs); + COPY_NODE_FIELD(output); + COPY_SCALAR_FIELD(absent_on_null); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonArrayQueryConstructor * +_copyJsonArrayQueryConstructor(const JsonArrayQueryConstructor *from) +{ + JsonArrayQueryConstructor *newnode = makeNode(JsonArrayQueryConstructor); + + COPY_NODE_FIELD(query); + COPY_NODE_FIELD(output); + COPY_NODE_FIELD(format); + COPY_SCALAR_FIELD(absent_on_null); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonAggConstructor * +_copyJsonAggConstructor(const JsonAggConstructor *from) +{ + JsonAggConstructor *newnode = makeNode(JsonAggConstructor); + + COPY_NODE_FIELD(output); + COPY_NODE_FIELD(agg_filter); + COPY_NODE_FIELD(agg_order); + COPY_NODE_FIELD(over); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static JsonObjectAgg * +_copyJsonObjectAgg(const JsonObjectAgg *from) +{ + JsonObjectAgg *newnode = makeNode(JsonObjectAgg); + + COPY_NODE_FIELD(constructor); + COPY_NODE_FIELD(arg); + COPY_SCALAR_FIELD(absent_on_null); + COPY_SCALAR_FIELD(unique); + + return newnode; +} + +static JsonArrayAgg * +_copyJsonArrayAgg(const JsonArrayAgg *from) +{ + JsonArrayAgg *newnode = makeNode(JsonArrayAgg); + + COPY_NODE_FIELD(constructor); + COPY_NODE_FIELD(arg); + COPY_SCALAR_FIELD(absent_on_null); + + return newnode; +} + static Query * _copyQuery(const Query *from) { @@ -3013,14 +3676,23 @@ _copyQuery(const Query *from) COPY_SCALAR_FIELD(hasModifyingCTE); COPY_SCALAR_FIELD(hasForUpdate); COPY_SCALAR_FIELD(hasRowSecurity); + COPY_SCALAR_FIELD(hasGroupRTE); + COPY_SCALAR_FIELD(isReturn); COPY_NODE_FIELD(cteList); COPY_NODE_FIELD(rtable); + COPY_NODE_FIELD(rteperminfos); COPY_NODE_FIELD(jointree); + COPY_NODE_FIELD(mergeActionList); + COPY_SCALAR_FIELD(mergeTargetRelation); + COPY_NODE_FIELD(mergeJoinCondition); COPY_NODE_FIELD(targetList); COPY_SCALAR_FIELD(override); COPY_NODE_FIELD(onConflict); + COPY_STRING_FIELD(returningOldAlias); + COPY_STRING_FIELD(returningNewAlias); COPY_NODE_FIELD(returningList); COPY_NODE_FIELD(groupClause); + COPY_SCALAR_FIELD(groupDistinct); COPY_NODE_FIELD(groupingSets); COPY_NODE_FIELD(havingQual); COPY_NODE_FIELD(windowClause); @@ -3028,6 +3700,7 @@ _copyQuery(const Query *from) COPY_NODE_FIELD(sortClause); COPY_NODE_FIELD(limitOffset); COPY_NODE_FIELD(limitCount); + COPY_SCALAR_FIELD(limitOption); COPY_NODE_FIELD(rowMarks); COPY_NODE_FIELD(setOperations); COPY_NODE_FIELD(constraintDeps); @@ -3059,7 +3732,7 @@ _copyInsertStmt(const InsertStmt *from) COPY_NODE_FIELD(cols); COPY_NODE_FIELD(selectStmt); COPY_NODE_FIELD(onConflictClause); - COPY_NODE_FIELD(returningList); + COPY_NODE_FIELD(returningClause); COPY_NODE_FIELD(withClause); COPY_SCALAR_FIELD(override); @@ -3074,7 +3747,7 @@ _copyDeleteStmt(const DeleteStmt *from) COPY_NODE_FIELD(relation); COPY_NODE_FIELD(usingClause); COPY_NODE_FIELD(whereClause); - COPY_NODE_FIELD(returningList); + COPY_NODE_FIELD(returningClause); COPY_NODE_FIELD(withClause); return newnode; @@ -3089,7 +3762,22 @@ _copyUpdateStmt(const UpdateStmt *from) COPY_NODE_FIELD(targetList); COPY_NODE_FIELD(whereClause); COPY_NODE_FIELD(fromClause); - COPY_NODE_FIELD(returningList); + COPY_NODE_FIELD(returningClause); + COPY_NODE_FIELD(withClause); + + return newnode; +} + +static MergeStmt * +_copyMergeStmt(const MergeStmt *from) +{ + MergeStmt *newnode = makeNode(MergeStmt); + + COPY_NODE_FIELD(relation); + COPY_NODE_FIELD(sourceRelation); + COPY_NODE_FIELD(joinCondition); + COPY_NODE_FIELD(mergeWhenClauses); + COPY_NODE_FIELD(returningClause); COPY_NODE_FIELD(withClause); return newnode; @@ -3106,12 +3794,14 @@ _copySelectStmt(const SelectStmt *from) COPY_NODE_FIELD(fromClause); COPY_NODE_FIELD(whereClause); COPY_NODE_FIELD(groupClause); + COPY_SCALAR_FIELD(groupDistinct); COPY_NODE_FIELD(havingClause); COPY_NODE_FIELD(windowClause); COPY_NODE_FIELD(valuesLists); COPY_NODE_FIELD(sortClause); COPY_NODE_FIELD(limitOffset); COPY_NODE_FIELD(limitCount); + COPY_SCALAR_FIELD(limitOption); COPY_NODE_FIELD(lockingClause); COPY_NODE_FIELD(withClause); COPY_SCALAR_FIELD(op); @@ -3139,6 +3829,30 @@ _copySetOperationStmt(const SetOperationStmt *from) return newnode; } +static ReturnStmt * +_copyReturnStmt(const ReturnStmt *from) +{ + ReturnStmt *newnode = makeNode(ReturnStmt); + + COPY_NODE_FIELD(returnval); + + return newnode; +} + +static PLAssignStmt * +_copyPLAssignStmt(const PLAssignStmt *from) +{ + PLAssignStmt *newnode = makeNode(PLAssignStmt); + + COPY_STRING_FIELD(name); + COPY_NODE_FIELD(indirection); + COPY_SCALAR_FIELD(nnames); + COPY_NODE_FIELD(val); + COPY_LOCATION_FIELD(location); + + return newnode; +} + static AlterTableStmt * _copyAlterTableStmt(const AlterTableStmt *from) { @@ -3146,7 +3860,7 @@ _copyAlterTableStmt(const AlterTableStmt *from) COPY_NODE_FIELD(relation); COPY_NODE_FIELD(cmds); - COPY_SCALAR_FIELD(relkind); + COPY_SCALAR_FIELD(objtype); COPY_SCALAR_FIELD(missing_ok); return newnode; @@ -3164,6 +3878,35 @@ _copyAlterTableCmd(const AlterTableCmd *from) COPY_NODE_FIELD(def); COPY_SCALAR_FIELD(behavior); COPY_SCALAR_FIELD(missing_ok); + COPY_SCALAR_FIELD(recurse); + + return newnode; +} + +static ATAlterConstraint * +_copyATAlterConstraint(const ATAlterConstraint *from) +{ + ATAlterConstraint *newnode = makeNode(ATAlterConstraint); + + COPY_STRING_FIELD(conname); + COPY_SCALAR_FIELD(alterEnforceability); + COPY_SCALAR_FIELD(is_enforced); + COPY_SCALAR_FIELD(alterDeferrability); + COPY_SCALAR_FIELD(deferrable); + COPY_SCALAR_FIELD(initdeferred); + COPY_SCALAR_FIELD(alterInheritability); + COPY_SCALAR_FIELD(noinherit); + + return newnode; +} + +static ReplicaIdentityStmt * +_copyReplicaIdentityStmt(const ReplicaIdentityStmt *from) +{ + ReplicaIdentityStmt *newnode = makeNode(ReplicaIdentityStmt); + + COPY_SCALAR_FIELD(identity_type); + COPY_STRING_FIELD(name); return newnode; } @@ -3205,6 +3948,7 @@ _copyGrantStmt(const GrantStmt *from) COPY_NODE_FIELD(privileges); COPY_NODE_FIELD(grantees); COPY_SCALAR_FIELD(grant_option); + COPY_NODE_FIELD(grantor); COPY_SCALAR_FIELD(behavior); return newnode; @@ -3217,6 +3961,7 @@ _copyObjectWithArgs(const ObjectWithArgs *from) COPY_NODE_FIELD(objname); COPY_NODE_FIELD(objargs); + COPY_NODE_FIELD(objfuncargs); COPY_SCALAR_FIELD(args_unspecified); return newnode; @@ -3241,7 +3986,7 @@ _copyGrantRoleStmt(const GrantRoleStmt *from) COPY_NODE_FIELD(granted_roles); COPY_NODE_FIELD(grantee_roles); COPY_SCALAR_FIELD(is_grant); - COPY_SCALAR_FIELD(admin_opt); + COPY_SCALAR_FIELD(opt); COPY_NODE_FIELD(grantor); COPY_SCALAR_FIELD(behavior); @@ -3288,6 +4033,7 @@ _copyCallStmt(const CallStmt *from) COPY_NODE_FIELD(funccall); COPY_NODE_FIELD(funcexpr); + COPY_NODE_FIELD(outargs); return newnode; } @@ -3299,7 +4045,7 @@ _copyClusterStmt(const ClusterStmt *from) COPY_NODE_FIELD(relation); COPY_STRING_FIELD(indexname); - COPY_SCALAR_FIELD(verbose); + COPY_NODE_FIELD(params); return newnode; } @@ -3316,6 +4062,7 @@ _copyCopyStmt(const CopyStmt *from) COPY_SCALAR_FIELD(is_program); COPY_STRING_FIELD(filename); COPY_NODE_FIELD(options); + COPY_NODE_FIELD(whereClause); return newnode; } @@ -3336,9 +4083,11 @@ CopyCreateStmtFields(const CreateStmt *from, CreateStmt *newnode) COPY_NODE_FIELD(partbound); COPY_NODE_FIELD(ofTypename); COPY_NODE_FIELD(constraints); + COPY_NODE_FIELD(nnconstraints); COPY_NODE_FIELD(options); COPY_SCALAR_FIELD(oncommit); COPY_STRING_FIELD(tablespacename); + COPY_STRING_FIELD(accessMethod); COPY_SCALAR_FIELD(if_not_exists); } @@ -3359,6 +4108,7 @@ _copyTableLikeClause(const TableLikeClause *from) COPY_NODE_FIELD(relation); COPY_SCALAR_FIELD(options); + COPY_SCALAR_FIELD(relationOid); return newnode; } @@ -3374,6 +4124,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; } @@ -3449,7 +4200,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); @@ -3459,15 +4209,20 @@ _copyIndexStmt(const IndexStmt *from) COPY_NODE_FIELD(excludeOpNames); COPY_STRING_FIELD(idxcomment); COPY_SCALAR_FIELD(indexOid); - COPY_SCALAR_FIELD(oldNode); + COPY_SCALAR_FIELD(oldNumber); + COPY_SCALAR_FIELD(oldCreateSubid); + COPY_SCALAR_FIELD(oldFirstRelfilelocatorSubid); COPY_SCALAR_FIELD(unique); + COPY_SCALAR_FIELD(nulls_not_distinct); COPY_SCALAR_FIELD(primary); COPY_SCALAR_FIELD(isconstraint); + COPY_SCALAR_FIELD(iswithoutoverlaps); COPY_SCALAR_FIELD(deferrable); COPY_SCALAR_FIELD(initdeferred); COPY_SCALAR_FIELD(transformed); COPY_SCALAR_FIELD(concurrent); COPY_SCALAR_FIELD(if_not_exists); + COPY_SCALAR_FIELD(reset_default_tblspc); return newnode; } @@ -3482,11 +4237,24 @@ _copyCreateStatsStmt(const CreateStatsStmt *from) COPY_NODE_FIELD(exprs); COPY_NODE_FIELD(relations); COPY_STRING_FIELD(stxcomment); + COPY_SCALAR_FIELD(transformed); COPY_SCALAR_FIELD(if_not_exists); return newnode; } +static AlterStatsStmt * +_copyAlterStatsStmt(const AlterStatsStmt *from) +{ + AlterStatsStmt *newnode = makeNode(AlterStatsStmt); + + COPY_NODE_FIELD(defnames); + COPY_NODE_FIELD(stxstattarget); + COPY_SCALAR_FIELD(missing_ok); + + return newnode; +} + static CreateFunctionStmt * _copyCreateFunctionStmt(const CreateFunctionStmt *from) { @@ -3498,6 +4266,7 @@ _copyCreateFunctionStmt(const CreateFunctionStmt *from) COPY_NODE_FIELD(parameters); COPY_NODE_FIELD(returnType); COPY_NODE_FIELD(options); + COPY_NODE_FIELD(sql_body); return newnode; } @@ -3511,6 +4280,7 @@ _copyFunctionParameter(const FunctionParameter *from) COPY_NODE_FIELD(argType); COPY_SCALAR_FIELD(mode); COPY_NODE_FIELD(defexpr); + COPY_LOCATION_FIELD(location); return newnode; } @@ -3563,6 +4333,7 @@ _copyAlterObjectDependsStmt(const AlterObjectDependsStmt *from) COPY_NODE_FIELD(relation); COPY_NODE_FIELD(object); COPY_NODE_FIELD(extname); + COPY_SCALAR_FIELD(remove); return newnode; } @@ -3605,6 +4376,17 @@ _copyAlterOperatorStmt(const AlterOperatorStmt *from) return newnode; } +static AlterTypeStmt * +_copyAlterTypeStmt(const AlterTypeStmt *from) +{ + AlterTypeStmt *newnode = makeNode(AlterTypeStmt); + + COPY_NODE_FIELD(typeName); + COPY_NODE_FIELD(options); + + return newnode; +} + static RuleStmt * _copyRuleStmt(const RuleStmt *from) { @@ -3661,6 +4443,8 @@ _copyTransactionStmt(const TransactionStmt *from) COPY_NODE_FIELD(options); COPY_STRING_FIELD(savepoint_name); COPY_STRING_FIELD(gid); + COPY_SCALAR_FIELD(chain); + COPY_LOCATION_FIELD(location); return newnode; } @@ -3827,6 +4611,16 @@ _copyAlterDatabaseStmt(const AlterDatabaseStmt *from) return newnode; } +static AlterDatabaseRefreshCollStmt * +_copyAlterDatabaseRefreshCollStmt(const AlterDatabaseRefreshCollStmt *from) +{ + AlterDatabaseRefreshCollStmt *newnode = makeNode(AlterDatabaseRefreshCollStmt); + + COPY_STRING_FIELD(dbname); + + return newnode; +} + static AlterDatabaseSetStmt * _copyAlterDatabaseSetStmt(const AlterDatabaseSetStmt *from) { @@ -3845,6 +4639,7 @@ _copyDropdbStmt(const DropdbStmt *from) COPY_STRING_FIELD(dbname); COPY_SCALAR_FIELD(missing_ok); + COPY_NODE_FIELD(options); return newnode; } @@ -3854,8 +4649,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; } @@ -3890,7 +4686,7 @@ _copyCreateTableAsStmt(const CreateTableAsStmt *from) COPY_NODE_FIELD(query); COPY_NODE_FIELD(into); - COPY_SCALAR_FIELD(relkind); + COPY_SCALAR_FIELD(objtype); COPY_SCALAR_FIELD(is_select_into); COPY_SCALAR_FIELD(if_not_exists); @@ -3909,17 +4705,6 @@ _copyRefreshMatViewStmt(const RefreshMatViewStmt *from) return newnode; } -static ReplicaIdentityStmt * -_copyReplicaIdentityStmt(const ReplicaIdentityStmt *from) -{ - ReplicaIdentityStmt *newnode = makeNode(ReplicaIdentityStmt); - - COPY_SCALAR_FIELD(identity_type); - COPY_STRING_FIELD(name); - - return newnode; -} - static AlterSystemStmt * _copyAlterSystemStmt(const AlterSystemStmt *from) { @@ -3965,7 +4750,9 @@ _copyVariableSetStmt(const VariableSetStmt *from) COPY_SCALAR_FIELD(kind); COPY_STRING_FIELD(name); COPY_NODE_FIELD(args); + COPY_SCALAR_FIELD(jumble_args); COPY_SCALAR_FIELD(is_local); + COPY_LOCATION_FIELD(location); return newnode; } @@ -4224,6 +5011,8 @@ _copyCreateTrigStmt(const CreateTrigStmt *from) { CreateTrigStmt *newnode = makeNode(CreateTrigStmt); + COPY_SCALAR_FIELD(replace); + COPY_SCALAR_FIELD(isconstraint); COPY_STRING_FIELD(trigname); COPY_NODE_FIELD(relation); COPY_NODE_FIELD(funcname); @@ -4233,7 +5022,6 @@ _copyCreateTrigStmt(const CreateTrigStmt *from) COPY_SCALAR_FIELD(events); COPY_NODE_FIELD(columns); COPY_NODE_FIELD(whenClause); - COPY_SCALAR_FIELD(isconstraint); COPY_NODE_FIELD(transitionRels); COPY_SCALAR_FIELD(deferrable); COPY_SCALAR_FIELD(initdeferred); @@ -4359,7 +5147,7 @@ _copyReindexStmt(const ReindexStmt *from) COPY_SCALAR_FIELD(kind); COPY_NODE_FIELD(relation); COPY_STRING_FIELD(name); - COPY_SCALAR_FIELD(options); + COPY_NODE_FIELD(params); return newnode; } @@ -4434,6 +5222,8 @@ _copyDeallocateStmt(const DeallocateStmt *from) DeallocateStmt *newnode = makeNode(DeallocateStmt); COPY_STRING_FIELD(name); + COPY_SCALAR_FIELD(isall); + COPY_LOCATION_FIELD(location); return newnode; } @@ -4536,7 +5326,7 @@ _copyPartitionSpec(const PartitionSpec *from) { PartitionSpec *newnode = makeNode(PartitionSpec); - COPY_STRING_FIELD(strategy); + COPY_SCALAR_FIELD(strategy); COPY_NODE_FIELD(partParams); COPY_LOCATION_FIELD(location); @@ -4579,6 +5369,32 @@ _copyPartitionCmd(const PartitionCmd *from) COPY_NODE_FIELD(name); COPY_NODE_FIELD(bound); + COPY_SCALAR_FIELD(concurrent); + + return newnode; +} + +static PublicationObjSpec * +_copyPublicationObject(const PublicationObjSpec *from) +{ + PublicationObjSpec *newnode = makeNode(PublicationObjSpec); + + COPY_SCALAR_FIELD(pubobjtype); + COPY_STRING_FIELD(name); + COPY_NODE_FIELD(pubtable); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static PublicationTable * +_copyPublicationTable(const PublicationTable *from) +{ + PublicationTable *newnode = makeNode(PublicationTable); + + COPY_NODE_FIELD(relation); + COPY_NODE_FIELD(whereClause); + COPY_NODE_FIELD(columns); return newnode; } @@ -4590,7 +5406,7 @@ _copyCreatePublicationStmt(const CreatePublicationStmt *from) COPY_STRING_FIELD(pubname); COPY_NODE_FIELD(options); - COPY_NODE_FIELD(tables); + COPY_NODE_FIELD(pubobjects); COPY_SCALAR_FIELD(for_all_tables); return newnode; @@ -4603,9 +5419,9 @@ _copyAlterPublicationStmt(const AlterPublicationStmt *from) COPY_STRING_FIELD(pubname); COPY_NODE_FIELD(options); - COPY_NODE_FIELD(tables); + COPY_NODE_FIELD(pubobjects); COPY_SCALAR_FIELD(for_all_tables); - COPY_SCALAR_FIELD(tableAction); + COPY_SCALAR_FIELD(action); return newnode; } @@ -4649,58 +5465,16 @@ _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; -} - #ifdef NOT_USED_IN_PGPOOL /* **************************************************************** * extensible.h copy functions * **************************************************************** */ static ExtensibleNode * -_copyExtensibleNode(const ExtensibleNode *from) +_copyExtensibleNode(const ExtensibleNode * from) { ExtensibleNode *newnode; - const ExtensibleNodeMethods *methods; + const ExtensibleNodeMethods *methods; methods = GetExtensibleNodeMethods(from->extnodename, false); newnode = (ExtensibleNode *) newNode(methods->node_size, @@ -4718,49 +5492,71 @@ _copyExtensibleNode(const ExtensibleNode *from) * value.h copy functions * **************************************************************** */ -static Value * -_copyValue(const Value *from) +static Integer * +_copyInteger(const Integer *from) { - Value *newnode = makeNode(Value); + Integer *newnode = makeNode(Integer); - /* See also _copyAConst when changing this code! */ + COPY_SCALAR_FIELD(ival); + + return newnode; +} + +static Float * +_copyFloat(const Float *from) +{ + Float *newnode = makeNode(Float); + + COPY_STRING_FIELD(fval); + + return newnode; +} + +static Boolean * +_copyBoolean(const Boolean *from) +{ + Boolean *newnode = makeNode(Boolean); + + COPY_SCALAR_FIELD(boolval); + + return newnode; +} + +static String * +_copyString(const String *from) +{ + String *newnode = makeNode(String); + + COPY_STRING_FIELD(sval); + + return newnode; +} + +static BitString * +_copyBitString(const BitString *from) +{ + BitString *newnode = makeNode(BitString); + + COPY_STRING_FIELD(bsval); - COPY_SCALAR_FIELD(type); - switch (from->type) - { - case T_Integer: - COPY_SCALAR_FIELD(val.ival); - break; - case T_Float: - case T_String: - case T_BitString: - COPY_STRING_FIELD(val.str); - break; - case T_Null: - /* nothing to do */ - break; - default: - elog(ERROR, "unrecognized node type: %d", - (int) from->type); - break; - } return newnode; } #ifdef NOT_USED_IN_PGPOOL static ForeignKeyCacheInfo * -_copyForeignKeyCacheInfo(const ForeignKeyCacheInfo *from) +_copyForeignKeyCacheInfo(const ForeignKeyCacheInfo * from) { ForeignKeyCacheInfo *newnode = makeNode(ForeignKeyCacheInfo); + COPY_SCALAR_FIELD(conoid); COPY_SCALAR_FIELD(conrelid); COPY_SCALAR_FIELD(confrelid); COPY_SCALAR_FIELD(nkeys); - /* COPY_SCALAR_FIELD might work for these, but let's not assume that */ - memcpy(newnode->conkey, from->conkey, sizeof(newnode->conkey)); - memcpy(newnode->confkey, from->confkey, sizeof(newnode->confkey)); - memcpy(newnode->conpfeqop, from->conpfeqop, sizeof(newnode->conpfeqop)); + COPY_SCALAR_FIELD(conenforced); + COPY_ARRAY_FIELD(conkey); + COPY_ARRAY_FIELD(confkey); + COPY_ARRAY_FIELD(conpfeqop); return newnode; } @@ -4851,6 +5647,9 @@ copyObjectImpl(const void *from) case T_TidScan: retval = _copyTidScan(from); break; + case T_TidRangeScan: + retval = _copyTidRangeScan(from); + break; case T_SubqueryScan: retval = _copySubqueryScan(from); break; @@ -4893,9 +5692,15 @@ copyObjectImpl(const void *from) case T_Material: retval = _copyMaterial(from); break; + case T_Memoize: + retval = _copyMemoize(from); + break; case T_Sort: retval = _copySort(from); break; + case T_IncrementalSort: + retval = _copyIncrementalSort(from); + break; case T_Group: retval = _copyGroup(from); break; @@ -4978,8 +5783,14 @@ copyObjectImpl(const void *from) case T_WindowFunc: retval = _copyWindowFunc(from); break; - case T_ArrayRef: - retval = _copyArrayRef(from); + case T_WindowFuncRunCondition: + retval = _copyWindowFuncRunCondition(from); + break; + case T_MergeSupportFunc: + retval = _copyMergeSupportFunc(from); + break; + case T_SubscriptingRef: + retval = _copySubscriptingRef(from); break; case T_FuncExpr: retval = _copyFuncExpr(from); @@ -5062,12 +5873,45 @@ copyObjectImpl(const void *from) case T_XmlExpr: retval = _copyXmlExpr(from); break; + case T_JsonFormat: + retval = _copyJsonFormat(from); + break; + case T_JsonReturning: + retval = _copyJsonReturning(from); + break; + case T_JsonValueExpr: + retval = _copyJsonValueExpr(from); + break; + case T_JsonConstructorExpr: + retval = _copyJsonConstructorExpr(from); + break; + case T_JsonIsPredicate: + retval = _copyJsonIsPredicate(from); + break; + case T_JsonBehavior: + retval = _copyJsonBehavior(from); + break; + case T_JsonExpr: + retval = _copyJsonExpr(from); + break; + case T_JsonTablePath: + retval = _copyJsonTablePath(from); + break; + case T_JsonTablePathScan: + retval = _copyJsonTablePathScan(from); + break; + case T_JsonTableSiblingJoin: + retval = _copyJsonTableSiblingJoin(from); + break; case T_NullTest: retval = _copyNullTest(from); break; case T_BooleanTest: retval = _copyBooleanTest(from); break; + case T_MergeAction: + retval = _copyMergeAction(from); + break; case T_CoerceToDomain: retval = _copyCoerceToDomain(from); break; @@ -5086,6 +5930,9 @@ copyObjectImpl(const void *from) case T_InferenceElem: retval = _copyInferenceElem(from); break; + case T_ReturningExpr: + retval = _copyReturningExpr(from); + break; case T_TargetEntry: retval = _copyTargetEntry(from); break; @@ -5110,6 +5957,9 @@ copyObjectImpl(const void *from) case T_PathKey: retval = _copyPathKey(from); break; + case T_GroupByOrdering: + retval = _copyGroupByOrdering(from); + break; case T_RestrictInfo: retval = _copyRestrictInfo(from); break; @@ -5132,18 +5982,26 @@ copyObjectImpl(const void *from) * VALUE NODES */ case T_Integer: + retval = _copyInteger(from); + break; case T_Float: + retval = _copyFloat(from); + break; + case T_Boolean: + retval = _copyBoolean(from); + break; case T_String: + retval = _copyString(from); + break; case T_BitString: - case T_Null: - retval = _copyValue(from); + retval = _copyBitString(from); break; /* * LIST NODES */ case T_List: - retval = _copyList(from); + retval = list_copy_deep(from); break; /* @@ -5152,6 +6010,7 @@ copyObjectImpl(const void *from) */ case T_IntList: case T_OidList: + case T_XidList: retval = list_copy(from); break; @@ -5183,18 +6042,33 @@ copyObjectImpl(const void *from) case T_UpdateStmt: retval = _copyUpdateStmt(from); break; + case T_MergeStmt: + retval = _copyMergeStmt(from); + break; case T_SelectStmt: retval = _copySelectStmt(from); break; case T_SetOperationStmt: retval = _copySetOperationStmt(from); break; + case T_ReturnStmt: + retval = _copyReturnStmt(from); + break; + case T_PLAssignStmt: + retval = _copyPLAssignStmt(from); + break; case T_AlterTableStmt: retval = _copyAlterTableStmt(from); break; case T_AlterTableCmd: retval = _copyAlterTableCmd(from); break; + case T_ATAlterConstraint: + retval = _copyATAlterConstraint(from); + break; + case T_ReplicaIdentityStmt: + retval = _copyReplicaIdentityStmt(from); + break; case T_AlterCollationStmt: retval = _copyAlterCollationStmt(from); break; @@ -5255,6 +6129,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; @@ -5282,6 +6159,9 @@ copyObjectImpl(const void *from) case T_AlterOperatorStmt: retval = _copyAlterOperatorStmt(from); break; + case T_AlterTypeStmt: + retval = _copyAlterTypeStmt(from); + break; case T_RuleStmt: retval = _copyRuleStmt(from); break; @@ -5336,6 +6216,9 @@ copyObjectImpl(const void *from) case T_AlterDatabaseStmt: retval = _copyAlterDatabaseStmt(from); break; + case T_AlterDatabaseRefreshCollStmt: + retval = _copyAlterDatabaseRefreshCollStmt(from); + break; case T_AlterDatabaseSetStmt: retval = _copyAlterDatabaseSetStmt(from); break; @@ -5357,9 +6240,6 @@ copyObjectImpl(const void *from) case T_RefreshMatViewStmt: retval = _copyRefreshMatViewStmt(from); break; - case T_ReplicaIdentityStmt: - retval = _copyReplicaIdentityStmt(from); - break; case T_AlterSystemStmt: retval = _copyAlterSystemStmt(from); break; @@ -5520,7 +6400,7 @@ copyObjectImpl(const void *from) retval = _copyDropSubscriptionStmt(from); break; case T_A_Expr: - retval = _copyAExpr(from); + retval = _copyA_Expr(from); break; case T_ColumnRef: retval = _copyColumnRef(from); @@ -5529,16 +6409,16 @@ copyObjectImpl(const void *from) retval = _copyParamRef(from); break; case T_A_Const: - retval = _copyAConst(from); + retval = _copyA_Const(from); break; case T_FuncCall: retval = _copyFuncCall(from); break; case T_A_Star: - retval = _copyAStar(from); + retval = _copyA_Star(from); break; case T_A_Indices: - retval = _copyAIndices(from); + retval = _copyA_Indices(from); break; case T_A_Indirection: retval = _copyA_Indirection(from); @@ -5585,6 +6465,9 @@ copyObjectImpl(const void *from) case T_IndexElem: retval = _copyIndexElem(from); break; + case T_StatsElem: + retval = _copyStatsElem(from); + break; case T_ColumnDef: retval = _copyColumnDef(from); break; @@ -5630,9 +6513,24 @@ copyObjectImpl(const void *from) case T_OnConflictClause: retval = _copyOnConflictClause(from); break; + case T_CTESearchClause: + retval = _copyCTESearchClause(from); + break; + case T_CTECycleClause: + retval = _copyCTECycleClause(from); + break; case T_CommonTableExpr: retval = _copyCommonTableExpr(from); break; + case T_MergeWhenClause: + retval = _copyMergeWhenClause(from); + break; + case T_ReturningOption: + retval = _copyReturningOption(from); + break; + case T_ReturningClause: + retval = _copyReturningClause(from); + break; case T_ObjectWithArgs: retval = _copyObjectWithArgs(from); break; @@ -5648,6 +6546,54 @@ copyObjectImpl(const void *from) case T_TriggerTransition: retval = _copyTriggerTransition(from); break; + case T_JsonOutput: + retval = _copyJsonOutput(from); + break; + case T_JsonArgument: + retval = _copyJsonArgument(from); + break; + case T_JsonFuncExpr: + retval = _copyJsonFuncExpr(from); + break; + case T_JsonTablePathSpec: + retval = _copyJsonTablePathSpec(from); + break; + case T_JsonTable: + retval = _copyJsonTable(from); + break; + case T_JsonTableColumn: + retval = _copyJsonTableColumn(from); + break; + case T_JsonKeyValue: + retval = _copyJsonKeyValue(from); + break; + case T_JsonParseExpr: + retval = _copyJsonParseExpr(from); + break; + case T_JsonScalarExpr: + retval = _copyJsonScalarExpr(from); + break; + case T_JsonSerializeExpr: + retval = _copyJsonSerializeExpr(from); + break; + case T_JsonObjectConstructor: + retval = _copyJsonObjectConstructor(from); + break; + case T_JsonArrayConstructor: + retval = _copyJsonArrayConstructor(from); + break; + case T_JsonArrayQueryConstructor: + retval = _copyJsonArrayQueryConstructor(from); + break; + case T_JsonAggConstructor: + retval = _copyJsonAggConstructor(from); + break; + case T_JsonObjectAgg: + retval = _copyJsonObjectAgg(from); + break; + case T_JsonArrayAgg: + retval = _copyJsonArrayAgg(from); + break; case T_PartitionElem: retval = _copyPartitionElem(from); break; @@ -5663,6 +6609,12 @@ copyObjectImpl(const void *from) case T_PartitionCmd: retval = _copyPartitionCmd(from); break; + case T_PublicationObjSpec: + retval = _copyPublicationObject(from); + break; + case T_PublicationTable: + retval = _copyPublicationTable(from); + break; #ifdef NOT_USED_IN_PGPOOL diff --git a/src/parser/gram.c b/src/parser/gram.c deleted file mode 100644 index 4fe27ae20..000000000 --- a/src/parser/gram.c +++ /dev/null @@ -1,46943 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - 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. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "3.0.4" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - -/* Substitute the variable and function names. */ -#define yyparse base_yyparse -#define yylex base_yylex -#define yyerror base_yyerror -#define yydebug base_yydebug -#define yynerrs base_yynerrs - - -/* Copy the first part of user declarations. */ -#line 1 "gram.y" /* yacc.c:339 */ - - -/*#define YYDEBUG 1*/ -/*------------------------------------------------------------------------- - * - * gram.y - * POSTGRESQL BISON rules/actions - * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/parser/gram.y - * - * HISTORY - * AUTHOR DATE MAJOR EVENT - * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion - * Andrew Yu Oct, 1994 lispy code conversion - * - * NOTES - * CAPITALS are used to represent terminal symbols. - * non-capitals are used to represent non-terminals. - * - * In general, nothing in this file should initiate database accesses - * nor depend on changeable state (such as SET variables). If you do - * database accesses, your code will fail when we have aborted the - * current transaction and are just parsing commands to find the next - * ROLLBACK or COMMIT. If you make use of SET variables, then you - * will do the wrong thing in multi-query strings like this: - * SET constraint_exclusion TO off; SELECT * FROM foo; - * because the entire string is parsed by gram.y before the SET gets - * executed. Anything that depends on the database or changeable state - * should be handled during parse analysis so that it happens at the - * right time not the wrong time. - * - * WARNINGS - * If you use a list, make sure the datum is a node so that the printing - * routines work. - * - * Sometimes we assign constants to makeStrings. Make sure we don't free - * those. - * - *------------------------------------------------------------------------- - */ - -#include "pool_parser.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include -#include -#include -#include -#include - -#include "nodes.h" -#include "keywords.h" -#include "gramparse.h" -#include "makefuncs.h" -#include "pool_string.h" -#include "parser.h" -#include "pg_class.h" -#include "pg_trigger.h" - -/* This is a configuration parameter since PostgreSQL 9.5. - * We set this false in pgpool-II. This is default in PostgreSQL. - */ -bool operator_precedence_warning = false; - -/* - * Definition taken from - * postgreSQL source code file: src/include/commands/trigger.h - */ -#define TRIGGER_FIRES_ON_ORIGIN 'O' -#define TRIGGER_FIRES_ALWAYS 'A' -#define TRIGGER_FIRES_ON_REPLICA 'R' -#define TRIGGER_DISABLED 'D' - -/* - * Definition taken from - * postgreSQL source code file: src/include/catalog/pg_class.h - */ - -#define REPLICA_IDENTITY_DEFAULT 'd' -#define REPLICA_IDENTITY_NOTHING 'n' -#define REPLICA_IDENTITY_FULL 'f' -#define REPLICA_IDENTITY_INDEX 'i' - -/* - * Definition taken from - * postgreSQL source code file: src/include/catalog/pg_attribute.h - */ -#define ATTRIBUTE_IDENTITY_ALWAYS 'a' -#define ATTRIBUTE_IDENTITY_BY_DEFAULT 'd' - -/* - * Definition taken from - * postgreSQL source code file: src/include/utils/xml.h - */ -typedef enum -{ - XML_STANDALONE_YES, - XML_STANDALONE_NO, - XML_STANDALONE_NO_VALUE, - XML_STANDALONE_OMITTED -} XmlStandaloneType; - -/* - * Location tracking support --- simpler than bison's default, since we only - * want to track the start position not the end position of each nonterminal. - */ -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if ((N) > 0) \ - (Current) = (Rhs)[1]; \ - else \ - (Current) = (-1); \ - } while (0) - -/* - * The above macro assigns -1 (unknown) as the parse location of any - * nonterminal that was reduced from an empty rule, or whose leftmost - * component was reduced from an empty rule. This is problematic - * for nonterminals defined like - * OptFooList: / * EMPTY * / { ... } | OptFooList Foo { ... } ; - * because we'll set -1 as the location during the first reduction and then - * copy it during each subsequent reduction, leaving us with -1 for the - * location even when the list is not empty. To fix that, do this in the - * action for the nonempty rule(s): - * if (@$ < 0) @$ = @2; - * (Although we have many nonterminals that follow this pattern, we only - * bother with fixing @$ like this when the nonterminal's parse location - * is actually referenced in some rule.) - * - * A cleaner answer would be to make YYLLOC_DEFAULT scan all the Rhs - * locations until it's found one that's not -1. Then we'd get a correct - * location for any nonterminal that isn't entirely empty. But this way - * would add overhead to every rule reduction, and so far there's not been - * a compelling reason to pay that overhead. - */ - -/* - * 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 - -/* Private struct for the result of privilege_target production */ -typedef struct PrivTarget -{ - GrantTargetType targtype; - ObjectType objtype; - List *objs; -} PrivTarget; - -/* Private struct for the result of import_qualification production */ -typedef struct ImportQual -{ - ImportForeignSchemaType type; - List *table_names; -} ImportQual; - -/* ConstraintAttributeSpec yields an integer bitmask of these flags: */ -#define CAS_NOT_DEFERRABLE 0x01 -#define CAS_DEFERRABLE 0x02 -#define CAS_INITIALLY_IMMEDIATE 0x04 -#define CAS_INITIALLY_DEFERRED 0x08 -#define CAS_NOT_VALID 0x10 -#define CAS_NO_INHERIT 0x20 - - -#define parser_yyerror(msg) scanner_yyerror(msg, yyscanner) -#define parser_errposition(pos) scanner_errposition(pos, yyscanner) - -static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, - const char *msg); -static RawStmt *makeRawStmt(Node *stmt, int stmt_location); -static void updateRawStmtEnd(RawStmt *rs, int end_location); -static Node *makeColumnRef(char *colname, List *indirection, - int location, core_yyscan_t yyscanner); -static Node *makeStringConst(char *str, int location); -static Node *makeFloatConst(char *str, int location); -static Node *makeBitStringConst(char *str, int location); -static Node *makeNullAConst(int location); -static Node *makeAConst(Value *v, int location); -static Node *makeBoolAConst(bool state, int location); -static RoleSpec *makeRoleSpec(RoleSpecType type, int location); -static void check_qualified_name(List *names, core_yyscan_t yyscanner); -static List *check_func_name(List *names, core_yyscan_t yyscanner); -static List *check_indirection(List *indirection, core_yyscan_t yyscanner); -static List *extractArgTypes(List *parameters); -static List *extractAggrArgTypes(List *aggrargs); -static List *makeOrderedSetArgs(List *directargs, List *orderedargs, - core_yyscan_t yyscanner); -static void insertSelectOptions(SelectStmt *stmt, - List *sortClause, List *lockingClause, - Node *limitOffset, Node *limitCount, - WithClause *withClause, - core_yyscan_t yyscanner); -static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg); -static Node *doNegate(Node *n, int location); -static void doNegateFloat(Value *v); -static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location); -static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location); -static Node *makeNotExpr(Node *expr, int location); -static Node *makeAArrayExpr(List *elements, int location); -static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, - int location); -static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, - List *args, int location); -static List *mergeTableFuncParameters(List *func_args, List *columns); -static TypeName *TableFuncTypeName(List *columns); -static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner); -static void SplitColQualList(List *qualList, - List **constraintList, CollateClause **collClause, - core_yyscan_t yyscanner); -static void processCASbits(int cas_bits, int location, const char *constrType, - bool *deferrable, bool *initdeferred, bool *not_valid, - bool *no_inherit, core_yyscan_t yyscanner); -static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); - - -#line 301 "gram.c" /* yacc.c:339 */ - -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "y.tab.h". */ -#ifndef YY_BASE_YY_Y_TAB_H_INCLUDED -# define YY_BASE_YY_Y_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int base_yydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - IDENT = 258, - FCONST = 259, - SCONST = 260, - BCONST = 261, - XCONST = 262, - Op = 263, - ICONST = 264, - PARAM = 265, - TYPECAST = 266, - DOT_DOT = 267, - COLON_EQUALS = 268, - EQUALS_GREATER = 269, - LESS_EQUALS = 270, - GREATER_EQUALS = 271, - NOT_EQUALS = 272, - ABORT_P = 273, - ABSOLUTE_P = 274, - ACCESS = 275, - ACTION = 276, - ADD_P = 277, - ADMIN = 278, - AFTER = 279, - AGGREGATE = 280, - ALL = 281, - ALSO = 282, - ALTER = 283, - ALWAYS = 284, - ANALYSE = 285, - ANALYZE = 286, - AND = 287, - ANY = 288, - ARRAY = 289, - AS = 290, - ASC = 291, - ASSERTION = 292, - ASSIGNMENT = 293, - ASYMMETRIC = 294, - AT = 295, - ATTACH = 296, - ATTRIBUTE = 297, - AUTHORIZATION = 298, - BACKWARD = 299, - BEFORE = 300, - BEGIN_P = 301, - BETWEEN = 302, - BIGINT = 303, - BINARY = 304, - BIT = 305, - BOOLEAN_P = 306, - BOTH = 307, - BY = 308, - CACHE = 309, - CALL = 310, - CALLED = 311, - CASCADE = 312, - CASCADED = 313, - CASE = 314, - CAST = 315, - CATALOG_P = 316, - CHAIN = 317, - CHAR_P = 318, - CHARACTER = 319, - CHARACTERISTICS = 320, - CHECK = 321, - CHECKPOINT = 322, - CLASS = 323, - CLOSE = 324, - CLUSTER = 325, - COALESCE = 326, - COLLATE = 327, - COLLATION = 328, - COLUMN = 329, - COLUMNS = 330, - COMMENT = 331, - COMMENTS = 332, - COMMIT = 333, - COMMITTED = 334, - CONCURRENTLY = 335, - CONFIGURATION = 336, - CONFLICT = 337, - CONNECTION = 338, - CONSTRAINT = 339, - CONSTRAINTS = 340, - CONTENT_P = 341, - CONTINUE_P = 342, - CONVERSION_P = 343, - COPY = 344, - COST = 345, - CREATE = 346, - CROSS = 347, - CSV = 348, - CUBE = 349, - CURRENT_P = 350, - CURRENT_CATALOG = 351, - CURRENT_DATE = 352, - CURRENT_ROLE = 353, - CURRENT_SCHEMA = 354, - CURRENT_TIME = 355, - CURRENT_TIMESTAMP = 356, - CURRENT_USER = 357, - CURSOR = 358, - CYCLE = 359, - DATA_P = 360, - DATABASE = 361, - DAY_P = 362, - DEALLOCATE = 363, - DEC = 364, - DECIMAL_P = 365, - DECLARE = 366, - DEFAULT = 367, - DEFAULTS = 368, - DEFERRABLE = 369, - DEFERRED = 370, - DEFINER = 371, - DELETE_P = 372, - DELIMITER = 373, - DELIMITERS = 374, - DEPENDS = 375, - DESC = 376, - DETACH = 377, - DICTIONARY = 378, - DISABLE_P = 379, - DISCARD = 380, - DISTINCT = 381, - DO = 382, - DOCUMENT_P = 383, - DOMAIN_P = 384, - DOUBLE_P = 385, - DROP = 386, - EACH = 387, - ELSE = 388, - ENABLE_P = 389, - ENCODING = 390, - ENCRYPTED = 391, - END_P = 392, - ENUM_P = 393, - ESCAPE = 394, - EVENT = 395, - EXCEPT = 396, - EXCLUDE = 397, - EXCLUDING = 398, - EXCLUSIVE = 399, - EXECUTE = 400, - EXISTS = 401, - EXPLAIN = 402, - EXTENSION = 403, - EXTERNAL = 404, - EXTRACT = 405, - FALSE_P = 406, - FAMILY = 407, - FETCH = 408, - FILTER = 409, - FIRST_P = 410, - FLOAT_P = 411, - FOLLOWING = 412, - FOR = 413, - FORCE = 414, - FOREIGN = 415, - FORWARD = 416, - FREEZE = 417, - FROM = 418, - FULL = 419, - FUNCTION = 420, - FUNCTIONS = 421, - GENERATED = 422, - GLOBAL = 423, - GRANT = 424, - GRANTED = 425, - GREATEST = 426, - GROUP_P = 427, - GROUPING = 428, - GROUPS = 429, - HANDLER = 430, - HAVING = 431, - HEADER_P = 432, - HOLD = 433, - HOUR_P = 434, - IDENTITY_P = 435, - IF_P = 436, - ILIKE = 437, - IMMEDIATE = 438, - IMMUTABLE = 439, - IMPLICIT_P = 440, - IMPORT_P = 441, - IN_P = 442, - INCLUDE = 443, - INCLUDING = 444, - INCREMENT = 445, - INDEX = 446, - INDEXES = 447, - INHERIT = 448, - INHERITS = 449, - INITIALLY = 450, - INLINE_P = 451, - INNER_P = 452, - INOUT = 453, - INPUT_P = 454, - INSENSITIVE = 455, - INSERT = 456, - INSTEAD = 457, - INT_P = 458, - INTEGER = 459, - INTERSECT = 460, - INTERVAL = 461, - INTO = 462, - INVOKER = 463, - IS = 464, - ISNULL = 465, - ISOLATION = 466, - JOIN = 467, - KEY = 468, - LABEL = 469, - LANGUAGE = 470, - LARGE_P = 471, - LAST_P = 472, - LATERAL_P = 473, - LEADING = 474, - LEAKPROOF = 475, - LEAST = 476, - LEFT = 477, - LEVEL = 478, - LIKE = 479, - LIMIT = 480, - LISTEN = 481, - LOAD = 482, - LOCAL = 483, - LOCALTIME = 484, - LOCALTIMESTAMP = 485, - LOCATION = 486, - LOCK_P = 487, - LOCKED = 488, - LOGGED = 489, - MAPPING = 490, - MATCH = 491, - MATERIALIZED = 492, - MAXVALUE = 493, - METHOD = 494, - MINUTE_P = 495, - MINVALUE = 496, - MODE = 497, - MONTH_P = 498, - MOVE = 499, - NAME_P = 500, - NAMES = 501, - NATIONAL = 502, - NATURAL = 503, - NCHAR = 504, - NEW = 505, - NEXT = 506, - NO = 507, - NONE = 508, - NOT = 509, - NOTHING = 510, - NOTIFY = 511, - NOTNULL = 512, - NOWAIT = 513, - NULL_P = 514, - NULLIF = 515, - NULLS_P = 516, - NUMERIC = 517, - OBJECT_P = 518, - OF = 519, - OFF = 520, - OFFSET = 521, - OIDS = 522, - OLD = 523, - ON = 524, - ONLY = 525, - OPERATOR = 526, - OPTION = 527, - OPTIONS = 528, - OR = 529, - ORDER = 530, - ORDINALITY = 531, - OTHERS = 532, - OUT_P = 533, - OUTER_P = 534, - OVER = 535, - OVERLAPS = 536, - OVERLAY = 537, - OVERRIDING = 538, - OWNED = 539, - OWNER = 540, - PARALLEL = 541, - PARSER = 542, - PARTIAL = 543, - PARTITION = 544, - PASSING = 545, - PASSWORD = 546, - PGPOOL = 547, - PLACING = 548, - PLANS = 549, - POLICY = 550, - POSITION = 551, - PRECEDING = 552, - PRECISION = 553, - PRESERVE = 554, - PREPARE = 555, - PREPARED = 556, - PRIMARY = 557, - PRIOR = 558, - PRIVILEGES = 559, - PROCEDURAL = 560, - PROCEDURE = 561, - PROCEDURES = 562, - PROGRAM = 563, - PUBLICATION = 564, - QUOTE = 565, - RANGE = 566, - READ = 567, - REAL = 568, - REASSIGN = 569, - RECHECK = 570, - RECURSIVE = 571, - REF = 572, - REFERENCES = 573, - REFERENCING = 574, - REFRESH = 575, - REINDEX = 576, - RELATIVE_P = 577, - RELEASE = 578, - RENAME = 579, - REPEATABLE = 580, - REPLACE = 581, - REPLICA = 582, - RESET = 583, - RESTART = 584, - RESTRICT = 585, - RETURNING = 586, - RETURNS = 587, - REVOKE = 588, - RIGHT = 589, - ROLE = 590, - ROLLBACK = 591, - ROLLUP = 592, - ROUTINE = 593, - ROUTINES = 594, - ROW = 595, - ROWS = 596, - RULE = 597, - SAVEPOINT = 598, - SCHEMA = 599, - SCHEMAS = 600, - SCROLL = 601, - SEARCH = 602, - SECOND_P = 603, - SECURITY = 604, - SELECT = 605, - SEQUENCE = 606, - SEQUENCES = 607, - SERIALIZABLE = 608, - SERVER = 609, - SESSION = 610, - SESSION_USER = 611, - SET = 612, - SETS = 613, - SETOF = 614, - SHARE = 615, - SHOW = 616, - SIMILAR = 617, - SIMPLE = 618, - SKIP = 619, - SMALLINT = 620, - SNAPSHOT = 621, - SOME = 622, - SQL_P = 623, - STABLE = 624, - STANDALONE_P = 625, - START = 626, - STATEMENT = 627, - STATISTICS = 628, - STDIN = 629, - STDOUT = 630, - STORAGE = 631, - STRICT_P = 632, - STRIP_P = 633, - SUBSCRIPTION = 634, - SUBSTRING = 635, - SYMMETRIC = 636, - SYSID = 637, - SYSTEM_P = 638, - TABLE = 639, - TABLES = 640, - TABLESAMPLE = 641, - TABLESPACE = 642, - TEMP = 643, - TEMPLATE = 644, - TEMPORARY = 645, - TEXT_P = 646, - THEN = 647, - TIES = 648, - TIME = 649, - TIMESTAMP = 650, - TO = 651, - TRAILING = 652, - TRANSACTION = 653, - TRANSFORM = 654, - TREAT = 655, - TRIGGER = 656, - TRIM = 657, - TRUE_P = 658, - TRUNCATE = 659, - TRUSTED = 660, - TYPE_P = 661, - TYPES_P = 662, - UNBOUNDED = 663, - UNCOMMITTED = 664, - UNENCRYPTED = 665, - UNION = 666, - UNIQUE = 667, - UNKNOWN = 668, - UNLISTEN = 669, - UNLOGGED = 670, - UNTIL = 671, - UPDATE = 672, - USER = 673, - USING = 674, - VACUUM = 675, - VALID = 676, - VALIDATE = 677, - VALIDATOR = 678, - VALUE_P = 679, - VALUES = 680, - VARCHAR = 681, - VARIADIC = 682, - VARYING = 683, - VERBOSE = 684, - VERSION_P = 685, - VIEW = 686, - VIEWS = 687, - VOLATILE = 688, - WHEN = 689, - WHERE = 690, - WHITESPACE_P = 691, - WINDOW = 692, - WITH = 693, - WITHIN = 694, - WITHOUT = 695, - WORK = 696, - WRAPPER = 697, - WRITE = 698, - XML_P = 699, - XMLATTRIBUTES = 700, - XMLCONCAT = 701, - XMLELEMENT = 702, - XMLEXISTS = 703, - XMLFOREST = 704, - XMLNAMESPACES = 705, - XMLPARSE = 706, - XMLPI = 707, - XMLROOT = 708, - XMLSERIALIZE = 709, - XMLTABLE = 710, - YEAR_P = 711, - YES_P = 712, - ZONE = 713, - NOT_LA = 714, - NULLS_LA = 715, - WITH_LA = 716, - POSTFIXOP = 717, - UMINUS = 718 - }; -#endif -/* Tokens. */ -#define IDENT 258 -#define FCONST 259 -#define SCONST 260 -#define BCONST 261 -#define XCONST 262 -#define Op 263 -#define ICONST 264 -#define PARAM 265 -#define TYPECAST 266 -#define DOT_DOT 267 -#define COLON_EQUALS 268 -#define EQUALS_GREATER 269 -#define LESS_EQUALS 270 -#define GREATER_EQUALS 271 -#define NOT_EQUALS 272 -#define ABORT_P 273 -#define ABSOLUTE_P 274 -#define ACCESS 275 -#define ACTION 276 -#define ADD_P 277 -#define ADMIN 278 -#define AFTER 279 -#define AGGREGATE 280 -#define ALL 281 -#define ALSO 282 -#define ALTER 283 -#define ALWAYS 284 -#define ANALYSE 285 -#define ANALYZE 286 -#define AND 287 -#define ANY 288 -#define ARRAY 289 -#define AS 290 -#define ASC 291 -#define ASSERTION 292 -#define ASSIGNMENT 293 -#define ASYMMETRIC 294 -#define AT 295 -#define ATTACH 296 -#define ATTRIBUTE 297 -#define AUTHORIZATION 298 -#define BACKWARD 299 -#define BEFORE 300 -#define BEGIN_P 301 -#define BETWEEN 302 -#define BIGINT 303 -#define BINARY 304 -#define BIT 305 -#define BOOLEAN_P 306 -#define BOTH 307 -#define BY 308 -#define CACHE 309 -#define CALL 310 -#define CALLED 311 -#define CASCADE 312 -#define CASCADED 313 -#define CASE 314 -#define CAST 315 -#define CATALOG_P 316 -#define CHAIN 317 -#define CHAR_P 318 -#define CHARACTER 319 -#define CHARACTERISTICS 320 -#define CHECK 321 -#define CHECKPOINT 322 -#define CLASS 323 -#define CLOSE 324 -#define CLUSTER 325 -#define COALESCE 326 -#define COLLATE 327 -#define COLLATION 328 -#define COLUMN 329 -#define COLUMNS 330 -#define COMMENT 331 -#define COMMENTS 332 -#define COMMIT 333 -#define COMMITTED 334 -#define CONCURRENTLY 335 -#define CONFIGURATION 336 -#define CONFLICT 337 -#define CONNECTION 338 -#define CONSTRAINT 339 -#define CONSTRAINTS 340 -#define CONTENT_P 341 -#define CONTINUE_P 342 -#define CONVERSION_P 343 -#define COPY 344 -#define COST 345 -#define CREATE 346 -#define CROSS 347 -#define CSV 348 -#define CUBE 349 -#define CURRENT_P 350 -#define CURRENT_CATALOG 351 -#define CURRENT_DATE 352 -#define CURRENT_ROLE 353 -#define CURRENT_SCHEMA 354 -#define CURRENT_TIME 355 -#define CURRENT_TIMESTAMP 356 -#define CURRENT_USER 357 -#define CURSOR 358 -#define CYCLE 359 -#define DATA_P 360 -#define DATABASE 361 -#define DAY_P 362 -#define DEALLOCATE 363 -#define DEC 364 -#define DECIMAL_P 365 -#define DECLARE 366 -#define DEFAULT 367 -#define DEFAULTS 368 -#define DEFERRABLE 369 -#define DEFERRED 370 -#define DEFINER 371 -#define DELETE_P 372 -#define DELIMITER 373 -#define DELIMITERS 374 -#define DEPENDS 375 -#define DESC 376 -#define DETACH 377 -#define DICTIONARY 378 -#define DISABLE_P 379 -#define DISCARD 380 -#define DISTINCT 381 -#define DO 382 -#define DOCUMENT_P 383 -#define DOMAIN_P 384 -#define DOUBLE_P 385 -#define DROP 386 -#define EACH 387 -#define ELSE 388 -#define ENABLE_P 389 -#define ENCODING 390 -#define ENCRYPTED 391 -#define END_P 392 -#define ENUM_P 393 -#define ESCAPE 394 -#define EVENT 395 -#define EXCEPT 396 -#define EXCLUDE 397 -#define EXCLUDING 398 -#define EXCLUSIVE 399 -#define EXECUTE 400 -#define EXISTS 401 -#define EXPLAIN 402 -#define EXTENSION 403 -#define EXTERNAL 404 -#define EXTRACT 405 -#define FALSE_P 406 -#define FAMILY 407 -#define FETCH 408 -#define FILTER 409 -#define FIRST_P 410 -#define FLOAT_P 411 -#define FOLLOWING 412 -#define FOR 413 -#define FORCE 414 -#define FOREIGN 415 -#define FORWARD 416 -#define FREEZE 417 -#define FROM 418 -#define FULL 419 -#define FUNCTION 420 -#define FUNCTIONS 421 -#define GENERATED 422 -#define GLOBAL 423 -#define GRANT 424 -#define GRANTED 425 -#define GREATEST 426 -#define GROUP_P 427 -#define GROUPING 428 -#define GROUPS 429 -#define HANDLER 430 -#define HAVING 431 -#define HEADER_P 432 -#define HOLD 433 -#define HOUR_P 434 -#define IDENTITY_P 435 -#define IF_P 436 -#define ILIKE 437 -#define IMMEDIATE 438 -#define IMMUTABLE 439 -#define IMPLICIT_P 440 -#define IMPORT_P 441 -#define IN_P 442 -#define INCLUDE 443 -#define INCLUDING 444 -#define INCREMENT 445 -#define INDEX 446 -#define INDEXES 447 -#define INHERIT 448 -#define INHERITS 449 -#define INITIALLY 450 -#define INLINE_P 451 -#define INNER_P 452 -#define INOUT 453 -#define INPUT_P 454 -#define INSENSITIVE 455 -#define INSERT 456 -#define INSTEAD 457 -#define INT_P 458 -#define INTEGER 459 -#define INTERSECT 460 -#define INTERVAL 461 -#define INTO 462 -#define INVOKER 463 -#define IS 464 -#define ISNULL 465 -#define ISOLATION 466 -#define JOIN 467 -#define KEY 468 -#define LABEL 469 -#define LANGUAGE 470 -#define LARGE_P 471 -#define LAST_P 472 -#define LATERAL_P 473 -#define LEADING 474 -#define LEAKPROOF 475 -#define LEAST 476 -#define LEFT 477 -#define LEVEL 478 -#define LIKE 479 -#define LIMIT 480 -#define LISTEN 481 -#define LOAD 482 -#define LOCAL 483 -#define LOCALTIME 484 -#define LOCALTIMESTAMP 485 -#define LOCATION 486 -#define LOCK_P 487 -#define LOCKED 488 -#define LOGGED 489 -#define MAPPING 490 -#define MATCH 491 -#define MATERIALIZED 492 -#define MAXVALUE 493 -#define METHOD 494 -#define MINUTE_P 495 -#define MINVALUE 496 -#define MODE 497 -#define MONTH_P 498 -#define MOVE 499 -#define NAME_P 500 -#define NAMES 501 -#define NATIONAL 502 -#define NATURAL 503 -#define NCHAR 504 -#define NEW 505 -#define NEXT 506 -#define NO 507 -#define NONE 508 -#define NOT 509 -#define NOTHING 510 -#define NOTIFY 511 -#define NOTNULL 512 -#define NOWAIT 513 -#define NULL_P 514 -#define NULLIF 515 -#define NULLS_P 516 -#define NUMERIC 517 -#define OBJECT_P 518 -#define OF 519 -#define OFF 520 -#define OFFSET 521 -#define OIDS 522 -#define OLD 523 -#define ON 524 -#define ONLY 525 -#define OPERATOR 526 -#define OPTION 527 -#define OPTIONS 528 -#define OR 529 -#define ORDER 530 -#define ORDINALITY 531 -#define OTHERS 532 -#define OUT_P 533 -#define OUTER_P 534 -#define OVER 535 -#define OVERLAPS 536 -#define OVERLAY 537 -#define OVERRIDING 538 -#define OWNED 539 -#define OWNER 540 -#define PARALLEL 541 -#define PARSER 542 -#define PARTIAL 543 -#define PARTITION 544 -#define PASSING 545 -#define PASSWORD 546 -#define PGPOOL 547 -#define PLACING 548 -#define PLANS 549 -#define POLICY 550 -#define POSITION 551 -#define PRECEDING 552 -#define PRECISION 553 -#define PRESERVE 554 -#define PREPARE 555 -#define PREPARED 556 -#define PRIMARY 557 -#define PRIOR 558 -#define PRIVILEGES 559 -#define PROCEDURAL 560 -#define PROCEDURE 561 -#define PROCEDURES 562 -#define PROGRAM 563 -#define PUBLICATION 564 -#define QUOTE 565 -#define RANGE 566 -#define READ 567 -#define REAL 568 -#define REASSIGN 569 -#define RECHECK 570 -#define RECURSIVE 571 -#define REF 572 -#define REFERENCES 573 -#define REFERENCING 574 -#define REFRESH 575 -#define REINDEX 576 -#define RELATIVE_P 577 -#define RELEASE 578 -#define RENAME 579 -#define REPEATABLE 580 -#define REPLACE 581 -#define REPLICA 582 -#define RESET 583 -#define RESTART 584 -#define RESTRICT 585 -#define RETURNING 586 -#define RETURNS 587 -#define REVOKE 588 -#define RIGHT 589 -#define ROLE 590 -#define ROLLBACK 591 -#define ROLLUP 592 -#define ROUTINE 593 -#define ROUTINES 594 -#define ROW 595 -#define ROWS 596 -#define RULE 597 -#define SAVEPOINT 598 -#define SCHEMA 599 -#define SCHEMAS 600 -#define SCROLL 601 -#define SEARCH 602 -#define SECOND_P 603 -#define SECURITY 604 -#define SELECT 605 -#define SEQUENCE 606 -#define SEQUENCES 607 -#define SERIALIZABLE 608 -#define SERVER 609 -#define SESSION 610 -#define SESSION_USER 611 -#define SET 612 -#define SETS 613 -#define SETOF 614 -#define SHARE 615 -#define SHOW 616 -#define SIMILAR 617 -#define SIMPLE 618 -#define SKIP 619 -#define SMALLINT 620 -#define SNAPSHOT 621 -#define SOME 622 -#define SQL_P 623 -#define STABLE 624 -#define STANDALONE_P 625 -#define START 626 -#define STATEMENT 627 -#define STATISTICS 628 -#define STDIN 629 -#define STDOUT 630 -#define STORAGE 631 -#define STRICT_P 632 -#define STRIP_P 633 -#define SUBSCRIPTION 634 -#define SUBSTRING 635 -#define SYMMETRIC 636 -#define SYSID 637 -#define SYSTEM_P 638 -#define TABLE 639 -#define TABLES 640 -#define TABLESAMPLE 641 -#define TABLESPACE 642 -#define TEMP 643 -#define TEMPLATE 644 -#define TEMPORARY 645 -#define TEXT_P 646 -#define THEN 647 -#define TIES 648 -#define TIME 649 -#define TIMESTAMP 650 -#define TO 651 -#define TRAILING 652 -#define TRANSACTION 653 -#define TRANSFORM 654 -#define TREAT 655 -#define TRIGGER 656 -#define TRIM 657 -#define TRUE_P 658 -#define TRUNCATE 659 -#define TRUSTED 660 -#define TYPE_P 661 -#define TYPES_P 662 -#define UNBOUNDED 663 -#define UNCOMMITTED 664 -#define UNENCRYPTED 665 -#define UNION 666 -#define UNIQUE 667 -#define UNKNOWN 668 -#define UNLISTEN 669 -#define UNLOGGED 670 -#define UNTIL 671 -#define UPDATE 672 -#define USER 673 -#define USING 674 -#define VACUUM 675 -#define VALID 676 -#define VALIDATE 677 -#define VALIDATOR 678 -#define VALUE_P 679 -#define VALUES 680 -#define VARCHAR 681 -#define VARIADIC 682 -#define VARYING 683 -#define VERBOSE 684 -#define VERSION_P 685 -#define VIEW 686 -#define VIEWS 687 -#define VOLATILE 688 -#define WHEN 689 -#define WHERE 690 -#define WHITESPACE_P 691 -#define WINDOW 692 -#define WITH 693 -#define WITHIN 694 -#define WITHOUT 695 -#define WORK 696 -#define WRAPPER 697 -#define WRITE 698 -#define XML_P 699 -#define XMLATTRIBUTES 700 -#define XMLCONCAT 701 -#define XMLELEMENT 702 -#define XMLEXISTS 703 -#define XMLFOREST 704 -#define XMLNAMESPACES 705 -#define XMLPARSE 706 -#define XMLPI 707 -#define XMLROOT 708 -#define XMLSERIALIZE 709 -#define XMLTABLE 710 -#define YEAR_P 711 -#define YES_P 712 -#define ZONE 713 -#define NOT_LA 714 -#define NULLS_LA 715 -#define WITH_LA 716 -#define POSTFIXOP 717 -#define UMINUS 718 - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE -{ -#line 239 "gram.y" /* yacc.c:355 */ - - core_YYSTYPE core_yystype; - /* these fields must match core_YYSTYPE: */ - int ival; - char *str; - const char *keyword; - - char chr; - bool boolean; - JoinType jtype; - DropBehavior dbehavior; - OnCommitAction oncommit; - List *list; - Node *node; - Value *value; - ObjectType objtype; - TypeName *typnam; - FunctionParameter *fun_param; - FunctionParameterMode fun_param_mode; - ObjectWithArgs *objwithargs; - DefElem *defelt; - SortBy *sortby; - WindowDef *windef; - JoinExpr *jexpr; - IndexElem *ielem; - Alias *alias; - RangeVar *range; - IntoClause *into; - WithClause *with; - InferClause *infer; - OnConflictClause *onconflict; - A_Indices *aind; - ResTarget *target; - struct PrivTarget *privtarget; - AccessPriv *accesspriv; - struct ImportQual *importqual; - InsertStmt *istmt; - VariableSetStmt *vsetstmt; - PartitionElem *partelem; - PartitionSpec *partspec; - PartitionBoundSpec *partboundspec; - RoleSpec *rolespec; - -#line 1311 "gram.c" /* yacc.c:355 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - -int base_yyparse (core_yyscan_t yyscanner); - -#endif /* !YY_BASE_YY_Y_TAB_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -#line 1341 "gram.c" /* yacc.c:358 */ - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 832 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 102341 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 481 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 667 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 2729 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 5480 - -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 718 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint16 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 470, 2, 2, - 475, 476, 468, 466, 479, 467, 477, 469, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 480, 478, - 462, 464, 463, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 473, 2, 474, 471, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 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, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 465, 472 -}; - -#if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 821, 821, 837, 849, 859, 860, 861, 862, 863, - 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, - 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, - 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, - 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, - 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, - 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, - 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, - 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, - 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, - 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, - 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, - 974, 975, 976, 977, 978, 979, 980, 981, 982, 984, - 993, 1008, 1019, 1020, 1021, 1030, 1031, 1035, 1036, 1040, - 1045, 1049, 1059, 1067, 1071, 1075, 1080, 1084, 1132, 1134, - 1138, 1142, 1146, 1150, 1164, 1182, 1190, 1201, 1202, 1206, - 1214, 1222, 1230, 1251, 1258, 1265, 1272, 1279, 1286, 1303, - 1321, 1332, 1333, 1344, 1354, 1364, 1379, 1397, 1398, 1402, - 1409, 1417, 1418, 1419, 1420, 1421, 1422, 1436, 1443, 1449, - 1455, 1464, 1472, 1480, 1484, 1492, 1500, 1507, 1516, 1517, - 1525, 1536, 1544, 1552, 1563, 1571, 1579, 1586, 1595, 1605, - 1606, 1610, 1611, 1614, 1616, 1620, 1621, 1622, 1623, 1627, - 1628, 1629, 1635, 1647, 1651, 1655, 1670, 1677, 1678, 1679, - 1683, 1684, 1685, 1689, 1690, 1694, 1695, 1704, 1705, 1712, - 1719, 1729, 1736, 1746, 1747, 1752, 1753, 1759, 1765, 1771, - 1777, 1783, 1789, 1795, 1805, 1815, 1816, 1820, 1821, 1829, - 1844, 1850, 1856, 1862, 1868, 1887, 1896, 1905, 1914, 1923, - 1934, 1945, 1954, 1963, 1972, 1983, 1994, 2003, 2012, 2021, - 2030, 2039, 2048, 2059, 2073, 2074, 2079, 2092, 2108, 2124, - 2133, 2142, 2151, 2160, 2169, 2177, 2185, 2194, 2210, 2219, - 2228, 2237, 2254, 2263, 2272, 2281, 2291, 2304, 2319, 2328, - 2337, 2352, 2360, 2370, 2380, 2387, 2394, 2402, 2410, 2417, - 2424, 2432, 2440, 2448, 2455, 2462, 2470, 2477, 2484, 2492, - 2500, 2508, 2516, 2524, 2532, 2542, 2549, 2557, 2565, 2573, - 2581, 2589, 2596, 2603, 2610, 2616, 2626, 2627, 2631, 2632, - 2633, 2637, 2645, 2649, 2650, 2654, 2661, 2668, 2675, 2685, - 2688, 2689, 2693, 2694, 2699, 2703, 2707, 2712, 2719, 2721, - 2726, 2730, 2734, 2745, 2753, 2806, 2819, 2833, 2845, 2852, - 2856, 2863, 2864, 2865, 2866, 2867, 2871, 2872, 2877, 2878, - 2883, 2893, 2903, 2923, 2936, 2937, 2942, 2951, 2961, 2971, - 2997, 3003, 3036, 3065, 3087, 3088, 3092, 3093, 3102, 3103, - 3104, 3107, 3108, 3113, 3114, 3118, 3122, 3126, 3130, 3134, - 3138, 3142, 3146, 3150, 3154, 3158, 3162, 3166, 3170, 3179, - 3183, 3187, 3191, 3195, 3199, 3203, 3204, 3209, 3213, 3220, - 3227, 3228, 3229, 3230, 3231, 3235, 3239, 3247, 3258, 3275, - 3293, 3312, 3331, 3350, 3382, 3383, 3384, 3385, 3386, 3393, - 3400, 3401, 3405, 3406, 3410, 3411, 3415, 3419, 3426, 3430, - 3437, 3438, 3439, 3443, 3444, 3447, 3469, 3488, 3510, 3511, - 3515, 3522, 3523, 3524, 3555, 3562, 3569, 3580, 3591, 3603, - 3614, 3623, 3641, 3642, 3661, 3668, 3675, 3682, 3693, 3703, - 3704, 3705, 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, - 3725, 3732, 3736, 3749, 3765, 3780, 3796, 3811, 3830, 3851, - 3852, 3856, 3857, 3861, 3862, 3865, 3871, 3872, 3875, 3879, - 3887, 3892, 3898, 3899, 3903, 3908, 3915, 3916, 3926, 3928, - 3930, 3932, 3935, 3938, 3941, 3945, 3946, 3947, 3948, 3949, - 3952, 3953, 3957, 3958, 3961, 3973, 3974, 3977, 3978, 3981, - 3992, 4003, 4017, 4018, 4019, 4020, 4023, 4024, 4025, 4026, - 4029, 4030, 4033, 4034, 4037, 4055, 4067, 4092, 4105, 4121, - 4135, 4136, 4137, 4149, 4162, 4178, 4191, 4192, 4204, 4224, - 4234, 4247, 4255, 4266, 4267, 4270, 4271, 4274, 4275, 4278, - 4282, 4286, 4290, 4294, 4298, 4302, 4306, 4310, 4314, 4318, - 4323, 4327, 4331, 4337, 4338, 4342, 4343, 4344, 4349, 4352, - 4353, 4365, 4377, 4392, 4393, 4401, 4402, 4406, 4407, 4411, - 4412, 4416, 4417, 4421, 4431, 4444, 4445, 4455, 4466, 4467, - 4480, 4487, 4504, 4512, 4523, 4526, 4530, 4534, 4538, 4542, - 4554, 4564, 4567, 4571, 4584, 4593, 4602, 4611, 4620, 4629, - 4638, 4647, 4656, 4665, 4674, 4683, 4692, 4701, 4710, 4719, - 4728, 4737, 4746, 4755, 4764, 4773, 4782, 4791, 4800, 4809, - 4818, 4827, 4845, 4856, 4857, 4858, 4859, 4863, 4864, 4868, - 4869, 4879, 4887, 4899, 4900, 4904, 4908, 4916, 4920, 4924, - 4931, 4935, 4940, 4945, 4952, 4959, 4964, 4974, 4986, 5001, - 5002, 5007, 5008, 5012, 5013, 5023, 5032, 5040, 5057, 5077, - 5097, 5118, 5149, 5158, 5179, 5194, 5195, 5199, 5207, 5222, - 5231, 5243, 5244, 5256, 5264, 5281, 5305, 5322, 5336, 5337, - 5341, 5342, 5346, 5347, 5351, 5352, 5356, 5370, 5374, 5375, - 5379, 5380, 5381, 5382, 5383, 5393, 5411, 5432, 5458, 5459, - 5460, 5464, 5466, 5488, 5490, 5492, 5494, 5496, 5501, 5502, - 5506, 5507, 5511, 5522, 5523, 5527, 5536, 5540, 5544, 5549, - 5559, 5560, 5564, 5565, 5569, 5570, 5574, 5575, 5576, 5580, - 5584, 5585, 5586, 5590, 5591, 5596, 5597, 5624, 5625, 5626, - 5627, 5628, 5629, 5642, 5652, 5666, 5668, 5673, 5678, 5680, - 5685, 5695, 5696, 5697, 5698, 5710, 5730, 5752, 5762, 5773, - 5783, 5793, 5804, 5813, 5820, 5827, 5836, 5845, 5854, 5863, - 5872, 5882, 5891, 5903, 5906, 5907, 5910, 5914, 5921, 5922, - 5923, 5924, 5925, 5926, 5929, 5932, 5933, 5941, 5948, 5949, - 5952, 5954, 5965, 5976, 5987, 5998, 6011, 6012, 6028, 6043, - 6044, 6048, 6060, 6070, 6078, 6087, 6096, 6097, 6100, 6101, - 6104, 6105, 6106, 6109, 6123, 6128, 6138, 6147, 6159, 6160, - 6164, 6172, 6184, 6194, 6207, 6217, 6239, 6249, 6267, 6277, - 6287, 6297, 6307, 6317, 6327, 6337, 6347, 6357, 6367, 6377, - 6391, 6392, 6393, 6394, 6395, 6396, 6397, 6398, 6399, 6400, - 6401, 6402, 6403, 6408, 6409, 6410, 6411, 6412, 6413, 6414, - 6419, 6420, 6421, 6425, 6426, 6429, 6430, 6433, 6435, 6440, - 6441, 6451, 6462, 6463, 6464, 6498, 6506, 6514, 6522, 6530, - 6538, 6546, 6554, 6562, 6575, 6583, 6591, 6599, 6607, 6615, - 6623, 6631, 6639, 6647, 6659, 6660, 6661, 6662, 6663, 6664, - 6665, 6666, 6667, 6668, 6669, 6670, 6671, 6672, 6677, 6678, - 6679, 6680, 6681, 6682, 6683, 6684, 6685, 6686, 6687, 6688, - 6692, 6693, 6707, 6717, 6727, 6737, 6747, 6757, 6767, 6777, - 6787, 6799, 6800, 6805, 6806, 6807, 6808, 6809, 6810, 6815, - 6816, 6817, 6818, 6819, 6820, 6821, 6822, 6825, 6826, 6836, - 6842, 6850, 6858, 6866, 6874, 6882, 6890, 6898, 6906, 6914, - 6922, 6930, 6938, 6946, 6954, 6962, 6970, 6980, 6981, 6984, - 6985, 6995, 7011, 7025, 7051, 7053, 7055, 7057, 7064, 7073, - 7074, 7077, 7084, 7091, 7098, 7112, 7120, 7128, 7136, 7144, - 7152, 7160, 7168, 7176, 7184, 7192, 7200, 7208, 7216, 7224, - 7232, 7240, 7248, 7256, 7264, 7276, 7277, 7281, 7282, 7287, - 7288, 7298, 7311, 7321, 7333, 7334, 7337, 7338, 7348, 7358, - 7359, 7363, 7367, 7371, 7382, 7395, 7409, 7426, 7427, 7428, - 7429, 7430, 7431, 7443, 7471, 7502, 7503, 7507, 7508, 7512, - 7513, 7517, 7518, 7521, 7522, 7530, 7541, 7552, 7565, 7566, - 7569, 7570, 7573, 7574, 7577, 7578, 7581, 7582, 7583, 7586, - 7587, 7588, 7604, 7616, 7629, 7641, 7656, 7657, 7660, 7661, - 7665, 7666, 7670, 7671, 7676, 7688, 7695, 7702, 7717, 7718, - 7722, 7723, 7738, 7747, 7756, 7765, 7774, 7786, 7787, 7788, - 7789, 7790, 7796, 7800, 7815, 7816, 7822, 7832, 7836, 7841, - 7849, 7890, 7894, 7898, 7902, 7910, 7911, 7915, 7925, 7926, - 7932, 7933, 7940, 7944, 7948, 7952, 7956, 7960, 7964, 7968, - 7972, 7976, 7980, 7984, 7988, 7992, 7996, 8001, 8008, 8012, - 8016, 8020, 8024, 8030, 8031, 8038, 8039, 8043, 8044, 8047, - 8059, 8063, 8078, 8086, 8094, 8106, 8107, 8112, 8113, 8130, - 8140, 8150, 8160, 8170, 8180, 8193, 8203, 8216, 8226, 8239, - 8247, 8249, 8251, 8256, 8258, 8263, 8264, 8269, 8287, 8296, - 8297, 8301, 8305, 8317, 8328, 8339, 8352, 8353, 8354, 8358, - 8370, 8371, 8381, 8393, 8397, 8401, 8405, 8412, 8432, 8441, - 8450, 8459, 8470, 8471, 8474, 8475, 8476, 8479, 8480, 8483, - 8493, 8502, 8519, 8528, 8537, 8546, 8555, 8564, 8573, 8582, - 8591, 8600, 8609, 8618, 8627, 8637, 8647, 8656, 8665, 8674, - 8683, 8692, 8701, 8711, 8721, 8731, 8741, 8751, 8761, 8771, - 8781, 8791, 8801, 8811, 8821, 8832, 8843, 8854, 8865, 8875, - 8885, 8896, 8907, 8917, 8927, 8935, 8944, 8953, 8962, 8971, - 8980, 8989, 8998, 9007, 9016, 9030, 9031, 9034, 9035, 9045, - 9053, 9061, 9069, 9078, 9086, 9103, 9112, 9121, 9130, 9139, - 9148, 9157, 9166, 9175, 9184, 9193, 9202, 9211, 9220, 9229, - 9238, 9247, 9256, 9265, 9274, 9283, 9292, 9301, 9310, 9319, - 9328, 9337, 9355, 9364, 9365, 9368, 9370, 9376, 9377, 9378, - 9379, 9380, 9389, 9397, 9405, 9413, 9421, 9429, 9437, 9445, - 9453, 9461, 9469, 9477, 9485, 9493, 9501, 9509, 9517, 9525, - 9533, 9541, 9549, 9557, 9565, 9573, 9591, 9610, 9611, 9615, - 9619, 9639, 9646, 9654, 9662, 9679, 9692, 9696, 9703, 9712, - 9721, 9730, 9739, 9749, 9759, 9777, 9785, 9801, 9818, 9819, - 9820, 9825, 9831, 9840, 9841, 9842, 9843, 9844, 9848, 9849, - 9852, 9853, 9854, 9855, 9859, 9860, 9861, 9873, 9883, 9884, - 9887, 9896, 9902, 9921, 9928, 9935, 9942, 9949, 9956, 9963, - 9970, 9977, 9984, 9991, 9998, 10005, 10012, 10021, 10022, 10023, - 10027, 10030, 10033, 10036, 10039, 10046, 10048, 10050, 10055, 10057, - 10069, 10082, 10095, 10113, 10134, 10135, 10136, 10137, 10147, 10163, - 10173, 10174, 10178, 10179, 10183, 10187, 10191, 10209, 10210, 10211, - 10212, 10213, 10214, 10215, 10222, 10223, 10234, 10241, 10248, 10259, - 10276, 10283, 10299, 10316, 10322, 10338, 10351, 10360, 10368, 10376, - 10385, 10396, 10407, 10417, 10418, 10429, 10439, 10450, 10461, 10472, - 10483, 10492, 10504, 10505, 10519, 10542, 10550, 10559, 10570, 10571, - 10583, 10598, 10608, 10609, 10613, 10614, 10615, 10616, 10617, 10629, - 10638, 10648, 10649, 10653, 10657, 10658, 10662, 10663, 10667, 10668, - 10671, 10672, 10675, 10676, 10680, 10681, 10685, 10692, 10694, 10699, - 10700, 10713, 10720, 10730, 10737, 10747, 10748, 10749, 10750, 10751, - 10752, 10753, 10754, 10755, 10759, 10763, 10770, 10777, 10778, 10782, - 10783, 10784, 10794, 10804, 10805, 10809, 10810, 10811, 10812, 10822, - 10829, 10847, 10848, 10858, 10864, 10870, 10876, 10892, 10910, 10914, - 10922, 10928, 10935, 10941, 10948, 10957, 10958, 10962, 10964, 10969, - 10980, 10990, 11000, 11006, 11015, 11024, 11030, 11031, 11042, 11056, - 11057, 11068, 11079, 11080, 11083, 11084, 11085, 11086, 11087, 11088, - 11089, 11090, 11093, 11094, 11098, 11099, 11100, 11111, 11129, 11130, - 11134, 11139, 11163, 11174, 11175, 11185, 11196, 11199, 11200, 11201, - 11202, 11203, 11206, 11207, 11208, 11256, 11257, 11261, 11262, 11277, - 11278, 11285, 11293, 11301, 11309, 11317, 11325, 11336, 11337, 11364, - 11378, 11393, 11394, 11413, 11417, 11421, 11438, 11445, 11452, 11462, - 11463, 11466, 11478, 11479, 11483, 11495, 11503, 11508, 11513, 11518, - 11523, 11531, 11539, 11544, 11549, 11556, 11557, 11561, 11562, 11563, - 11570, 11571, 11575, 11576, 11580, 11581, 11585, 11589, 11590, 11593, - 11602, 11615, 11616, 11617, 11618, 11622, 11623, 11627, 11629, 11645, - 11647, 11652, 11655, 11660, 11661, 11669, 11689, 11690, 11692, 11697, - 11698, 11702, 11703, 11706, 11707, 11732, 11733, 11737, 11738, 11742, - 11743, 11744, 11745, 11746, 11750, 11763, 11770, 11777, 11784, 11785, - 11789, 11790, 11794, 11795, 11799, 11800, 11804, 11815, 11816, 11817, - 11818, 11822, 11823, 11833, 11839, 11857, 11858, 11862, 11863, 11869, - 11874, 11882, 11889, 11897, 11903, 11910, 11945, 11970, 11974, 12000, - 12004, 12016, 12029, 12043, 12054, 12069, 12075, 12080, 12086, 12093, - 12094, 12102, 12106, 12110, 12116, 12123, 12128, 12129, 12130, 12131, - 12135, 12136, 12148, 12149, 12154, 12161, 12168, 12175, 12186, 12187, - 12200, 12204, 12211, 12224, 12237, 12238, 12253, 12263, 12275, 12280, - 12281, 12284, 12285, 12288, 12289, 12294, 12295, 12300, 12301, 12309, - 12314, 12315, 12319, 12323, 12329, 12354, 12364, 12377, 12378, 12382, - 12396, 12453, 12467, 12469, 12474, 12476, 12478, 12480, 12485, 12487, - 12492, 12500, 12520, 12525, 12532, 12537, 12543, 12548, 12557, 12559, - 12562, 12566, 12567, 12568, 12569, 12570, 12571, 12576, 12596, 12597, - 12598, 12599, 12610, 12616, 12624, 12625, 12631, 12636, 12641, 12646, - 12651, 12656, 12661, 12666, 12672, 12678, 12684, 12691, 12713, 12722, - 12726, 12734, 12738, 12746, 12758, 12779, 12783, 12789, 12793, 12806, - 12814, 12824, 12826, 12828, 12830, 12832, 12834, 12839, 12840, 12847, - 12856, 12864, 12873, 12884, 12892, 12893, 12894, 12898, 12900, 12902, - 12904, 12906, 12908, 12910, 12915, 12920, 12926, 12934, 12939, 12946, - 12953, 12957, 12961, 12997, 12998, 13000, 13008, 13023, 13025, 13027, - 13029, 13031, 13033, 13035, 13037, 13039, 13041, 13043, 13045, 13047, - 13049, 13052, 13054, 13056, 13059, 13061, 13063, 13065, 13068, 13073, - 13081, 13086, 13094, 13099, 13107, 13112, 13121, 13129, 13137, 13145, - 13163, 13171, 13179, 13187, 13195, 13211, 13219, 13227, 13235, 13243, - 13251, 13259, 13263, 13267, 13271, 13275, 13283, 13291, 13299, 13307, - 13327, 13349, 13360, 13367, 13383, 13388, 13394, 13419, 13421, 13423, - 13425, 13427, 13429, 13431, 13433, 13435, 13437, 13439, 13441, 13443, - 13445, 13447, 13449, 13451, 13453, 13455, 13457, 13461, 13465, 13469, - 13473, 13478, 13494, 13495, 13496, 13511, 13545, 13547, 13549, 13560, - 13584, 13595, 13606, 13613, 13623, 13633, 13642, 13646, 13652, 13659, - 13666, 13676, 13683, 13711, 13746, 13757, 13758, 13765, 13771, 13775, - 13779, 13783, 13787, 13791, 13795, 13799, 13803, 13807, 13811, 13815, - 13819, 13823, 13827, 13831, 13833, 13837, 13846, 13851, 13858, 13873, - 13880, 13884, 13888, 13892, 13896, 13903, 13911, 13919, 13923, 13927, - 13931, 13935, 13939, 13945, 13949, 13958, 13962, 13966, 13971, 13985, - 13987, 13991, 13993, 13995, 13998, 14001, 14004, 14005, 14008, 14016, - 14026, 14027, 14030, 14031, 14032, 14037, 14041, 14045, 14049, 14060, - 14061, 14065, 14066, 14074, 14075, 14079, 14080, 14085, 14093, 14095, - 14109, 14112, 14139, 14140, 14143, 14144, 14152, 14159, 14166, 14174, - 14183, 14200, 14245, 14253, 14261, 14269, 14277, 14288, 14289, 14290, - 14291, 14292, 14306, 14307, 14308, 14311, 14312, 14315, 14318, 14319, - 14320, 14323, 14324, 14327, 14328, 14329, 14330, 14331, 14332, 14333, - 14334, 14335, 14336, 14337, 14338, 14341, 14343, 14348, 14350, 14355, - 14357, 14359, 14361, 14363, 14365, 14377, 14381, 14388, 14392, 14398, - 14402, 14411, 14422, 14423, 14426, 14430, 14434, 14440, 14441, 14446, - 14450, 14457, 14458, 14459, 14460, 14461, 14462, 14463, 14464, 14474, - 14478, 14485, 14492, 14493, 14509, 14513, 14518, 14522, 14537, 14542, - 14546, 14549, 14552, 14553, 14554, 14557, 14564, 14574, 14588, 14589, - 14593, 14604, 14605, 14608, 14609, 14612, 14616, 14623, 14627, 14631, - 14639, 14650, 14651, 14655, 14656, 14660, 14661, 14664, 14665, 14675, - 14676, 14680, 14681, 14684, 14700, 14708, 14716, 14738, 14739, 14750, - 14754, 14781, 14783, 14788, 14791, 14794, 14796, 14798, 14800, 14810, - 14812, 14823, 14827, 14831, 14835, 14839, 14848, 14855, 14887, 14891, - 14897, 14904, 14908, 14912, 14918, 14919, 14921, 14922, 14923, 14927, - 14960, 14987, 14991, 14997, 14999, 15016, 15017, 15018, 15023, 15024, - 15025, 15030, 15031, 15032, 15033, 15039, 15040, 15041, 15042, 15043, - 15063, 15064, 15065, 15066, 15067, 15068, 15069, 15070, 15071, 15072, - 15073, 15074, 15075, 15076, 15077, 15078, 15079, 15080, 15081, 15082, - 15083, 15084, 15085, 15086, 15087, 15088, 15089, 15090, 15091, 15092, - 15093, 15094, 15095, 15096, 15097, 15098, 15099, 15100, 15101, 15102, - 15103, 15104, 15105, 15106, 15107, 15108, 15109, 15110, 15111, 15112, - 15113, 15114, 15115, 15116, 15117, 15118, 15119, 15120, 15121, 15122, - 15123, 15124, 15125, 15126, 15127, 15128, 15129, 15130, 15131, 15132, - 15133, 15134, 15135, 15136, 15137, 15138, 15139, 15140, 15141, 15142, - 15143, 15144, 15145, 15146, 15147, 15148, 15149, 15150, 15151, 15152, - 15153, 15154, 15155, 15156, 15157, 15158, 15159, 15160, 15161, 15162, - 15163, 15164, 15165, 15166, 15167, 15168, 15169, 15170, 15171, 15172, - 15173, 15174, 15175, 15176, 15177, 15178, 15179, 15180, 15181, 15182, - 15183, 15184, 15185, 15186, 15187, 15188, 15189, 15190, 15191, 15192, - 15193, 15194, 15195, 15196, 15197, 15198, 15199, 15200, 15201, 15202, - 15203, 15204, 15205, 15206, 15207, 15208, 15209, 15210, 15211, 15212, - 15213, 15214, 15215, 15216, 15217, 15218, 15219, 15220, 15221, 15222, - 15223, 15224, 15225, 15226, 15227, 15228, 15229, 15230, 15231, 15232, - 15233, 15234, 15235, 15236, 15237, 15238, 15239, 15240, 15241, 15242, - 15243, 15244, 15245, 15246, 15247, 15248, 15249, 15250, 15251, 15252, - 15253, 15254, 15255, 15256, 15257, 15258, 15259, 15260, 15261, 15262, - 15263, 15264, 15265, 15266, 15267, 15268, 15269, 15270, 15271, 15272, - 15273, 15274, 15275, 15276, 15277, 15278, 15279, 15280, 15281, 15282, - 15283, 15284, 15285, 15286, 15287, 15288, 15289, 15290, 15291, 15292, - 15293, 15294, 15295, 15296, 15297, 15298, 15299, 15300, 15301, 15302, - 15303, 15304, 15305, 15306, 15307, 15308, 15309, 15310, 15311, 15312, - 15313, 15314, 15315, 15316, 15317, 15318, 15319, 15320, 15321, 15322, - 15323, 15324, 15325, 15326, 15327, 15328, 15329, 15330, 15331, 15332, - 15333, 15334, 15335, 15336, 15337, 15338, 15339, 15340, 15341, 15342, - 15343, 15344, 15345, 15346, 15347, 15348, 15349, 15350, 15351, 15352, - 15366, 15367, 15368, 15369, 15370, 15371, 15372, 15373, 15374, 15375, - 15376, 15377, 15378, 15379, 15380, 15381, 15382, 15383, 15384, 15385, - 15386, 15387, 15388, 15389, 15390, 15391, 15392, 15393, 15394, 15395, - 15396, 15397, 15398, 15399, 15400, 15401, 15402, 15403, 15404, 15405, - 15406, 15407, 15408, 15409, 15410, 15411, 15412, 15413, 15414, 15415, - 15429, 15430, 15431, 15432, 15433, 15434, 15435, 15436, 15437, 15438, - 15439, 15440, 15441, 15442, 15443, 15444, 15445, 15446, 15447, 15448, - 15449, 15450, 15451, 15461, 15462, 15463, 15464, 15465, 15466, 15467, - 15468, 15469, 15470, 15471, 15472, 15473, 15474, 15475, 15476, 15477, - 15478, 15479, 15480, 15481, 15482, 15483, 15484, 15485, 15486, 15487, - 15488, 15489, 15490, 15491, 15492, 15493, 15494, 15495, 15496, 15497, - 15498, 15499, 15500, 15501, 15502, 15503, 15504, 15505, 15506, 15507, - 15508, 15509, 15510, 15511, 15512, 15513, 15514, 15515, 15516, 15517, - 15518, 15519, 15520, 15521, 15522, 15523, 15524, 15525, 15526, 15527, - 15528, 15529, 15530, 15531, 15532, 15533, 15534, 15535, 15536, 15537 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "IDENT", "FCONST", "SCONST", "BCONST", - "XCONST", "Op", "ICONST", "PARAM", "TYPECAST", "DOT_DOT", "COLON_EQUALS", - "EQUALS_GREATER", "LESS_EQUALS", "GREATER_EQUALS", "NOT_EQUALS", - "ABORT_P", "ABSOLUTE_P", "ACCESS", "ACTION", "ADD_P", "ADMIN", "AFTER", - "AGGREGATE", "ALL", "ALSO", "ALTER", "ALWAYS", "ANALYSE", "ANALYZE", - "AND", "ANY", "ARRAY", "AS", "ASC", "ASSERTION", "ASSIGNMENT", - "ASYMMETRIC", "AT", "ATTACH", "ATTRIBUTE", "AUTHORIZATION", "BACKWARD", - "BEFORE", "BEGIN_P", "BETWEEN", "BIGINT", "BINARY", "BIT", "BOOLEAN_P", - "BOTH", "BY", "CACHE", "CALL", "CALLED", "CASCADE", "CASCADED", "CASE", - "CAST", "CATALOG_P", "CHAIN", "CHAR_P", "CHARACTER", "CHARACTERISTICS", - "CHECK", "CHECKPOINT", "CLASS", "CLOSE", "CLUSTER", "COALESCE", - "COLLATE", "COLLATION", "COLUMN", "COLUMNS", "COMMENT", "COMMENTS", - "COMMIT", "COMMITTED", "CONCURRENTLY", "CONFIGURATION", "CONFLICT", - "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONTENT_P", "CONTINUE_P", - "CONVERSION_P", "COPY", "COST", "CREATE", "CROSS", "CSV", "CUBE", - "CURRENT_P", "CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_ROLE", - "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", - "CURSOR", "CYCLE", "DATA_P", "DATABASE", "DAY_P", "DEALLOCATE", "DEC", - "DECIMAL_P", "DECLARE", "DEFAULT", "DEFAULTS", "DEFERRABLE", "DEFERRED", - "DEFINER", "DELETE_P", "DELIMITER", "DELIMITERS", "DEPENDS", "DESC", - "DETACH", "DICTIONARY", "DISABLE_P", "DISCARD", "DISTINCT", "DO", - "DOCUMENT_P", "DOMAIN_P", "DOUBLE_P", "DROP", "EACH", "ELSE", "ENABLE_P", - "ENCODING", "ENCRYPTED", "END_P", "ENUM_P", "ESCAPE", "EVENT", "EXCEPT", - "EXCLUDE", "EXCLUDING", "EXCLUSIVE", "EXECUTE", "EXISTS", "EXPLAIN", - "EXTENSION", "EXTERNAL", "EXTRACT", "FALSE_P", "FAMILY", "FETCH", - "FILTER", "FIRST_P", "FLOAT_P", "FOLLOWING", "FOR", "FORCE", "FOREIGN", - "FORWARD", "FREEZE", "FROM", "FULL", "FUNCTION", "FUNCTIONS", - "GENERATED", "GLOBAL", "GRANT", "GRANTED", "GREATEST", "GROUP_P", - "GROUPING", "GROUPS", "HANDLER", "HAVING", "HEADER_P", "HOLD", "HOUR_P", - "IDENTITY_P", "IF_P", "ILIKE", "IMMEDIATE", "IMMUTABLE", "IMPLICIT_P", - "IMPORT_P", "IN_P", "INCLUDE", "INCLUDING", "INCREMENT", "INDEX", - "INDEXES", "INHERIT", "INHERITS", "INITIALLY", "INLINE_P", "INNER_P", - "INOUT", "INPUT_P", "INSENSITIVE", "INSERT", "INSTEAD", "INT_P", - "INTEGER", "INTERSECT", "INTERVAL", "INTO", "INVOKER", "IS", "ISNULL", - "ISOLATION", "JOIN", "KEY", "LABEL", "LANGUAGE", "LARGE_P", "LAST_P", - "LATERAL_P", "LEADING", "LEAKPROOF", "LEAST", "LEFT", "LEVEL", "LIKE", - "LIMIT", "LISTEN", "LOAD", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP", - "LOCATION", "LOCK_P", "LOCKED", "LOGGED", "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", "NULLS_P", "NUMERIC", "OBJECT_P", "OF", - "OFF", "OFFSET", "OIDS", "OLD", "ON", "ONLY", "OPERATOR", "OPTION", - "OPTIONS", "OR", "ORDER", "ORDINALITY", "OTHERS", "OUT_P", "OUTER_P", - "OVER", "OVERLAPS", "OVERLAY", "OVERRIDING", "OWNED", "OWNER", - "PARALLEL", "PARSER", "PARTIAL", "PARTITION", "PASSING", "PASSWORD", - "PGPOOL", "PLACING", "PLANS", "POLICY", "POSITION", "PRECEDING", - "PRECISION", "PRESERVE", "PREPARE", "PREPARED", "PRIMARY", "PRIOR", - "PRIVILEGES", "PROCEDURAL", "PROCEDURE", "PROCEDURES", "PROGRAM", - "PUBLICATION", "QUOTE", "RANGE", "READ", "REAL", "REASSIGN", "RECHECK", - "RECURSIVE", "REF", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", - "RELATIVE_P", "RELEASE", "RENAME", "REPEATABLE", "REPLACE", "REPLICA", - "RESET", "RESTART", "RESTRICT", "RETURNING", "RETURNS", "REVOKE", - "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROUTINE", "ROUTINES", "ROW", - "ROWS", "RULE", "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", - "TABLE", "TABLES", "TABLESAMPLE", "TABLESPACE", "TEMP", "TEMPLATE", - "TEMPORARY", "TEXT_P", "THEN", "TIES", "TIME", "TIMESTAMP", "TO", - "TRAILING", "TRANSACTION", "TRANSFORM", "TREAT", "TRIGGER", "TRIM", - "TRUE_P", "TRUNCATE", "TRUSTED", "TYPE_P", "TYPES_P", "UNBOUNDED", - "UNCOMMITTED", "UNENCRYPTED", "UNION", "UNIQUE", "UNKNOWN", "UNLISTEN", - "UNLOGGED", "UNTIL", "UPDATE", "USER", "USING", "VACUUM", "VALID", - "VALIDATE", "VALIDATOR", "VALUE_P", "VALUES", "VARCHAR", "VARIADIC", - "VARYING", "VERBOSE", "VERSION_P", "VIEW", "VIEWS", "VOLATILE", "WHEN", - "WHERE", "WHITESPACE_P", "WINDOW", "WITH", "WITHIN", "WITHOUT", "WORK", - "WRAPPER", "WRITE", "XML_P", "XMLATTRIBUTES", "XMLCONCAT", "XMLELEMENT", - "XMLEXISTS", "XMLFOREST", "XMLNAMESPACES", "XMLPARSE", "XMLPI", - "XMLROOT", "XMLSERIALIZE", "XMLTABLE", "YEAR_P", "YES_P", "ZONE", - "NOT_LA", "NULLS_LA", "WITH_LA", "'<'", "'>'", "'='", "POSTFIXOP", "'+'", - "'-'", "'*'", "'/'", "'%'", "'^'", "UMINUS", "'['", "']'", "'('", "')'", - "'.'", "';'", "','", "':'", "$accept", "stmtblock", "stmtmulti", "stmt", - "CallStmt", "CreateRoleStmt", "opt_with", "OptRoleList", - "AlterOptRoleList", "AlterOptRoleElem", "CreateOptRoleElem", - "CreateUserStmt", "AlterRoleStmt", "opt_in_database", "AlterRoleSetStmt", - "DropRoleStmt", "CreateGroupStmt", "AlterGroupStmt", "add_drop", - "CreateSchemaStmt", "OptSchemaName", "OptSchemaEltList", "schema_stmt", - "VariableSetStmt", "set_rest", "generic_set", "set_rest_more", - "var_name", "var_list", "var_value", "iso_level", - "opt_boolean_or_string", "zone_value", "opt_encoding", - "NonReservedWord_or_Sconst", "VariableResetStmt", "reset_rest", - "generic_reset", "SetResetClause", "FunctionSetResetClause", - "VariableShowStmt", "ConstraintsSetStmt", "constraints_set_list", - "constraints_set_mode", "CheckPointStmt", "DiscardStmt", - "AlterTableStmt", "alter_table_cmds", "partition_cmd", - "index_partition_cmd", "alter_table_cmd", "alter_column_default", - "opt_drop_behavior", "opt_collate_clause", "alter_using", - "replica_identity", "reloptions", "opt_reloptions", "reloption_list", - "reloption_elem", "alter_identity_column_option_list", - "alter_identity_column_option", "PartitionBoundSpec", - "hash_partbound_elem", "hash_partbound", "partbound_datum", - "partbound_datum_list", "range_datum_list", "PartitionRangeDatum", - "AlterCompositeTypeStmt", "alter_type_cmds", "alter_type_cmd", - "ClosePortalStmt", "CopyStmt", "copy_from", "opt_program", - "copy_file_name", "copy_options", "copy_opt_list", "copy_opt_item", - "opt_binary", "opt_oids", "copy_delimiter", "opt_using", - "copy_generic_opt_list", "copy_generic_opt_elem", "copy_generic_opt_arg", - "copy_generic_opt_arg_list", "copy_generic_opt_arg_list_item", - "CreateStmt", "OptTemp", "OptTableElementList", - "OptTypedTableElementList", "TableElementList", "TypedTableElementList", - "TableElement", "TypedTableElement", "columnDef", "columnOptions", - "ColQualList", "ColConstraint", "ColConstraintElem", "generated_when", - "ConstraintAttr", "TableLikeClause", "TableLikeOptionList", - "TableLikeOption", "TableConstraint", "ConstraintElem", "opt_no_inherit", - "opt_column_list", "columnList", "columnElem", "opt_c_include", - "key_match", "ExclusionConstraintList", "ExclusionConstraintElem", - "ExclusionWhereClause", "key_actions", "key_update", "key_delete", - "key_action", "OptInherit", "OptPartitionSpec", "PartitionSpec", - "part_strategy", "part_params", "part_elem", "OptWith", "OnCommitOption", - "OptTableSpace", "OptConsTableSpace", "ExistingIndex", "CreateStatsStmt", - "CreateAsStmt", "create_as_target", "opt_with_data", "CreateMatViewStmt", - "create_mv_target", "OptNoLog", "RefreshMatViewStmt", "CreateSeqStmt", - "AlterSeqStmt", "OptSeqOptList", "OptParenthesizedSeqOptList", - "SeqOptList", "SeqOptElem", "opt_by", "NumericOnly", "NumericOnly_list", - "CreatePLangStmt", "opt_trusted", "handler_name", "opt_inline_handler", - "validator_clause", "opt_validator", "DropPLangStmt", "opt_procedural", - "CreateTableSpaceStmt", "OptTableSpaceOwner", "DropTableSpaceStmt", - "CreateExtensionStmt", "create_extension_opt_list", - "create_extension_opt_item", "AlterExtensionStmt", - "alter_extension_opt_list", "alter_extension_opt_item", - "AlterExtensionContentsStmt", "CreateFdwStmt", "fdw_option", - "fdw_options", "opt_fdw_options", "AlterFdwStmt", - "create_generic_options", "generic_option_list", "alter_generic_options", - "alter_generic_option_list", "alter_generic_option_elem", - "generic_option_elem", "generic_option_name", "generic_option_arg", - "CreateForeignServerStmt", "opt_type", "foreign_server_version", - "opt_foreign_server_version", "AlterForeignServerStmt", - "CreateForeignTableStmt", "AlterForeignTableStmt", - "ImportForeignSchemaStmt", "import_qualification_type", - "import_qualification", "CreateUserMappingStmt", "auth_ident", - "DropUserMappingStmt", "AlterUserMappingStmt", "CreatePolicyStmt", - "AlterPolicyStmt", "RowSecurityOptionalExpr", - "RowSecurityOptionalWithCheck", "RowSecurityDefaultToRole", - "RowSecurityOptionalToRole", "RowSecurityDefaultPermissive", - "RowSecurityDefaultForCmd", "row_security_cmd", "CreateAmStmt", - "CreateTrigStmt", "TriggerActionTime", "TriggerEvents", - "TriggerOneEvent", "TriggerReferencing", "TriggerTransitions", - "TriggerTransition", "TransitionOldOrNew", "TransitionRowOrTable", - "TransitionRelName", "TriggerForSpec", "TriggerForOptEach", - "TriggerForType", "TriggerWhen", "TriggerFuncArgs", "TriggerFuncArg", - "OptConstrFromTable", "ConstraintAttributeSpec", - "ConstraintAttributeElem", "CreateEventTrigStmt", - "event_trigger_when_list", "event_trigger_when_item", - "event_trigger_value_list", "AlterEventTrigStmt", "enable_trigger", - "CreateAssertStmt", "DropAssertStmt", "DefineStmt", "definition", - "def_list", "def_elem", "def_arg", "old_aggr_definition", - "old_aggr_list", "old_aggr_elem", "opt_enum_val_list", "enum_val_list", - "AlterEnumStmt", "opt_if_not_exists", "CreateOpClassStmt", - "opclass_item_list", "opclass_item", "opt_default", "opt_opfamily", - "opclass_purpose", "opt_recheck", "CreateOpFamilyStmt", - "AlterOpFamilyStmt", "opclass_drop_list", "opclass_drop", - "DropOpClassStmt", "DropOpFamilyStmt", "DropOwnedStmt", - "ReassignOwnedStmt", "DropStmt", "drop_type_any_name", "drop_type_name", - "drop_type_name_on_any_name", "any_name_list", "any_name", "attrs", - "type_name_list", "TruncateStmt", "opt_restart_seqs", "CommentStmt", - "comment_type_any_name", "comment_type_name", "comment_text", - "SecLabelStmt", "opt_provider", "security_label_type_any_name", - "security_label_type_name", "security_label", "FetchStmt", "fetch_args", - "from_in", "opt_from_in", "GrantStmt", "RevokeStmt", "privileges", - "privilege_list", "privilege", "privilege_target", "grantee_list", - "grantee", "opt_grant_grant_option", "GrantRoleStmt", "RevokeRoleStmt", - "opt_grant_admin_option", "opt_granted_by", "AlterDefaultPrivilegesStmt", - "DefACLOptionList", "DefACLOption", "DefACLAction", - "defacl_privilege_target", "IndexStmt", "opt_unique", "opt_concurrently", - "opt_index_name", "access_method_clause", "index_params", "index_elem", - "opt_include", "index_including_params", "opt_collate", "opt_class", - "opt_asc_desc", "opt_nulls_order", "CreateFunctionStmt", - "opt_or_replace", "func_args", "func_args_list", - "function_with_argtypes_list", "function_with_argtypes", - "func_args_with_defaults", "func_args_with_defaults_list", "func_arg", - "arg_class", "param_name", "func_return", "func_type", - "func_arg_with_default", "aggr_arg", "aggr_args", "aggr_args_list", - "aggregate_with_argtypes", "aggregate_with_argtypes_list", - "createfunc_opt_list", "common_func_opt_item", "createfunc_opt_item", - "func_as", "transform_type_list", "opt_definition", "table_func_column", - "table_func_column_list", "AlterFunctionStmt", "alterfunc_opt_list", - "opt_restrict", "RemoveFuncStmt", "RemoveAggrStmt", "RemoveOperStmt", - "oper_argtypes", "any_operator", "operator_with_argtypes_list", - "operator_with_argtypes", "DoStmt", "dostmt_opt_list", "dostmt_opt_item", - "CreateCastStmt", "cast_context", "DropCastStmt", "opt_if_exists", - "CreateTransformStmt", "transform_element_list", "DropTransformStmt", - "ReindexStmt", "reindex_target_type", "reindex_target_multitable", - "reindex_option_list", "reindex_option_elem", "AlterTblSpcStmt", - "RenameStmt", "opt_column", "opt_set_data", "AlterObjectDependsStmt", - "AlterObjectSchemaStmt", "AlterOperatorStmt", "operator_def_list", - "operator_def_elem", "operator_def_arg", "AlterOwnerStmt", - "CreatePublicationStmt", "opt_publication_for_tables", - "publication_for_tables", "AlterPublicationStmt", - "CreateSubscriptionStmt", "publication_name_list", - "publication_name_item", "AlterSubscriptionStmt", "DropSubscriptionStmt", - "RuleStmt", "RuleActionList", "RuleActionMulti", "RuleActionStmt", - "RuleActionStmtOrEmpty", "event", "opt_instead", "NotifyStmt", - "notify_payload", "ListenStmt", "UnlistenStmt", "TransactionStmt", - "opt_transaction", "transaction_mode_item", "transaction_mode_list", - "transaction_mode_list_or_empty", "ViewStmt", "opt_check_option", - "LoadStmt", "CreatedbStmt", "createdb_opt_list", "createdb_opt_items", - "createdb_opt_item", "createdb_opt_name", "opt_equal", - "AlterDatabaseStmt", "AlterDatabaseSetStmt", "DropdbStmt", - "AlterCollationStmt", "AlterSystemStmt", "CreateDomainStmt", - "AlterDomainStmt", "opt_as", "AlterTSDictionaryStmt", - "AlterTSConfigurationStmt", "any_with", "CreateConversionStmt", - "ClusterStmt", "cluster_index_specification", "VacuumStmt", - "vacuum_option_list", "vacuum_option_elem", "AnalyzeStmt", - "analyze_option_list", "analyze_option_elem", "analyze_keyword", - "opt_analyze", "opt_verbose", "opt_full", "opt_freeze", "opt_name_list", - "vacuum_relation", "vacuum_relation_list", "opt_vacuum_relation_list", - "ExplainStmt", "ExplainableStmt", "explain_option_list", - "explain_option_elem", "explain_option_name", "explain_option_arg", - "PrepareStmt", "prep_type_clause", "PreparableStmt", "ExecuteStmt", - "execute_param_clause", "DeallocateStmt", "InsertStmt", "insert_target", - "insert_rest", "override_kind", "insert_column_list", - "insert_column_item", "opt_on_conflict", "opt_conf_expr", - "returning_clause", "DeleteStmt", "using_clause", "LockStmt", "opt_lock", - "lock_type", "opt_nowait", "opt_nowait_or_skip", "UpdateStmt", - "set_clause_list", "set_clause", "set_target", "set_target_list", - "DeclareCursorStmt", "cursor_name", "cursor_options", "opt_hold", - "SelectStmt", "select_with_parens", "select_no_parens", "select_clause", - "simple_select", "with_clause", "cte_list", "common_table_expr", - "opt_with_clause", "into_clause", "OptTempTableName", "opt_table", - "all_or_distinct", "distinct_clause", "opt_all_clause", - "opt_sort_clause", "sort_clause", "sortby_list", "sortby", - "select_limit", "opt_select_limit", "limit_clause", "offset_clause", - "select_limit_value", "select_offset_value", "select_fetch_first_value", - "I_or_F_const", "row_or_rows", "first_or_next", "group_clause", - "group_by_list", "group_by_item", "empty_grouping_set", "rollup_clause", - "cube_clause", "grouping_sets_clause", "having_clause", - "for_locking_clause", "opt_for_locking_clause", "for_locking_items", - "for_locking_item", "for_locking_strength", "locked_rels_list", - "values_clause", "from_clause", "from_list", "table_ref", "joined_table", - "alias_clause", "opt_alias_clause", "func_alias_clause", "join_type", - "join_outer", "join_qual", "relation_expr", "relation_expr_list", - "relation_expr_opt_alias", "tablesample_clause", "opt_repeatable_clause", - "func_table", "rowsfrom_item", "rowsfrom_list", "opt_col_def_list", - "opt_ordinality", "where_clause", "where_or_current_clause", - "OptTableFuncElementList", "TableFuncElementList", "TableFuncElement", - "xmltable", "xmltable_column_list", "xmltable_column_el", - "xmltable_column_option_list", "xmltable_column_option_el", - "xml_namespace_list", "xml_namespace_el", "Typename", "opt_array_bounds", - "SimpleTypename", "ConstTypename", "GenericType", "opt_type_modifiers", - "Numeric", "opt_float", "Bit", "ConstBit", "BitWithLength", - "BitWithoutLength", "Character", "ConstCharacter", "CharacterWithLength", - "CharacterWithoutLength", "character", "opt_varying", "ConstDatetime", - "ConstInterval", "opt_timezone", "opt_interval", "interval_second", - "a_expr", "b_expr", "c_expr", "func_application", "func_expr", - "func_expr_windowless", "func_expr_common_subexpr", "xml_root_version", - "opt_xml_root_standalone", "xml_attributes", "xml_attribute_list", - "xml_attribute_el", "document_or_content", "xml_whitespace_option", - "xmlexists_argument", "within_group_clause", "filter_clause", - "window_clause", "window_definition_list", "window_definition", - "over_clause", "window_specification", "opt_existing_window_name", - "opt_partition_clause", "opt_frame_clause", "frame_extent", - "frame_bound", "opt_window_exclusion_clause", "row", "explicit_row", - "implicit_row", "sub_type", "all_Op", "MathOp", "qual_Op", "qual_all_Op", - "subquery_Op", "expr_list", "func_arg_list", "func_arg_expr", - "type_list", "array_expr", "array_expr_list", "extract_list", - "extract_arg", "overlay_list", "overlay_placing", "position_list", - "substr_list", "substr_from", "substr_for", "trim_list", "in_expr", - "case_expr", "when_clause_list", "when_clause", "case_default", - "case_arg", "columnref", "indirection_el", "opt_slice_bound", - "indirection", "opt_indirection", "opt_asymmetric", "opt_target_list", - "target_list", "target_el", "qualified_name_list", "qualified_name", - "name_list", "name", "database_name", "access_method", "attr_name", - "index_name", "file_name", "func_name", "AexprConst", "Iconst", "Sconst", - "SignedIconst", "RoleId", "RoleSpec", "role_list", "ColId", - "type_function_name", "NonReservedWord", "ColLabel", - "unreserved_keyword", "col_name_keyword", "type_func_name_keyword", - "reserved_keyword", YY_NULLPTR -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, - 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, - 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, - 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, - 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, - 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, - 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, - 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, - 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, - 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, - 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, - 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, - 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, - 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, - 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, - 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, - 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, - 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, - 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, - 715, 716, 60, 62, 61, 717, 43, 45, 42, 47, - 37, 94, 718, 91, 93, 40, 41, 46, 59, 44, - 58 -}; -# endif - -#define YYPACT_NINF -4903 - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-4903))) - -#define YYTABLE_NINF -2636 - -#define yytable_value_is_error(Yytable_value) \ - (!!((Yytable_value) == (-2636))) - - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const int yypact[] = -{ - 8413, 43, 15411, -4903, -4903, 43, 60997, -4903, 68749, 466, - 684, 68, 242, 15047, 69205, 76957, 802, 342, 5843, 43, - 76957, 1051, 52333, 66013, 883, 76957, 1219, 1032, 52333, 76957, - 1745, 77413, 1146, 1271, 863, 77869, 69661, 64645, 1065, 76957, - 1403, 391, 78325, 70117, 1337, 70573, 1032, 48713, 344, 1330, - 78781, 76957, 2034, 1901, 1461, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -2, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, 2111, -4903, 1280, 2162, 1708, 825, 1544, -4903, -4903, - -4903, 60997, 76957, 76957, 76957, 1736, 76957, 1550, 76957, 199, - 60997, 56893, 71029, 1823, 1635, 45059, 79237, -4903, 60997, 76957, - 55069, 60997, 76957, 76957, 79693, 76957, 76957, 76957, 1162, 67381, - 76957, 1731, 76957, 76957, 55525, 80149, 1882, 1509, 232, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, 1630, 1746, -4903, 237, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, 76957, 17108, 1219, -4903, - -4903, 2034, 76957, 1932, 60997, 76957, 1704, 80605, 1735, 76957, - -4903, 76957, 1816, 81061, 203, 1802, 56893, 1978, 45516, 1900, - 76957, 76957, 56893, 81517, 81973, 82429, 76957, 76957, -4903, -4903, - 1883, 76957, 76957, -4903, 2003, 57349, 1634, 2025, 2198, 2120, - 1575, -4903, 71485, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, 60085, 342, -4903, -4903, 2092, 61453, 76957, 2158, -4903, - -4903, 82885, 99231, 1942, -4903, 429, 61909, 57805, 2270, 1931, - 45973, 2344, -4903, 62365, -4903, 58261, 62821, -4903, -4903, -4903, - -4903, -4903, 83341, -4903, 83797, 2058, 2158, -4903, 99673, 58717, - -4903, 2207, 84253, 84709, 85165, -4903, 1975, 1446, 1796, 40922, - -4903, -4903, -4903, 466, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, 306, 1088, 212, 207, 222, -4903, -4903, 215, - 220, 223, 306, 2459, 2459, -4903, 76957, -4903, -4903, 1088, - 600, 2012, 2012, 2012, 2212, 4, -4903, 2012, 2148, -4903, - -4903, -4903, -4903, 70573, -4903, 2033, 71941, 76957, 72397, 1219, - 2048, 2486, 2121, -4903, -4903, -4903, -4903, -4903, 2134, 76957, - 76957, 76957, -4903, -4903, 2533, 2139, 2392, 2141, -4903, -4903, - -4903, 2347, 2354, 2358, 115, 1219, 2246, -4903, 2480, -4903, - 2382, 27839, 27839, 1219, 72853, 85621, 209, 60085, 1219, 73309, - 2200, 955, 2390, -4903, -4903, -4903, 518, -4903, 2639, 2230, - 2493, 2141, 1509, 42298, -4903, 2265, 1746, 70573, -4903, -4903, - -4903, 358, 2550, 29731, 76957, 2240, -4903, 2266, 2240, 2275, - 2282, 1708, -4903, 8413, 2317, 76957, 997, 997, 2711, 997, - 1524, 1909, -4903, 2538, -4903, 2618, 2595, 70573, 2335, 1552, - 2336, 1281, 2338, 1597, 1235, -4903, -4903, 253, 76957, 267, - 2391, 73765, 5281, 2352, 1746, 2370, -4903, -4903, -4903, 2527, - 964, -4903, -4903, -4903, -4903, 2668, 2713, 7860, 324, 74221, - -4903, -4903, -4903, -4903, 76957, 76957, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, 2416, 136, -4903, -4903, 2380, - 2750, 2646, 6047, 1449, 2729, 2598, 1409, 11770, 2666, 1543, - 2802, 7376, 1842, 1829, 1533, 71941, 76957, 2769, 2813, 8244, - 1815, 780, 2691, 1022, 2729, 2804, 2641, 1409, 2820, 3103, - 76957, -4903, 2744, 2854, 104, -4903, 111, -4903, 22721, 29731, - 48257, -4903, 1746, 2553, 2704, 908, 2735, 60997, 2503, -4903, - -4903, 76957, -4903, -4903,100115, 2585, -4903, 479, 60997, -4903, - 2738, 2571, 46430, 76957, 60997, -4903, -4903, 60997, 76957, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, 2656, 2846, 76957,100115, - -4903, 2791, 76957, 76957, -4903, 2531, -4903, -4903, -4903, -4903, - 2012, 76957, 2534, 2942,100115, 2757, 144, 76957, 1139, 2977, - 76957, 2760, 1139, 2580, 86077, -4903, -4903, 1139, -4903, -4903, - -4903, 76957, 76957, 2548, 1460, 2756, 2868, 1139, 2773, 2986, - 2991, 2789, 2638, 2794, 2266, 2972, 2771, 967, 328, 244, - 1721, 1139, 2627, 86533, 86989, 76957, 2629, 76957, 2985, 60997, - 60997, 76957, 2905, -4903, 2762, -4903, -4903, 1518, -4903, -4903, - -4903, -4903, -4903, 2922, -4903, 226, 259, 2924, 2597, 2927, - -4903, -4903, -4903, 2647, -4903, 2647, 2647, 2599, 2599, 2778, - 2603, 2933, -4903, -4903, -4903, 2192, 2647, 2599, -4903,100999, - -4903, -7, 1643, -4903, 255, -4903, 3046, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, 2607, -4903, 837, 1835, -4903, - -4903, 2643, -4903, 2937, 279, -4903, 2941, -4903, 2609, 87445, - -4903, 87901, 88357, 2943, 300, -4903, 56893, 2947, 279, 2948, - 2609, 2949, 279, 2953, 259, 2957, -4903, 1023, 2951, 2959, - 255, 2960, 1913, 2609, 60541, 2961, 302, -4903, 2964, 320, - -4903, 2965, 2844, 29731, -4903, 2731, -4903, 1330, -4903, -23, - -4903, 51421, -4903, 1796, 1088, -4903, 76957, 1088, 76957, 1088, - 76957, 1088, 76957, 1088, 76957, 76957, 76957, 1088, -4903, -4903, - -4903, 76957, 2642, 76957, 76957, -4903, -4903, -4903, 66469, 56893, - 66925, -4903, 76957, -4903, 386, 1219, -4903, -4903, -4903, 1267, - -4903, 2141, -4903,100115, 3081, 56893, 2985, -4903, 1760, -4903, - -4903, -4903, -4903, -4903, -4903, 2896, 76957, 2966, 2970, 66469, - 56893, -4903, 88813, 60085, 2853, 2648, -4903, -4903, -4903, -4903, - -4903, 1795, 3124, 238, 3125, 29731, 2657, 238, 238, 2659, - 2979, -4903, -4903, -4903, 252, 2660, 2663, -4903, 239, 239, - -4903, 2665, 2671, -4903, 250, 2673, 2674, 3136, 3138, 251, - 2675, 2676, 2679, 2192, 238, 29731, -4903, 2681, 239, 2682, - 2684, 2685, 3156, 2694, -4903, 3161, 2695, 257, 269, 2696, - 2700, -4903, 2665, -4903, 254, 2701, 2703, 2705, 2706, 2707, - 2709, 2710, 2712, 29731, 29731, 29731, -4903, 26420, 1746, 1219, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, 256, 6084, - -4903, 2747, -4903, -4903, 2907, -4903, -4903, 29731, -4903, -4903, - 107, -4903, 258, -4903, -4903, -4903, 1746, 2982, 2714, -4903, - -4903, 315, 2717, -4903, 1924, -4903, -4903, -4903, -4903, -4903, - -4903, 59173, 3155, -4903, 293, 1219, 111, 1703, 3096, 50509, - 50965, -4903, -4903, 2975, -4903, 76957, -4903, -4903, 1746, 245, - -4903, -4903, -4903, -4903, 1843, -4903, -4903, -4903, 466, 15042, - 1880, 2240, 76957, 76957, 3164, -4903, -4903, -4903, -4903, 1897, - -4903, -4903, 2721, -4903, 2266, -4903, -4903, 1708, 1708, 29731, - 1708, 1066, 1844, 28312, 30204, 3043, 2938, 1151, 1472, 3047, - -4903, 2944, 1524, 1909, 70573, 76957, 89269, 2850, 29731, 2815, - 2818, 2865, 49625, -4903, 2821, 2790, 2823, 2877, 53245, 2758, - 2837, 2845, 2880, -4903, 3022, -4903, -4903, 2856, 2921, 2860, - 89725, -4903, -4903, 927, -4903, -4903, -4903, 927, -4903, 2801, - 195, 783, 1440, 2862, 340, 211, 3183, -4903, 867, -4903, - -4903, 2931, -4903, 6606, 76957, 3130, 9143, 3008, 324, 3009, - 2930, -4903, -4903, 3060, 2886, 76957, 2889, 3029, 324, 287, - 90181, -4903, -4903, -4903, -4903, -4903, -4903, 7729, 25535, -4903, - 1957, 2897, 2876, 2908, 76957, 63733, 2122, 3010, 3028, 3032, - 1445, 2125, 589, 2962, 76957, 1650, 3040, 76957, 2832, 2914, - 2915, 3133, 2840, 1313, 3232, 2838, -4903, -4903, -4903, -4903, - 1884, 1949, 3037, -4903, 3140, 3177, 3098, 2917, 2919, 97905, - -4903, 2945, 775, 46887, 76957, 76957, 3071, 2946, 2950, 90637, - 7729, 2963, 2974, 2958, 2968, 743, 3237, 1482, 2973, -4903, - -4903, -4903, 1482, 3075, 2976, 2978, 91093, 7729, 76957, 2981, - 2984, 76957,100999, 324, -4903, 3306, 324, 324, 1920, 3307, - 2989, 301, 3116, 1485, 1139, 2838, 3723, -4903, 2993, 2995, - 313, -4903, 3097, 2996, 2997, 3031, 1219, -4903, -4903, 2998, - 3070, 2999, 54, -4903, -4903, 2994, 70573, 3107, 3108, 196, - 2016, 2838, -4903, 3003, 3004, 2840, 2840, 76957, 76957, 76957, - 76957, 76957, 210, 3345, 3360, 3007, 216, 3063, 2929, -4903, - 1482, 55981, 3013, -4903, 1482, 76957, 3014, 2129, 2838, 1663, - 1602, -4903, -4903, -4903, 1509, -4903, 29731, 29731, 29731, 2935, - -4903, 2402, 15042, 73, -4903, 280, 11525, 2932, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, 76957, -4903, 76957, -4903, 3204,100115, - 3145, 3206, -4903, 2987, -4903, 3208, 324, -4903, 76957, 76957, - 3211, 3154, 3215, 3219, 3163, 1160,100115, 3165, 3224, -4903, - 3227, 3229, 3044, 3001, 3035, 50067, -4903, 2548, 2967, 3408, - 3298, 76957, 53245, -4903, 3424, 927, -4903,100115, 3187, 3313, - -4903, 76957, 3207, 61, -4903, 3350, 3045, -4903, -4903, 641, - 76957, 277, 3025, -4903, -4903, 3319, 56893, 325, 3321, 1219, - 3038, 3323, 3201, 1219, 56893, 3240, 76957, 76957, 76957, 76957, - -4903, -4903, 3209, 907, 156, -4903, 55981, 3221, -4903, 76957, - 3222, 3723, 3226, 3443, 62, 2012, 91549, 3328, -4903, 92005, - 3006, 3006, 3452,100115, 3283, -4903, 1951, -4903, 3153, -4903, - 60997, -4903, -4903, 60997, -4903, -4903, -4903,100115, 76957, -4903, - 3033, -4903, -4903, 29731, -4903, -4903, -4903, 2459, -4903,100115, - 2647, 2647, -4903, -4903, 3466, 3109, 3110, 2459, -4903, 2459, - -4903,100115, -4903, 3034, 3036, 2459, 3114, 3117, 3118, -4903, - 3041, 3121, 2459, -4903, -4903, 1958, -4903, -4903, 60997, 60997, - -4903, 56893, 56893, 3366, 302, 3377, 3105, 3380, 3112, 46887, - 46887, -4903, 322, 60997, -4903, 56893, 60997, -4903, 76957, -4903, - 76957, -4903, -4903, -4903, -4903,100115,100115, -4903, 56893, 55981, - 3383, 3387, 259, 76957, 76957, -4903, 76957, 76957, -4903, 76957, - 76957, 1922, 92461, 1796, 59629, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, 76957, -4903, 76957, -4903, 76957, -4903, 76957, - -4903, 76957, -4903, -4903, -4903, 76957, -4903, 76957, 1923, -4903, - -4903, 1928, 1136, 76957, 76957, 204, 60997, 76957, 3271, 60997, - 60997, 76957, 76957, 76957, 76957, 76957, 3139, 2717, 8, -4903, - 1404, 494, 70573, 3278, -4903, -4903, 1938, 2034, 1090, 76957, - 1043, 2134, -4903, -4903, 66925, 66013, 3374, 363, 76957, -4903, - -4903, 6097, 29731, 1746, 27366, -4903, -4903, 15042, 3104, 29731, - 29731, 3065, 2459, 2459, -4903, 830, 29731, 29731, 29731, 2459, - 2459, 7836, 29731, 46887, 29731, 34934, 23669, 29731, 29731, 26893, - -4903, 29731, 3297, 36341, 29731, 1703, 3301, 29731, 1703, 7836, - 3532, 3532, 1192, 6383, 3068, 1746, -4903, 2459, 179, -4903, - 443,100115, 29731, 29731, 29731, 29731, 53245, 3157, 221, 76957, - 29731, 3073, 1707, -4903, 29731, -4903, 3077, 29731, 3159, 1041, - 29731, 29731, 29731, 29731, 29731, 29731, 29731, 29731, 29731, -4903, - 37715, 449, 3381, 3403, 657, 420, 74677, 27839, 3396, 22721, - -4903, 231, 3396, -4903, -4903, -4903, 76957, 3155, -4903, -4903, - 3162, -4903, -4903, -4903, -4903, -4903, 282, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, 3082, -4903, -4903, -4903, -4903, 3082, - -4903, 3086, 3391, 3392, 259, 76957, 358, 2324, -4903, 29731, - -4903, 1948, 3092, 76957, 2317, 76957, -4903, 3368, -4903, 3100, - -4903, 12035, 3368, -4903, -4903, 35401, 3217, 3367, 3316, -4903, - -4903, -4903, 3111, 15042, 30677, 30677, -4903, 2135, 15042, 2178, - -4903, -4903, -4903, -4903, -4903, -4903, 1352, -4903, 76957, 1089, - 3043, 1472, 3168, 847, 3553, 76957, -4903, 42756, 1950, 56893, - 76957, 76957, 3311, -4903, 3538, -4903,100999, -4903, 3119, -4903, - 100557, 96565, -4903, -4903, 853, -4903, 1019, 56893, -4903, 76957, - 76957, -4903, 53245, 56893, 76957, 76957, -4903, 56893, 76957, 76957, - -4903, -4903, -4903, -4903, -4903, 51877, 60, 66013, 3250, 65101, - -4903, -4903, 3122, 76957, 3179, 3386, 3388, -11, -4903, -4903, - 92917, -4903, 3341, 56893, 76957, 76957, 29731, 3343, 76957, 76957, - -4903, 547, 3210, 3212, -4903, 76957, 3228, 3365, 60997, 3132, - 76957, 76957,100115, 3225, 493, 60997, 3191, 47344, 60997, 60997, - 76957, 76957, 76957, 76957, 3276, 3469,100115, 76957, 3414, 1393, - 70573, 275, 2361, 2838, 3371, -4903, 3490, 878, -4903, 56893, - -4903, 76957, 3373, -4903, -4903, -4903, 75133, 3601, 3281, -4903, - -4903, 93373, -4903, -4903, -4903, 1960, -4903, 56893, 56893, 76957, - 9167, 93829, 989, 3395, -4903, -4903,100115, -4903, 76957, 75589, - 76957, 76957, 3502, 3428, 76957, 67837, 94285, 94741, 1114, 1353, - 3430, 76957, 68293, 3433, -4903, 3317, 76957, -4903, -4903, 53701, - 56893, 76957, 810, 53245, -4903, -4903, 76957, -4903, 3397, 336, - -4903, 76957, 10140, -4903, -4903, 3263, 3279, 76957, 3400, 412, - 2443, 2838, 76957, 76957, 3186, 1972, 56893, 76957, 53245, -4903, - 3402, 1382, 3525, 56893, 76957, 75133, -4903, 70573, 70573, 56893, - 76957, 70573, -4903, 76957, 85621, -4903, 56893, 1266, -4903, 3526, - 56893, 76957, 75133, -4903, 3351, 56893, 76957, 10145, -4903, -4903, - -4903, 324, -4903, -4903, -4903, -4903, -4903, 76957, 76957, 324, - 76957, 76957, 324, 1389, -4903, 56893, 76957, -4903, -4903, -4903, - 56893, 76957, 76957, -4903, 56893, 3025, 76957, 53245, -4903, 76957, - 8921, 76957, 76957, 76957, 76957, 76957, 76957, 56893, 76957, -4903, - -4903, 1122, 1232, 113, 1408, 777, 76957, 3495, 76957, 95197, - 56893, 76957, 76957, 1219, 76957, 369, -4903, -4903, 3324, -4903, - 56893, 1266, -4903, 9497, 76957, 76957, 3284, 3285, 240, 3370, - -4903, -4903, -4903, 85, 85, 3404, -4903, 29731, 29731, 28785, - 3214, -4903, -4903, 29731, -4903, -4903, -4903, 334, 3642, 95653, - 334, -4903, 334, 3474, 3265, 3266, 334, 76957, 334, 334, - 76957, -4903, -4903, -4903, -4903, 3471, 76957, 334, 334, 334, - 3384, 3421, 157, 3500, 3230, 1976, -4903, -4903, 29731,100115, - 76957, -4903, 1981, -4903, 3231, 907, -4903, -4903, 53245, 76957, - 161, 785, 3550, 3435, 64189, 2726, 3539, 76957, 3275, 76957, - 3672, 3325, 70573, 2548, -4903, 2726, 76957, -4903, 1008, 66013, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, 76957, -4903, -4903, - 3549, 76957, 29731, 3405, -4903, 1219, 2548, 2548, 2548, 2548, - -4903, -4903, -4903, -4903, 3447, 1866, -4903, 3238, 2548, 76957, - 3358, 3569, 2726, 3242, 3572, -4903, 3723, 3574, 1417, 76957, - 3457, 64189, 2006, 3287, 3468, 3691, 2012, 1219, 3476, 3462, - -4903, 25977, 7219, 7685, 3463, 3518, 60085, 3557, 3560, 3583, - -4903, 226, -4903, 3707, -4903, 29731, 2007, 3267, 255, -4903, - -4903, 3272, 3036, 3288, 3289, 3273, 3274, -4903, 2459, 217, - 3277, 1094, 731, 3406, 2459, 3505, 3280, -4903, 279, -4903, - 2609, -4903, 76957, -4903, 76957, 76957, 76957, 76957, 300, -4903, - -4903, 279, 2609, 279, 259, -4903, 3536, 255, 2609, 3398, - 3597, 60085, -4903, 302, -4903, 320, -4903, 3488, 259, -4903, - 3507, 2012, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - 2009, -4903, 76957, -4903, 3578, 3582, 3584, 3585, 3586, 3291, - 3295, 3333, 76957, 3299, 3291, 324, 3299, 3299, 3291, 2717, - 2717, 3291, 3295, 56437, 3736, 3606, -4903, 3385, 3304, 3620, - 181, -4903, 185, 957, 3542, -4903, -4903, -4903, -4903,100115, - -4903, 56893, 3347, 76957, 76957, -4903, 208, 3519, 3308, 56437, - 3737, 259, -4903, 60997, -4903, -4903,100115, 3393, 3409, 60997, - 3529, 3364, 60997, -4903, -4903, 60997, -4903, -4903, -4903, -4903, - -4903,100115, -4903, 3581, 76957, 76957, 2018, -4903, -4903, 1681, - -4903, 1784, 29731, 167, -4903, 13215, 2028, 29731, 3326, 3329, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, 3330, 3626, -4903, - 2032, 2038, 2059, 3331, 3332, 3809, 3334, 13359, 3335, 3322, - 34934, 34934, 26420, 2513, -4903, 34934, 3336, 3520, 2061, 12399, - 3320, 3337, 13898, 29258, 29731, 29258, 29258, 14047, 3320, 3338, - 2069, 53245, 3531, 14165, 2070, -4903, 29731, 53245, 5858, 29731, - -4903, 29731, 3340, -4903, -4903, 5016, 5016, 5016, 7836, -4903, - 3361, -4903, 34934, 34934, -4903, 3166, 26420, -4903, -4903, 3646, - -4903, -4903, 1698, -4903, 3354, -4903, -4903, 3234, 46887, 10637, - 29731, 262, 29731, 3073, 29731, 3426, 5016, 5016, 5016, 431, - 431, 295, 295, 295, 1970, 420, -4903, -4903, -4903, 3355, - 3357, 3369, 3555, 3375, 29731, -4903, 2279, 2290, 76957, 2852, - 2928, 4641, -4903, -4903, -4903, 38632, 3401, 73, 3401, -4903, - 1509, 2459, 179, 51421, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, 76957, 15042, -4903, 2034, -4903, -4903, -4903, 29731, -4903, - -4903, 551, 3379, 75, 3570, 2273, 2273, 2135, 3576, -4903, - -4903, 3425, -4903, 29731, 2242, -4903, 2247, -4903, -4903, -4903, - -4903, 2717, -4903, 3619, -4903, -4903, -4903, 38632, 3419, 3432, - 1341, 41839, 3589, -4903, 76957, -4903, 76957, 298, -4903, 3399, - -4903, -4903, -4903, -4903, -4903, -4903, 96565, 1835, -4903,100557, - -4903,100557, -4903, 1835, 3806, -4903, 96565, 1738, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, 56893, 56893, 3591, 76957, 3593, 3592, 29731, 419, 76957, - 3394, 3407, 1470, 3675, 76957, -4903, 3721, 259, -4903, -4903, - 3477, -4903, 15042, -4903, -4903, -4903, -4903, -4903, 56893, 76957, - -4903, 60085, -4903, 76957, -4903,100115, -4903, -4903, -4903, 76957, - 3434, 76957, -4903, 76957, 76957, 76957, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, 1175,100115, -4903, -4903, 76957, 76957, 710, - 3479, 3481, 76957, -4903, 152, 3097, 9809, 76957, 76957, 76957, - 3671, 76957, -4903, -4903, -4903, -4903, 3621, -4903, -4903, 96565, - -4903, 2609, 948, 3483, 2838, 3634, -4903, 3741, 3616, -4903, - 3537, 1269, -4903, -4903, 76957, 3546, -4903, -4903, -4903, -4903, - 3750, 259, 3752, 259, 76957, 76957, 76957, 76957, 3551, -4903, - -4903, -4903, -4903, 3552, 3676, -4903, 53245, 53245, 53245, 2071, - -4903, -4903, 1219, -4903, -4903, -4903, -4903, -4903, -4903, 3711, - -4903, 2082, -4903, -15, -4903, -4903, -4903, -4903, -4903, -4903, - 56893, 76957, 11129, 3755, 76957, 76957, 76957, 1846, -4903, 1462, - 100115, -4903, 98347, -4903, -4903, 2083, -4903, 3440, 76957, 3509, - 56893, 3487, 76957, -4903, -4903, -4903, 3429, 3429, -4903, -4903, - 3429, -4903, -4903, -4903, 3685, 3627, -4903, 861, 3628, 56893, - 3496, -4903, 76957, -4903, -4903, -4903, 3528, -4903, -4903, 3530, - 2626, 2838, 3723, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, 961, -4903, - -4903, 1145, 427, 2727, 2838, -4903, 1478, -4903, 3533, -4903, - 3534, -4903, -4903, -4903, 3687, 3702, 3704, 3544, 3545, 3598, - 3547, 3554, 3602, -4903, 3556, 3603, 3558, 3604, 3682, 3559, - 259,100115, 3699, 1219, 3599, 3811, 259, -4903, 3562, -4903, - 3563, -4903, 3918, -4903, 76957, -4903, 3571, 2808, 2838, -4903, - -4903, 56893, 76957, -4903, -4903, -4903, 29731, 3492, 3493, 3494, - 15042, 15042, 29731, -4903, -4903, 15042, 3497, -4903, -4903, -4903, - 100115, 76957, 3757, -4903, -4903, 334, 76957, 76957, -4903, 3765, - -4903, -4903, 3767, 76957, 3768, -4903, -4903, -4903, -4903, 446, - -4903, -4903, -4903, 3384, 3803, 44133, -4903, 3976, 6462, 3504, - 289, -4903, 53245, 44133, 2044, 1439, 154, 1139, -4903, 60085, - 76957, 60085, -4903, 785, 3616, 76957, 76957, 76957, 3506, 3508, - -4903, -4903, -4903, -4903, 56893, 190, 56893, 2459, -4903, -4903, - 3575, -4903, 76957, 2012, 3980, 3827, -4903, 3429, -4903, 3945, - 2991, 325, 3666, 1737, 2638, 3888, 2266, 317, 53245, 3287, - -4903, -4903, -4903, -4903, 76957, 76957, 907, 1219, -4903, 3521, - 3516, -4903, 76957, 3843, 76957, 76957, 76957, 76957, 3347, 3527, - 76957, 3548,100115, 64, 3743, 3734, 2840, 3977, 3867, 2034, - 3287, 3625, 3869, 70573, -4903, 2089, 169, -4903, 1219, 60085, - 97463, 3865, -4903, 7685, -4903, -4903, 7685, 940, 76957, 3850, - -4903, -4903, 2034, -4903,100115, 2095, -4903, -4903, -4903, 2459, - -4903, -4903, -4, -4, 3561, -4903, 3564, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, 3565, -4903, -4903, -4903, 302, 3607, - 259, 3608, 259, -4903, -4903, -4903, -4903, 76957, -4903, 76957, - 55981, 259, -4903, -4903, 76957, -4903, 3882, -4903, -4903, 3686, - 3688, 3690, 3692, 3693, 76957, 3291, -4903, 3566, 56893, 1100, - -4903, -4903, 3759, -4903, -4903, 70573, 3689, -4903, -4903, -4903, - -4903, 3885, 3895, -4903, -4903, -4903, 271, -4903, -4903, -4903, - 56893, 66469, 323, 56893, -4903, 3831, 3833, -4903, -4903, 3835, - 324, -4903, 3838, 3839, 3840, -4903, 3841, 3842, -4903, -4903, - -4903, 3580, 14397, 29731, -4903, 3921,100115, -4903, 6648, -4903, - -4903, -4903, 29731, -4903, -4903, -4903, -4903, -4903, 29731, -4903, - 29731, 3891, -4903, 24143, 4044, 4044, 3588,100115, 34934, 34934, - 34934, 34934, 1632, 2682, 34934, 34934, 34934, 34934, 34934, 34934, - 34934, 34934, 34934, 35874, 480, -4903, 3778, 29731, 29731, 3902, - 3891, -4903,100115, 3594, 3320, 3595, 3596, 29731, -4903, -4903, - 2099, 36799, 3609, 53245, -4903, 29731, 12735, 2113, 3632, 14701, - 1746, 6951, 1219, 29731, 2569, 2583, 29731, 2114, 29731, 3906, - -4903, -4903, -4903, 3590, -4903, -4903,100115, 29731, 3610, 4104, - 34934, 34934, 4657, -4903, 5132, 29731, 26420, -4903, 3404, 3640, - 43214, -4903, 24617, 3600, 1032, 1032, 1032, 1032, -4903, 76957, - 76957, 76957, 39090, 3915, 3629, 38173, 76045, 3622, 1925, -4903, - 76045, 76501, 76045, -4903, 3641, -4903, 1746, 29731, 3933, 3630, - 3933, 111, 3638, -4903, -4903, -4903, 3643, -4903, 3635, -4903, - 3379, 921, -4903, -4903, -4903, 3846, -4903, -4903, -4903, -4903, - 3622, 31150, 3777, -4903, -4903, -4903, 3694, 2126, -4903, -4903, - 4027, 3777, -4903, -4903, 2138, 42756, 3419, 29731, 1746, 2165, - 1803, -4903, -4903, 96565, -4903, 3714, 2609, 2609, 1793, 3291, - 3965, 1793, 6985, -4903, -4903, 39548, 76957, 76957, -4903, 76957, - 2171, 1661, 76957, -4903, 76957, -4903, -4903, -4903, -4903, 4089, - -4903, 76957, -4903, -4903, 3706, 3708, 76957, 76957, 76957, 76957, - 3913, -4903, -4903, 2338, -4903, -4903, 56893, 76957, -4903, -4903, - -4903, 430, 2828, 2838, -4903, 3735, -4903, -4903, -4903, 3934, - -4903, 4081, 3748, 76957, 3990, 76957, 3662, -4903, 1661, 3769, - 3971, 1081, 2840, 301, 4264, -4903, 1576, -4903, -4903, 3739, - -4903, -4903, 76957, -4903, 76957, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, 3800, -4903, -4903, -4903, -4903, 53701, -4903, -4903, - 76957, -4903, 53245, 44133, 53245, -4903, 1405, 442, 2911, 2838, - 76957, -4903, 3751, -4903, 3754, 3756, 3812, 949, 1260, 3761, - 3762, 3816, 3679, 3696, 3697, -4903, 53245, 44602, 3837, 76957, - 2609, 3695, 3724, -4903, 306, 1219, -4903, -4903, 1219, 2609, - 1219, -4903, 76957, 76957, 76957, 53245, -4903, 4111, 3781, 76957, - 76957, 76957, 76957, -4903, 3740, -4903, 76957, 76957, 4011, 243, - 2004, 56893, 76957, 76957, 56893, 76957, 76957, 76957, 76957, 76957, - 76957, 4026, 76957, -4903, 4103, 4032, 1985, 4075, 3775, 76957, - -4903, 76957, 1219, 3097, 76957, 76957, -4903, -4903, -4903, -4903, - -4903, 3404, -4903, 3709, 3973, 334, -4903, 3974, 3975, 334, - 334, 3981, 334, -4903, -4903, 1139, -4903, 446, 76957, -4903, - 3635, 1884, 1949, -4903, -4903, -4903, -4903, -4903, -4903, 3230, - -4903, -4903, 2333, 76957, -4903, -4903, -4903, 76957, 3716, 76957, - 76957, 34934, -4903, 1578, 1056, 797, -4903, 3979, 76957, 3025, - -4903, -4903, -4903, 3883, 76957, -4903, -4903, -4903, -4903, -4903, - 619, 3527, -4903, 3999, 64189, 2609, 56893, 56893, 2609, -4903, - 100115, 3719, 3287, -4903, 522, 3799, 56893, 325, 1616, 96109, - 3038, 3760, 3928, 38632, 961, -4903, 3720, 3879, -4903, 3725, - 3726, -4903, -4903, 76957, 3616, 55981, 2173, 3723, 4168, 632, - 1975, -4903, 65557, 3919, 3527, 3999, -4903, -4903, -4903, 4132, - 3824, -4903, 2034, 76957, 3347, 3824, 1219, 76957, 3179, -4903, - 96565, 29731, 29731, -4903, 3733, -4903, 3738, 7685, -4903, 3808, - 3742, -4903, -4903, -4903, -4903, -4903, 3819, 3744, 76957, -4903, - 3746, -4903, 3749, -4903, -4903, -4903, -4903, -4903, -4903, 76957, - -4903, 76957, -4903, 259, -4903, 3862, -4903, 259, 76957, 76957, - 76957, 76957, 76957, 76957, 3291, 324, -4903, 4048, 56437, -4903, - -4903, 2180, 76957, -4903, -4903, -4903, 4119, 363, 4062, -4903, - -4903, 923, 923, 923, 4017, 923, 923, 923, 923, 923, - -4903, 29731, 15042, -4903, 3753, -4903, 15042, 7455, 15042, 3902, - -4903, 2184, 29731, -4903, 2463, 2463, 2463, 3875, 4064, -4903, - 1296, 3758, 2463, 2463, 2463, 495, 495, 205, 205, 205, - 4044, 480, 15042, 15042, -4903, -4903, 3764, -4903, -4903, -4903, - 3320, -4903, 31623, 3911, 4178, -4903, -4903, -4903, 3796, 3801, - 3766, -4903, 29731, 32096, 3771,100999, 3953, -4903, 418, 29731, - 29731, 4254, -4903, 8143, 29731,100115, 2195, 4254, 463, 29731, - 3147, 3917, 29731, 29731, 5357, 7765, 3770, 29731, 97007, -4903, - -4903, -4903, 2210, 29731, 76957, 76957, 76957, 76957, -4903, -4903, - -4903, 76045, 76501, 76045, 3763, 37257, 25076, 1925, 3776, 76957, - -4903, -4903, 3772, 38632, 4024, 3962, -4903, 38632, 3962, 1549, - 3962, 4033, 3858, 43672, -4903, -4903, 3779, -4903, 3982, -4903, - 1957, 15042, 4198, 4077, 1219, 4077, 1219, -4903, 46887, -4903, - -4903, -4903, -4903, 3991, 15042, 27839, -4903, 2034, 2182, 76957, - 1746, 65, -4903, 3792, 76957, -4903, 3777, 15042, -4903, 3851, - 2214, -4903, -4903, -4903, -4903, -4903, -4903, -4903, 3863, 66013, - 4097, -4903, 29731, 2216, -4903, 3826, 4194, 168, 2222, 2223, - 1661, -4903, 4082, -4903, 1290, 4076, 278, -4903, 259, -4903, - 100115, -4903, 76957, 76957, -4903, -4903, -4903, -4903, 76957, 2758, - -4903, -4903, 76957, 76957, 76957, 76957, -4903, 56893, 76957, -4903, - 76957, -4903, 53245, 1439, 306, 1578, 4093, 4022, -4903, 324, - -4903, 1578, 4023, 306, 76957, -4903, -4903, 3633, -4903,100115, - 259, 259, -4903, -4903, -4903, -4903, -4903, 3820, 4230, 3898, - 76957, 76957, 76957, -4903, 76957, 56893, 76957, 76957, 2459, 2459, - 100115, 3813, -4903, 2459, 2459, 3814, -4903, 56893, 76957, 76957, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, 3894, -4903, 29731, 4221, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, 56893, 76957, 3900, -4903, 3901, -4903, - 915, -4903, -4903, 76957, 76957, 76957, 76957, 4152, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -4903, 76957, -4903, - 76957, -4903, -4903, 1219, 1219,100115, 259, 259, -4903, -4903, - -4903, -4903, 3830, 4091, 334, -4903, 334, 334, -4903, -4903, - 334, -4903, 3832, 425, -4903, 1661, 274, 4143, -4903, 4146, - 29731, -4903, 1113, 3875, -4903, 4200, 4275, -4903, -4903, -4903, - -4903, 3025, 2012, 3896, 60997, 379, -4903, 4126, 161, 4050, - 64189, 1478, 1250, 3844, 3966, -4903, 2609, 2609, 3897, 76957, - 4286, -4903, -4903, -4903, -4903, -4903, -4903, 56893, 3487, -4903, - 4068, 851, 4163, 76957, 29731, 3622, -4903, 795, 4166, -4903, - 1219, -4903, -4903, 3978, 3287, -4903, 2034, 76957, 4063, 64189, - 3347, 2232, -4903, -4903, -4903, 3892, 4276, 2006, -4903, 1478, - 3919, 1135, 76957, -4903, 3893, 4298, -4903, -4903, 4172, 4067, - 3874, -4903, 15042, 15042, 1219,101441, 7685,100115, 4182, 76957, - 729, 4155, 259, -4903, 259, 259, -4903, 76957, -4903, 3291, - 3291, 3291, 3291, 3291, -4903, 4080, -4903, -4903, 4148, -4903, - 259, 56437, -4903, -4903, -4903, -4903, -4903, 923, -4903, -4903, - -4903, -4903, -4903, 15042, -4903, -4903, -4903, -4903, 8907, 34934, - 4190, -4903, 3881,100115, -4903, 3884, 2244, 2245, 36341, 4040, - -4903, -4903, -4903, 8987, 3936, 15042, 3988, 3886, 3889, 4254, - 4254, 8143, 2249, -4903, 4254, 29731, 29731, 4254, 4254, 29731, - -4903, -4903, 9340, 4072, -4903, -4903, 9458, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, 54157, 3899, 3531, 76045, 3907, 76957, - 1925, 38632, -4903, -4903, 2197, -4903, 38632, 4154, -4903, 38632, - 60997, -4903, 76957, 3914, 76957, -4903, 32569, 29731, 3927, -4903, - 3927, -4903, 3916, 76957, 2714, -4903, 1341, -4903, -4903, 4283, - 39548, 4243, 29731, -4903, -4903, -4903, -4903, 56437, 4102, 56437, - 1661, 9681, 4082, 39548, 47801, 76957, 76957, 76957, 4054, 4082, - 3920, 3025, -4903, -4903, -4903, -4903, -4903, -4903, 3922, -4903, - -4903, -4903, -4903, 3994, -4903, -4903, 9, 3278, -4903, 2251, - -4903, -4903, 4338, 4231, -4903, -4903, -4903, -4903, -4903, -4903, - 4103, -4903, -4903, 44133, 56893, 76957, -4903, 3998, -4903, -4903, - -4903, -4903, -4903, 41381, 46887, -4903, 949, 3929, 3930, 1260, - -4903, -4903, -4903, 76957, 9824, 3932, 765, 3278, 76957, 76957, - 3935, 3940, 3941, 1647, 1318, 1727, 3291, 4238, -4903, -4903, - -4903, -4903, 4103, -4903, -4903, -4903, 334, -4903, -4903, -4903, - -4903, 53245, -4903, 3605, -4903, 1139, 4278, 60997, 4368, 4368, - 76957, -4903, 9982, 4149, -4903, -4903, 4229, 3896, 4175, 4226, - -4903, 3943, 76957, 4113, 3946, 76957, 3944, 4071, 1163, 1163, - 76957, 76957, 76957, 2256, 2034, 2609, 3724, 325, 4280, 64189, - 4317, 3616, 372, -4903, -4903, 795, -4903, 699, 4295, 3995, - -4903, 76957, 4393, 3347, 3527, 76957, 3956, -4903, -4903, 65557, - 4160, 1439,101883, 3734, 3919, 2006, 4096, -4903, 4098, -4903, - 1294, -4903, 2034, 76957, 70573, 39548, -4903,100557, -4903, 2261, - -4903, -4903, 4028, 3401, 4074, 4078, 3964, 76957, 760, -4903, - -4903, -4903, -4903, -4903, 76957, -4903, 323, -4903, -4903, 5307, - 34934,100115, 2263, 29731, -4903, 29731, -4903, 4391, -4903, -4903, - -4903, 94, -4903, -4903, -4903, 4254, 4254, 4254, -4903, 4392, - 3404, -4903, -4903, 2274, 4412, 33988, 4373, -4903, 76957, 2281, - -4903, 29731, 3985, -4903, -4903, 38632, 2197, 3986, 2286, 76957, - 2296,100115, 3987, 32, 3992, 23195, 3972, -4903, -4903, -4903, - -4903, -4903, 15042, 15042, 76957, -4903, -4903, -4903, -4903, 4029, - 76957, 2319, -4903, 165, 15042, 1100, 1793, 323, 4194, 3025, - -4903, 3996, -4903, -4903, -4903, 890, 890, 76957, 3025, 76957, - 3896, -4903, 76957, 4070, -4903, -4903, 53245, 4270, -4903, 4046, - -4903, 858, 3278, 76957,100115, -4903, 124, 4311, -4903,100115, - 100115, -4903, -4903, -4903, 29731, 4086, -4903, -4903, -4903, 1259, - 409, 63277, -4903, -4903, 76957, 76957, 76957, 76957, 76957, 259, - -4903, 2327, -4903, 40464, -4903, -4903, 2977, 1219, 2977, 1561, - -4903, -4903, 2977, -4903, 2977, -4903, 3832, 1219, 4368, 1020, - -4903, -4903, -4903, 1898, 4224, 4002, -4903, 872, 4210, 4095, - 4004, -4903, 60997, 4480, 3527, 3999, 76957, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, 2341, 3616, 4334, - 3287, 3893, -4903, 76957, 4045, -4903, 38632, -4903, -4903, -4903, - 2977, -4903, 1512, 4013, 4346, 3616, 2034, -4903, 3919, 3527, - 3999, -4903, -4903, -4903, 4019, -4903, 3824, 2006, 3734, -4903, - -4903, 4426, 4223, 4432, 3347, -4903, 3179, 2343, -4903, 7685, - 101441,100115, 4374, 4079, 4083, -4903, -4903, 4087, 76957, -4903, - -4903, 3616, -4903, 5307, 2349, -4903, 2355, 2356, 4183, 4085, - -4903, 29731, 873, 3641, 54157, 4031, -4903, 34934, 2365, -4903, - 2983, 76957, 2367, -4903, 15042, 76957, -4903, -4903, 29731, -4903, - 2371, -4903, 29731, 4037, 29731, -4903, 32569, 4035, -4903, 4484, - 2034, -4903, 3401, 39548, -4903, 4165, -4903, 4364, -4903, 76957, - 3896, 46887, 3379, 3379, 2012, 3896, 2377, -4903, -4903, 76957, - -4903, 4002, 29731, -4903, 4145, -4903, -4903, 2385, 1362, 4218, - 4218, 2387, 2395, 10299, 76957, -4903, -4903, -4903, -4903, -4903, - -4903, 2397, -4903, -4903, -4903, -4903, 2399, -4903, 2403, 2459, - 3295, 1727, 3295, -4903, 3291, -4903, -4903, 53245, -4903, 54613, - -4903, -4903, -4903, 1219, -4903, 1219, 4277, 76957, 49169, 1219, - 1219, -4903, -4903, -4903, -4903, -4903, 4402, 4342, -4903, 3723, - -4903, -4903, -4903, -4903, 454, -4903, 4268, 4269, 76957, -4903, - 4065, -4903, 2409, 1478, 4185, 3616, -4903, -4903, 76957, 4506, - 4508, -4903, 909, 76957, 3622, 76957, -4903, -4903, -4903, 29731, - 4241, -4903, 3893, 2006, 1478, 3919, 1439, 40006, -4903, 3734, - 3824, 4279, -4903, 4281, -4903, 4090, 4361, 7685, -4903, -4903, - 329, 4385, 4387, -4903, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, 3320, 33042, 33042, 33042, 4088, -4903, -4903, 76957, 3875, - 4099, 33988, 53245, 2414, -4903, 98789, -4903, 2419, 2421, -4903, - 2427, 32569, 2428, -4903, 76957, 4092, -4903, -4903, -4903, 42756, - 56437, 890, 4120, 4100, -4903, -4903, 4175, -4903, -4903, 1661, - 3278, -4903, 15042, 76957, 60997, 4501, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, 3278, 4170, 1259, -4903, 409, -4903, 63277, - -4903, 76957, -4903, -4903, 2433, -4903, -4903, -4903, 76957, 3720, - -4903, 3720, -4903, -4903, 4216, -4903, 2423, 1180, 1180, 4445, - -4903, 4151, -4903, -4903, 4105, -4903, 4564, 4228, 76957, -4903, - -4903, 949, 2034, 64189, 3616, -4903, -4903, 10448, 60997, -4903, - 3734, 3919, 2006, 29731, 2435, -4903, 4194, 168, 3824, -4903, - -4903, -4903, 39548, 4108, 3287, -4903, -4903, 1813, 60997, 60997, - 34461, 4237, 977, 12865, 4438, -4903, 4438, 4438, -4903, 2444, - 36341, -4903, -4903, -4903, 76957, 4309, 1121, -4903, 4261, -4903, - 2445, -4903, -4903, -4903, 969, 323, 3379, 4112, -4903, -4903, - 4210, 1661, -4903, 3278, -4903, 76957, -4903, 4116, -4903, -4903, - -4903, -4903, -4903, 54613, 3720, 3995, -4903, -4903, 4571, -4903, - 284, -4903, -4903, -4903, -4903, 76957, 3616, 3813, 3893, -4903, - -4903, 4121, 3824, 2006, 3734, 10577, -4903, 40006, 76957, 76957, - -4903, 2460, 39548, 3824, -4903, 1945, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, 4115, 4122, 4567, -4903, -4903, -4903, -4903, - -4903, 1193, -4903, -4903, -4903, -4903, 3531, -4903, -4903, 34934, - 34934, 4344, -4903, 1121, -4903, 4130, -4903, -4903, -4903, -4903, - -4903, 29731, 1661, -4903, -4903, -4903, 1259, -4903, 4461, -4903, - -4903, -4903, 3616, -4903, -4903, 52789, -4903, 3734, 3824, 4194, - -4903, -4903, -4903, 4361, -4903, 2465, 3401, 2301, -4903, -4903, - 2312, 2282, 4214, 4454, 33515, 4282, -4903, 4343, -4903, 4548, - 3875, 3875, -4903, -4903, 29731, 10954, 1661, 2466, 4318, -4903, - -4903, 2471, -4903, -4903, -4903, -4903, 3824, -4903, 76957, 3287, - -4903, 39548, -4903, -4903, 1945, 4257, 4258, -4903, -4903, -4903, - 76957, 11506, -4903, -4903, 60997, -4903, 52789, -4903, -4903, 3824, - -4903, -4903, 4189, 4191, 2476, -4903, 4153, -4903, 3401, 4465, - 4466, -4903, 52789, -4903, 60997, 60997, 2478, -4903, -4903, -4903 -}; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_uint16 yydefact[] = -{ - 1673, 1449, 636, 1535, 1534, 1449, 0, 259, 0, 1539, - 0, 1449, 430, 1127, 0, 0, 0, 0, 636, 1449, - 0, 1673, 0, 0, 0, 0, 0, 1686, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1449, 0, - 0, 1693, 0, 0, 0, 0, 1686, 0, 1541, 0, - 0, 0, 0, 0, 2, 4, 37, 72, 73, 31, - 30, 92, 55, 18, 63, 126, 125, 127, 42, 38, - 80, 26, 28, 39, 43, 65, 67, 45, 56, 104, - 64, 24, 62, 87, 68, 90, 50, 12, 13, 51, - 14, 52, 15, 53, 16, 100, 74, 93, 35, 61, - 23, 44, 70, 71, 5, 46, 82, 78, 11, 57, - 58, 60, 84, 85, 86, 109, 88, 121, 41, 118, - 97, 98, 115, 99, 116, 9, 101, 54, 17, 112, - 111, 113, 81, 47, 83, 69, 91, 110, 27, 114, - 19, 20, 22, 21, 59, 29, 66, 32, 89, 117, - 107, 103, 122, 120, 128, 105, 75, 7, 8, 94, - 6, 25, 49, 10, 34, 33, 48, 40, 124, 36, - 1539, 96, 108, 95, 76, 102, 79, 106, 123, 77, - 119, 1646, 1645, 1695, 1649, 1672, 0, 1661, 1448, 1447, - 1433, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 635, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1459, 2275, 2290, - 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, 2299, 2300, - 2301, 2302, 2303, 2304, 2305, 2630, 2306, 2307, 2308, 2580, - 2581, 2631, 2582, 2583, 2309, 2310, 2311, 2312, 2313, 2314, - 2315, 2316, 2584, 2585, 2317, 2318, 2319, 2320, 2321, 2586, - 2632, 2322, 2323, 2324, 2325, 2326, 2633, 2327, 2328, 2329, - 2330, 2331, 2332, 2333, 2334, 2335, 2634, 2336, 2337, 2338, - 2635, 2339, 2340, 2341, 2342, 2343, 2344, 2587, 2588, 2345, - 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, - 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, - 2366, 2367, 2368, 2369, 2370, 2371, 2589, 2372, 2373, 2374, - 2590, 2375, 2376, 2377, 2591, 2378, 2379, 2380, 2636, 2637, - 2381, 2382, 2383, 2384, 2385, 2592, 2593, 2386, 2387, 2388, - 2389, 2390, 2391, 2392, 2638, 2393, 2394, 2395, 2396, 2397, - 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2639, 2594, 2405, - 2406, 2407, 2408, 2595, 2596, 2597, 2409, 2640, 2641, 2410, - 2642, 2411, 2412, 2413, 2414, 2415, 2416, 2598, 2643, 2417, - 2644, 2418, 2419, 2420, 2421, 2422, 2423, 2424, 2425, 2426, - 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, 2435, 2436, - 2599, 2645, 2600, 2437, 2438, 2439, 2601, 2440, 2441, 2646, - 2442, 2602, 2443, 2603, 2444, 2445, 2446, 2447, 2448, 2449, - 2450, 2451, 2452, 2453, 2604, 2647, 2454, 2648, 2605, 2455, - 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, - 2606, 2466, 2607, 2469, 2467, 2468, 2470, 2471, 2472, 2473, - 2474, 2475, 2476, 2477, 2478, 2479, 2608, 2480, 2481, 2482, - 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, - 2493, 2494, 2495, 2496, 2497, 2649, 2498, 2499, 2500, 2501, - 2502, 2609, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, - 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2610, 2519, - 2520, 2650, 2521, 2522, 2611, 2523, 2524, 2525, 2526, 2527, - 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2612, 2536, - 2537, 2538, 2651, 2539, 2540, 2541, 2542, 2543, 2544, 2613, - 2614, 2545, 2546, 2615, 2547, 2616, 2548, 2549, 2550, 2551, - 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, - 2562, 2563, 2564, 2617, 2618, 2565, 2652, 2566, 2567, 2568, - 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2619, 2620, - 2621, 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2577, - 2578, 2579, 130, 0, 0, 2249, 2276, 2277, 2280, 2275, - 401, 400, 1636, 2243, 2276, 1538, 1516, 636, 0, 1436, - 429, 1673, 0, 0, 0, 0, 0, 0, 0, 0, - 866, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 178, 0, 0, 0, 0, 455, 454, - 0, 0, 0, 1095, 460, 0, 0, 0, 0, 0, - 624, 1585, 2467, 1583, 1637, 260, 263, 264, 261, 262, - 2265, 0, 1228, 1229, 1231, 0, 0, 0, 1241, 906, - 907, 0, 0, 0, 915, 0, 0, 0, 904, 0, - 0, 0, 920, 0, 917, 0, 0, 921, 918, 901, - 919, 908, 0, 900, 0, 0, 1241, 922, 0, 0, - 902, 0, 0, 0, 0, 1437, 1582, 461, 1673, 0, - 1560, 1561, 1562, 1539, 1551, 1563, 1556, 1558, 1557, 1559, - 1555, 2264, 2291, 1030, 1030, 1030, 1030, 1027, 1028, 1030, - 1030, 1030, 2487, 0, 0, 1009, 0, 1011, 2266, 1030, - 1035, 522, 522, 522, 0, 1034, 1039, 522, 0, 1430, - 1468, 2248, 1685, 0, 1010, 1429, 0, 0, 0, 2545, - 1574, 0, 0, 1256, 1252, 1254, 1255, 1253, 0, 0, - 0, 2505, 1441, 242, 2516, 2613, 2545, 241, 235, 237, - 209, 2295, 0, 0, 1034, 0, 1438, 1439, 992, 1692, - 1690, 0, 2230, 2315, 2330, 2420, 232, 2498, 2506, 2516, - 2613, 2545, 2576, 188, 198, 193, 0, 253, 2516, 2613, - 2545, 249, 1459, 0, 1662, 1794, 2239, 0, 1432, 1431, - 1540, 0, 1543, 0, 2482, 1666, 1669, 1545, 1667, 1658, - 0, 0, 1, 1673, 0, 1550, 1689, 1689, 0, 1689, - 0, 1650, 1658, 1653, 1657, 0, 0, 0, 0, 0, - 0, 0, 925, 0, 1471, 2244, 1080, 0, 0, 0, - 0, 0, 0, 0, 1136, 1135, 2281, 2271, 2272, 0, - 2269, 2270, 2282, 2283, 2284, 0, 2392, 0, 0, 0, - 2141, 2152, 2153, 2154, 2319, 2375, 2149, 2150, 2151, 2143, - 2144, 2145, 2146, 2147, 2148, 0, 0, 1223, 2142, 0, - 2392, 0, 0, 0, 157, 0, 134, 0, 0, 0, - 2392, 0, 0, 0, 0, 0, 0, 0, 2392, 0, - 0, 0, 0, 0, 157, 2425, 0, 134, 2392, 0, - 0, 1453, 0, 0, 0, 1455, 1458, 1434, 0, 2222, - 0, 2223, 2250, 1519, 0, 2239, 0, 0, 0, 961, - 954, 0, 962, 969, 0, 0, 971, 0, 0, 955, - 0, 0, 0, 0, 0, 974, 975, 0, 0, 976, - 956, 977, 957, 978, 958, 979, 0, 0, 0, 0, - 959, 0, 0, 0, 1445, 0, 1576, 1578, 1577, 1575, - 522, 0, 0, 0, 0, 2392, 0, 0, 134, 1504, - 0, 2392, 134, 0, 0, 459, 458, 134, 2269, 457, - 456, 2319, 2375, 0, 1126, 0, 1388, 134, 2392, 0, - 180, 2392, 710, 2392, 1545, 0, 639, 0, 0, 821, - 2425, 134, 0, 0, 0, 0, 0, 0, 1098, 0, - 0, 0, 0, 623, 636, 1586, 1584, 0, 1232, 234, - 233, 1230, 913, 2392, 1168, 350, 350, 0, 0, 2392, - 1490, 2278, 1869, 1898, 1876, 1898, 1898, 1865, 1865, 2359, - 1878, 2392, 1866, 1867, 1903, 0, 1898, 1865, 1870, 0, - 1868, 1906, 1906, 1893, 350, 929, 1850, 1851, 1852, 1853, - 1879, 1880, 1854, 1885, 1886, 1890, 1855, 1920, 1865, 2279, - 914, 0, 905, 2392, 350, 1132, 2392, 2273, 167, 0, - 903, 2319, 2375, 2392, 350, 1225, 0, 2392, 350, 2392, - 163, 2392, 350, 2392, 350, 2392, 640, 0, 0, 2392, - 350, 2392, 2425, 165, 0, 2392, 350, 923, 2392, 350, - 2241, 2392, 0, 0, 1579, 0, 1553, 2617, 1568, 0, - 1564, 1571, 1567, 1673, 1030, 1029, 0, 1030, 0, 1030, - 0, 1030, 0, 1030, 0, 0, 0, 1030, 2267, 2268, - 1012, 0, 1036, 0, 0, 1043, 1042, 1041, 0, 0, - 0, 1044, 0, 1798, 1613, 0, 1427, 236, 187, 0, - 248, 247, 1444, 0, 0, 0, 1098, 1259, 0, 1257, - 1248, 1249, 1440, 240, 238, 0, 0, 0, 0, 0, - 0, 1446, 0, 0, 0, 0, 2252, 2254, 2255, 2155, - 2225, 0, 2581, 2582, 2583, 2214, 0, 2584, 2585, 2586, - 2632, 2051, 2038, 2047, 2052, 2039, 2041, 2048, 2587, 2588, - 1986, 2589, 2590, 2262, 2591, 2592, 2593, 2595, 2596, 2597, - 2598, 2043, 2045, 2599, 2600, 0, 2263, 2602, 2603, 2449, - 2605, 2606, 2608, 2609, 2049, 2611, 2612, 2613, 2614, 2615, - 2616, 2261, 0, 2050, 2618, 2620, 2621, 2622, 2623, 2625, - 2626, 2627, 2628, 0, 0, 0, 2236, 0, 2018, 0, - 1858, 1859, 1881, 1882, 1860, 1887, 1888, 1861, 0, 2235, - 1923, 2100, 2017, 2034, 0, 2023, 2024, 0, 2016, 2012, - 1675, 2231, 0, 2013, 2251, 2253, 2215, 1675, 2229, 201, - 255, 0, 256, 2237, 2516, 189, 231, 203, 230, 204, - 202, 0, 2317, 190, 0, 0, 191, 0, 0, 0, - 0, 252, 250, 0, 1435, 0, 1796, 1795, 2240, 934, - 1528, 1526, 1527, 1525, 0, 1522, 1524, 1542, 1539, 2165, - 0, 1668, 0, 0, 0, 1648, 1647, 3, 1533, 0, - 1531, 1547, 1549, 1529, 1545, 1687, 1688, 0, 0, 0, - 0, 0, 0, 0, 0, 1743, 1703, 1704, 1706, 1740, - 1744, 1752, 0, 1654, 0, 0, 1800, 0, 0, 0, - 0, 0, 0, 1167, 0, 0, 0, 0, 0, 926, - 0, 0, 0, 1477, 0, 1479, 1480, 1481, 0, 0, - 0, 1482, 1483, 1471, 244, 1489, 1487, 1470, 1472, 1485, - 0, 0, 0, 0, 0, 0, 0, 1496, 0, 171, - 172, 0, 652, 636, 0, 2392, 0, 0, 0, 0, - 0, 1175, 1182, 0, 0, 0, 0, 0, 0, 0, - 0, 1176, 1174, 1177, 246, 1186, 1205, 1208, 0, 1134, - 1137, 0, 0, 0, 0, 0, 1316, 0, 0, 0, - 0, 1316, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 271, 273, 284, 345, 615, - 0, 0, 0, 618, 0, 2392, 0, 0, 0, 0, - 1227, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1208, 0, 0, 0, 0, 0, 0, 0, 0, 132, - 133, 138, 0, 0, 0, 0, 0, 1208, 0, 0, - 0, 0, 0, 0, 601, 614, 0, 0, 0, 0, - 0, 611, 0, 0, 134, 276, 591, 597, 0, 0, - 0, 717, 716, 0, 0, 0, 0, 1404, 1403, 0, - 0, 0, 0, 1494, 1493, 0, 0, 0, 0, 1316, - 0, 265, 267, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 393, 394, - 0, 0, 0, 138, 0, 0, 0, 0, 278, 0, - 0, 1454, 1451, 1452, 0, 1457, 0, 0, 0, 0, - 2026, 0, 2169, 1695, 2167, 1152, 2221, 0, 2285, 2653, - 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, - 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, - 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, - 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, - 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, - 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, - 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, - 2724, 2725, 2726, 2727, 2728, 2729, 2218, 2217, 2246, 2286, - 2287, 2288, 2289, 2224, 0, 1515, 0, 968, 0, 0, - 0, 0, 970, 0, 963, 0, 0, 960, 2319, 2375, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 973, - 0, 0, 0, 432, 0, 0, 818, 0, 0, 0, - 0, 0, 0, 829, 0, 1471, 1503, 0, 0, 0, - 645, 0, 2392, 0, 136, 867, 0, 819, 460, 0, - 0, 0, 1198, 1387, 136, 0, 0, 174, 0, 0, - 714, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 759, 758, 0, 0, 0, 820, 0, 0, 136, 0, - 2392, 594, 2392, 0, 522, 522, 0, 0, 1097, 1100, - 0, 0, 0, 0, 0, 1640, 1642, 1641, 0, 1639, - 0, 348, 349, 0, 1215, 816, 1240, 0, 0, 1897, - 1884, 1892, 1891, 0, 1874, 1873, 1872, 0, 1871, 0, - 1898, 1898, 1896, 1875, 1850, 0, 0, 0, 1902, 0, - 1900, 0, 896, 1846, 1842, 0, 1909, 1910, 1911, 1908, - 1921, 1907, 0, 1856, 1912, 1865, 1862, 916, 0, 0, - 1209, 0, 0, 2392, 350, 2392, 0, 2392, 0, 0, - 0, 1217, 350, 0, 1211, 0, 0, 1213, 0, 1405, - 0, 912, 910, 909, 911, 0, 0, 894, 0, 0, - 0, 2392, 350, 0, 0, 889, 0, 0, 891, 0, - 0, 0, 0, 1673, 0, 220, 221, 219, 1569, 222, - 1570, 1566, 1552, 0, 1020, 0, 1024, 0, 1015, 0, - 1021, 0, 1016, 1013, 1014, 0, 1019, 0, 0, 523, - 525, 0, 0, 2342, 2358, 0, 2381, 2413, 2414, 2473, - 2501, 2506, 2512, 0, 2539, 2550, 0, 1045, 1075, 1040, - 728, 0, 0, 1623, 1428, 2172, 0, 1673, 0, 0, - 0, 0, 239, 210, 0, 0, 0, 1077, 2505, 1443, - 991, 636, 0, 2014, 0, 2021, 2022, 2213, 0, 0, - 0, 0, 0, 0, 2020, 2180, 0, 0, 0, 0, - 0, 1946, 0, 0, 0, 2193, 0, 2199, 0, 0, - 1983, 0, 0, 0, 0, 0, 0, 0, 0, 1947, - 1927, 1928, 2018, 2165, 0, 2019, 2258, 0, 1920, 2234, - 2155, 0, 2152, 2153, 2154, 0, 0, 0, 2228, 0, - 2163, 0, 0, 1961, 2161, 1963, 0, 0, 0, 0, - 2149, 2150, 2151, 2143, 2144, 2145, 2146, 2147, 2148, 2159, - 1943, 0, 0, 2102, 0, 1942, 0, 0, 1756, 0, - 2256, 2216, 1756, 257, 258, 254, 0, 0, 206, 205, - 0, 224, 228, 229, 200, 227, 0, 223, 208, 2091, - 2090, 207, 199, 196, 194, 211, 213, 214, 197, 195, - 251, 0, 0, 0, 350, 1550, 0, 1537, 1753, 0, - 1670, 0, 0, 1550, 0, 0, 1546, 1665, 1664, 1696, - 1697, 1118, 1663, 1723, 1724, 0, 0, 0, 0, 1749, - 1747, 1714, 1707, 1713, 0, 0, 1711, 0, 1715, 1923, - 1742, 1652, 1701, 1702, 1705, 1651, 0, 1745, 0, 1626, - 1743, 1706, 1610, 0, 1588, 0, 1801, 0, 0, 0, - 0, 0, 1147, 1149, 0, 1148, 0, 1151, 0, 1160, - 0, 0, 1146, 1165, 0, 1154, 1152, 0, 1492, 0, - 0, 927, 0, 0, 0, 0, 1478, 0, 0, 2539, - 243, 1481, 1486, 1473, 1484, 0, 0, 0, 0, 0, - 1079, 1078, 0, 0, 1102, 0, 0, 0, 1499, 511, - 0, 347, 0, 0, 0, 0, 0, 0, 0, 0, - 814, 811, 0, 0, 810, 0, 650, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 690, - 0, 1316, 0, 722, 0, 1184, 0, 0, 1183, 0, - 1187, 0, 0, 1185, 1180, 1181, 2506, 2516, 2545, 245, - 1207, 0, 1206, 1202, 1129, 0, 1130, 0, 0, 0, - 0, 0, 2368, 2392, 289, 309, 0, 1315, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 332, 0, 0, 335, 334, 0, - 0, 0, 0, 0, 339, 318, 0, 319, 0, 0, - 338, 0, 0, 616, 617, 0, 0, 0, 0, 1316, - 0, 280, 0, 0, 0, 0, 0, 0, 0, 1224, - 0, 745, 0, 0, 0, 2506, 1203, 0, 0, 0, - 0, 0, 1391, 0, 0, 160, 0, 155, 159, 0, - 0, 0, 2506, 1204, 0, 0, 0, 0, 599, 600, - 613, 0, 604, 605, 602, 606, 607, 0, 0, 0, - 0, 0, 0, 0, 598, 0, 0, 712, 711, 715, - 0, 0, 0, 1400, 0, 1198, 0, 0, 1399, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1261, - 1260, 0, 0, 0, 0, 0, 0, 857, 0, 0, - 0, 0, 0, 0, 0, 0, 162, 732, 0, 731, - 0, 156, 161, 0, 0, 0, 0, 0, 0, 0, - 218, 1450, 1456, 1695, 1695, 1695, 2032, 0, 0, 0, - 0, 1694, 2219, 2222, 1518, 2247, 1517, 0, 0, 0, - 0, 972, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 964, 965, 966, 967, 0, 0, 0, 0, 0, - 407, 0, 0, 0, 2278, 0, 845, 817, 0, 0, - 0, 831, 0, 834, 837, 0, 1469, 479, 0, 0, - 642, 690, 0, 0, 463, 169, 0, 0, 0, 0, - 747, 0, 0, 0, 1386, 131, 178, 180, 461, 0, - 179, 181, 183, 184, 185, 182, 186, 0, 709, 713, - 0, 0, 0, 0, 638, 0, 0, 0, 0, 0, - 760, 764, 763, 767, 765, 0, 761, 0, 0, 1821, - 0, 0, 154, 0, 0, 589, 593, 0, 0, 0, - 0, 463, 565, 361, 2392, 0, 522, 0, 2392, 0, - 1099, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1638, 350, 1169, 0, 1491, 0, 0, 0, 350, 1895, - 1894, 1847, 1843, 0, 0, 0, 0, 930, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1863, 350, 1133, - 168, 2274, 0, 898, 0, 0, 0, 0, 350, 1226, - 886, 350, 164, 350, 350, 641, 0, 350, 166, 0, - 0, 0, 633, 350, 924, 350, 2242, 0, 350, 1581, - 2392, 522, 1554, 1565, 1017, 1026, 1025, 1023, 1022, 1018, - 0, 1037, 0, 521, 0, 0, 0, 0, 0, 1053, - 1054, 0, 0, 1050, 1055, 0, 1051, 1052, 1057, 1047, - 1046, 1058, 1059, 0, 0, 1077, 726, 0, 0, 0, - 0, 1620, 0, 1618, 0, 1799, 1622, 1611, 1573, 0, - 1572, 0, 582, 0, 0, 1258, 0, 0, 1034, 0, - 0, 350, 1442, 0, 993, 999, 0, 0, 0, 0, - 0, 0, 0, 1002, 1003, 0, 1004, 995, 1005, 996, - 1006, 0, 997, 0, 0, 0, 0, 2226, 2176, 0, - 2177, 0, 0, 2212, 2208, 0, 0, 0, 0, 0, - 2181, 2184, 2185, 2186, 2183, 2187, 2182, 0, 0, 2188, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2609, - 0, 0, 0, 0, 1987, 0, 0, 2136, 0, 2165, - 2198, 0, 0, 0, 0, 0, 0, 2165, 2204, 0, - 0, 0, 0, 2089, 0, 2086, 0, 0, 0, 0, - 2225, 0, 0, 2259, 1924, 1938, 1939, 1940, 1944, 2233, - 0, 2227, 0, 0, 1925, 1952, 0, 2205, 1979, 0, - 1984, 1967, 0, 1960, 0, 1965, 1969, 1948, 0, 1945, - 0, 2228, 2164, 0, 2162, 0, 1935, 1936, 1937, 1929, - 1930, 1931, 1932, 1933, 1934, 1941, 2140, 2138, 2139, 0, - 0, 0, 2110, 0, 0, 1964, 2384, 2420, 0, 1686, - 1686, 1686, 1674, 1684, 2232, 0, 1816, 1695, 1816, 2238, - 0, 0, 1920, 0, 1797, 932, 933, 931, 1521, 1523, - 1536, 1550, 2166, 1544, 1673, 1530, 1532, 1548, 0, 1116, - 1117, 0, 1121, 2609, 2503, 0, 0, 0, 0, 1716, - 1750, 0, 1741, 0, 2252, 1717, 2251, 1718, 1721, 1722, - 1712, 1751, 1624, 0, 1746, 1656, 1655, 0, 1819, 0, - 0, 0, 1602, 1590, 0, 1802, 0, 1756, 1628, 0, - 2225, 1754, 1362, 1262, 1325, 1150, 0, 1865, 1161, 0, - 1145, 0, 1144, 1865, 0, 1162, 0, 1865, 1363, 1263, - 1326, 928, 1364, 1264, 1327, 1365, 1265, 1488, 1476, 1475, - 1474, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 795, 2392, 350, 1497, 1366, - 0, 1266, 346, 1498, 1328, 1502, 813, 812, 0, 0, - 1329, 0, 651, 0, 655, 0, 657, 658, 659, 0, - 0, 0, 660, 0, 2319, 2375, 662, 665, 666, 667, - 674, 679, 669, 0, 0, 681, 675, 0, 0, 0, - 0, 0, 0, 687, 692, 0, 0, 0, 0, 0, - 0, 0, 1178, 1179, 1367, 1269, 0, 1330, 1128, 0, - 1270, 170, 0, 0, 272, 2392, 291, 0, 694, 795, - 0, 1318, 288, 316, 0, 0, 331, 326, 327, 325, - 2392, 350, 2392, 350, 0, 0, 0, 0, 0, 328, - 323, 324, 320, 0, 0, 333, 2294, 2360, 2517, 0, - 698, 700, 0, 705, 336, 1290, 357, 356, 355, 0, - 340, 0, 362, 365, 337, 314, 317, 315, 311, 285, - 0, 0, 0, 0, 0, 0, 0, 0, 2245, 0, - 0, 1219, 0, 1370, 1331, 0, 1353, 0, 0, 0, - 0, 739, 0, 1373, 1276, 1334, 1392, 1394, 1384, 1277, - 1393, 158, 1305, 147, 0, 0, 143, 0, 0, 0, - 0, 137, 0, 1374, 1278, 1335, 0, 1375, 1279, 0, - 0, 277, 592, 603, 608, 1284, 612, 609, 1343, 610, - 1382, 1280, 1378, 1308, 1338, 1385, 1401, 1281, 1198, 1396, - 1398, 0, 1316, 0, 266, 268, 0, 287, 0, 1282, - 0, 1336, 1377, 1307, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1505, 0, 0, 0, 0, 0, 0, - 350, 0, 0, 0, 1318, 2392, 350, 1376, 0, 1313, - 0, 1351, 0, 395, 0, 1306, 0, 0, 279, 1286, - 1345, 0, 0, 216, 215, 217, 0, 0, 0, 0, - 2170, 2171, 0, 2168, 2027, 2221, 0, 981, 939, 980, - 0, 2358, 0, 938, 940, 0, 0, 0, 941, 0, - 945, 946, 0, 0, 0, 937, 935, 936, 406, 0, - 431, 404, 405, 407, 0, 0, 844, 0, 0, 0, - 0, 833, 0, 0, 0, 1495, 0, 134, 649, 0, - 0, 0, 644, 689, 694, 0, 0, 0, 0, 462, - 466, 470, 471, 472, 0, 0, 0, 0, 148, 135, - 0, 875, 0, 522, 0, 749, 1390, 1389, 1197, 0, - 180, 173, 0, 0, 710, 0, 1545, 0, 0, 361, - 828, 826, 825, 827, 0, 0, 0, 849, 824, 0, - 1820, 1822, 0, 0, 0, 0, 0, 0, 582, 465, - 0, 0, 525, 0, 0, 569, 0, 0, 0, 0, - 361, 0, 0, 0, 1139, 0, 1157, 1140, 0, 0, - 0, 0, 1191, 1124, 1192, 1170, 1125, 0, 0, 621, - 1643, 1644, 0, 1216, 0, 0, 1864, 1877, 897, 0, - 1905, 1904, 1906, 1906, 0, 1848, 0, 1889, 1914, 1915, - 1916, 1917, 1918, 1919, 0, 1913, 1857, 1210, 350, 0, - 350, 0, 350, 1218, 1212, 1214, 1406, 0, 895, 0, - 0, 350, 888, 890, 0, 892, 0, 1038, 524, 0, - 0, 0, 0, 0, 0, 1049, 619, 1056, 0, 1070, - 1065, 1067, 0, 1071, 725, 0, 0, 1621, 1614, 1616, - 1615, 0, 0, 1612, 2173, 887, 0, 588, 1250, 1251, - 0, 0, 350, 0, 1072, 0, 0, 1000, 994, 0, - 0, 998, 0, 0, 0, 1001, 0, 0, 1691, 2174, - 2175, 0, 0, 0, 2209, 0, 0, 2064, 0, 2040, - 2042, 2054, 0, 2065, 2025, 2066, 2044, 2046, 0, 2156, - 0, 0, 2055, 0, 1989, 1990, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2005, 2004, 2056, 2135, 0, 0, 2196, - 2197, 2057, 0, 0, 2203, 0, 0, 0, 2062, 2067, - 0, 0, 0, 0, 2073, 0, 2094, 0, 0, 0, - 2015, 2166, 0, 0, 0, 0, 0, 0, 0, 0, - 1985, 1968, 1962, 0, 1966, 1970, 0, 0, 0, 1956, - 0, 0, 1954, 1980, 1950, 0, 0, 1981, 0, 0, - 0, 2033, 0, 0, 1686, 1686, 1686, 1686, 1683, 0, - 0, 0, 0, 2503, 2629, 0, 1780, 1755, 1757, 1767, - 1780, 1785, 1780, 2035, 1814, 2036, 2239, 0, 1726, 0, - 1726, 192, 0, 225, 212, 1520, 0, 1698, 0, 2157, - 1121, 0, 1700, 1720, 1719, 0, 1710, 1748, 1708, 1625, - 1609, 0, 1607, 1594, 1596, 1595, 0, 0, 1597, 2225, - 0, 1607, 1589, 1633, 0, 0, 1819, 0, 1632, 0, - 1865, 1142, 1143, 0, 1166, 0, 1082, 1083, 0, 1081, - 0, 0, 0, 510, 1101, 0, 0, 0, 795, 0, - 0, 514, 0, 1500, 0, 1383, 1304, 653, 654, 0, - 668, 0, 677, 676, 0, 0, 0, 0, 0, 0, - 0, 661, 683, 625, 684, 686, 0, 0, 685, 688, - 691, 1316, 0, 723, 1292, 0, 1349, 1172, 1319, 0, - 1131, 0, 0, 0, 0, 0, 0, 479, 310, 0, - 0, 0, 0, 370, 0, 293, 302, 368, 308, 0, - 1324, 342, 0, 313, 0, 306, 329, 321, 330, 322, - 341, 343, 0, 702, 703, 701, 697, 0, 704, 706, - 0, 359, 0, 0, 0, 1369, 0, 1316, 0, 281, - 0, 1288, 0, 1347, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1352, 0, 0, 0, 0, - 744, 0, 741, 1320, 0, 0, 140, 139, 0, 146, - 0, 1321, 0, 0, 0, 0, 1402, 0, 0, 0, - 0, 0, 0, 377, 0, 286, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 396, 352, 0, 852, 0, 0, 0, - 398, 0, 0, 0, 0, 0, 1368, 1271, 2030, 2031, - 2028, 1695, 2220, 0, 0, 0, 952, 0, 0, 0, - 0, 0, 0, 409, 410, 134, 408, 0, 0, 843, - 2449, 2143, 2144, 841, 847, 838, 840, 842, 839, 0, - 846, 795, 0, 0, 830, 835, 836, 0, 0, 0, - 0, 0, 494, 0, 0, 0, 485, 0, 0, 1198, - 478, 481, 482, 0, 0, 645, 648, 646, 647, 682, - 0, 465, 501, 551, 0, 150, 0, 0, 151, 149, - 0, 0, 361, 746, 0, 743, 0, 176, 461, 0, - 714, 0, 0, 0, 1198, 637, 766, 769, 762, 0, - 848, 850, 822, 0, 694, 0, 0, 594, 0, 522, - 1582, 577, 0, 553, 465, 551, 563, 562, 564, 0, - 571, 360, 0, 0, 582, 571, 0, 0, 1102, 1138, - 0, 0, 0, 1188, 1193, 1189, 0, 0, 1153, 0, - 1190, 1171, 1422, 1423, 1420, 1421, 0, 0, 0, 1635, - 0, 1883, 0, 1901, 1899, 1844, 1849, 1922, 899, 0, - 882, 0, 884, 350, 733, 0, 634, 350, 0, 0, - 0, 0, 0, 0, 1048, 0, 1068, 0, 0, 1031, - 1074, 0, 0, 1619, 1617, 580, 0, 1077, 0, 1032, - 1076, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2178, 0, 2211, 2207, 0, 2037, 2179, 0, 2191, 2190, - 2136, 0, 0, 1988, 2000, 2001, 2002, 2192, 0, 2010, - 0, 0, 1997, 1998, 1999, 1991, 1992, 1993, 1994, 1995, - 1996, 2003, 2201, 2200, 2194, 2195, 0, 2059, 2060, 2061, - 2202, 2068, 0, 2309, 2095, 2072, 2088, 2087, 0, 0, - 0, 2075, 0, 0, 2084, 0, 2137, 2260, 1926, 0, - 0, 1953, 2206, 1971, 0, 0, 0, 1949, 2156, 0, - 0, 0, 0, 0, 1958, 0, 0, 0, 2113, 2108, - 2109, 2133, 0, 0, 0, 0, 0, 0, 1677, 1676, - 1682, 1780, 1785, 1780, 0, 0, 1658, 0, 1767, 0, - 1779, 1765, 1778, 0, 0, 1791, 1789, 0, 1791, 0, - 1791, 0, 1759, 0, 1781, 1761, 1778, 1763, 0, 1806, - 2240, 1815, 0, 1739, 2027, 1739, 0, 1671, 0, 1699, - 1119, 1120, 1709, 2338, 1817, 0, 1608, 0, 0, 0, - 1599, 1605, 1587, 0, 0, 1629, 1607, 1630, 1163, 0, - 0, 1155, 1088, 1089, 1092, 1090, 1087, 1091, 0, 0, - 0, 795, 0, 0, 532, 0, 1113, 1113, 0, 0, - 516, 574, 527, 798, 0, 0, 0, 796, 350, 1267, - 0, 678, 0, 0, 673, 671, 670, 672, 0, 626, - 1381, 1268, 0, 0, 0, 0, 1173, 0, 0, 1291, - 0, 290, 0, 475, 0, 0, 303, 0, 299, 0, - 1317, 0, 0, 0, 0, 298, 372, 0, 369, 0, - 350, 350, 344, 699, 358, 363, 364, 367, 0, 0, - 0, 0, 0, 1323, 0, 0, 0, 0, 0, 0, - 0, 876, 859, 0, 0, 877, 878, 0, 0, 0, - 1221, 1222, 1220, 1354, 1355, 1360, 1357, 1356, 1359, 1361, - 1358, 0, 1274, 0, 0, 737, 144, 141, 142, 145, - 1302, 1285, 1344, 1397, 0, 0, 0, 1283, 0, 1337, - 0, 1298, 1294, 0, 0, 0, 0, 0, 1380, 1312, - 1342, 1379, 1310, 1340, 1309, 1339, 1311, 1341, 0, 1303, - 0, 1824, 856, 0, 0, 0, 350, 350, 855, 735, - 1287, 1346, 0, 0, 0, 942, 0, 0, 944, 947, - 0, 949, 414, 434, 755, 815, 0, 0, 832, 794, - 0, 483, 0, 489, 492, 0, 0, 496, 497, 495, - 484, 1198, 522, 573, 0, 0, 805, 0, 643, 0, - 463, 0, 498, 0, 0, 467, 153, 152, 0, 0, - 0, 750, 754, 752, 751, 753, 748, 0, 739, 180, - 2392, 0, 0, 0, 0, 575, 1395, 0, 779, 823, - 0, 1823, 729, 0, 361, 590, 0, 0, 0, 463, - 582, 0, 468, 473, 474, 479, 0, 565, 552, 0, - 553, 0, 0, 579, 1467, 0, 583, 585, 0, 0, - 0, 1141, 1158, 1159, 0, 0, 1122, 0, 0, 0, - 0, 628, 350, 1845, 350, 350, 1247, 0, 893, 1062, - 1063, 1064, 1061, 1060, 620, 0, 1066, 727, 0, 581, - 350, 0, 1008, 986, 1007, 985, 987, 0, 989, 990, - 984, 982, 983, 2210, 2053, 2063, 2189, 2135, 2166, 0, - 0, 2011, 0, 0, 2058, 2619, 0, 0, 0, 0, - 2092, 2093, 2074, 0, 2439, 2079, 0, 0, 0, 1977, - 1975, 1972, 0, 1973, 1957, 0, 0, 1955, 1951, 0, - 1982, 2099, 0, 2115, 2112, 2132, 2166, 1681, 1680, 1679, - 1678, 1766, 1762, 1764, 0, 2624, 0, 1769, 1776, 0, - 1758, 0, 1790, 1786, 0, 1787, 0, 0, 1788, 0, - 0, 1760, 0, 1776, 0, 1813, 0, 0, 2104, 2257, - 2104, 226, 0, 0, 1606, 1591, 0, 1592, 1598, 0, - 0, 0, 0, 1634, 1627, 1156, 1164, 0, 0, 0, - 512, 0, 527, 0, 0, 0, 1115, 1115, 0, 527, - 0, 1198, 800, 799, 802, 797, 801, 1501, 0, 663, - 664, 680, 1293, 0, 1350, 1300, 0, 1623, 292, 0, - 695, 297, 0, 0, 294, 371, 373, 295, 296, 300, - 352, 312, 305, 0, 0, 0, 1289, 0, 1348, 1296, - 1371, 1272, 1332, 0, 0, 865, 0, 0, 0, 0, - 1372, 1273, 1333, 0, 0, 0, 0, 1623, 0, 0, - 0, 0, 0, 0, 0, 0, 1510, 0, 1322, 351, - 854, 853, 352, 397, 1314, 2029, 0, 943, 950, 951, - 948, 0, 403, 411, 435, 134, 0, 0, 1238, 1238, - 0, 795, 0, 0, 480, 493, 0, 573, 531, 0, - 486, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 742, 741, 175, 0, 463, - 0, 694, 0, 773, 774, 768, 770, 0, 781, 785, - 851, 0, 0, 582, 465, 0, 0, 1580, 464, 0, - 0, 476, 0, 569, 553, 565, 0, 566, 0, 570, - 0, 1460, 0, 0, 0, 0, 1194, 0, 1200, 0, - 1152, 1195, 0, 1816, 0, 0, 0, 0, 632, 1239, - 883, 885, 734, 1069, 0, 1073, 350, 988, 2137, 2006, - 0, 0, 0, 0, 2069, 0, 2070, 2097, 2096, 2076, - 2080, 0, 2077, 2078, 1974, 1978, 1976, 1959, 2101, 0, - 1695, 2134, 1809, 0, 1812, 0, 0, 1768, 0, 0, - 1770, 0, 0, 1772, 1774, 0, 0, 0, 0, 0, - 0, 2243, 2337, 2593, 2500, 0, 1725, 1727, 1730, 1732, - 1731, 1733, 1729, 1738, 0, 1660, 1659, 2158, 1818, 0, - 0, 0, 1103, 0, 1631, 1070, 0, 350, 1113, 1198, - 533, 2449, 534, 1112, 1114, 1118, 1118, 0, 1198, 0, - 573, 656, 0, 0, 274, 693, 0, 0, 304, 354, - 366, 0, 1623, 0, 0, 863, 872, 872, 860, 0, - 0, 879, 1275, 738, 0, 0, 269, 1299, 1295, 0, - 0, 0, 1512, 1513, 0, 0, 0, 0, 0, 350, - 953, 0, 437, 444, 415, 420, 1504, 0, 1504, 0, - 417, 421, 1504, 416, 1504, 413, 414, 0, 1238, 0, - 1235, 1234, 793, 0, 520, 596, 487, 0, 542, 0, - 0, 806, 0, 0, 465, 551, 0, 509, 502, 503, - 504, 505, 506, 507, 508, 500, 499, 0, 694, 869, - 361, 1467, 736, 0, 0, 707, 0, 771, 776, 775, - 1504, 780, 0, 0, 0, 694, 0, 578, 553, 465, - 551, 469, 479, 555, 0, 556, 571, 565, 569, 567, - 568, 0, 0, 0, 582, 1514, 1102, 0, 1199, 0, - 0, 0, 0, 0, 0, 1242, 627, 0, 0, 631, - 622, 694, 1033, 2007, 0, 2008, 0, 0, 0, 2082, - 2081, 0, 2119, 1814, 0, 0, 1808, 0, 0, 1838, - 0, 0, 0, 1777, 1793, 0, 1773, 1771, 0, 1782, - 0, 1784, 0, 0, 0, 1734, 0, 2103, 2105, 0, - 0, 1604, 1816, 0, 1601, 0, 1084, 0, 1085, 1115, - 573, 0, 1121, 1121, 522, 573, 0, 795, 1301, 0, - 696, 596, 0, 307, 0, 282, 1297, 0, 0, 874, - 874, 0, 0, 0, 0, 384, 391, 390, 385, 383, - 392, 0, 388, 382, 381, 386, 0, 379, 0, 0, - 1506, 0, 1507, 1508, 1511, 399, 412, 0, 442, 0, - 440, 439, 441, 0, 428, 0, 0, 0, 0, 0, - 0, 402, 433, 1233, 1237, 1236, 0, 0, 488, 0, - 490, 528, 529, 530, 0, 491, 538, 539, 0, 803, - 0, 808, 0, 0, 0, 694, 550, 718, 0, 0, - 0, 1461, 0, 0, 576, 0, 782, 783, 778, 0, - 0, 730, 1467, 565, 0, 553, 477, 0, 450, 569, - 571, 0, 1464, 0, 584, 0, 1109, 1123, 1201, 1196, - 1426, 0, 0, 630, 629, 724, 2009, 2085, 2071, 2098, - 2083, 2114, 0, 0, 0, 0, 1807, 1810, 0, 1841, - 0, 0, 0, 0, 1827, 0, 1775, 0, 0, 1783, - 0, 0, 0, 1728, 0, 0, 1593, 1603, 1104, 0, - 0, 1118, 537, 0, 1106, 1105, 531, 795, 526, 513, - 1623, 301, 353, 0, 0, 0, 870, 873, 861, 862, - 881, 880, 740, 1623, 0, 0, 375, 0, 374, 0, - 378, 0, 438, 447, 0, 445, 418, 423, 0, 427, - 425, 424, 419, 422, 0, 519, 0, 0, 0, 0, - 540, 0, 541, 572, 0, 807, 0, 0, 0, 720, - 868, 0, 0, 463, 694, 772, 777, 0, 0, 1462, - 569, 553, 565, 0, 0, 557, 1113, 1113, 571, 448, - 1465, 1466, 0, 0, 361, 1425, 1424, 1673, 0, 0, - 2580, 2338, 2552, 0, 2131, 2120, 2131, 2131, 2111, 0, - 0, 1839, 1840, 1825, 0, 0, 1829, 1792, 1805, 1736, - 0, 1735, 2106, 2107, 1816, 350, 1121, 0, 795, 535, - 542, 515, 275, 1623, 864, 0, 270, 0, 389, 387, - 380, 1509, 443, 0, 426, 785, 595, 547, 0, 546, - 0, 544, 543, 804, 809, 0, 694, 858, 1467, 708, - 784, 0, 571, 565, 569, 0, 554, 0, 1115, 1115, - 452, 0, 0, 571, 1408, 1673, 1407, 1409, 1417, 1414, - 1416, 1415, 1413, 1245, 1246, 0, 2124, 2123, 2122, 2126, - 2125, 0, 2118, 2116, 2117, 1811, 0, 1828, 1831, 0, - 0, 0, 1837, 1830, 1832, 0, 1803, 1737, 1600, 1086, - 1107, 0, 517, 795, 283, 871, 0, 446, 0, 545, - 549, 548, 694, 719, 1463, 788, 451, 569, 571, 1113, - 558, 560, 559, 1109, 1110, 0, 1816, 0, 1418, 1412, - 1658, 1645, 0, 0, 0, 0, 2128, 0, 2129, 0, - 1834, 1835, 1836, 1833, 0, 0, 518, 0, 0, 721, - 790, 0, 786, 789, 791, 792, 571, 449, 1115, 361, - 1108, 0, 1093, 1410, 1673, 0, 0, 2121, 2127, 2130, - 0, 0, 536, 376, 0, 756, 0, 453, 561, 571, - 1111, 1411, 0, 0, 0, 1804, 0, 787, 1816, 0, - 0, 1826, 788, 1094, 0, 0, 0, 1243, 1244, 757 -}; - - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -4903, -4903, -4903, 3805, -4903, -4903, -895, 356, 3039, -1003, - -4903, -4903, -4903, 1217, -4903, -4903, -4903, -4903, 3773, -4903, - 2118, -2447, -4903, -4903, 99, 213, -1287, 125, 3296, 1776, - -4903, -1146, -4903, -4903, -588, 139, -4903, 296, 81, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -839, 2248, -4903, - 2322, 1604, 1210, -2801, -4903, -4903, -1314, -3190, -4903, 917, - -4903, 941, -4179, -559, -4903, -4543, -4903, -731, -549, -4903, - -4903, 2233, -4903, -4903, -4903, 1406, 820, -226, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -406, -4903, -4903, -651, 140, - 38, -2457, -3729, -4903, -4903, 779, -45, -1419, -4903, -3602, - -4903, 330, -2494, -4903, -4903, -4903, -12, -1388, 1712, -4903, - -721, -1157, 2019, -2833, -511, -4903, 110, -4903, -623, -419, - -417, -548, -3795, -4266, -4903, -4903, -4903, -655, -4265, -4474, - -3803, -4383, 1722, -4903, 145, -3122, -3212, 147, 752, -4903, - 148, 155, -4903, 769, -344, -910, -1510, -4903, 29, -4903, - -4903, -4903, -2933, -4903, -4903, -4903, -4903, 56, -4903, -4903, - -4903, -4903, 813, -4903, -4903, -4903, -4903, -4903, -4903, -2703, - 2188, 2190, -4903, -2859, -4903, -867, -4903, 965, -2967, 1626, - -4903, -4903, 1390, 3783, 796, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -1720, -4903, -4903, -4903, -4903, 327, 14, -4903, - -4903, -4903, -4903, -4903, -4903, 159, -4903, 2203, 1385, -4903, - -4903, 7, -4903, -4903, -4903, -4903, -4903, -4903, -609, -765, - -748, -4903, -2945, -4903, -4903, -4903, 37, -4903, -4903, -4903, - -4903, -4903, -4903, -878, -4903, 1448, -3170, -4903, -4903, 1454, - -4903, -4903, -4903, -4903, -4903, -529, 98, 2969, -4903, -132, - -324, -4903, -4903, -4903, 112, -4903, -4903, -4903, -4903, -4903, - -4903, -4903, -4903, -1098, 9893, -803, -577, -4903, -4903, -4903, - -4903, -4903, -2034, -4903, -4903, -4903, -4903, -3665, -4903, 4698, - 1780, 387, 163, -4903, -10, 90, 3568, -1144, -2639, 742, - -80, -4903, -4903, -4903, -2591, -4903, -4903, -4903, -4903, -3524, - 166, -4903, 3567, -4903, -3820, -4534, -3531, -663, -4903, -4040, - -4403, -4533, -3519, -4903, -4903, -4903, -4903, -555, -158, 2939, - -4903, -1420, 2570, -847, -4903, -2061, 803, 1806, 3774, -2749, - -133, 2934, -2510, -673, -3278, -4903, -4903, -2326, -209, -4903, - -4903, 1423, 348, -4903, -4903, -4903, -4903, -620, 2874, -201, - -4903, -4903, 4106, -4903, -4346, -4903, 4059, -4903, -4903, -4903, - -4903, 2788, 2797, -4903, 2793, -4903, -4903, -1414, 1565, -4903, - -4903, -4903, -4903, 1004, -4903, -4903, -4903, -4903, -4903, -4903, - -4903, 1453, 995, -4903, -4903, -4903, -4903, -4903, -496, -672, - -4903, -4903, 170, -4903, -4903, -4903, -4903, 2079, -877, -735, - 3961, 171, -4645, -4903, -4903, -1135, -4903, 3349, -4903, -4903, - -4903, -4903, -4903, -4903, -4903, -4903, -4903, -2597, -4903, -4903, - -4407, -4903, -4903, -4903, -4903, -4903, 2680, -4903, -4903, 2667, - 141, -4903, -62, -4903, -4903, -962, 2670, -4903, -1933, -4903, - -604, -4903, 2866, -4903, -4903, -4903, -4903, -1844, 174, 854, - -4903, 10, -4903, -4903, 241, -4903, 639, -4903, -4903, -3410, - 12, -4903, -4903, -4903, -4903, -4363, -4903, 15, -389, 1166, - -2818, -4903, 175, -1, -4903, -4903, 6, 4784, -17, -36, - -16, 3, 103, 3431, -4903, 3478, -4903, 18, 1984, -4903, - -4903, -825, -174, -4903, 1919, -643, 2649, 3415, 3417, -4903, - 1908, 2686, -1968, -1953, -4903, 1216, -364, -197, -4903, -4903, - -4903, -4903, 677, -639, 2664, -4903, 3427, -4903, -4903, -4903, - -1934, -2839, -3455, 1240, -3456, -3347, 716, 700, -1281, 34, - -43, -760, 3436, -4903, -4903, 1252, -162, -4903, -4903, -157, - -2758, 1199, -4903, -4334, -2339, 1255, -622, -455, -4903, -542, - -4903, -329, 7472, 2990, -1045, -4903, -4903, -985, 13915, -4903, - -4903, -4903, 14506, 14985, -4903, -4903, 15454, 16341, -4903, -873, - 16445, 13361, -1021, -1885, -608, 12488, -1848, -866, 83, -4903, - -3512, -2345, -4903, -4903, -4903, 80, 1310, 658, -4903, -4387, - -4903, -4903, 303, -4903, -334, -4903, -333, -4903, -4903, -4903, - -2775, -4902, -2814, 2777, -4903, -4903, -4903, -165, -4903, 17287, - -2757, -4903, -546, -1349, -1530, -3431, -1888, -4903, -4903, -4903, - -4903, -4903, -4903, -4903, -1546, -3303, -474, 2022, -4903, -4903, - 2116, -4903, -4903, -4903, -890, 2394, -762, -2630, 2029, -4903, - -767, 2784, -766, 11452, -648, 8906, -513, -2177, -1262, -1628, - -4903, 3053, -4903, 365, 6430, 16, -113, 4101, -614, -6, - 12957, -556, -927, 3798, 11611, 10597, -3129 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 53, 54, 55, 56, 57, 1531, 2505, 2357, 3288, - 3289, 58, 59, 1527, 60, 61, 62, 63, 1443, 64, - 1019, 1777, 2520, 65, 2190, 804, 805, 806, 2094, 2095, - 2441, 2096, 2084, 1327, 1919, 1464, 778, 779, 1425, 1465, - 67, 68, 1321, 2075, 69, 70, 71, 1495, 1582, 1496, - 1497, 1437, 1824, 4311, 5033, 3080, 2320, 3337, 3081, 3082, - 3706, 3707, 3785, 5057, 5058, 5050, 5056, 5051, 5052, 72, - 1598, 1599, 73, 74, 3253, 3249, 3835, 4652, 4653, 4885, - 612, 2482, 4655, 4656, 4871, 4872, 5071, 5214, 5215, 2521, - 1769, 3331, 3923, 3279, 4401, 3280, 4402, 3281, 4403, 3265, - 3870, 3871, 4346, 3872, 3282, 4362, 4915, 3283, 2209, 5088, - 2562, 1941, 1939, 4571, 4898, 4173, 4174, 5298, 5095, 5096, - 5097, 5321, 4364, 4407, 4408, 4944, 5254, 5255, 3335, 3930, - 4413, 4670, 2965, 76, 710, 1803, 3437, 711, 2565, 647, - 712, 2522, 81, 2555, 5090, 2556, 1557, 2371, 5053, 3417, - 82, 1044, 3672, 4738, 4969, 4970, 83, 226, 84, 1785, - 85, 86, 2500, 3272, 87, 2226, 2982, 88, 89, 3013, - 3014, 3015, 90, 3697, 4589, 1498, 3069, 3070, 3071, 3072, - 3728, 91, 1780, 2529, 2530, 92, 93, 94, 95, 2678, - 2679, 96, 2428, 97, 98, 99, 100, 3762, 4275, 4378, - 3111, 3295, 3895, 4376, 101, 2523, 1793, 2545, 2546, 4388, - 4695, 4696, 4697, 4930, 5245, 4699, 4932, 5118, 4934, 5431, - 5432, 4661, 3651, 4187, 103, 4355, 4356, 5102, 104, 2224, - 105, 106, 107, 1753, 2492, 2493, 3844, 1746, 2485, 2486, - 3909, 3910, 108, 3193, 109, 4251, 4252, 648, 5109, 5039, - 5198, 110, 111, 4255, 4256, 112, 113, 114, 115, 116, - 702, 703, 704, 1136, 1137, 2937, 1084, 117, 2104, 118, - 982, 983, 3228, 119, 1214, 2724, 2725, 4453, 120, 735, - 1155, 1156, 2524, 122, 744, 2698, 746, 1956, 3419, 3420, - 3989, 123, 124, 2675, 2701, 125, 1430, 2200, 2201, 4168, - 2525, 649, 1809, 2569, 2960, 4811, 4812, 5264, 5405, 4566, - 4825, 2882, 3602, 127, 650, 1469, 2275, 1104, 1105, 2572, - 3345, 2169, 2170, 2171, 3947, 2172, 3347, 2173, 1403, 2174, - 1054, 1055, 3353, 3354, 3355, 3943, 3950, 2514, 4728, 4729, - 128, 1467, 2273, 129, 130, 131, 1510, 895, 1114, 1115, - 132, 662, 663, 133, 4890, 134, 1058, 135, 4736, 136, - 137, 769, 770, 1198, 1199, 138, 139, 2289, 3709, 140, - 141, 142, 3105, 3106, 4267, 143, 144, 1772, 1773, 145, - 146, 3158, 3159, 147, 148, 149, 5346, 5407, 5408, 5409, - 3956, 5267, 5348, 1186, 151, 152, 153, 190, 935, 936, - 937, 2526, 4721, 155, 156, 1426, 1427, 1428, 1429, 2195, - 157, 158, 159, 160, 161, 162, 163, 1757, 164, 165, - 4864, 166, 167, 1715, 168, 1354, 1355, 169, 1369, 1370, - 170, 2871, 606, 822, 1358, 1364, 1371, 1372, 1373, 171, - 714, 1149, 1150, 1151, 1921, 172, 1194, 985, 715, 1144, - 174, 716, 2153, 2912, 3616, 3617, 3618, 3621, 4551, 4146, - 717, 2908, 177, 1963, 2684, 2687, 2904, 718, 2917, 2918, - 2919, 3624, 719, 737, 1047, 2579, 720, 1288, 182, 183, - 184, 831, 825, 826, 186, 2068, 2852, 753, 1377, 791, - 792, 840, 2451, 2119, 2120, 2144, 2145, 1386, 1387, 2132, - 2136, 2137, 2895, 2888, 2125, 4133, 4796, 4797, 4798, 4799, - 4800, 4801, 4538, 2140, 2141, 1389, 1390, 1391, 2149, 187, - 2856, 3577, 3578, 3579, 4110, 4111, 4125, 4121, 4523, 4783, - 3580, 1184, 1397, 4531, 5376, 3581, 4772, 4773, 4986, 4129, - 3588, 3612, 3319, 3320, 3321, 3582, 5163, 5164, 5373, 5374, - 4988, 4989, 2175, 1854, 1086, 1289, 1087, 1866, 1290, 1838, - 1089, 1291, 1292, 1293, 1092, 1294, 1295, 1296, 1095, 1830, - 1297, 1298, 1848, 1863, 1864, 1359, 4990, 1300, 1301, 1302, - 3584, 1303, 4064, 4487, 4476, 2784, 2785, 2091, 4060, 3522, - 2063, 2842, 4805, 5007, 5008, 3561, 4089, 4503, 4770, 5155, - 5274, 5275, 5362, 1304, 1305, 1306, 2839, 2059, 898, 1307, - 3846, 2061, 2778, 1623, 1624, 1966, 1986, 2731, 2747, 2748, - 2758, 3481, 2766, 2771, 3509, 3510, 2779, 2808, 1308, 2733, - 2734, 3465, 1988, 1309, 941, 1627, 942, 1983, 2803, 1317, - 1310, 1311, 1957, 815, 4779, 1140, 854, 3097, 1707, 944, - 750, 1312, 1313, 1314, 1315, 1503, 869, 1107, 1108, 603, - 595, 871, 3073, 604, 597, 598, 1712 -}; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int16 yytable[] = -{ - 594, 1556, 814, 185, 896, 1918, 180, 601, 1013, 841, - 175, 1874, 176, 1708, 654, 178, 1938, 747, 1392, 749, - 1175, 1176, 1177, 755, 185, 1318, 1181, 783, 1322, 772, - 780, 747, 1603, 787, 1844, 830, 780, 780, 739, 816, - 897, 819, 862, 2208, 739, 1561, 2384, 3278, 2276, 1409, - 902, 646, 1713, 907, 1348, 1139, 2284, 1349, 849, 1615, - 3442, 1850, 1782, 3356, 817, 1976, 1336, 2297, 3610, 3156, - 3301, 1120, 1555, 1048, 701, 3951, 2550, 3190, 3951, 3678, - 1581, 4139, 1834, 1835, 3423, 1133, 2454, 2285, 2445, 592, - 1608, 1621, 1843, 3856, 3698, 4213, 2730, 905, 3623, 3723, - 3590, 3725, 1470, 1755, 1146, 1050, 998, 1760, 835, 2930, - 2932, 926, 1764, 745, 4175, 4076, 3921, 4170, 4420, 3905, - 4107, 1130, 1774, 2690, 3600, 4124, 3848, 784, 1118, 4776, - 4410, 1122, 4417, 4176, 3848, 1767, 1798, 4567, 2858, 66, - 75, 803, 4713, 2793, 4715, 77, 2181, 78, 79, 843, - 3935, 1795, 4361, 1152, 828, 80, 3099, 2763, 1060, 102, - 3530, 777, 713, 121, 4826, 2405, 126, 2897, 811, 844, - 150, 154, 2868, 2269, 173, 179, 919, 3629, 2314, 2629, - 2875, 2570, 4677, 1348, 2900, 594, 852, 852, 855, 1466, - 852, 4957, 1831, 1832, 864, 4409, 816, 1385, 4788, 899, - 4790, 1388, 864, 1842, 3918, 864, 4044, -2377, 816, 1329, - 852, 4152, -2306, 816, 660, -2415, 3487, 852, 3268, 816, - -2438, 721, -2380, -2470, 4834, 931, 721, 4866, 4867, 1466, - 4714, 721, 2269, 4122, 1466, 4127, -2250, -2278, 1157, 4946, - 4565, 1050, -2279, -1898, -1865, -2278, -2278, 1850, 1161, 2269, - -2279, -2279, 2416, 1834, 1835, -1878, -1903, -2635, 2421, -1893, - 2801, 660, -1906, 660, 4856, -2635, -2635, 2443, 2444, 1743, - 2287, 2409, 2410, 1843, -1906, 1431, 5111, 1360, 1210, 1794, - 2403, 3941, 5038, 1821, 4896, -2249, 1856, 660, 2192, 1439, - 3628, 610, 5022, 5023, 2547, 1865, 2081, 1499, 660, 3873, - 3463, 2801, 721, 2511, 860, -134, 2031, 1751, 1003, 2661, - -134, 3679, 1821, 4891, 2066, 721, 1821, 5055, 660, 3213, - 3251, 1326, 932, 2216, 3269, 3427, 2559, 3008, 1499, 3429, - 3291, 3926, 2102, 721, 4549, 2037, 1821, 4455, 4456, 660, - 4458, 4459, 4460, 4461, 4462, -1721, 4979, 660, 838, 2287, - 2503, 2560, 1790, 2196, 1831, 1832, 5265, 1821, 1857, 1821, - 838, 1350, 3886, 2397, 2197, 933, 4833, 2039, 5355, 608, - 727, 3440, -2436, 1791, 1612, 727, 3995, 1821, 727, 1821, - 1821, 1842, 2198, 727, 1432, 727, 727, 738, 3, 4, - 5003, 3202, 4575, 738, 728, 2951, 5390, 1593, 1440, 728, - 1179, 4294, 728, 2264, 3009, 2082, 3086, 728, 2963, 728, - 728, 4672, 2116, 1499, 660, 3879, 2518, 789, 721, 1858, - 5014, 1511, 1859, 934, 2214, -689, 3233, 605, 3234, 2031, - 2073, 2031, 3238, 1845, 3240, 3241, 1845, 3184, 3390, 4657, - 3392, 188, 2031, 3245, 3246, 3247, 2674, 5027, 4947, 3733, - 4948, 660, 3853, 1913, 1846, 5000, 1914, 1846, 1713, 1615, - 2037, 2855, 3734, 897, 2964, 2217, 188, 2548, 1847, -2141, - 3185, 2037, 4658, 834, 5130, 2836, -2141, 5249, 2952, 5035, - 3903, 1708, 2837, 1180, 189, 2202, 2287, 1872, 1872, -2160, - 2039, 3487, 2039, 1512, 2519, 2265, -2160, 2368, 2074, 1074, - 1594, 2287, 1882, 2039, 2287, 3270, 3487, 1997, 820, 189, - 3585, 3779, 5447, 1007, 2680, 897, 2287, 790, 2139, 1017, - 1351, 2083, 1352, 3996, 4673, 3887, 2025, 1860, 2199, 1752, - 1792, 5266, 1031, 2700, 1101, 4926, 2504, 2561, 1433, 2313, - 4550, 3428, 5083, 5391, -436, 3430, 1902, 1613, 4371, 1922, - 3483, 4980, 2449, 3252, 2071, 2218, 1822, 661, 2662, 880, - 5045, 2204, 3585, 4236, 3216, 1958, 881, 882, 883, 4295, - 3679, 5227, 2387, 1961, 2103, 3012, 2976, 1434, 1050, 2205, - 1713, 1968, 5015, 861, 1723, 1822, 2067, 1004, 3874, 1822, - 1614, 3271, 2404, 3227, 1180, 1050, 1977, 1911, 2990, 1509, - 945, 2732, 2802, 3087, 3848, -2436, 816, 2253, 594, 1822, - 1435, 852, 2422, 855, 185, 852, 5181, 989, 2298, 1752, - 2496, 986, 899, 987, 1441, 1980, 988, 1020, 4270, 852, - 1822, 2549, 1822, 3942, 2417, 1861, 852, 5182, 2681, 4372, - 2423, 939, 5187, 3550, 4492, 940, 4124, 2352, 5296, 3214, - 1822, 1153, 1822, 1822, 5211, 5258, 2379, 1050, 4520, 2382, - 594, 2512, 4524, 981, 5309, 855, 1829, 2331, 5048, 1393, - 864, 3017, 5123, -2436, 899, 1436, 3502, 864, 733, 734, - 864, 1338, 5129, 5394, 1442, -2377, -2436, 1180, 733, 734, - -2306, 3375, 830, -2415, 2398, 2389, 852, 1845, -2438, 4576, - -2380, -2470, 4370, 4180, 939, 1823, -2250, -2278, 940, 1845, - 1183, 185, -2279, -1898, 1833, 2111, 4466, 611, 1846, 1752, - 2857, 2206, 4416, 4373, 1962, 1837, -1903, -2635, 5341, -1893, - 1846, 2027, 1847, 2069, 1851, 1170, 2215, 2442, 1154, 1529, - 1159, 2024, 1163, 2079, 1849, 1145, 4554, 816, 1167, 2150, - 780, 780, 780, 2151, 4511, -2249, 4513, 2861, 1869, 1500, - 1501, 1730, 1530, 816, 1752, 1202, 2058, -134, -134, 1621, - 1621, 1621, 733, 734, 1183, 1050, 5332, 3625, 5019, 1880, - 2650, 1904, 3644, 1050, 1050, 1316, 1316, 1353, 816, 780, - 1500, 1501, 4747, 780, 2272, 843, 2109, 897, 2450, 1907, - 1725, 1872, 3988, 4711, 1396, 2633, 1732, 816, 3094, 1733, - -2141, 816, 5049, 1102, 1718, 844, 2838, 1316, 1446, 821, - 3833, 3834, 3598, 3780, 5279, 2494, 4202, 5302, 655, 816, - -2160, 2207, 3776, 2740, 2682, 660, 185, 3018, 4240, 180, - 5306, 816, 1872, 175, 4654, 176, 2660, 2272, 178, 2202, - 1148, 2109, 2158, 3897, 2683, 816, 3918, 2672, 5250, 5252, - 5398, 1587, 3036, 1724, 2272, 1962, 660, 2203, 3631, 2487, - 3632, 5228, 4374, 816, 2977, 1500, 1501, 2991, 852, 852, - 2607, 777, 1189, 1191, 4160, 3674, 2053, 2054, 2055, 2056, - 2057, 2058, 4734, 2339, 1325, 605, 4397, 3188, 1333, 2055, - 2056, 2057, 2058, 1588, 1172, 4334, 4335, 1502, 4359, 780, - 780, 4349, 3484, 3485, 1339, 3095, 2299, 3504, 2897, 3223, - 2941, 4398, 3076, 5436, 5237, 2204, 2879, 1361, 660, 2300, - 1413, 2301, 1316, 1316, 3605, 5401, 5402, 2741, 3595, 4375, - 5384, 594, 845, 2205, 1856, 5251, 3497, 3498, 3499, 3500, - 3501, 3502, 864, 607, 3534, 3535, 899, 2508, 864, 2909, - 3008, 864, 1356, 3499, 3500, 3501, 3502, 2589, 2590, 763, - 1188, 3381, 66, 75, 3077, 4938, 852, 3593, 77, 5419, - 78, 79, 1340, 3626, 2269, 5333, 1439, 5334, 80, 4150, - 2302, 2220, 102, 1424, 3022, 1206, 121, 2843, 816, 126, - 4268, 2221, 4774, 150, 154, 852, 852, 173, 179, 2742, - 1414, 2880, 4967, 886, 887, 888, 1857, 889, 890, 891, - 892, 893, 894, 1375, 2541, 4431, 846, 816, 816, 816, - 3596, 852, 4175, 594, 594, 5458, 5091, 3009, 4176, 4928, - 777, 1189, 4752, 748, 1592, 4693, 2384, 5152, 1786, 2949, - 1593, 4176, 1187, -1865, 764, 4392, 4350, 3952, 5084, 3827, - 3828, 4777, 1415, 4694, 4385, 3078, 4780, 1589, 5397, 931, - 2743, 4784, 2509, 2744, 4786, 1173, 4140, 1858, 4630, 1860, - 1859, 3, 4, 4929, 2563, 2206, 3023, 738, 2821, 738, - 1787, 738, 618, 2727, 4360, 1440, 656, 738, 1168, 1169, - 1814, 3189, 4631, 852, 1891, 852, 852, 4399, 2542, 2799, - 5104, 1158, 1160, 1162, 4248, 2559, 1164, 1165, 1166, 2337, - 3766, 1844, 4855, 1376, 5369, 4735, 1171, 2351, 2934, 1574, - 2910, -1865, 2844, 3675, 5357, 1713, 5135, 1316, 4141, 2764, - 2560, 3953, 707, 5128, 3174, 5125, 1892, 2782, 3951, 763, - 3175, 3346, 2222, 1594, 657, 1924, 185, 1926, 1416, 1928, - 5092, 1930, 15, 1932, 1933, 1934, 932, 1940, 1940, 1590, - 1936, 4347, 816, 4397, 747, 5103, 625, -2247, 2745, 3858, - 1920, 1713, 4452, 4968, 5153, 1860, 2669, 2670, 4707, 4907, - 658, 2223, 659, 2211, 3845, 2207, 20, 41, 4398, -1096, - 1973, 3826, 3845, 816, 4702, 5085, 1979, 765, 3012, 933, - 5124, 1573, 2191, 4176, 5154, 5034, 5338, 5339, 1752, 1316, - 4249, 2123, 1621, 2822, 660, 3861, 4560, 3585, 2823, 3079, - 3585, 45, 3691, 5370, 764, 5093, 627, 5317, 1413, 4348, - 4908, 2471, 847, 738, 1872, 4590, 766, 767, 4909, 1316, - 2338, 727, 4716, 3176, 1788, 1708, 3666, 2610, 2635, 2889, - 2025, 4216, 2588, 1499, 660, 2824, 4717, 934, 721, 3123, - 830, 2622, 49, 3378, 5358, 728, 4910, 1316, 1316, 1316, - 3863, 1316, 3302, 2472, 2628, 50, 2746, 2586, 5415, 3948, - 3954, 3700, 5017, 1861, -1865, 2659, 2107, 3431, 3667, 2664, - 3585, 1316, 2654, 2668, 1381, 3692, 2671, 1595, 51, 2642, - 1893, 2543, 1862, 2608, 1421, 2584, 1422, 2124, 1414, 2627, - 4974, 1335, 2911, 2929, 2544, 4250, 4689, 5259, 2621, 2935, - 4996, 2623, 2936, -1658, 3379, 4217, 4553, 1872, 768, 816, - 5126, 2117, 2118, 4911, 2122, -1658, 1596, 2902, 897, 3124, - -1658, 1396, 4951, 4632, 3131, 4912, 1789, 3955, 1152, 5438, - 4952, 844, 844, 2085, 844, 5416, 785, 4663, 2097, 2097, - 1415, 33, 3866, 1316, 3432, 5371, 1383, 1316, 1316, 1597, - 5372, 939, 2901, 2756, 5243, 940, 3083, 765, 816, 816, - 2156, 2663, 1316, 4678, 2666, 2667, 638, -1658, 639, 2513, - 3701, 41, 3125, 2825, 3587, 4572, 4450, 3177, 2959, 641, - 5045, 3107, 1894, 5037, 780, 3867, 752, -1658, 5041, 5042, - 643, 836, 4470, 1768, 4471, 4253, 766, 767, 3131, 3777, - 761, 3868, 5318, 4840, 4718, 45, 2726, 4426, 2729, 4679, - 3775, 3034, 1860, 2655, 2736, 5417, 3178, 2473, 3625, 2260, - 2750, 2751, 2752, 2903, 780, 5340, 3054, 3142, -1658, 3126, - 2768, 2770, 3668, 188, -1102, 2780, 1416, -1658, 816, 2286, - 3160, 1521, 4774, 4573, 3848, 2656, 49, 2255, 816, 3179, - 708, 852, 5178, -1865, 3747, 837, 2691, 2263, 2657, 50, - 915, 4937, -1865, 2374, 1833, -1865, 1408, 5046, -1865, 2248, - 5047, 4176, 3778, 5184, 5185, 3858, 189, 899, 762, 816, - 5319, 3859, 51, 780, 3388, 3055, 738, 3180, 5048, 916, - 1417, 2658, 4953, 3860, 2210, 3869, 709, 1418, 3141, 5396, - 780, 4254, 816, 2400, 3183, 816, 4913, 5320, 3987, 4914, - 5406, 1923, 1488, 4353, 1925, 2676, 1927, 2315, 1929, 2474, - 1931, 3861, 2211, 3862, 1935, 838, 3181, 3127, 3585, 1419, - 4472, 3164, 3327, 36, 3669, 2126, 1404, 1815, 3008, 1872, - 816, 3266, 2369, 4010, 4391, 2372, 2373, 1529, 4386, 3988, - 1522, 852, 852, 852, 852, 816, 5418, 3116, 3117, 3182, - 3783, 3120, 1420, 3748, 3208, 5437, 1526, 3702, 3703, 816, - 1530, 1405, 1621, -1658, 2127, 1406, 3863, 4344, 2355, 3690, - 1316, 1316, 1316, 2358, 625, 5256, 1566, 788, 3217, 3218, - 3219, 1816, 1421, 931, 1422, 1381, 3704, 2375, 625, 2677, - 2376, 4345, 2384, 5457, 3864, 3298, 3784, 5195, 1407, 1050, - 4024, 4025, 4026, 4027, 4865, 3009, 4032, 4033, 4034, 4035, - 4036, 4037, 4038, 4039, 4040, 4041, 5468, 1567, 3310, 3311, - 3312, 3313, 5049, 1339, 3031, 939, 1424, 1568, 1365, 940, - 3318, 1424, 3845, 1423, 627, 2946, 3128, 1381, 3010, 2619, - 3975, 2426, 1382, -587, 3129, 2432, 3223, 3130, 627, 4238, - 2582, 839, 3821, 3865, 2212, 3056, 4266, 1383, 3866, 738, - 2316, -157, 4080, 4081, 738, 738, 3109, 1752, 2455, 5196, - 816, 2609, 2129, 4115, 897, 897, 4893, 3011, 1817, 2315, - 932, 4592, 852, 852, 3614, 1500, 1501, 4596, 2317, 4819, - 5110, 1340, 3186, -2269, 1523, 812, 4828, -157, 1384, 1424, - 1039, 3867, 5134, 1424, 1206, 852, 4116, 3749, 3781, 1383, - 4176, 2318, 3297, 2319, 3057, 2463, 4862, 3868, 4028, 3615, - 4029, 4526, 4239, 933, 816, 3187, -157, 41, 3585, 2130, - 1818, 4118, 3585, 1524, 1418, 4183, -461, 5380, 3110, 4863, - 852, 852, 852, 852, 625, 2293, 3750, 2294, 2313, 2089, - 1384, 4325, 4434, 816, 4435, 4328, 4329, 1907, 4331, 4839, - 816, 45, 736, 2455, 4966, 823, 1525, 3650, 736, 2305, - 36, 5404, 4746, 738, 594, 5076, 3012, 594, 1569, 3751, - 5077, 934, 855, 738, 3539, 5256, 3540, 1316, 1539, 2381, - 4176, 2090, 4925, 2809, 638, 2810, 639, 1399, 897, 2354, - 3121, 4869, 49, 2306, 627, 3340, 2295, 1529, 638, 3541, - 639, 3869, 5116, 1570, 3520, 50, 4184, 1571, 2811, 3951, - 3527, 644, 864, 864, 1819, 1168, 1169, 1540, 2346, 5030, - 1530, 5078, 2316, 899, 899, 1768, 1400, 864, 51, 1796, - 864, 1040, 1410, 4120, 5117, 2363, 4030, 707, 2323, 2963, - 1572, -461, 52, 721, 2764, 2764, 4031, 852, 852, 2764, - 2317, 832, 1797, 4676, 852, 3703, 816, 15, 738, 1401, - 5460, 738, 738, 4185, 2438, 4186, 185, 1041, 4815, 2685, - 4817, 1411, 2644, 2318, 2645, 2319, 2646, 2439, 2647, 4176, - 2648, 1940, 4687, 4227, 2649, 4019, 2764, 2764, 852, 833, - 864, 20, 4706, 864, 864, 3647, 816, 816, 2436, 852, - 1032, 858, 2607, 2324, 1412, 2440, 816, 3542, 721, 4162, - 2313, 2812, 3543, 816, 4045, 2697, 2813, 1331, 747, 747, - 185, 2814, 2702, 989, 1042, 4962, 1316, 986, 1316, 987, - 1043, 2031, 988, 1316, 1316, 1033, 3307, 2437, 3359, 2077, - 1316, 1316, 1316, 3380, 3382, 3383, 1316, 899, 1316, 1316, - 1316, 1316, 1316, 1316, 638, 1316, 639, 1316, 1316, 4313, - 2037, 1316, 4183, 4343, 3415, 4579, 4580, 4114, 1034, 3927, - 1050, 4181, 3931, 848, 2374, 4667, 1316, 1316, 1316, 1316, - 4314, 1768, 3589, 852, 1316, 5144, 2996, 2723, 1316, 3365, - 856, 1316, 2039, 3401, 1316, 1316, 1316, 1316, 1316, 1316, - 1316, 1316, 1316, 1032, 1316, 1148, 5086, 2126, 41, 5107, - 816, 1316, -1694, 1316, 2696, 1035, 879, -1694, 5344, 29, - 816, 1899, 897, 756, 5343, 1050, 5121, 2992, 921, 2305, - 2997, 2998, 5189, 1845, 227, 4862, 878, 5114, 1033, 4115, - 609, 738, 45, 4184, 1900, 2984, 2127, 930, 705, 816, - 1583, 3544, 757, 1316, 1846, 938, 758, 816, 4863, 816, - 2815, 3545, 5145, 2306, 1563, 1488, 33, 786, 1849, 1316, - 2816, 3899, 4116, 1532, 3630, 3591, 1907, 1558, 1316, 1316, - 2515, 3744, 4163, 49, -1694, 3315, 997, 4117, 4164, 1584, - 3316, 1600, 816, 1585, 1604, 4165, 41, 4118, 3680, 2915, - 4185, 2920, 4186, 1564, 2552, 3459, 2128, 3906, 2375, 2913, - 2109, 2376, 4296, 41, 3030, 4862, 1559, 3916, 1035, 3585, - 3745, 991, 1586, 4119, 3708, -1694, 3585, 3683, 4166, 994, - 45, 3585, 855, 52, 3585, 4297, 1565, 2953, 4863, 2956, - 1005, 747, 1006, 747, 4226, 4393, 2287, 45, 3548, 2287, - 4167, 29, 2587, 3746, 2129, 3585, 2288, 3016, 3635, 2296, - 1316, 2950, 2595, 1833, 2596, 2182, 3486, 1000, 3585, 939, - 2600, 49, 594, 940, 852, 852, 1014, 2606, 3514, 864, - 1027, 899, 864, 864, 50, 852, 1970, 852, 49, 1971, - -586, 852, 5301, 3122, 816, 4830, 5239, 1356, 2870, 5459, - 2315, 50, -1658, 3739, 5177, 1840, 1841, 51, 3460, 4120, - 3537, 2130, 1036, 3461, -1658, 780, 1825, 4203, 1984, -1658, - 52, 52, 1560, 4159, 51, 2286, 4211, 3603, 1833, 5073, - 2182, 5075, 721, 3041, 816, 5079, 1037, 5080, 5345, 4114, - 4647, 3053, 4648, 4649, 1852, 41, 4650, 3998, 3563, 3513, - 816, 3515, 3516, -1657, 1183, 1183, 3639, 1050, 1183, 4419, - 1833, 1038, 1408, 3857, 1870, -1657, -1658, 3205, 3316, 2105, - -1657, 816, 2106, 4241, 1881, 1520, 3098, 3098, 1884, 45, - 1537, 1052, 1887, 5115, 1889, 2494, -1658, 3636, 3637, 1057, - 1897, 816, 816, 1100, 3902, 816, 1905, 855, 780, 1908, - 1109, 3963, 3964, 5382, 3, 4, 2108, 2738, 2739, 2109, - 2406, 4115, 1110, 2315, 2753, 2754, 1009, -1657, 1010, 1621, - 49, 852, 3875, 2113, 852, 1621, 2114, -1658, 5276, 5277, - 3585, 3160, 3854, 50, 41, 5329, -1658, -1657, 4218, 2577, - 4225, 2578, 2792, 3657, 4116, 816, 816, 1116, 2639, 2651, - 3143, 2109, 2652, 2316, 2653, 1127, 51, 2652, 3146, 4117, - 3191, 3149, 3194, 3196, 2688, 2447, 2448, 2689, 45, 4118, - 52, -1419, 1134, -1419, 2873, 1050, 2921, 1907, -1657, 2109, - 939, 2317, -2250, 1833, 940, 2182, 3028, -1657, 5426, 3029, - 3585, 1316, 1316, 1316, 3333, 4119, 3334, 1316, 3101, 5137, - 1143, 3102, 3256, 852, 2318, 3257, 2319, 3261, 1542, 49, - 3262, 852, 5363, 5364, 852, 4546, 4781, 5393, 721, 1183, - 852, 1219, 50, 2435, 3487, 2898, 2899, 1543, -2636, -2636, - -2636, 1178, 1316, 3366, 852, 3407, 2109, 1174, 2652, 4178, - 4179, 2313, 1182, 5020, 3458, 51, 3760, 2109, 2286, 2896, - 2896, 3098, 5025, 816, 3467, 4919, 816, 2109, 3473, 52, - 3300, 2109, 1185, 747, 3474, 3769, 2316, 2109, -1716, -1716, - 3346, 1219, -1658, 1193, 3487, 852, 1316, 1544, 3488, 3489, - 3490, 4120, 41, 5429, 4404, 3475, 5378, 3506, 2109, 1195, - 2109, 5295, 3845, 3191, 2317, 3519, 3524, 3726, 2109, 3525, - 3727, 3449, 1196, 852, 3452, 3332, 3303, 3453, 3731, 3755, - 738, 3732, 3756, 1197, 3328, 3939, 45, 2318, 3940, 2319, - 3445, 3961, 3892, -1657, 2109, 4051, 1203, 1219, 4052, 1316, - 3487, 3585, -1720, -1720, 3488, 3489, 3490, -1719, -1719, 4061, - 4072, 1219, 4062, 2109, 3487, 2315, 4056, 1204, 3488, 3489, - 3490, 4069, 4148, 1205, 2313, 4149, 852, 49, 852, 3098, - 852, 3098, 4870, 1545, 4153, 4070, 4782, 4154, 1206, 1207, - 50, 4749, 2764, 2764, 2764, 2764, 1208, 1209, 2764, 2764, - 2764, 2764, 2764, 2764, 2764, 2764, 2764, 2764, 1213, 3585, - 2727, 4158, 1212, 51, 2936, 2607, 1940, 4182, 5442, 4394, - 2652, 1215, 2652, 897, 3040, 4054, 4447, 52, 1334, 1962, - 4467, 1546, 1337, 2109, 1547, 3991, 4958, 3564, 3585, 3565, - 3885, 4493, 3888, 2786, 2689, 2383, 2789, 2315, 3566, 836, - 3567, 3876, 1341, 3878, 2764, 2764, 4505, 816, 1342, 2109, - 4556, -1695, 4562, 2936, 3416, 4563, -1695, 594, 4568, 4569, - 3491, 2652, 2652, 864, 1343, 3019, 864, 1549, 4708, 864, - 5473, 4709, 1357, 1050, 1615, 1050, 3599, 4226, 852, 1362, - 4754, 4756, 3492, 4755, 2109, 4764, 1316, 4835, 2689, 3123, - 4836, 1316, 4920, 1347, 3493, 2652, 738, 4959, 2727, 4975, - 4960, 1363, 2689, 837, 738, 830, 1368, 738, 2316, 3284, - 4983, 1365, 1551, 4984, 1316, 1316, 1316, 4993, 1366, 1316, - 1907, 3945, 4999, -1695, 1379, 3913, 3984, 1316, 1316, 1316, - 1316, 4336, 5001, 4337, 1552, 3913, 2317, 5443, 3492, 5444, - 1316, 1394, 3585, 1316, 3493, 1316, 4706, 3096, 1365, 830, - -1646, 4588, 3492, 1050, 1554, 5012, 1316, 1316, 5013, 2318, - 1316, 2319, 1395, 5066, -1695, 3083, 5067, 4237, 4219, 3124, - 1398, 1402, 899, 838, 1316, 1408, 1316, 5106, 1316, 5136, - 2076, 1378, 5013, 1380, 4130, 5146, 3997, 1468, 2689, 3107, - 2316, 5147, 5148, 1444, 3525, 2109, 2313, 4525, 1316, 4528, - 3493, 5160, 816, 5166, 5161, -2280, 1907, 5169, 3160, 3586, - 3913, 1471, -2540, 5188, 3493, 1473, 2652, 1513, 2317, 1474, - 2315, 5194, 3125, 5200, 2689, 816, 2689, 3569, 3570, 3571, - 4199, 5201, 1316, 5204, 2689, 5206, 5205, 185, 5207, 5208, - 989, 2318, 5209, 2319, 986, 5235, 987, 1316, 5236, 988, - 5283, 1509, 2097, 5284, 830, 5287, 1514, 5288, 1907, 5316, - 2109, 3586, 4973, 5289, 5291, 3619, 2109, 2109, 3622, 5312, - 2920, 5336, 5313, 3285, 5337, 1515, 1526, 3585, 2313, 3126, - 5365, 5377, 1528, 3913, 5006, -2636, -2636, -2636, -2542, 3497, - 3498, 3499, 3500, 3501, 3502, 1538, 5403, 4021, 3583, 5013, - 4332, 5440, 5453, -2540, 5441, 5205, 4319, 5455, 1541, 839, - 5456, 1316, 5471, 3098, 5479, 5284, 1575, 5456, 1940, 1576, - 1591, 2315, 1601, 3374, 3376, 1602, 1605, 1610, 1611, 3384, - 3774, 4050, 1714, 1716, 1717, 3494, 3495, 3496, 1719, 3497, - 3498, 3499, 3500, 3501, 3502, 852, 1722, 852, 852, 852, - 3583, 1219, 3585, -2540, 3487, 2764, 4322, 3585, 3488, 3489, - 3490, 1726, 1727, 1735, 1736, -2540, 1739, 1742, 1748, 1745, - -2540, 1750, 1756, 2316, 1759, -2540, 4092, 3127, 5162, -2542, - 4488, -2540, 1761, 1752, -2540, 1770, 1771, 1775, -2540, 1776, - 738, 3494, 3495, 3496, -177, 3497, 3498, 3499, 3500, 3501, - 3502, 2317, 2315, 1778, 1779, 3494, 3495, 3496, 1781, 3497, - 3498, 3499, 3500, 3501, 3502, 1783, 1784, -2540, 1799, 593, - 1806, 3286, 2315, 1813, 2318, 1808, 2319, 207, 1820, -2542, - 1826, 3782, 1827, 1828, 1833, 1829, 1836, -2540, 1837, 1839, - 1853, -2542, 1855, 1868, 2613, 1867, -2542, 1871, 1872, 1879, - 3599, -2542, 2620, 1883, 1885, 1886, 3585, -2542, 3599, 1888, - -2542, 2313, 816, 1890, -2542, 1896, 1898, 1903, 3287, 1895, - 1906, 1909, 2632, 1910, 2316, 1912, 1967, 1937, -2540, 1972, - 1475, -2540, 1981, 1982, 1974, 1475, 1476, -2540, 1975, -1869, - -1876, 1476, 1989, -2542, 1990, 1992, 3128, 1991, 1993, 5159, - 52, -1866, 2317, -1867, 3129, 2315, 1995, 3130, 1996, 1997, - 1998, 1999, 3815, -2542, 2000, 1219, 2002, 2003, 3487, 2004, - 2005, -1870, 3488, 3489, 3490, 2318, -1868, 2319, 1478, 2006, - 2007, 2008, 4204, 1478, 2030, 2009, 2011, 2031, 2012, 4495, - 2013, 2014, 2015, -2540, 2016, 2017, 2062, 2018, 2064, 2066, - 2080, 2092, 3492, 2067, -2542, 2316, 2076, -2542, 2100, 2112, - 2115, 1382, 2313, -2542, 1384, 2146, 2037, 2157, 2148, 2161, - 1316, 2159, 4683, -2636, 2160, 2316, 1316, 2177, 2328, 2179, - 2178, 2180, 1480, 2317, 2185, 852, 3592, 1480, 738, 1481, - 3098, 3098, 1482, 2183, 1481, 2182, 752, 1482, 2039, 4516, - 1713, 2184, 2030, 2317, 850, 2031, 2318, 2186, 2319, 756, - 3604, 3604, 2187, 863, 3493, 4242, 2188, 1483, 2213, -2542, - 2727, 863, 1483, -2540, 863, 2194, 2318, 2219, 2319, 816, - 816, 816, 4366, 4367, 2037, 2225, 2250, 2254, 2256, 2257, - 2258, -2636, 2259, 2313, 3843, 2261, 816, -2540, 2262, -2540, - -2540, 1484, 3843, 2277, 2278, 2279, 1484, 2291, 2316, 2290, - 3938, 2292, 2303, 2313, 2307, 3536, 2039, 2309, 1940, 816, - 2310, 2311, 752, 2312, 2867, 2313, 2321, 2322, 1940, 816, - 816, 4404, 2325, 2327, 816, -2540, 2317, 2326, -2540, -2540, - -2540, 4439, 4440, 4441, 4442, 4443, 2332, 816, 2333, -2542, - 2342, 2336, 2343, 2353, 2359, 3934, 2344, 2347, -2636, 2318, - 1485, 2319, 1486, -2636, 2349, 1485, 3492, 1486, 2348, 2370, - 2377, 2380, 1487, -2542, 2350, -2542, -2542, 1487, 3959, 2356, - 1488, 1488, 2360, 3547, 2361, 2392, 1488, 2365, 4544, 2395, - 2366, 2399, 1183, 1489, 4086, 2378, 2313, 2418, 1489, 2385, - -2636, 2386, 2390, 2391, 2394, 2396, 2401, 2402, 852, 2407, - 2408, -2542, 2419, 2420, -2542, -2542, -2542, 2424, 2425, 2430, - 2434, 2446, 2453, 2457, 2459, 2460, -2636, 2462, 3493, 816, - 2466, -2636, 2329, 2467, 2468, 1491, 1492, 1606, 2469, 2461, - 1491, 1492, 2470, 2477, 2476, 816, 2478, 2046, 2479, 2481, - 2480, 2483, 2488, 2489, 2490, 3494, 3495, 3496, 2495, 3497, - 3498, 3499, 3500, 3501, 3502, 2330, 2498, 1316, -2636, 2499, - 1607, 2502, 620, 2513, 2507, 2516, 1316, 2527, 1560, 2531, - 2532, 2535, 1316, 2540, 1316, 2551, 2554, 1316, 2558, 4004, - 2557, 2571, 1316, 1316, 1316, 1316, 2567, 2574, 1316, 1316, - 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 2576, 2580, - 2591, 1316, 1316, 2593, 2594, 2046, 4477, 2598, 2585, 2599, - 2601, 1316, 2612, 2602, 2603, 1316, 2604, 2605, 4542, 1316, - 1494, 5420, 5421, 2614, 2615, 1494, 2616, 1316, -2636, 2630, - 1316, 2617, 1316, 2631, 2665, 2673, 2686, 2699, 2732, 830, - 2737, 1316, 2781, 2031, 1316, 1316, 2787, 2791, 2806, 1316, - 1316, 2800, 2818, 2840, 4090, 2820, 1316, 2841, 830, 2855, - 2860, 2863, 2864, 816, 816, 816, 594, 2874, 3599, 3586, - 4112, 2865, 2866, 837, 4112, 4126, 4112, 2890, 4727, 2878, - 2891, 1316, 4094, 4095, 4096, 4097, 2892, 2907, 2914, 2925, - 2893, 2926, 3599, 4586, 2954, 2928, -2636, 2957, 2959, 2961, - 2968, 2962, 2973, 2764, 2983, 1316, 2978, 2985, 2979, 3494, - 3495, 3496, 4757, 3497, 3498, 3499, 3500, 3501, 3502, 2920, - 738, 1316, 2993, 3003, 2981, -2636, 2989, 3004, 738, 3007, - 3020, 4668, 2053, 2054, 2055, 2056, 2057, 2058, 3021, 4177, - 1940, 1940, 3026, 2455, 1331, 4633, 4634, 1335, 4636, 3037, - 3044, 3045, 3889, 3058, 4874, 3583, 3063, 3064, 3583, 3090, - 852, 852, 852, 852, 3085, 3100, 3091, 992, 1542, 3093, - 4626, 3108, 5026, 3112, 3132, 3136, 3192, 3230, 3204, 838, - 3211, 3212, 3215, 3235, 3236, 3237, 3243, 1543, 3250, 2286, - 3224, 3254, 3248, -2636, 3255, 3263, 3275, 3290, 4875, 3276, - 2053, 2054, 2055, 2056, 2057, 2058, 3292, 3294, 4231, 3305, - 3296, 3314, 3322, 3317, 3308, 3323, 2384, 3324, 3325, 850, - 3326, 3330, 3338, 4876, 4873, 3336, 3339, 5070, 3583, 863, - 3342, 3343, 3357, 3358, 3962, 3360, 863, 1544, 3361, 863, - 4877, 3362, 3364, 3367, 4878, 3369, 3370, 3371, 3385, 3372, - 3373, 3397, 3399, 3377, 1860, 3400, 3386, 3404, 1542, 3422, - 4886, 3406, 3843, 4685, 4879, 3409, 5060, 4880, 5062, 3410, - 1907, 3411, 3412, 3413, 1904, 3414, 2700, 1543, 1869, 3425, - 4276, 3424, 4881, 3426, 3433, 3436, 4265, 1180, 3441, 3472, - 3443, 3363, 3450, 3448, 3447, 3451, 3455, 3483, 3368, 2109, - 4221, -2133, 3469, 4316, 596, 3470, 3471, 3476, 3477, 3538, - 3479, 3482, 3505, 3511, 3518, 738, 3532, 2030, 3387, 3533, - 2031, 3521, 3555, 1545, 2032, 2033, 2034, 1544, 3393, 3546, - 3556, 3394, 3558, 3395, 3396, 3560, 3587, 3398, 4692, 3601, - -1722, 2035, 3607, 3402, 3559, 3403, 3606, 852, 3405, 2037, - 3562, 816, 3609, 852, 3611, 1316, 2038, 3613, 3620, 3633, - 3638, 3641, 816, 3627, 4882, 3640, 3649, 3652, 4357, 3645, - 3687, 1546, 4883, 3654, 1547, 3676, 3661, 3677, 2286, 3693, - 3689, 2039, 3646, 1219, 2764, 2383, 3487, 3695, 3694, 3696, - 3488, 3489, 3490, 816, 3699, 3711, 3712, 3586, 3714, 3722, - 3720, 3721, 3730, 3740, 3757, 3759, 3761, 3191, 1962, 2764, - 3764, 3444, 3770, 1545, 4917, 4884, 4405, 1549, 3765, 3768, - 5219, 5221, 3788, 5213, 3772, 1219, 3773, 816, 3487, 3786, - 3787, 2455, 3488, 3489, 3490, 1316, 1316, 3789, 4414, 3790, - 3791, 3792, 3793, 3794, 4822, 4982, 3796, 3798, 3800, 4496, - 3795, 3801, 3797, 3805, 3799, 3802, 3807, 3809, 3811, 3812, - 2416, 1546, 1551, 3098, 1547, 3098, 3825, 3814, 3818, 3819, - 3820, 3822, 816, 897, 3829, 2383, 3830, 3832, 3838, 3849, - 3852, 3890, 3883, 3893, 1552, 3894, 3583, 3884, 3896, 596, - 4841, 2040, 3898, 3901, 4846, 3913, 2041, 3912, 596, 872, - 850, 3915, 3922, 3929, 1554, 1316, 596, 1549, 872, 596, - 3928, 863, 3932, 3933, 4444, 3937, 1316, 863, 2042, 2043, - 863, 3936, 872, 3949, 3925, 3958, 3969, 3971, 3978, 3993, - 3979, 3990, 3980, 2044, 3981, 3965, 3982, 3983, 3966, 3994, - 4001, 3967, 4002, 3992, 4003, 3985, 1316, 4005, 4006, 4007, - 4008, 4009, 1551, 1984, 3508, 3487, 1316, 1316, 4013, -2132, - 3507, 5314, 4063, 1316, 1316, 4075, 2045, 4022, 1316, 4074, - 4047, 4048, 4049, 1316, 1552, 4087, 1316, 1316, 4104, 4093, - 2046, 1316, 4504, 2047, 3492, 4055, 4078, 1316, 816, 816, - 816, 816, 1810, 1811, 1554, 4112, 4126, 4112, 738, 1316, - 4112, 4113, 4128, 4518, 4105, 4132, 4134, 3586, 4145, 4151, - 4138, 3586, 2030, 4727, 4136, 2031, 4142, 4533, 4147, 4137, - 4161, 2764, 738, 4169, 4190, 4192, 3492, 4193, 4198, 738, - 4992, 4205, 899, 4206, 4207, 4208, 4210, 4212, 4215, 1316, - 4873, 4992, 4214, 3619, 2037, 4229, 3493, 4244, 2920, 4232, - 4245, -2636, 4246, 4545, 4547, 4260, 4247, 4257, 4258, 4558, - 4259, 4271, 4274, 747, 4284, 4290, 1316, 5213, 4285, 4293, - 4273, 2048, 4261, 4262, 4308, 4310, 2039, 3653, 4312, 5226, - 4220, 4315, 4324, 4326, 4327, 4323, 3098, 3098, 3493, 4354, - 4330, 4340, 4351, 4363, 4369, 4377, 3583, 4384, 4387, 2652, - 3583, 4389, 4383, 4396, 2286, 4390, 1168, 1169, 4406, 4977, - 4411, 4412, 4424, 4425, 4427, 4429, 4437, 4445, 4599, 4430, - 5064, 4428, 4432, 4433, 4449, 4451, 4457, 4469, 4478, 4464, - 4591, 4479, 4480, 4473, -2134, 5282, 4521, 4481, 4514, 4598, - 4474, 4522, 4482, 4079, 4530, 4529, 4501, 4519, 4595, 2024, - 4486, 4536, 4517, 4537, 4534, 4543, 4552, 4555, 4535, 4557, - 4559, 3713, 2030, 3715, 4564, 2031, 4565, 1316, 2049, 4574, - 4570, 2050, 2051, 2052, 4593, 2053, 2054, 2055, 2056, 2057, - 2058, 4594, 4597, 4604, 4603, 4605, -2636, 4625, 3478, 852, - 4623, -2636, 4616, 4619, 2037, 2764, 4628, 4629, 4637, 1542, - 4646, -2636, 870, 5186, 852, 5059, 4645, 4651, 4659, 4660, - 4666, 906, 4665, 4674, 4675, 4669, 4682, 1050, 1543, 4680, - 4681, 4684, 4688, 4690, 4698, 927, 2039, 4705, -2636, 4712, - 4710, 4720, 4701, 4722, 1316, 4723, 4724, 3494, 3495, 3496, - 4732, 3497, 3498, 3499, 3500, 3501, 3502, 5167, 594, 4725, - 738, 4737, 4743, 4750, 2286, 4744, 4751, 4758, 4761, 4753, - 4760, 4769, 4762, 1940, 4804, 4763, 4785, 4810, 1544, 4220, - 4813, 4816, 4827, 4837, 4775, 2046, 2216, 4838, 1316, 3494, - 3495, 3496, 4778, 3497, 3498, 3499, 3500, 3501, 3502, 4789, - 4832, 852, 4807, 3332, 4843, 4829, 4868, 4887, 4831, 897, - 3803, 5183, 4703, 4889, 4849, 4850, 3810, 4854, 4350, 4895, - 4859, 4897, 596, 4847, 5366, 4860, 4861, 4899, 4900, 4902, - 4905, 4903, 4924, 816, 872, 4906, 4923, 4931, 4936, 4933, - 872, 4221, 4940, 4942, 4961, 5151, -2636, 4949, 3599, 4950, - 4965, -2636, 4963, 872, 4978, 4981, 4964, 4985, 4991, 897, - 5031, 5006, 5168, 5010, 1545, 4845, 5170, 5029, 5172, 872, - 4995, 4998, 5002, 1316, 596, 5032, -2636, 5004, 5435, 5038, - 1099, 5021, 1316, 5044, 596, 872, 5087, 5089, -2636, 5094, - 5099, 596, 5098, 872, 596, 5101, 5108, 5113, 5119, 1316, - 1316, 5120, 5131, 1316, 5127, 5132, 1099, 872, 5133, 4888, - 5149, 5140, 1546, 2764, 2764, 1547, 5158, 872, 594, 5150, - 5143, 4112, 5171, 1050, 5174, 3586, 2383, 5141, 4222, 5175, - 3586, 5142, 5179, 3586, 594, 2046, 3191, 5180, 4791, 5435, - 1316, 1316, 5193, 5197, 5224, 5225, 5218, 5229, 5231, 5238, - 5234, 5241, 4808, 5242, 4177, 5435, 1316, 5248, 1549, 5263, - 5268, 5260, 5269, 5261, 5305, 5297, 5315, 4177, 899, 852, - 852, 852, 5227, -2636, 5278, 5262, 5307, 4088, 5228, 5324, - 2053, 2054, 2055, 2056, 2057, 2058, 5299, 5356, 5280, 738, - 5361, 5323, 5325, 5342, 738, 5368, 5375, 5381, 738, 596, - 596, 5386, 5389, 1551, 5412, 872, 5395, 3583, 3968, 5414, - 3970, 5413, 3972, 5422, 3583, 5424, 5428, 864, 899, 3583, - 5445, 3976, 3583, 4613, 4614, 1552, -2636, 5446, 4617, 4618, - 5449, 596, 5448, 5450, 5454, 5462, 5463, 5469, 5472, 5470, - 5474, 5475, 3843, 3583, 3299, 1554, 2099, 4223, 1367, 3594, - 4224, -2557, 2431, 1472, 3089, 3705, 3583, 4228, 3165, 4235, - 5310, 864, 3999, 5059, 816, 5427, 5308, 4333, 3203, 3837, - 5081, 5212, 5387, 4365, 4941, 2030, 4357, 4916, 2031, 816, - 3643, 3408, 4664, 4820, 816, 5300, 3098, 5383, 5232, 5230, - 5322, 4956, 5400, 2286, 3648, 4415, 4395, 5191, 4358, 3273, - 4921, 3274, 4233, 3724, 3900, 1562, 4382, 2037, 3264, 816, - 4922, 3908, 4927, 4405, -2636, 4686, 5388, 5476, 5467, 4901, - 3855, 3850, 5327, -2636, 4848, 5040, 5199, 852, 816, 4177, - 2053, 2054, 2055, 2056, 2057, 2058, 754, 1008, 4954, 2039, - 4446, 4851, -2557, 1008, 2506, 5016, 596, 596, 1709, 2313, - 5439, 2931, 3634, 4421, 1316, 596, 1008, 1316, 1959, 1316, - 2573, 5138, 1099, 2618, 2581, 1128, 596, 1050, 2693, 3808, - 4263, 3904, 596, 1969, 2695, 596, 1747, 2694, 1051, 1316, - 4283, 5347, 5461, 1344, 4400, 1316, 2193, 1099, 830, 3586, - 2643, 2876, -2557, 4791, 181, 2877, 2869, 4809, 4548, 1316, - 5294, 4155, 1099, 2110, -2557, 2072, 4082, 3597, 5009, -2557, - 2906, 3608, 2143, 2142, -2557, 181, 4135, 5290, 3583, 5173, - -2557, 2887, 4540, -2557, 2905, 4108, 2147, -2557, 4512, 4527, - 4997, 816, 5157, 1940, 4102, 4156, 5156, 4103, 5464, 5367, - 2152, 5423, 5281, 4976, 2592, 4057, 829, 596, 596, -2636, - 5292, 2845, 5293, 4806, -2636, 3553, -2557, 3226, 1316, 3464, - 3551, 2854, 0, 0, 0, 0, 897, 0, 852, 852, - 852, 852, 0, 0, 0, 0, -2557, 0, 3583, 0, - 0, 0, 0, 850, 0, 0, 850, 1099, 0, 0, - 0, -2636, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 594, 0, 0, 0, - 0, 0, 5072, 0, 0, 0, 0, -2557, 0, 0, - -2557, 0, 0, 0, 872, 0, -2557, 816, 0, 0, - 3586, 863, 863, 0, 0, 0, 0, 0, 2046, 0, - 0, 0, 872, 0, 0, 0, 863, 0, 0, 863, - 0, 596, 5122, 0, 0, 0, 0, 0, 0, 872, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 738, 842, - 0, 0, -2557, 0, 0, 1316, 0, 872, 594, 0, - 0, 1316, 0, 0, 0, 5165, 0, 0, 0, 0, - 0, 1099, 1316, 872, 0, 0, 1316, 0, 1316, 863, - 1316, 0, 863, 863, 0, 0, 0, 4177, 872, 3583, - 0, 872, 0, 852, 0, 899, 5176, 0, 0, -2636, - 0, 0, 0, 596, 2030, 752, 1316, 2031, 0, 0, - 0, -2636, -2636, -2636, 0, 0, 5304, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -2557, 596, 0, 0, 2037, 0, 0, 0, - 0, 0, 0, 2038, 0, 0, 0, 3583, 0, 0, - 0, 1940, 1940, 0, 0, 0, -2557, 0, -2557, -2557, - 0, 596, 596, 596, 0, 596, 0, 0, 2039, 0, - 0, 0, 0, 0, 0, 0, 3583, 0, 0, 0, - 0, 0, 852, 0, 0, 596, 0, 0, 0, 5246, - 5353, 5354, 0, 1316, -2557, 0, -2636, -2557, -2557, -2557, - 0, 5257, 0, 2053, 2054, 2055, 2056, 2057, 2058, 872, - 0, 0, 0, 0, 0, 0, 0, 872, 872, 0, - 2030, 0, 0, 2031, 0, 0, 1316, 1316, 1316, 0, - 0, 0, 3191, 0, 0, 1316, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1316, 0, 0, 5009, 0, - 0, 0, 2037, 2920, 0, 0, 0, 596, 0, -2636, - 0, 596, 596, 4436, 0, 0, 0, 4438, 864, 0, - 0, 0, 0, 0, 0, 0, 596, 0, 2040, 0, - 1099, 0, 0, 2041, 2039, 852, 1709, 0, 0, 0, - 3583, 0, 1940, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 738, 738, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2286, 738, 0, - 2044, 0, 594, 0, 0, 0, 0, 1316, 5328, 0, - 0, 0, 0, 0, 0, 0, 4177, 0, 0, 0, - 0, 0, 864, 864, 1316, 0, 1099, 0, 0, 0, - 185, 4083, 0, 5352, 1316, 0, 0, 5349, 5165, 5350, - 0, 850, 5351, 0, 0, 0, 0, 2046, 863, 0, - 0, 863, 863, 0, 0, 0, 0, 0, 0, 852, - 0, 0, 0, 0, 0, 0, 0, 1099, 0, 0, - 0, 0, 0, 0, -2636, 1219, 5477, 5478, 3487, -2636, - 0, 0, 3488, 3489, 3490, 0, 0, 0, 5411, 0, - 0, 5257, 852, 852, 0, 0, 4177, 1447, 0, 0, - 1099, 0, 0, 0, 0, 3583, 0, 0, 185, 0, - 0, 5352, 0, 0, 0, 5349, -2636, 5350, 0, 0, - 5351, 0, 0, 1316, 1316, 2030, 0, 0, 2031, 0, - 0, 1448, 0, 0, 0, 1316, 0, 0, 2048, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 181, 0, 2037, 4577, 872, - 0, 1449, 0, 2046, -2636, 0, 0, 0, 1316, 0, - 0, 0, 0, 0, 596, 596, 596, 0, 1316, 0, - 3583, 0, 0, 0, 5210, 3583, 0, 0, 0, 2039, - 1450, 0, 852, 0, 0, 4177, 0, 0, 0, 0, - 4601, 4602, 0, 0, 5165, 0, 0, 185, 594, 0, - 5352, 0, 0, 0, 5349, 0, 5350, 0, 0, 5351, - 0, 0, 0, 0, 0, 1451, 0, 0, 864, 864, - 0, 0, 0, 0, 0, 2049, 0, 0, -2636, -2636, - -2636, 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, - 0, 0, 181, 829, -2636, 0, 4499, 0, 0, 0, - 0, 1452, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -2636, 1099, 0, 0, - 0, 0, 0, 0, 3583, 0, 4643, 4644, 0, 0, - 0, 0, 0, 0, 1099, 1453, 0, 0, 0, -2636, - 0, 0, 0, 1099, -2636, 0, 0, 0, 0, 0, - 1709, 0, 0, 0, 0, 1099, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1454, 1455, 0, 0, - 738, 0, 738, 1418, 872, 0, 0, 0, 3493, 0, - 0, -2636, 872, 0, 0, 0, 0, 0, 0, 0, - 0, -2636, 0, 0, 872, 0, 0, 0, 2053, 2054, - 2055, 2056, 2057, 2058, 0, 1456, 0, 0, 0, 36, - 0, 1099, 0, 1457, 0, 842, 0, 181, 596, 0, - 0, 596, 1458, 0, 0, 1099, 0, 0, 2046, 0, - 1459, 596, 0, 0, 0, 0, 0, 1099, 1460, 0, - 0, 0, 4739, 0, 4740, 4741, 0, 0, 0, 1099, - 1461, 0, 0, 0, 0, 0, 0, 0, 1462, 0, - 4745, 0, 0, 0, 0, 0, 596, 596, 0, 872, - 872, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 596, 0, 872, 596, 0, 0, 0, 0, 0, - 0, 0, 0, 1099, 1099, 0, 872, 872, 0, 0, - 0, 0, 2429, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 872, 0, 1463, 0, 0, 0, 0, -2636, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 596, 0, 0, 596, 596, 0, - 0, 738, 0, 0, 0, 0, 850, 0, 0, 0, - 5433, 0, 863, 0, 0, 863, 0, 0, 863, 3494, - 3495, 3496, 0, 3497, 3498, 3499, 3500, 3501, 3502, 0, - 596, 0, 596, 0, 0, 0, 0, 596, 596, 0, - 0, 0, 0, 0, 596, 596, 596, 0, 0, 0, - 596, 0, 596, 596, 596, 596, 596, 596, 0, 596, - 0, 596, 596, 0, 0, 596, -2636, 0, 0, 0, - 0, 5433, 0, 2053, 2054, 2055, 2056, 2057, 2058, 1099, - 596, 596, 596, 596, 1709, 0, 0, 5433, 596, 0, - 0, 0, 596, 0, 0, 596, 0, 0, 596, 596, - 596, 596, 596, 596, 596, 596, 596, 0, 596, 0, - 0, 0, 0, 665, 0, 596, 2030, 596, 666, 2031, - 0, 0, 0, 2032, 2033, 2034, 0, 2517, 0, 0, - 667, 0, 0, 0, 0, 2534, 0, 0, 0, 0, - 2035, 0, 0, 0, 0, 0, 0, 2429, 2037, 0, - 0, 0, 0, 668, 0, 2038, 0, 596, 593, 0, - 0, 0, 0, 0, 0, 0, 669, 0, 0, 0, - 0, 0, 0, 596, 0, 0, 0, 0, 0, 0, - 2039, 670, 596, 596, 0, 0, 0, 181, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 671, - 0, 0, 0, 0, 0, 0, 4972, 872, 0, 0, - 593, 0, 0, 0, 1099, 0, 0, 0, 1099, 1099, - 0, 0, 672, 2611, 0, 872, 0, 0, 0, 0, - 1709, 872, 0, 673, 0, 872, 0, 0, 0, 0, - 0, 674, 0, 872, 0, 0, 0, 0, 0, 0, - 2429, 0, 0, 675, 0, 1985, 0, 0, 676, 0, - 0, 872, 0, 0, 596, 677, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1994, 596, 5018, 0, 0, - 1099, 0, 0, 596, 678, 0, 596, 596, 0, 0, - 2040, 0, 0, 0, 1099, 2041, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2010, 872, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2042, 2043, 0, - 0, 2022, 0, 0, 0, 872, 872, 0, 0, 5065, - 679, 0, 2044, 0, 1099, 0, 0, 2029, 0, 0, - 0, 0, 2030, 0, 0, 2031, 0, 0, 0, 2032, - 2033, 2034, 0, 1447, 0, 0, 0, 1709, 872, 0, - 0, 1709, 0, 0, 680, 2045, 2035, 0, 0, 2036, - 0, 0, 2703, 0, 2037, 0, 0, 681, 0, 2046, - 0, 2038, 2047, 0, 872, 0, 1709, 1448, 682, 0, - 0, 872, 0, 0, 0, 0, 0, 872, 207, 683, - 0, 0, 684, 0, 872, 0, 2039, 0, 872, 0, - 0, 842, 842, 872, 842, 0, 0, 1516, 0, 0, - 0, 2704, 0, 0, 0, 0, 0, 0, 685, 0, - 0, 686, 0, 872, 0, 687, 0, 688, 872, 0, - 0, 0, 872, 0, 689, 1709, 1450, 690, 0, 0, - 0, 0, 0, 2705, 0, 872, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 691, 0, 872, 0, - 2048, 0, 692, 0, 0, 0, 2706, 693, 872, 0, - 694, 1451, 0, 0, 695, 0, 0, 2707, 0, 0, - 0, 0, 696, 0, 697, 596, 596, 596, 0, 698, - 0, 596, 0, 0, 0, 0, 0, 2708, 0, 0, - 2922, 699, 2709, 0, 0, 0, 2040, 1452, 0, 0, - 0, 2041, 0, 0, 700, 0, 0, 0, 2938, 0, - 0, 0, 0, 0, 2942, 0, 596, 1099, 2945, 0, - 0, 0, 0, 2042, 2043, 0, 1709, 0, 0, 0, - 0, 1453, 0, 0, 0, 0, 0, 0, 2044, 0, - 0, 0, 0, 2710, 2969, 0, 0, 2049, 0, 0, - 2050, 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, - 596, 0, 1517, 1455, 2711, 0, 0, 3528, 0, 1418, - 0, 2045, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2046, 0, 0, 2047, 0, - 3024, 0, 0, 0, 0, 0, 0, 0, 0, 1099, - 0, 1518, 0, 0, 872, 36, 0, 0, 1008, 1457, - 0, 0, 0, 596, 0, 0, 0, 0, 1458, 0, - 0, 2030, 0, 0, 2031, 0, 1459, 0, 2032, 2033, - 2034, 0, 207, 2712, 1519, 0, 2713, 0, 0, 0, - 0, 3074, 0, 0, 0, 2035, 1461, 0, 0, 0, - 0, 0, 0, 2037, 1462, 0, 0, 0, 0, 872, - 2038, 0, 2714, 0, 0, 2715, 0, 3103, 0, 0, - 0, 2716, 0, 0, 3113, 0, 2048, 664, 2717, 0, - 3118, 0, 0, 0, 0, 2039, 751, 1008, 0, 0, - 0, 3133, 0, 0, 0, 0, 3137, 0, 0, 0, - 2030, 872, 0, 2031, 0, 0, 2718, 2032, 2033, 2034, - 1463, 2719, 0, 0, 2720, 0, 3150, 1099, 0, 872, - 0, 3152, 0, 0, 2035, 3155, 0, 872, 0, 0, - 0, 596, 2037, 2721, 1099, 5379, 0, 596, 3172, 2038, - 596, 0, 0, 596, 0, 0, 0, 0, 0, 1099, - 0, 3197, 0, 0, 0, 0, 0, 0, 2722, 0, - 596, 1008, 0, 0, 2039, 596, 0, 0, 0, 0, - 0, 0, 0, 2049, 0, 0, 2050, 2051, 2052, 0, - 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 596, 596, - 596, 0, 0, 596, 0, 2040, 0, 0, 0, 0, - 2041, 596, 596, 596, 596, 0, 0, 0, 0, 1709, - 0, 0, 0, 0, 596, 1709, 0, 596, 0, 596, - 0, 0, 2042, 2043, 0, 0, 0, 0, 0, 0, - 596, 596, 0, 0, 596, 0, 0, 2044, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 596, 0, - 596, 0, 596, 0, 0, 593, 2227, 0, 593, 0, - 0, 2228, 0, 0, 0, 0, 0, 0, 0, 0, - 2045, 0, 596, 0, 2040, 0, 0, 0, 0, 2041, - 0, 0, 0, 596, 2046, 0, 2030, 2047, 0, 2031, - 0, 872, 0, 2032, 2033, 2034, 2229, 0, 0, 0, - 0, 2042, 2043, 0, 0, 0, 596, 0, 0, 2230, - 2035, 0, 0, 0, 0, 0, 2044, 0, 2037, 0, - 0, 596, 0, 0, 2231, 2038, 0, 181, 593, 0, - 0, 0, 0, 0, 0, 596, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2045, - 2039, 0, 0, 0, 1099, 0, 0, 1099, 0, 1099, - 0, 0, 0, 2046, 1099, 2232, 2047, 0, 0, 0, - 0, 0, 0, 0, 0, 2048, 2233, 0, 0, 872, - 872, 181, 0, 0, 0, 596, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2234, 0, 0, 0, - 0, 2235, 0, 0, 3421, 0, 872, 0, 0, 872, - 0, 0, 0, 1099, 0, 0, 0, 0, 0, 0, - 0, 0, 3435, 0, 0, 0, 0, 0, 0, 0, - 3421, 0, 1099, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2048, 2807, 0, 1099, 0, 0, - 2040, 0, 0, 0, 0, 2041, 0, 0, 0, 0, - 0, 0, 2049, 2236, 0, 2050, 2051, 2052, 0, 2053, - 2054, 2055, 2056, 2057, 2058, 0, 0, 2042, 2043, 2790, - 0, 0, 0, 0, 1709, 1709, 1709, 0, 0, 0, - 0, 0, 2044, 0, 0, 0, 0, 2237, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 872, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1099, 0, - 1099, 0, 0, 0, 0, 2045, 0, 0, 872, 0, - 0, 207, 2238, 0, 0, 0, 0, 0, 0, 2046, - 0, 2049, 2047, 0, 2050, 2051, 2052, 872, 2053, 2054, - 2055, 2056, 2057, 2058, 0, 0, 0, 181, 3851, 0, - 0, 0, 0, 0, 2239, 0, 0, 0, 0, 0, - 2240, 0, 0, 0, 0, 0, 593, 2241, 0, 2030, - 2242, 0, 2031, 0, 0, 0, 2032, 2033, 2034, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2035, 0, 0, 0, 0, 0, 1099, - 2243, 2037, 0, 2030, 0, 0, 2031, 2244, 2038, 0, - 2032, 2033, 2034, 0, 0, 2245, 0, 0, 0, 872, - 2048, 0, 2246, 0, 596, 0, 0, 2035, 0, 0, - 596, 0, 0, 2039, 0, 2037, 0, 0, 1099, 0, - 0, 0, 2038, 0, 0, 0, 0, 2247, 984, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1099, 0, 0, 0, 2039, 0, 0, - 1709, 1099, 0, 0, 0, 0, 0, 872, 0, 872, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3655, - 0, 0, 872, 0, 872, 0, 0, 0, 0, 0, - 0, 1049, 664, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1709, 2049, 0, 0, - 2050, 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, - 0, 0, 0, 0, 4015, 0, 0, 0, 0, 0, - 1099, 0, 0, 2040, 0, 0, 0, 0, 2041, 0, - 0, 0, 0, 0, 0, 0, 0, 872, 1099, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2042, 2043, 1099, 0, 0, 0, 593, 2040, 0, 0, - 593, 0, 2041, 0, 0, 2044, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1192, - 0, 3735, 0, 0, 2042, 2043, 0, 0, 872, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2045, 2044, - 0, 0, 0, 0, 0, 1211, 872, 0, 0, 0, - 0, 0, 2046, 1319, 0, 2047, 1328, 1049, 1330, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 872, 0, - 0, 872, 2045, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3348, 0, 2046, 0, 0, 2047, - 0, 596, 0, 0, 1099, 0, 0, 0, 0, 0, - 596, 0, 0, 0, 0, 1447, 596, 0, 596, 0, - 0, 596, 0, 0, 0, 1099, 596, 596, 596, 596, - 0, 0, 596, 596, 596, 596, 596, 596, 596, 596, - 596, 596, 0, 0, 0, 596, 596, 0, 0, 1448, - 1099, 0, 3816, 2048, 0, 596, 0, 0, 0, 596, - 0, 1709, 0, 596, 0, 0, 0, 0, 0, 0, - 0, 596, 0, 0, 596, 0, 596, 0, 0, 0, - 0, 0, 181, 0, 1099, 596, 0, 2048, 596, 596, - 0, 0, 0, 596, 596, 0, 0, 0, 0, 0, - 596, 0, 0, 0, 0, 0, 0, 0, 1450, 0, - 596, 0, 0, 596, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 596, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1475, 0, - 0, 0, 0, 1451, 1476, 0, 0, 4671, 0, 596, - 2049, 1542, 0, 2050, 2051, 2052, 0, 2053, 2054, 2055, - 2056, 2057, 2058, 0, 0, 596, 0, 4066, 0, 0, - 1543, 1099, 0, 0, 3349, 0, 0, 0, 0, 1452, - 0, 0, 0, 596, 2049, 0, 1478, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, - 0, 4171, 0, 2030, 0, 0, 2031, 0, 0, 0, - 2032, 2033, 2034, 1453, 872, 0, 0, 0, 0, 0, - 1544, 0, 0, 0, 0, 0, 0, 2035, 0, 0, - 0, 0, 0, 0, 0, 2037, 0, 0, 0, 0, - 1480, 2429, 2038, 0, 0, 1455, 0, 1481, 0, 0, - 1482, 1418, 0, 0, 0, 0, 0, 0, 0, 3986, - 0, 0, 0, 0, 0, 1709, 0, 2039, 0, 0, - 1709, 1099, 1709, 0, 0, 1483, 0, 0, 0, 0, - 0, 0, 0, 0, 4000, 0, 2022, 36, 0, 0, - 0, 3350, 0, 0, 1709, 1099, 0, 0, 0, 0, - 1458, 0, 0, 0, 1049, 0, 1545, 593, 1459, 1484, - 0, 0, 0, 1709, 593, 0, 2271, 0, 0, 593, - 0, 1049, 593, 4787, 0, 0, 0, 0, 1461, 872, - 2022, 0, 872, 0, 0, 0, 1462, 0, 0, 0, - 0, 0, 0, 593, 0, 0, 0, 2807, 0, 0, - 0, 0, 0, 0, 1546, 1964, 593, 1547, 3351, 0, - 0, 0, 0, 3557, 0, 0, 0, 0, 1548, 0, - 1486, 0, 0, 0, 0, 0, 0, 2040, 0, 3576, - 1487, 0, 2041, 1049, 0, 0, 0, 0, 0, 1488, - 0, 0, 1463, 0, 0, 0, 3352, 0, 181, 596, - 1549, 1489, 0, 0, 2042, 2043, 863, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2044, - 0, 0, 0, 0, 872, 872, 0, 0, 1099, 0, - 0, 3576, 0, 0, 872, 829, 0, 0, 0, 0, - 1550, 596, 0, 1491, 1492, 1551, 0, 0, 0, 0, - 863, 0, 2045, 872, 0, 0, 0, 0, 0, 2026, - 3348, 0, 0, 0, 0, 0, 2046, 1552, 2028, 2047, - 0, 0, 0, 1553, 0, 0, 0, 0, 1099, 596, - 596, 1447, 2070, 0, 0, 0, 0, 1554, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1049, 0, 0, 2087, 2088, 0, 0, 0, 1049, - 1049, 0, 0, 2030, 0, 1448, 2031, 4200, 593, 0, - 2032, 2033, 2034, 0, 0, 1447, 872, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2035, 1494, 0, - 0, 0, 0, 0, 0, 2037, 0, 0, 0, 596, - 0, 0, 2038, 0, 0, 0, 0, 2048, 0, 1448, - 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1450, 0, 0, 2039, 593, 0, - 0, 0, 0, 0, 2030, 0, 0, 2031, 0, 0, - 596, 2032, 2033, 2034, 0, 0, 0, 0, 0, 0, - 596, 596, 0, 1099, 0, 0, 0, 596, 596, 1451, - 0, 0, 596, 1099, 0, 0, 2037, 596, 1450, 0, - 596, 596, 1475, 2038, 0, 596, 0, 0, 1476, 0, - 0, 596, 4298, 0, 0, 4301, 0, 0, 0, 0, - 3349, 1477, 0, 596, 0, 1452, 0, 0, 2039, 0, - 0, 596, 0, 1451, 2049, 596, 0, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, - 1478, 4465, 0, 0, 0, 0, 0, 0, 0, 1453, - 0, 0, 0, 596, 0, 0, 0, 2040, 0, 1452, - 0, 0, 2041, 0, 0, 5100, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 596, 1455, 0, 0, 2042, 2043, 0, 1418, 0, 593, - 1479, 0, 0, 1453, 1480, 0, 0, 0, 1099, 2044, - 2388, 1481, 0, 0, 1482, 0, 2393, 4379, 0, 0, - 0, 0, 0, 0, 0, 872, 0, 0, 0, 0, - 1709, 0, 0, 36, 0, 1455, 2429, 1457, 2040, 1483, - 0, 1418, 2045, 2041, 0, 0, 1458, 1099, 0, 0, - 0, 0, 0, 0, 1459, 0, 2046, 593, 0, 2047, - 0, 0, 2271, 872, 0, 2042, 2043, 0, 1099, 0, - 0, 0, 0, 1484, 1461, 872, 0, 36, 0, 2270, - 2044, 1457, 1462, 0, 0, 0, 593, 0, 0, 0, - 1458, 596, 0, 0, 0, 0, 0, 0, 1459, 0, - 0, 0, 872, 0, 3351, 0, 2271, 0, 0, 3421, - 0, 0, 0, 2045, 0, 0, 0, 0, 1461, 0, - 0, 0, 0, 0, 0, 0, 1462, 2046, 0, 0, - 0, 0, 1485, 1099, 1486, 0, 0, 0, 1463, 0, - 0, 0, 3352, 181, 1487, 0, 0, 2048, 0, 0, - 0, 0, 0, 1488, 0, 0, 0, 0, 596, 0, - 0, 0, 0, 0, 1085, 1489, 181, 0, 0, 0, - 0, 2030, 596, 0, 2031, 0, 0, 0, 2032, 2033, - 2034, 0, 1463, 0, 0, 0, 0, 0, 0, 0, - 1085, 0, 0, 0, 0, 872, 0, 0, 0, 0, - 593, 0, 596, 2037, 1490, 0, 0, 1491, 1492, 0, - 2038, 0, 0, 0, 0, 0, 0, 0, 2048, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2528, - 0, 0, 0, 2533, 0, 2039, 0, 1493, 0, 0, - 0, 0, 0, 1099, 2049, 1099, 0, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, - 0, 4500, 0, 0, 0, 0, 0, 863, 0, 872, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1475, 596, 0, 0, - 0, 1099, 1476, 0, 0, 0, 596, 0, 0, 0, - 0, 0, 1494, 0, 0, 1577, 0, 0, 0, 0, - 0, 0, 0, 596, 596, 2049, 0, 596, 2050, 2051, - 2052, 5331, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, - 0, 0, 596, 0, 1478, 593, 0, 0, 0, 596, - 0, 863, 863, 0, 596, 2040, 0, 596, 596, 0, - 2041, 0, 0, 0, 596, 596, 0, 0, 0, 0, - 2022, 0, 0, 0, 0, 0, 4610, 0, 596, 0, - 596, 0, -2636, -2636, 0, 872, 4101, 872, 4620, 4106, - 0, 596, 0, 0, 0, 0, 1578, 2044, 1480, 0, - 0, 0, 0, 0, 0, 1481, 0, 0, 1482, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 593, 0, 0, 0, 0, 593, 0, 0, 0, 0, - -2636, 1099, 872, 1483, 0, 0, 0, 0, 0, 0, - 0, 596, 0, -129, 2046, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2749, 1721, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 1484, 0, 0, - 0, 2, 0, 3, 4, 0, 0, 0, 0, 1709, - 0, 1738, 0, 0, 0, 596, 0, 0, 0, 5, - 0, 0, 0, 0, 0, 0, 1749, 0, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 8, 9, 0, 0, 0, 0, 0, 10, - 0, 11, 0, 0, 593, 0, 1485, 0, 1486, 0, - 0, 0, 12, 0, 13, 2048, 0, 5466, 1487, 0, - 4945, 0, 0, 0, 0, 0, 2862, 1488, 0, 0, - 0, 14, 0, 596, 15, 1099, 0, 863, 863, 1489, - 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, - 17, 0, 0, 0, 18, 0, 0, 0, 596, 1099, - 19, 596, 3421, 596, 0, 0, 0, 0, 20, 0, - 21, 0, 0, 0, 0, 0, 22, 0, 1579, 0, - 0, 1491, 1492, 596, 0, 0, 0, 0, 0, 596, - 0, 0, 23, 596, 0, 0, 0, 0, 0, 1099, - 0, 0, 0, 596, 0, 0, 0, 0, 0, 24, - 0, 1580, 2049, 0, 0, 2050, 2051, 2052, 0, 2053, - 2054, 2055, 2056, 2057, 2058, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1049, 0, 0, 0, 0, - 0, 0, 0, 0, 1709, 0, 0, 0, 0, 25, - 26, 0, 1099, 0, 0, 27, 0, 1099, 1099, 0, - 0, 0, 596, 0, 0, 0, 0, 28, 3421, 872, - 3421, 0, 0, 0, 0, 1965, 1494, 0, 0, 29, - 0, 872, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3576, 0, 0, - 0, 0, 0, 0, 0, 0, 1330, 0, 0, 0, - 596, 0, 0, 0, 0, 30, 0, 0, 0, 0, - 0, 0, 0, 31, 0, 0, 181, 0, 0, 0, - 0, 0, 0, 0, 596, 0, 0, 32, 0, 0, - 0, 0, 0, 33, 34, 0, 35, 0, 0, 0, - 0, 36, 0, 0, 0, 0, 37, 0, 0, 38, - 0, 0, 0, 0, 0, 0, 39, 0, 1099, 1099, - 0, 0, 40, 41, 0, 0, 0, 0, 0, 0, - 42, 0, 0, 0, 43, 1330, 0, 0, 0, 596, - 0, 0, 596, 0, 44, 596, 0, 0, 0, 0, - 0, 0, 1330, 0, 0, 0, 596, 45, 0, 0, - 596, 0, 596, 0, 596, 0, 0, 0, 0, 0, - 0, 596, 0, 0, 0, 0, 0, 46, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, - 596, 0, 0, 48, 0, 0, 0, 0, 49, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 0, 3200, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1709, 0, 872, 0, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3229, 52, 0, - 3229, -129, 3229, 0, 0, 0, 3229, 3576, 3229, 3229, - 0, 3576, 0, 0, 0, 0, 0, 3229, 3229, 3229, - 0, 0, 0, 0, 602, 2030, 0, 596, 2031, 0, - 653, 602, 2032, 2033, 2034, 596, 706, 0, 602, 0, - 0, 181, 181, 0, 602, 0, 0, 760, 0, 2035, - 0, 0, 0, 1475, 0, 0, 0, 2037, 0, 1476, - 596, 596, 596, 0, 2038, 0, 827, 827, 0, 596, - 1709, 0, 1577, 1099, 0, 3309, 0, 0, 0, 596, - 0, 0, 0, 0, 0, 0, 0, 0, 872, 2039, - 0, 2335, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1478, 596, 0, 0, 2030, 0, 3341, 2031, 0, - 0, 0, 2032, 2033, 2034, 0, 1049, 872, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2035, - 0, 0, 0, 0, 0, 0, 0, 2037, 0, 0, - 0, 0, 0, 0, 2038, 0, 0, 0, 0, 0, - 0, 0, 0, 1578, 0, 1480, 596, 0, 0, 0, - 0, 596, 1481, 0, 0, 1482, 0, 0, 0, 2039, - 596, 1049, 0, 0, 0, 0, 596, 596, 596, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 596, 0, - 1483, 0, 0, 0, 0, 0, 0, 0, 0, 2040, - 0, 0, 0, 0, 2041, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 859, 0, 0, 0, 0, 0, - 0, 872, 901, 0, 1484, 903, 2042, 2043, 908, 909, - 0, 912, 0, 914, 0, 0, 920, 0, 922, 0, - 0, 2044, 0, 0, 0, 596, 0, 0, 0, 0, - 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2045, 1475, 0, 596, 596, 2040, - 0, 1476, 0, 1485, 2041, 1486, 0, 0, 2046, 596, - 181, 2047, 0, 0, 0, 1487, 0, 0, 0, 1475, - 0, 2458, 0, 1709, 1488, 1476, 2042, 2043, 0, 0, - 0, 0, 0, 0, 0, 0, 1489, 0, 2475, 0, - 0, 2044, 596, 1478, 0, 0, 0, 0, 0, 0, - 0, 0, 596, 0, 0, 0, 0, 0, 0, 2497, - 0, 0, 0, 0, 0, 0, 0, 1478, 0, 596, - 0, 0, 0, 0, 2045, 3162, 0, 0, 1491, 1492, - 0, 0, 596, 0, 1709, 0, 0, 0, 2046, 0, - 0, 2047, 0, 0, 0, 0, 0, 1480, 0, 2048, - 1709, 0, 596, 596, 1481, 0, 0, 1482, 3163, 0, - 0, 3421, 0, 0, 0, 2575, 0, 0, 0, 0, - 0, 1480, 0, 1049, 0, 0, 0, 0, 1481, 2583, - 0, 1482, 1483, 0, 0, 3576, 0, 0, 0, 0, - 3576, 1085, 0, 3576, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2597, 0, 0, 1483, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1484, 0, 0, 0, - 0, 0, 0, 1494, 0, 0, 0, 0, 2030, 2048, - 0, 2031, 0, 0, 0, 2032, 2033, 2034, 0, 0, - 1484, 0, 0, 0, 0, 0, 2049, 2626, 1085, 2050, - 2051, 2052, 2035, 2053, 2054, 2055, 2056, 2057, 2058, 0, - 2037, 0, 0, 4748, 0, 0, 0, 2038, 0, 0, - 0, 0, 0, 0, 0, 1485, 0, 1486, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1487, 0, 0, - 0, 1049, 2039, 0, 0, 0, 1488, 0, 0, 1485, - 0, 1486, 0, 0, 0, 0, 0, 0, 1489, 0, - 0, 1487, 0, 0, 0, 0, 0, 0, 0, 0, - 1488, 0, 0, 0, 0, 0, 2049, 0, 0, 2050, - 2051, 2052, 1489, 2053, 2054, 2055, 2056, 2057, 2058, 0, - 0, 0, 0, 4759, 0, 0, 2030, 2251, 181, 2031, - 1491, 1492, 0, 2032, 2033, 2034, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2035, 3033, 0, 0, 1491, 1492, 0, 0, 2037, 0, - 2252, 0, 3729, 2794, 0, 2038, 181, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1475, - 0, 993, 2040, 0, 1493, 1476, 0, 2041, 0, 1002, - 2039, 0, 0, 0, 0, 0, 1015, 1016, 0, 0, - 1022, 0, 1025, 1026, 0, 0, 0, 1028, 0, 2042, - 2043, 0, 0, 0, 0, 0, 0, 3767, 1046, 0, - 0, 0, 0, 0, 2044, 1494, 0, 1478, 0, 3576, - 0, 0, 0, 1056, 0, 0, 0, 0, 0, 2022, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1494, - 0, 0, 0, 0, 0, 0, 0, 2045, 1124, 0, - 1126, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1142, 2046, 0, 0, 2047, 0, 0, 0, 0, 0, - 0, 1480, 0, 3806, 0, 0, 0, 0, 1481, 0, - 0, 1482, 0, 0, 0, 0, 0, 0, 0, 0, - 2040, 0, 602, 0, 0, 2041, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1483, 0, 0, 0, - 0, 0, 0, 0, 0, 3229, 0, 2042, 2043, 0, - 0, 0, 0, 0, 0, 0, 1201, 0, 0, 3836, - 0, 0, 2044, 0, 0, 3847, 0, 0, 0, 2030, - 1484, 0, 2031, 3847, 0, 0, 2032, 2033, 2034, 1049, - 0, 1049, 2048, 0, 2988, 0, 0, 0, 0, 0, - 3576, 0, 0, 2035, 0, 2045, 0, 0, 3005, 0, - 181, 2037, 0, 0, 0, 0, 0, 0, 2038, 2046, - 827, 0, 2047, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3911, 0, 1485, - 0, 1486, 0, 2039, 0, 0, 0, 0, 3038, 0, - 0, 1487, 0, 0, 1438, 0, 0, 0, 0, 0, - 1488, 0, 0, 0, 0, 0, 0, 0, 3944, 1049, - 0, 0, 1489, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 181, 0, 0, 0, 0, 2049, - 0, 0, 2050, 2051, 2052, 0, 2053, 2054, 2055, 2056, - 2057, 2058, 0, 0, 0, 0, 4768, 0, 0, 0, - 2048, 3206, 0, 0, 1491, 1492, 0, 0, 0, 0, - 0, 1475, 2030, 0, 0, 2031, 1609, 1476, 0, 2032, - 2033, 2034, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3207, 0, 2035, 1720, 0, 0, - 0, 0, 0, 2040, 2037, 0, 0, 0, 2041, 1731, - 0, 2038, 0, 0, 1734, 0, 0, 0, 0, 1478, - 0, 0, 0, 0, 1737, 0, 0, 0, 0, 1741, - 2042, 2043, 0, 0, 0, 0, 2039, 1744, 0, 0, - 0, 0, 0, 1754, 0, 2044, 1758, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2049, 0, 1494, - 2050, 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, - 0, 0, 0, 1480, 4771, 0, 0, 0, 2045, 0, - 1481, 0, 0, 1482, 0, 0, 0, 1812, 0, 0, - 0, 0, 2046, 0, 0, 2047, 0, 0, 0, 0, - 0, 3259, 4067, 0, 0, 0, 0, 0, 1483, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2030, 0, 0, 2031, 0, 0, 0, 2032, 2033, 2034, - 0, 0, 1484, 0, 0, 0, 2040, 0, 0, 0, - 0, 2041, 0, 0, 2035, 0, 0, 0, 0, 0, - 0, 0, 2037, 0, 0, 0, 181, 0, 0, 2038, - 0, 0, 0, 2042, 2043, 0, 0, 0, 0, 0, - 0, 0, 0, 2048, 0, 0, 0, 0, 2044, 0, - 0, 181, 0, 0, 2039, 0, 0, 0, 0, 0, - 0, 1485, 602, 1486, 602, 0, 602, 0, 602, 0, - 602, 602, 602, 1487, 0, 0, 0, 602, 0, 0, - 0, 2045, 1488, 0, 0, 851, 853, 0, 1960, 857, - 0, 0, 0, 0, 1489, 2046, 0, 0, 2047, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 913, - 0, 0, 0, 0, 0, 0, 923, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5410, - 0, 0, 0, 3681, 0, 0, 1491, 1492, 0, 0, - 2049, 0, 0, 2050, 2051, 2052, 0, 2053, 2054, 2055, - 2056, 2057, 2058, 0, 0, 0, 0, 4818, 0, 0, - 0, 3434, 1475, 3847, 2040, 0, 3682, 1475, 1476, 2041, - 0, 0, 0, 1476, 0, 0, 0, 0, 3446, 0, - 1542, 0, 0, 0, 0, 0, 2048, 4269, 0, 0, - 0, 2042, 2043, 3454, 0, 4277, 0, 0, 4278, 1543, - 4279, 0, 0, 0, 0, 0, 2044, 0, 0, 0, - 1478, 0, 0, 0, 0, 1478, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 181, 0, - 0, 1494, 0, 0, 0, 0, 0, 0, 0, 2045, - 0, 0, 4318, 0, 0, 0, 0, 0, 0, 1544, - 0, 0, 0, 2046, 0, 3229, 2047, 0, 0, 3229, - 3229, 0, 3229, 0, 1480, 0, 0, 3836, 827, 1480, - 0, 1481, 0, 0, 1482, 0, 1481, 0, 0, 1482, - 0, 0, 0, 2049, 0, 0, 2050, 2051, 2052, 0, - 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, 1483, - 4853, 0, 0, 0, 1483, 0, 0, 2030, 0, 0, - 2031, 0, 0, 0, 2032, 2033, 2034, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2035, 0, 1484, 0, 1545, 0, 0, 1484, 2037, - 0, 0, 0, 0, 2048, 0, 2038, 0, 0, 0, - 2249, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4418, 0, 0, 0, - 0, 2039, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1546, 0, 0, 1547, 0, 0, 0, - 0, 0, 1485, 0, 1486, 0, 0, 1548, 0, 1486, - 0, 0, 0, 0, 1487, 0, 0, 0, 0, 1487, - 0, 0, 0, 1488, 0, 0, 0, 0, 1488, 0, - 2340, 0, 0, 0, 0, 1489, 0, 0, 0, 1549, - 1489, 4454, 4454, 4454, 0, 4454, 4454, 4454, 4454, 4454, - 0, 2049, 0, 0, 2050, 2051, 2052, 0, 2053, 2054, - 2055, 2056, 2057, 2058, 0, 0, 2030, 3659, 4894, 2031, - 0, 0, 0, 2032, 2033, 2034, 0, 1491, 1492, 3139, - 0, 0, 1491, 1492, 1551, 0, 3670, 0, 0, 0, - 2035, 2040, 0, 0, 0, 0, 2041, 0, 2037, 0, - 0, 0, 0, 0, 0, 2038, 1552, 1493, 0, 0, - 0, 0, 3140, 0, 0, 0, 0, 0, 2042, 2043, - 996, 0, 0, 0, 999, 0, 1554, 0, 0, 0, - 2039, 0, 0, 2044, 0, 0, 0, 0, 1024, 0, - 0, 0, 0, 0, 0, 1029, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2045, 0, 0, 0, - 0, 0, 1494, 0, 4539, 0, 4541, 1494, 0, 0, - 2046, 0, 3752, 2047, 3754, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2030, 0, 0, 2031, 0, - 0, 0, 2032, 2033, 2034, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2035, - 0, 0, 0, 0, 0, 0, 0, 2037, 0, 0, - 0, 0, 0, 0, 2038, 0, 0, 0, 0, 0, - 2040, 0, 0, 0, 0, 2041, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2030, 0, 0, 2031, 2039, - 0, 0, 2032, 2033, 2034, 0, 0, 2042, 2043, 0, - 0, 2048, 0, 3804, 0, 0, 0, 2501, 0, 2035, - 0, 0, 2044, 0, 0, 0, 0, 2037, 0, 0, - 0, 0, 0, 0, 2038, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3823, 0, 0, 2045, 0, 0, 0, 2039, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2046, - 0, 0, 2047, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4640, 4641, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3229, 0, 3229, 3229, 2049, 2040, - 3229, 2050, 2051, 2052, 2041, 2053, 2054, 2055, 2056, 2057, - 2058, 0, 0, 0, 0, 5202, 0, 1507, 1508, 0, - 0, 0, 0, 0, 0, 0, 2042, 2043, 0, 0, - 0, 0, 0, 0, 2624, 0, 2625, 865, 874, 0, - 0, 2044, 0, 0, 3038, 865, 0, 874, 865, 0, - 2048, 0, 0, 2636, 0, 2637, 0, 0, 0, 2040, - 4700, 874, 0, 0, 2041, 0, 0, 0, 0, 602, - 0, 602, 0, 602, 2045, 602, 3960, 602, 0, 0, - 0, 602, 0, 0, 0, 0, 2042, 2043, 2046, 0, - 0, 2047, 0, 0, 4726, 0, 0, 0, 0, 0, - 0, 2044, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1740, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4454, 0, 0, - 0, 0, 0, 0, 2045, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1765, 1766, 0, 2049, 2046, 0, - 2050, 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, - 0, 0, 0, 0, 5330, 0, 0, 0, 0, 0, - 1807, 0, 0, 0, 0, 0, 0, 0, 4014, 2048, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4023, - 0, 0, 2030, 0, 0, 2031, 0, 0, 0, 2032, - 2033, 2034, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4046, 0, 2035, 0, 0, 0, - 0, 0, 0, 0, 2037, 0, 0, 0, 0, 2048, - 0, 2038, 0, 0, 1876, 1878, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1965, 0, - 0, 0, 0, 0, 0, 0, 2039, 0, 0, 0, - 0, 0, 0, 3847, 0, 0, 2049, 0, 0, 2050, - 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, - 0, 0, 0, 5399, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2923, 2924, 0, 0, - 0, 0, 0, 0, 0, 0, 3229, 0, 0, 0, - 0, 0, 0, 0, 0, 2939, 2940, 0, 0, 0, - 2943, 2944, 0, 0, 0, 2947, 2049, 0, 0, 2050, - 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, 2958, - 0, 0, 0, 0, 0, 0, 2967, 0, 0, 0, - 2970, 2971, 0, 0, 2974, 2975, 0, 0, 0, 0, - 0, 2980, 0, 0, 0, 0, 2040, 0, 0, 0, - 0, 2041, 0, 0, 0, 0, 2999, 0, 3001, 0, - 0, 1475, 0, 0, 0, 0, 0, 1476, 0, 0, - 0, 0, 0, 2042, 2043, 0, 0, 3025, 0, 0, - 0, 0, 3027, 0, 0, 0, 0, 0, 2044, 0, - 0, 0, 0, 0, 0, 3032, 0, 0, 0, 0, - 0, 0, 0, 0, 3039, 0, 0, 3043, 0, 1478, - 3046, 3049, 3051, 0, 0, 0, 0, 3059, 3062, 0, - 0, 2045, 0, 0, 0, 0, 0, 3075, 0, 0, - 0, 0, 3084, 874, 0, 2046, 0, 3088, 2047, 874, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 874, 3104, 0, 0, 0, 0, 0, 0, - 3114, 3115, 0, 1480, 0, 0, 3119, 0, 874, 0, - 1481, 0, 0, 1482, 0, 0, 0, 3134, 3135, 0, - 0, 0, 3138, 865, 874, 0, 0, 0, 0, 0, - 865, 0, 874, 865, 3145, 0, 0, 3148, 1483, 5054, - 5054, 0, 3151, 0, 0, 0, 874, 3153, 3154, 0, - 0, 0, 3157, 1049, 0, 3161, 874, 5074, 0, 3168, - 3169, 3170, 3171, 0, 3173, 0, 2048, 5082, 0, 0, - 0, 0, 1484, 0, 0, 0, 0, 3198, 3199, 0, - 3201, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3209, 3210, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4368, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2308, 1485, 0, 1486, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1487, 874, 0, 0, 0, 0, 0, - 0, 0, 1488, 0, 0, 3267, 0, 0, 0, 0, - 0, 0, 0, 2049, 1489, 0, 2050, 2051, 2052, 0, - 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, 0, - 5452, 0, 0, 3304, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3737, 0, 0, 1491, 1492, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2411, 2412, 2413, 2414, 0, 0, 3738, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1049, - 0, 0, 0, 5216, 0, 5217, 0, 0, 0, 5222, - 5223, 0, 0, 0, 2030, 0, 0, 2031, 0, 0, - 0, 2032, 2033, 2034, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2030, 0, 0, 2031, 1711, 2035, 0, - 2032, 2033, 2034, 0, 0, 0, 2037, 1965, 0, 0, - 0, 1494, 0, 2038, 0, 865, 0, 2035, 0, 0, - 0, 865, 0, 0, 865, 2037, 0, 0, 0, 0, - 0, 0, 2038, 0, 0, 0, 0, 0, 2039, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2039, 0, 0, - 3439, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2464, 2465, 0, 0, 0, 0, 0, 0, 0, - 0, 3457, 0, 0, 0, 5054, 0, 5054, 0, 0, - 0, 0, 0, 0, 2491, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 877, 0, 0, 0, 0, 0, - 0, 0, 4578, 0, 0, 0, 911, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 929, 0, 2536, - 2537, 2538, 2539, 0, 0, 0, 0, 0, 2040, 0, - 0, 0, 0, 2041, 0, 0, 0, 0, 0, 0, - 0, 4600, 0, 0, 0, 0, 0, 2040, 0, 0, - 0, 0, 2041, 874, 0, 2042, 2043, 0, 0, 0, - 0, 0, 4615, 0, 0, 0, 0, 0, 0, 0, - 2044, 874, 0, 0, 2042, 2043, 0, 0, 0, 0, - 0, 0, 0, 1049, 0, 0, 0, 0, 874, 2044, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2045, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 874, 2046, 0, 0, - 2047, 0, 2045, 0, 0, 0, 0, 4642, 0, 0, - 0, 0, 874, 0, 0, 0, 2046, 2634, 0, 2047, - 0, 0, 0, 2638, 0, 0, 0, 874, 0, 0, - 874, 0, 873, 0, 0, 0, 5054, 0, 0, 0, - 0, 873, 0, 0, 0, 5434, 1447, 0, 0, 0, - 0, 0, 0, 0, 0, 873, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1448, 0, 0, 0, 0, 0, 0, 0, 2048, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3656, 5434, 2048, 0, 3658, - 1533, 0, 0, 0, 0, 3660, 0, 0, 0, 4731, - 0, 0, 5434, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3671, 3673, 0, 0, 0, 3673, 1450, - 0, 0, 0, 3684, 3685, 3686, 0, 3688, 874, 0, - 0, 0, 2804, 0, 0, 0, 874, 874, 0, 0, - 0, 0, 0, 0, 0, 1965, 0, 0, 0, 0, - 3710, 0, 0, 0, 1451, 0, 0, 0, 0, 0, - 3716, 3717, 3718, 3719, 0, 2049, 0, 0, 2050, 2051, - 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, - 0, 0, 5465, 0, 2049, 0, 0, 2050, 2051, 2052, - 1452, 2053, 2054, 2055, 2056, 2057, 2058, 3736, 0, 2452, - 3741, 3742, 3743, 0, 0, 1711, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3763, 0, - 0, 0, 0, 0, 1453, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3771, 0, - 0, 0, 0, 2030, 0, 0, 2031, 0, 0, 0, - 2032, 2033, 2034, 0, 0, 1534, 1455, 0, 943, 0, - 0, 0, 1418, 0, 990, 0, 0, 2035, 0, 0, - 0, 2879, 0, 0, 0, 2037, 0, 0, 0, 0, - 0, 0, 2038, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1535, 0, 0, 0, 36, 0, - 0, 0, 1457, 0, 0, 0, 0, 2039, 0, 0, - 3813, 1458, 0, 0, 0, 0, 0, 0, 3817, 1459, - 0, 0, 0, 2986, 2987, 0, 0, 1536, 0, 0, - 0, 0, 0, 0, 3000, 0, 3002, 0, 0, 1461, - 3006, 0, 0, 0, 0, 0, 0, 1462, 0, 3831, - 0, 0, 0, 0, 0, 0, 2880, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3877, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 874, 0, - 0, 0, 0, 1463, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2040, 0, 0, - 0, 1200, 2041, 1965, 0, 0, 0, 0, 3914, 0, - 0, 0, 0, 3920, 0, 0, 0, 873, 0, 0, - 0, 0, 0, 873, 2042, 2043, 1323, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 873, 0, 0, 2044, - 0, 0, 0, 3804, 3957, 1346, 0, 0, 0, 0, - 3144, 0, 873, 3147, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1374, 873, 0, - 0, 0, 2045, 0, 0, 0, 873, 0, 0, 0, - 0, 0, 0, 3973, 0, 3974, 2046, 0, 0, 2047, - 873, 0, 0, 0, 0, 0, 1965, 0, 0, 0, - 873, 1965, 1965, 0, 0, 0, 0, 0, 0, 0, - 0, 1506, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1711, - 0, 0, 3232, 0, 0, 0, 0, 0, 0, 0, - 3239, 0, 0, 3242, 0, 0, 0, 0, 0, 3244, - 0, 0, 0, 874, 0, 0, 0, 0, 0, 0, - 0, 874, 0, 3260, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 874, 0, 0, 0, 2048, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2030, 873, 0, - 2031, 0, 0, 0, 2032, 2033, 2034, 0, 0, 0, - 0, 0, 0, 0, 3306, 0, 0, 0, 0, 0, - 0, 2035, 0, 5139, 0, 0, 0, 0, 0, 2037, - 0, 0, 0, 0, 0, 0, 2038, 0, 0, 0, - 0, 0, 3329, 0, 2881, 0, 1763, 0, 0, 0, - 0, 0, 0, 0, 0, 865, 865, 0, 874, 874, - 0, 2039, 0, 0, 0, 0, 0, 0, 0, 0, - 865, 0, 874, 865, 0, 1801, 1804, 1805, 0, 0, - 0, 0, 0, 0, 2049, 874, 874, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 3389, 0, 3391, - 0, 874, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 865, 0, 0, 865, 865, 0, 0, - 0, 1710, 0, 0, 0, 0, 0, 3507, 4188, 0, - 4189, 0, 3508, 0, 0, 0, 0, 4191, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2040, 0, 4201, 0, 0, 2041, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4209, - 0, 0, 0, 0, 0, 0, 0, 0, 2042, 2043, - 0, 0, 0, 0, 0, 0, 0, 3456, 4230, 0, - 0, 0, 0, 2044, 0, 0, 0, 0, 0, 0, - 1323, 0, 0, 1711, 0, 0, 4234, 5286, 0, 0, - 0, 0, 0, 0, 0, 0, 4243, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2045, 0, 0, 0, - 0, 1323, 0, 0, 0, 4272, 0, 0, 0, 0, - 2046, 0, 0, 2047, 0, 0, 0, 0, 4280, 4281, - 4282, 0, 0, 0, 0, 4286, 4287, 4288, 4289, 0, - 0, 0, 4291, 4292, 0, 0, 0, 0, 4299, 4300, - 0, 4302, 4303, 4304, 4305, 4306, 4307, 0, 4309, 0, - 0, 0, 0, 0, 0, 0, 0, 4317, 0, 0, - 4320, 4321, 0, 0, 0, 0, 0, 873, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2030, 3673, 873, 2031, 0, 0, 0, - 2032, 2033, 2034, 0, 0, 0, 874, 0, 0, 0, - 0, 2048, 873, 0, 0, 0, 4342, 2035, 0, 0, - 0, 0, 0, 0, 874, 2037, 0, 0, 0, 1711, - 874, 0, 2038, 0, 874, 0, 0, 0, 0, 0, - 873, 0, 874, 0, 0, 0, 0, 2101, 0, 0, - 0, 0, 0, 0, 0, 0, 873, 2039, 0, 0, - 874, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 873, 0, 0, 873, 0, 0, 0, 0, 0, - 0, 0, 865, 0, 0, 865, 865, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2154, 0, 0, - 0, 0, 0, 0, 0, 0, 874, 0, 2049, 0, - 0, 2050, 2051, 2052, 3673, 2053, 2054, 2055, 2056, 2057, - 2058, 0, 0, 2030, 874, 874, 2031, 0, 0, 0, - 2032, 2033, 2034, 0, 3662, 0, 3663, 3664, 3665, 0, - 0, 0, 0, 0, 0, 0, 0, 2035, 4448, 0, - 0, 0, 0, 0, 0, 2037, 1711, 874, 0, 0, - 1711, 0, 2038, 0, 0, 0, 0, 2040, 0, 0, - 0, 0, 2041, 0, 0, 0, 2280, 0, 0, 0, - 0, 0, 0, 874, 0, 1711, 2304, 2039, 0, 0, - 874, 0, 873, 0, 2042, 2043, 874, 0, 0, 0, - 873, 873, 0, 874, 0, 0, 0, 874, 0, 2044, - 0, 0, 874, 0, 0, 0, 0, 2341, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 874, 0, 0, 0, 0, 874, 0, 0, - 2364, 874, 2045, 2367, 1711, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 874, 0, 2046, 0, 0, 2047, - 0, 0, 0, 0, 0, 0, 0, 874, 0, 1710, - 0, 0, 5359, 0, 0, 0, 0, 874, 0, 0, - 0, 0, 0, 0, 4058, 0, 0, 0, 0, 0, - 0, 0, 0, 2415, 0, 0, 0, 2040, 0, 0, - 0, 0, 2041, 0, 0, 0, 0, 2433, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2042, 2043, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2044, - 0, 0, 0, 0, 0, 1711, 0, 2048, 0, 0, - 0, 0, 0, 0, 4581, 0, 0, 0, 4582, 4583, - 4584, 4585, 0, 4059, 4587, 0, 0, 0, 0, 0, - 0, 0, 2045, 0, 3824, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2046, 0, 0, 2047, - 0, 0, 0, 0, 0, 0, 4606, 4607, 4608, 0, - 4609, 0, 4611, 4612, 0, 0, 0, 0, 0, 0, - 0, 0, 5360, 0, 4621, 4622, 0, 0, 2456, 0, - 0, 0, 0, 874, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4627, 0, 0, 2049, 0, 0, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, - 0, 0, 873, 0, 4638, 0, 0, 0, 0, 0, - 0, 0, 2510, 2030, 0, 0, 2031, 2048, 874, 0, - 2032, 2033, 2034, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2035, 0, 0, - 3466, 2553, 0, 0, 0, 2037, 0, 0, 2566, 0, - 0, 0, 2038, 0, 0, 0, 0, 0, 0, 0, - 874, 0, 0, 0, 0, 0, 0, 0, 0, 1299, - 1299, 0, 0, 0, 0, 0, 0, 2039, 874, 4691, - 0, 0, 0, 0, 0, 0, 874, 3977, 0, 0, - 0, 0, 0, 0, 0, 0, 865, 0, 0, 865, - 0, 0, 865, 0, 0, 0, 0, 0, 4719, 0, - 0, 0, 0, 0, 2049, 0, 0, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, - 0, 0, 0, 4742, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1710, 2641, 0, 0, 2030, 0, 0, - 2031, 0, 0, 0, 2032, 2033, 2034, 0, 1711, 0, - 0, 0, 0, 0, 1711, 0, 0, 873, 0, 0, - 0, 2035, 0, 0, 0, 873, 0, 2040, 0, 2037, - 0, 0, 2041, 0, 1323, 1323, 2038, 873, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2692, 0, 0, 2042, 2043, 1622, 1626, 0, 0, - 0, 2039, 0, 0, 0, 0, 0, 0, 0, 2044, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 602, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 874, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2045, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 873, 873, 0, 0, 2046, 0, 0, 2047, - 0, 0, 0, 0, 0, 0, 873, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 873, - 873, 4842, 0, 0, 0, 0, 0, 0, 2853, 0, - 0, 0, 0, 0, 0, 873, 0, 0, 2859, 4852, - 0, 0, 0, 0, 4857, 4858, 0, 0, 0, 0, - 0, 2040, 0, 0, 0, 0, 2041, 0, 874, 874, - 0, 0, 0, 0, 0, 0, 0, 1374, 0, 4194, - 4195, 4196, 4197, 0, 0, 1374, 0, 1374, 2042, 2043, - 0, 0, 0, 0, 0, 874, 0, 2048, 874, 0, - 0, 0, 0, 2044, 0, 0, 0, 4918, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1323, 0, 0, 0, 0, 0, 0, 4935, 0, 0, - 0, 0, 0, 0, 0, 0, 2045, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1098, - 2046, 0, 0, 2047, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3673, 0, 0, 0, 1710, 0, 0, - 4971, 0, 3480, 0, 0, 1098, 0, 0, 0, 0, - 0, 0, 0, 1711, 1711, 1711, 0, 0, 0, 0, - 0, 0, 0, 0, 2049, 0, 0, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 874, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 874, 0, 0, - 0, 0, 0, 1987, 0, 0, 5011, 0, 0, 0, - 0, 2048, 0, 0, 0, 0, 874, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5028, 0, - 0, 0, 3042, 2001, 0, 0, 4338, 0, 0, 5036, - 0, 0, 4341, 0, 0, 0, 0, 0, 3065, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 873, 2019, 2020, 2021, 0, 2023, 0, 0, 0, 3092, - 0, 0, 0, 0, 0, 0, 0, 0, 873, 0, - 0, 0, 0, 1710, 873, 2065, 0, 0, 873, 0, - 0, 0, 0, 0, 0, 0, 873, 0, 874, 0, - 0, 0, 5105, 0, 0, 0, 0, 0, 2049, 0, - 0, 2050, 2051, 2052, 873, 2053, 2054, 2055, 2056, 2057, - 2058, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3166, 3167, 0, 0, 0, 0, 1711, - 0, 0, 0, 0, 0, 0, 874, 2121, 874, 0, - 873, 2133, 2138, 0, 3673, 0, 0, 0, 0, 0, - 0, 874, 0, 874, 0, 0, 0, 0, 873, 873, - 0, 0, 0, 0, 0, 1625, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1711, 2030, 0, 0, 2031, - 0, 1098, 0, 2032, 2033, 2034, 0, 0, 0, 0, - 1710, 873, 0, 0, 1710, 0, 0, 0, 0, 0, - 2035, 0, 0, 3512, 0, 5190, 1098, 0, 2037, 0, - 0, 0, 0, 0, 0, 2038, 874, 873, 0, 1710, - 5203, 1098, 0, 0, 873, 0, 0, 0, 0, 0, - 873, 3293, 0, 0, 0, 0, 0, 873, 0, 0, - 2039, 873, 0, 0, 0, 0, 873, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 873, 874, 0, 0, - 0, 873, 0, 0, 5233, 873, 0, 0, 1710, 0, - 0, 0, 0, 0, 0, 874, 0, 0, 873, 5244, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 873, 0, 1097, 0, 0, 1098, 874, 0, 0, - 874, 873, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2030, 0, 0, 2031, 1097, - 0, 0, 2032, 2033, 2034, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2035, - 2040, 0, 0, 0, 0, 2041, 0, 2037, 0, 0, - 0, 0, 0, 0, 2038, 0, 0, 0, 0, 5303, - 0, 0, 0, 0, 1622, 1622, 1622, 2042, 2043, 1710, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2039, - 1711, 0, 2044, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5326, 3438, 0, 0, 0, 0, - 1098, 0, 0, 0, 0, 2045, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2046, - 0, 0, 2047, 2030, 0, 0, 2031, 0, 0, 0, - 2032, 2033, 2034, 0, 0, 0, 0, 873, 4635, 0, - 0, 0, 0, 0, 0, 0, 0, 2035, 0, 0, - 3523, 0, 0, 4639, 0, 2037, 0, 0, 0, 0, - 3517, 0, 2038, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2040, - 0, 5392, 0, 0, 2041, 0, 0, 2039, 0, 0, - 0, 0, 873, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2042, 2043, 0, 0, - 2048, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2044, 0, 874, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 873, 0, 0, 0, 0, 0, - 4704, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3568, 0, 873, 0, 2045, 0, 0, 0, 0, 0, - 873, 0, 0, 0, 0, 1097, 0, 0, 2046, 0, - 0, 2047, 0, 1374, 1711, 0, 0, 0, 0, 1711, - 0, 1711, 0, 0, 0, 0, 0, 0, 0, 0, - 1097, 0, 0, 0, 0, 0, 0, 2040, 0, 0, - 0, 0, 2041, 1711, 0, 1097, 0, 2049, 0, 2176, - 2050, 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, - 0, 0, 1711, 0, 2042, 2043, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 874, 2044, - 0, 874, 1710, 0, 0, 0, 0, 0, 1710, 0, - 0, 0, 0, 0, 0, 2030, 0, 0, 2031, 2048, - 0, 0, 2032, 2033, 2034, 0, 0, 0, 0, 0, - 0, 0, 2045, 0, 0, 2176, 0, 0, 0, 2035, - 0, 0, 0, 0, 0, 0, 2046, 2037, 0, 2047, - 1097, 0, 0, 0, 2038, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4823, 4824, - 4824, 0, 0, 0, 0, 0, 1098, 0, 0, 2039, - 0, 0, 0, 0, 873, 0, 0, 2735, 0, 0, - 0, 0, 0, 874, 874, 0, 0, 0, 0, 0, - 2755, 0, 2757, 874, 0, 2769, 2772, 2777, 0, 1098, - 0, 0, 2783, 0, 0, 2788, 2049, 0, 0, 2050, - 2051, 2052, 874, 2053, 2054, 2055, 2056, 2057, 2058, 0, - 2795, 2796, 2797, 2798, 0, 0, 0, 2048, 2805, 0, - 0, 0, 2817, 0, 0, 2819, 0, 0, 2826, 2827, - 2828, 2829, 2830, 2831, 2832, 2833, 2834, 0, 2835, 0, - 0, 0, 0, 0, 1097, 1299, 0, 1622, 0, 0, - 3758, 0, 873, 873, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1625, 1625, 1625, 0, 0, 0, 2040, - 0, 0, 0, 0, 2041, 874, 0, 1088, 0, 873, - 0, 0, 873, 0, 0, 0, 0, 2872, 0, 0, - 0, 0, 0, 0, 0, 0, 2042, 2043, 0, 0, - 0, 0, 0, 1088, 0, 0, 4955, 0, 0, 0, - 0, 2044, 2020, 2021, 2049, 0, 0, 2050, 2051, 2052, - 0, 2053, 2054, 2055, 2056, 2057, 2058, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2045, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2046, 0, - 0, 2047, 0, 0, 0, 0, 1098, 1710, 1710, 1710, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1098, 0, 2086, 0, 0, 0, 0, - 0, 873, 2176, 0, 2972, 0, 0, 0, 0, 2030, - 0, 0, 2031, 0, 1098, 0, 2032, 2033, 2034, 0, - 0, 873, 0, 0, 0, 0, 0, 3880, 3881, 3882, - 0, 0, 0, 2035, 0, 0, 4065, 0, 0, 0, - 873, 2037, 0, 0, 3891, 0, 0, 0, 2038, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5061, 2048, - 5063, 0, 0, 1097, 0, 0, 0, 3907, 0, 0, - 1098, 0, 0, 2039, 0, 0, 0, 3917, 3919, 0, - 0, 0, 3924, 0, 1098, 0, 0, 0, 0, 4011, - 0, 0, 0, 0, 0, 0, 1098, 0, 0, 0, - 0, 0, 0, 0, 874, 0, 0, 0, 1098, 1711, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 873, 0, 0, 0, 0, 0, 0, 1097, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 874, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1098, 1098, 874, 0, 2049, 0, 0, 2050, - 2051, 2052, 0, 2053, 2054, 2055, 2056, 2057, 2058, 1088, - 1097, 0, 0, 1710, 0, 0, 0, 0, 0, 0, - 873, 874, 873, 2040, 0, 0, 0, 0, 2041, 0, - 0, 0, 0, 1323, 1088, 873, 0, 873, 0, 0, - 0, 0, 0, 1097, 0, 0, 0, 0, 0, 1088, - 2042, 2043, 4824, 0, 0, 0, 0, 0, 0, 1710, - 0, 0, 0, 0, 0, 2044, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3220, 3221, 1622, 0, 0, - 0, 3225, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2045, 0, - 873, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2046, 0, 874, 2047, 3258, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1098, 0, - 0, 0, 0, 0, 1088, 0, 0, 0, 0, 0, - 0, 5240, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 873, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4098, 4099, 4100, 0, 0, 1625, 0, 0, 873, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 874, 0, - 2030, 873, 0, 2031, 873, 0, 0, 2032, 2033, 2034, - 0, 0, 0, 2048, 0, 0, 0, 613, 0, 0, - 0, 0, 614, 0, 2035, 0, 0, 0, 0, 0, - 1097, 0, 2037, 0, 615, 0, 0, 0, 0, 2038, - 0, 0, 0, 0, 0, 0, 0, 1097, 0, 0, - 0, 0, 0, 0, 5311, 0, 1097, 616, 1088, 0, - 0, 0, 0, 0, 2039, 0, 0, 0, 1097, 0, - 617, 0, 0, 2927, 0, 0, 0, 2176, 2933, 0, - 0, 618, 0, 0, 1710, -867, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 619, 874, 0, 874, 0, 0, 620, - 2049, 0, 0, 2050, 2051, 2052, 0, 2053, 2054, 2055, - 2056, 2057, 2058, 0, 1097, 0, 621, 0, 1090, 0, - 0, 0, 0, 0, 0, 0, 0, 622, 1097, 1098, - 0, 0, 0, 0, 0, 623, 0, 0, 5385, 0, - 1097, 874, 0, 1098, 1090, 0, 0, 624, 0, 0, - 865, 0, 1097, 0, 0, 625, 0, 0, 0, 626, - 3462, 0, 0, 0, 2040, 3468, 0, 0, 0, 2041, - 0, 4824, 4824, 0, 0, 0, 0, 0, -1096, 0, - 0, 0, 0, 1098, 0, 0, 0, 0, 1711, 0, - 2023, 2042, 2043, 0, 865, 0, 1097, 1097, 0, 0, - 0, 2777, 0, 2777, 2777, 0, 2044, 0, 0, 0, - 0, 0, 0, 0, 3526, 627, 0, 3529, 0, 3531, - 0, 0, 0, 0, -587, 0, 0, 873, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2045, - 0, 0, 0, 0, 0, 0, 0, 0, 3549, 4339, - 3552, 0, 3554, 2046, 0, 0, 2047, 1088, 628, 0, - 4352, 629, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4824, 0, 0, 0, 0, 0, 0, 1710, 0, - 0, 0, 630, 1710, 0, 1710, 0, 0, 0, 0, - 0, 4381, 0, 0, 0, 0, 631, 0, 0, 0, - 0, 0, 0, -461, 0, 0, 2121, 1710, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2138, 632, 1088, 0, 2566, 1710, 0, 0, 0, - 0, 633, 1097, 0, 0, 0, 0, 0, -461, 0, - 0, 634, 873, 0, 2048, 873, 1625, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 635, 0, 0, 0, 1088, 0, 636, 0, 0, 0, - 2641, -461, 0, 1711, 637, 638, 191, 639, 640, 0, - 0, 0, 0, 0, 0, 3642, 1098, 0, 641, 0, - 0, 0, 0, 642, 0, 0, 0, 1088, 874, 643, - 1090, 0, 644, 0, 0, 645, 0, 0, 0, 0, - 874, 0, 0, 0, 0, 0, 0, 0, -461, 0, - 0, 0, 0, 0, 192, 1090, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 873, 873, 193, - 1090, 2049, 0, 0, 2050, 2051, 2052, 873, 2053, 2054, - 2055, 2056, 2057, 2058, 0, 0, 0, 194, 0, 0, - 0, 0, 0, 195, 0, 0, 873, 1097, 2176, 0, - 0, 1097, 1097, 0, 0, 0, 0, 0, 0, 0, - 196, 0, 0, 0, 0, 0, 4507, 4508, 4509, 4510, - 0, 197, 0, 0, 0, 0, 0, 0, 0, 198, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 199, 0, 0, 0, 0, 200, 0, 0, 0, - 0, 0, 0, 201, 0, 1090, 0, 0, 0, 0, - 0, 0, 0, 1097, 0, 0, 0, 0, 0, 873, - 0, 0, 202, 0, 0, 0, 0, 1097, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, - 0, 0, 0, 0, 1088, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1098, 1097, 204, 0, - 0, 1088, 0, 0, 0, 0, 0, 1091, 0, 0, - 1088, 0, 0, 1098, 1711, 0, 874, 0, 0, 0, - 0, 0, 1088, 0, 0, 0, 0, 0, 1098, 0, - 0, 0, 205, 1091, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1090, - 0, 0, 0, 0, 1622, 0, 206, 0, 0, 0, - 1622, 0, 0, 0, 0, 0, 207, 208, 0, 0, - 209, 0, 0, 0, 0, 0, 0, 0, 1088, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1088, 0, 0, 0, 210, 0, 0, 211, - 0, 0, 0, 212, 1088, 213, 0, 0, 0, 1711, - 0, 0, 214, 0, 0, 215, 1088, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 874, 0, 0, - 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, - 217, 865, 0, 0, 218, 219, 0, 0, 220, 0, - 0, 0, 221, 0, 0, 0, 874, 0, 0, 0, - 1088, 1088, 222, 0, 0, 0, 0, 223, 873, 0, - 0, 0, 0, 1710, 0, 0, 0, 0, 0, 224, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, - 1097, 0, 0, 0, 0, 0, 873, 0, 0, 0, - 0, 0, 0, 0, 0, 865, 865, 0, 873, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4733, 0, 2176, 0, 0, 2933, 0, 2933, 0, - 0, 0, 0, 2176, 0, 873, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1090, 0, - 874, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1097, 0, 0, 0, 0, 0, 0, 1091, - 0, 0, 1098, 0, 0, 0, 1088, 0, 0, 0, - 0, 4012, 0, 0, 0, 0, 0, 0, 0, 0, - 4016, 1098, 0, 0, 1091, 0, 4017, 0, 4018, 0, - 0, 0, 0, 0, 1090, 0, 0, 0, 0, 1091, - 0, 0, 0, 0, 0, 0, 2176, 0, 873, 0, - 0, 0, 1711, 0, 0, 4042, 4043, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2783, 0, 1090, 0, 0, 0, 0, - 0, 4068, 0, 0, 4071, 0, 4073, 0, 0, 0, - 0, 0, 0, 0, 0, 4077, 0, 0, 0, 0, - 0, 0, 0, 4084, 4085, 0, 0, 0, 1090, 0, - 1097, 0, 0, 1711, 0, 0, 0, 1098, 0, 1098, - 0, 0, 873, 0, 1091, 0, 0, 1097, 0, 1711, - 0, 865, 865, 0, 0, 4131, 0, 0, 0, 0, - 0, 1088, 1097, 0, 0, 1088, 1088, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4144, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4892, 0, 0, 4157, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1093, 4904, 0, 0, - 0, 0, 1323, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1088, 1098, 0, - 0, 0, 1093, 0, 0, 0, 0, 4939, 0, 0, - 0, 1088, 0, 0, 0, 0, 0, 0, 873, 0, - 873, 0, 0, 1625, 0, 0, 0, 0, 1091, 1625, - 0, 0, 0, 0, 0, 0, 0, 1098, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1088, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2933, 0, 0, 873, 0, 0, 0, 0, - 2933, 0, 0, 0, 0, 1090, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1090, 0, 0, 0, 0, 0, 0, 0, - 0, 1090, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1710, 1090, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5024, - 0, 0, 0, 0, 0, 0, 0, 1097, 0, 1098, - 1097, 0, 1097, 0, 0, 0, 0, 1097, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2933, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1090, - 0, 1098, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1090, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1090, 1097, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1090, 0, 0, - 0, 0, 0, 0, 0, 1097, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5112, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1091, 0, 0, - 1097, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1090, 1090, 0, 1088, 0, 0, 0, 1093, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1098, 0, 0, 0, 0, 0, 4422, - 4423, 0, 0, 1093, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1098, 0, 0, 1710, 1093, 0, - 0, 0, 0, 1091, 0, 0, 0, 0, 0, 0, - 0, 1097, 0, 1097, 0, 0, 0, 0, 0, 1098, - 0, 0, 873, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 873, 0, 1088, 0, 0, 0, - 0, 0, 0, 0, 1091, 0, 0, 0, 0, 4463, - 0, 0, 0, 1098, 0, 0, 0, 0, 0, 0, - 4468, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1091, 0, 0, - 0, 0, 0, 1093, 0, 0, 0, 1090, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4483, 4485, 1097, 0, 0, 0, 0, 4489, 4490, 0, - 0, 0, 4491, 0, 0, 0, 0, 4494, 0, 0, - 4497, 4498, 0, 0, 0, 4502, 0, 0, 0, 0, - 0, 4506, 0, 0, 0, 0, 0, 0, 0, 0, - 2176, 1097, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1088, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1097, 0, 0, 0, - 0, 1088, 0, 0, 1097, 0, 0, 0, 0, 0, - 0, 0, 0, 1299, 0, 0, 1088, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1093, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4561, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1090, 0, 0, 0, 1090, 1090, 1710, 0, - 873, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2933, 0, 0, 1097, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1091, 0, 0, 0, 0, 0, - 0, 1097, 0, 0, 2933, 0, 0, 0, 0, 0, - 0, 1091, 0, 0, 0, 1097, 0, 0, 0, 0, - 1091, 0, 0, 0, 0, 0, 0, 0, 1090, 0, - 0, 0, 1091, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1090, 0, 0, 0, 0, 0, 0, 0, - 0, 4624, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1710, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 873, 1090, 0, 0, 0, 0, 0, 1091, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1091, 0, 0, 0, 0, 0, 0, 0, - 873, 0, 0, 0, 1091, 0, 0, 1097, 4662, 0, - 0, 0, 0, 0, 0, 0, 1091, 0, 0, 0, - 0, 1088, 0, 0, 1088, 0, 1088, 1098, 1097, 0, - 0, 1088, 0, 0, 0, 0, 1093, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1097, 0, 0, 0, 0, 0, 0, - 1091, 1091, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2176, 0, 0, - 1088, 0, 0, 0, 0, 0, 0, 1097, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1088, - 0, 0, 1093, 0, 873, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1088, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1093, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4765, 4766, 0, 0, 4767, 0, 0, - 0, 0, 0, 0, 1097, 1090, 1093, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1710, 0, 0, 0, - 0, 0, 0, 1094, 0, 1088, 1091, 1088, 0, 0, - 0, 0, 1098, 0, 4802, 4803, 0, 0, 0, 0, - 0, 0, 1098, 0, 0, 0, 0, 0, 0, 1094, - 4814, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1710, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1090, 0, 0, - 0, 0, 0, 1710, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1097, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1088, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1096, 1097, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 946, 0, - 0, 0, 0, 947, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1096, 0, 1088, 0, 1098, 0, 0, - 0, 1091, 0, 0, 0, 1091, 1091, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 948, 0, - 1088, 0, 0, 1093, 0, 0, 0, 0, 1088, 0, - 0, 949, 950, 0, 0, 0, 1098, 0, 0, 0, - 1093, 0, 951, 0, 0, 1090, 952, 0, 0, 1093, - 0, 0, 0, 0, 0, 0, 0, 1098, 0, 0, - 0, 1093, 1090, 0, 953, 0, 0, 1091, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1090, 0, 0, - 0, 1091, 0, 0, 0, 0, 0, 954, 0, 0, - 0, 2783, 0, 0, 0, 0, 0, 1088, 955, 0, - 0, 1097, 0, 0, 0, 0, 956, 0, 0, 0, - 0, 0, 0, 0, 0, 1088, 0, 1093, 957, 4994, - 0, 1091, 1098, 958, 0, 0, 0, 0, 0, 1088, - 0, 1093, 0, 2023, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1093, 0, 1094, 0, 0, 0, 959, - 0, 1097, 0, 0, 0, 1093, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1094, 0, 0, 0, 960, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1094, 0, 0, 0, 0, - 0, 0, 5043, 0, 0, 961, 0, 0, 0, 1093, - 1093, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 962, - 0, 1088, 4730, 0, 1098, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1096, - 0, 0, 1088, 963, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 207, 964, 0, 0, 965, 0, 0, - 1094, 0, 0, 0, 1096, 0, 1097, 1088, 0, 0, - 1098, 0, 1090, 0, 0, 1090, 1097, 1090, 0, 1096, - 0, 0, 1090, 966, 0, 0, 967, 0, 0, 0, - 968, 0, 969, 0, 0, 0, 0, 0, 0, 970, - 0, 1088, 971, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1091, 0, 0, 0, 0, 0, - 0, 972, 0, 0, 0, 1093, 0, 973, 0, 0, - 0, 1090, 974, 0, 4802, 975, 0, 0, 0, 976, - 0, 0, 0, 0, 0, 0, 0, 977, 0, 978, - 1090, 0, 0, 0, 979, 0, 0, 0, 0, 0, - 5192, 0, 0, 0, 1096, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1094, 1090, 0, 0, 0, 980, - 0, 0, 0, 0, 0, 0, 0, 0, 1088, 0, - 0, 1097, 0, 0, 0, 0, 1091, 0, 0, 0, - 2933, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1097, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1090, 5247, 1090, 0, - 0, 1097, 0, 0, 0, 0, 0, 0, 0, 0, - 1093, 0, 0, 0, 1093, 1093, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1096, 0, - 5273, 5273, 5273, 0, 0, 0, 0, 0, 1088, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4802, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1088, 0, 1091, 0, 1097, 0, 0, 0, - 0, 0, 0, 0, 2933, 0, 1093, 0, 0, 0, - 0, 1091, 0, 0, 0, 0, 0, 1090, 0, 0, - 1093, 0, 0, 0, 0, 0, 1091, 0, 1098, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1090, 0, 0, 0, - 1093, 5335, 0, 1094, 0, 0, 0, 0, 1098, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5273, 0, - 0, 1090, 0, 0, 0, 0, 0, 0, 0, 1090, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1097, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1098, 0, 0, 0, 1088, 1098, 1098, 0, 1094, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1097, 0, 0, 0, 1090, 0, - 0, 0, 0, 0, 0, 0, 0, 1096, 0, 0, - 1094, 0, 0, 0, 0, 1088, 1090, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5425, - 1090, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1094, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5273, 0, 0, 0, 0, 0, 0, 0, - 0, 1091, 5451, 1096, 1091, 0, 1091, 4730, 1098, 0, - 0, 1091, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1093, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1097, 0, 0, 0, 0, 0, - 1091, 0, 1090, 0, 0, 0, 0, 0, 0, 0, - 1088, 0, 0, 0, 0, 0, 0, 1096, 0, 1091, - 1088, 0, 0, 1090, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1091, 0, 0, 0, 1090, 0, - 0, 0, 0, 0, 0, 1093, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1090, 0, 0, 0, 0, 0, 0, 0, - 1094, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1094, 0, 0, - 0, 0, 0, 0, 0, 1091, 1094, 1091, 1097, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1094, 0, - 0, 0, 0, 0, 0, 1088, 0, 0, 0, 0, - 0, 0, 1097, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1098, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1090, - 0, 0, 0, 1093, 1088, 0, 0, 0, 0, 0, - 0, 0, 1097, 0, 1094, 0, 0, 0, 0, 0, - 1093, 0, 0, 0, 1096, 1088, 0, 0, 1094, 0, - 0, 0, 0, 0, 0, 1093, 1091, 0, 0, 0, - 1094, 1096, 0, 0, 0, 0, 0, 0, 0, 0, - 1096, 0, 1094, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1096, 0, 0, 1097, 0, 0, 0, 0, - 1097, 1097, 0, 0, 0, 1091, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1088, 0, 0, 0, 0, 0, 1094, 1094, 0, 1090, - 1091, 0, 0, 0, 0, 0, 0, 0, 1091, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1096, 0, - 0, 0, 0, 1090, 0, 0, 0, 0, 0, 0, - 0, 0, 1096, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1091, 0, 0, - 0, 0, 1097, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1091, 0, 0, 0, 0, - 1096, 1096, 1088, 0, 0, 0, 0, 0, 0, 1091, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1094, 0, 0, 0, 0, 0, 0, 0, - 1093, 0, 0, 1093, 0, 1093, 0, 0, 1088, 0, - 1093, 0, 0, 0, 0, 0, 1090, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1093, - 0, 0, 0, 0, 0, 0, 1090, 0, 0, 0, - 0, 1091, 0, 0, 0, 0, 0, 0, 1093, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1091, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 1093, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1091, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1094, 0, 0, - 0, 1094, 1094, 0, 0, 0, 0, 0, 1088, 0, - 0, 0, 0, 0, 0, 0, 1097, 0, 0, 0, - 0, 1091, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1093, 0, 1093, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1090, 0, 1094, 0, 0, 0, 0, 0, 0, - 0, 1090, 0, 0, 0, 0, 2060, 1094, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1096, 0, 0, 0, 1096, 1096, 0, 1091, 0, - 0, 0, 0, 0, 0, 0, 0, 1094, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1088, 0, 0, 1093, 2060, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1088, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1096, 0, 0, - 0, 0, 0, 0, 1093, 0, 0, 0, 0, 0, - 0, 1096, 0, 0, 0, 0, 1090, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1088, 0, 0, 1093, - 0, 0, 0, 0, 0, 0, 0, 1093, 1091, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1096, 0, 0, 0, 1090, 0, 0, 0, 0, - 0, 0, 1091, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1090, 0, 0, 1088, - 0, 0, 0, 0, 1088, 1088, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1093, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1093, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1093, 0, - 0, 1090, 0, 0, 0, 0, 0, 0, 0, 0, - 1094, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1091, 1088, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 0, 0, 1094, 2060, 0, 0, 0, 0, 0, 0, - 1093, 0, 0, 0, 0, 1091, 0, 0, 0, 0, - 0, 0, 0, 1090, 1096, 0, 0, 0, 0, 0, - 0, 1093, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1093, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1090, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1093, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1094, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1094, 0, 0, - 1091, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1091, 0, 1094, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1088, 0, 0, 0, 0, 0, 0, 1093, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1090, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1096, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 0, 0, 1091, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1093, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1093, 0, 0, 1091, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1090, 0, 1091, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1090, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1094, 0, 0, - 1094, 0, 1094, 0, 2060, 0, 0, 1094, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2060, 0, - 0, 0, 2765, 0, 0, 0, 0, 1090, 0, 0, - 1091, 0, 0, 0, 0, 0, 2060, 2060, 2060, 0, - 2060, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1094, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1093, 1094, 0, 0, 0, 0, - 1090, 0, 2060, 0, 0, 1090, 1090, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1094, 1096, 0, 0, 1096, 0, 1096, 0, 0, 0, - 0, 1096, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1093, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2060, 0, - 0, 0, 1091, 0, 0, 0, 0, 0, 0, 0, - 2060, 0, 0, 0, 0, 2060, 0, 0, 0, 0, - 1096, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1094, 0, 1094, 0, 0, 0, 0, 0, 1096, - 0, 0, 0, 0, 0, 0, 0, 0, 1091, 0, - 0, 0, 0, 0, 0, 0, 0, 1090, 0, 0, - 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1093, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1093, - 0, 0, 1094, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1096, 0, 1096, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1091, 0, - 0, 0, 0, 0, 0, 0, 1094, 0, 0, 0, - 0, 0, 0, 0, 1094, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 0, 1093, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1090, 0, 1094, 0, 1096, 0, 0, 0, 0, - 0, 0, 0, 1093, 0, 0, 0, 0, 0, 0, - 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, - 1096, 0, 0, 0, 1093, 1094, 0, 0, 1096, 0, - 0, 0, 1091, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1091, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1093, - 0, 0, 0, 0, 0, 0, 1091, 1096, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1094, 0, 1096, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1094, 1091, - 0, 0, 0, 0, 1091, 1091, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1094, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1093, 0, 0, 0, 0, 0, 1094, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1096, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1093, 0, 0, - 0, 0, 1096, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1091, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1096, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1094, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1096, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2060, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2060, 0, 2060, 0, 0, 2765, 2765, 0, - 3503, 0, 2765, 0, 0, 0, 2060, 1093, 0, 2060, - 0, 0, 0, 0, 2060, 0, 0, 0, 0, 0, - 2060, 0, 0, 0, 1094, 2060, 0, 0, 1096, 0, - 0, 0, 2060, 2060, 2060, 2060, 0, 0, 0, 2765, - 2765, 0, 2060, 0, 0, 0, 0, 0, 1094, 0, - 0, 0, 0, 0, 2060, 0, 2060, 0, 0, 0, - 0, 0, 0, 2060, 2060, 2060, 2060, 2060, 2060, 2060, - 2060, 2060, 2060, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1091, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1096, 0, - 0, 1093, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1096, 0, 0, 1093, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1093, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1093, 0, - 0, 0, 0, 1093, 1093, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1094, 0, 0, 0, - 0, 0, 0, 0, 0, 1093, 1094, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2060, 2060, 0, - 1096, 0, 2060, 0, 0, 0, 0, 0, 0, 0, - 1096, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2060, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1094, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1094, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1093, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1094, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1096, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1096, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 0, 0, 0, 0, 0, 2060, 0, 0, 0, 0, - 1096, 0, 0, 0, 0, 0, 0, 0, 1094, 0, - 0, 3503, 3503, 0, 0, 2765, 2765, 2765, 2765, 0, - 0, 2765, 2765, 2765, 2765, 2765, 2765, 2765, 2765, 2765, - 2765, 3503, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2060, 1094, 0, 2060, 0, 2060, 0, - 0, 3503, 3503, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2060, 2765, 2765, 2060, - 0, 2060, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1096, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1096, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1094, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1096, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1094, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1094, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1094, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2765, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1096, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1094, 0, 0, 0, 0, - 1094, 1094, 0, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1096, - 0, 0, 0, 0, 1096, 1096, 0, 0, 0, 2060, - 0, 0, 1094, 2060, 2060, 2060, 0, 0, 0, 0, - 0, 3503, 3503, 3503, 3503, 0, 0, 0, 0, 3503, - 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 2060, - 2060, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2060, 0, 0, 2060, 0, - 2060, 0, 0, 0, 2060, 0, 0, 3503, 3503, 0, - 0, 2060, 2060, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1096, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2060, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2060, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2060, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1094, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1096, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3503, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 2060, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2060, 0, 0, 0, 0, 2060, 2765, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2060, 0, 2060, 0, 0, 0, 2060, 2060, 2060, 0, - 0, 2060, 0, 0, 2060, 2060, 0, 0, 0, 2060, - 0, 0, 0, 2060, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2060, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2060, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3503, 2765, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2060, 2060, 2060, 0, 0, 0, 0, 0, - 0, 0, 2765, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 2060, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2060, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3503, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2765, 0, 0, 3503, 0, 0, - 0, 2060, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2060, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3503, 0, 2765, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2060, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2060, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2060, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2060, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2765, 2765, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3503, 3503, 0, - 0, 0, 2060, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 1216, 660, 1217, 1218, 1219, - 721, 1220, 0, 0, 0, 0, 0, 0, 2060, 229, - 230, 231, 232, 233, 234, 235, 236, 1616, 237, 238, - 239, 0, 0, 0, 0, 1221, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 1222, - 251, 1223, 1224, 0, 254, 255, 256, 257, 258, 259, - 1225, 1226, 260, 261, 1227, 1228, 264, 0, 265, 266, - 267, 268, 1229, 0, 1230, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 1231, 1232, 1233, - 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, - 1238, 1239, 299, 1240, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 1617, 0, 311, - 312, 1069, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 1241, 327, 328, - 329, 1242, 1243, 331, 0, 332, 333, 1244, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 1245, 0, 1246, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 1247, 1248, 0, 1249, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 1250, 388, 389, 390, 0, 391, 392, 393, - 1251, 1252, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 1253, 411, - 1254, 413, 414, 415, 416, 1255, 417, 418, 419, 420, - 1256, 1257, 422, 1258, 424, 425, 426, 0, 427, 428, - 0, 0, 1259, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 1260, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 1261, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 1262, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 1263, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 1264, 506, 507, - 508, 509, 510, 511, 512, 513, 1265, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 1266, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 1267, 1268, 0, 0, 541, - 542, 1269, 544, 1270, 1271, 546, 547, 548, 549, 550, - 551, 552, 0, 1272, 553, 554, 555, 556, 557, 1273, - 0, 558, 559, 560, 561, 562, 563, 1274, 1618, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, - 1278, 583, 1279, 1280, 1281, 1282, 588, 589, 590, 591, - 1283, 0, 0, 0, 0, 0, 0, 1284, 1285, 1619, - 0, 0, 0, 0, 0, 0, 1287, 1620, 228, 1216, - 660, 1217, 1218, 1219, 721, 1220, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 1221, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 1222, 251, 1223, 1224, 0, 254, 255, - 256, 257, 258, 259, 1225, 1226, 260, 261, 1227, 1228, - 264, 0, 265, 266, 267, 268, 1229, 0, 1230, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, - 293, 294, 295, 296, 1238, 1239, 299, 1240, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 1241, 327, 328, 329, 1242, 1243, 331, 0, 332, - 333, 1244, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 1245, 0, 1246, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 1247, 1248, - 0, 1249, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 1250, 388, 389, 390, - 0, 391, 392, 393, 1251, 1252, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1253, 411, 1254, 413, 414, 415, 416, 1255, - 417, 418, 419, 420, 1256, 1257, 422, 1258, 424, 425, - 426, 0, 427, 428, 0, 0, 1259, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 1260, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 1261, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1262, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 1263, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 41, 501, 502, 503, 504, - 505, 1264, 506, 507, 508, 509, 510, 511, 512, 513, - 1265, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 1266, 0, 529, 530, 45, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1267, - 1268, 0, 0, 541, 542, 1269, 544, 1270, 1271, 546, - 547, 548, 549, 550, 551, 552, 0, 1272, 553, 554, - 555, 556, 557, 1273, 0, 558, 559, 560, 561, 562, - 1147, 1274, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 50, 572, 573, 574, 575, 576, 577, - 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, - 588, 589, 590, 591, 1283, 0, 51, 0, 0, 0, - 0, 1284, 1285, 0, 0, 0, 0, 0, 0, 0, - 1287, 5005, 228, 1216, 660, 1217, 1218, 1219, 721, 1220, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 1221, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 1222, 251, 1223, - 1224, 0, 254, 255, 256, 257, 258, 259, 1225, 1226, - 260, 261, 1227, 1228, 264, 0, 265, 266, 267, 268, - 1229, 0, 1230, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 1231, 1232, 1233, 1234, 1235, - 1236, 1237, 291, 292, 293, 294, 295, 296, 1238, 1239, - 299, 1240, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 1069, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 1241, 327, 328, 329, 1242, - 1243, 331, 0, 332, 333, 1244, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 1245, 0, 1246, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 1247, 1248, 0, 1249, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 1250, 388, 389, 390, 0, 391, 392, 393, 1251, 1252, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 1253, 411, 1254, 413, - 414, 415, 416, 1255, 417, 418, 419, 420, 1256, 1257, - 422, 1258, 424, 425, 426, 0, 427, 428, 0, 0, - 1259, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 1260, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 1261, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 1262, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 1263, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 1264, 506, 507, 508, 509, - 510, 511, 512, 513, 1265, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 1266, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 1267, 1268, 0, 0, 541, 542, 1269, - 544, 1270, 1271, 546, 547, 548, 549, 550, 551, 552, - 0, 1272, 553, 554, 555, 556, 557, 1273, 0, 558, - 559, 560, 561, 562, 563, 1274, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 1275, 1276, 1277, 1278, 583, - 1279, 1280, 1281, 1282, 588, 589, 590, 591, 1283, 0, - 0, 0, 0, 0, 0, 1284, 1285, 0, 0, 0, - 0, 0, 0, 0, 1287, 2767, 228, 1216, 660, 1217, - 1218, 1219, 721, 1220, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 1221, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 1222, 251, 1223, 1224, 0, 254, 255, 256, 257, - 258, 259, 1225, 1226, 260, 261, 1227, 1228, 264, 0, - 265, 266, 267, 268, 1229, 0, 1230, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 1231, - 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, 293, 294, - 295, 296, 1238, 1239, 299, 1240, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 1069, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 1241, - 327, 328, 329, 1242, 1243, 331, 0, 332, 333, 1244, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 1245, 0, 1246, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 1247, 1248, 0, 1249, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 1250, 388, 389, 390, 0, 391, - 392, 393, 1251, 1252, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 1253, 411, 1254, 413, 414, 415, 416, 1255, 417, 418, - 419, 420, 1256, 1257, 422, 1258, 424, 425, 426, 0, - 427, 428, 0, 0, 1259, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 1260, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 1261, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 1262, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 1263, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 1264, - 506, 507, 508, 509, 510, 511, 512, 513, 1265, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 1266, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 1267, 1268, 0, - 0, 541, 542, 1269, 544, 1270, 1271, 546, 547, 548, - 549, 550, 551, 552, 0, 1272, 553, 554, 555, 556, - 557, 1273, 0, 558, 559, 560, 561, 562, 563, 1274, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 1275, - 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, 589, - 590, 591, 1283, 0, 0, 0, 0, 0, 0, 1284, - 1285, 0, 0, 0, 0, 0, 0, 0, 1287, 4020, - 228, 1216, 660, 1217, 1218, 1219, 721, 1220, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 1221, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 1222, 251, 1223, 1224, 0, - 254, 255, 256, 257, 258, 259, 1225, 1226, 260, 261, - 1227, 1228, 264, 0, 265, 266, 267, 268, 1229, 0, - 1230, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 291, 292, 293, 294, 295, 296, 1238, 1239, 299, 1240, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 1069, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 1241, 327, 328, 329, 1242, 1243, 331, - 0, 332, 333, 1244, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 1245, 0, - 1246, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 1247, 1248, 0, 1249, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 1250, 388, - 389, 390, 0, 391, 392, 393, 1251, 1252, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 1253, 411, 1254, 413, 414, 415, - 416, 1255, 417, 418, 419, 420, 1256, 1257, 422, 1258, - 424, 425, 426, 0, 427, 428, 0, 0, 1259, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 1260, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 1261, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 1262, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 1263, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 1264, 506, 507, 508, 509, 510, 511, - 512, 513, 1265, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 1266, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 1267, 1268, 0, 0, 541, 542, 1269, 544, 1270, - 1271, 546, 547, 548, 549, 550, 551, 552, 0, 1272, - 553, 554, 555, 556, 557, 1273, 0, 558, 559, 560, - 561, 562, 563, 1274, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, - 1281, 1282, 588, 589, 590, 591, 1283, 0, 0, 599, - 0, 0, 0, 1284, 1285, 0, 0, 0, 0, 0, - 0, 0, 1287, 4091, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 0, 0, 0, 0, - 0, 4109, 0, 240, 241, 0, 242, 243, 244, 0, - 246, 247, 248, 249, 250, 0, 252, 253, 0, 254, - 255, 256, 257, 258, 259, 0, 0, 260, 261, 262, - 263, 264, 0, 265, 266, 267, 268, 269, 0, 0, - 0, 271, 272, 273, 274, 275, 0, 277, 278, 279, - 0, 280, 281, 282, 283, 284, 285, 0, -1780, 287, - 288, 289, 0, 0, 0, 0, 0, 0, 0, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 0, 300, - 0, 301, 302, 303, 304, 305, 306, 0, 307, 308, - 309, 310, 0, 0, 311, 312, 313, 314, 315, 0, - 316, 317, 318, 0, 319, 320, 321, 0, 322, 323, - 324, 325, 326, 327, 328, 329, 330, 0, 331, 0, - 332, 333, 334, 335, 0, 336, 0, 337, 0, 0, - -1780, 340, 341, 342, 343, 0, 344, 345, 0, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 0, 355, - 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, - 365, 0, 366, -1780, 368, 369, 370, 371, 372, 373, - 374, 0, 375, 0, 376, 0, 0, 379, -1780, 381, - 382, 383, 384, 385, 0, 0, 386, 387, -1780, 389, - 0, 0, 391, 392, 393, 0, 0, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, -1780, 412, 413, 414, 415, 416, - 0, 417, 418, 0, 420, 0, 421, 422, 423, 424, - 425, 426, 0, 427, 428, 0, 0, 429, 430, 431, - 0, 0, 432, 433, 434, 0, 436, 0, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 0, 0, - 448, 449, 450, 451, 452, 453, 454, 455, 0, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 0, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 0, 483, 484, - -1780, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 0, 501, 502, 503, - 504, 505, 0, 506, 507, 508, 509, 510, 0, 512, - 513, 514, 515, 0, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 528, 0, 529, 530, - 0, 531, 0, 533, 534, 535, 536, 537, 0, 538, - 539, 540, 0, 0, 541, 542, 543, 544, 545, 0, - 546, 547, 548, 549, 550, 551, 552, 0, 0, 553, - 554, 555, 556, 557, 0, 0, 558, 559, 560, 561, - 562, 563, 564, 0, 565, 0, 567, 568, 569, 570, - 0, 0, 571, 0, 0, 572, 573, 574, 575, 576, - 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, - 587, 588, 589, 590, 591, 0, 0, 0, 1061, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1365, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 0, 1062, 251, 1063, 1064, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 1065, 1066, - 264, 0, 265, 266, 267, 268, 0, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 1067, 1068, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 0, 327, 328, 329, 0, 0, 331, 0, 332, - 333, 1070, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 0, 0, 0, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 2162, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 2163, 369, 370, 371, 372, 1072, 1073, - 0, 1074, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 0, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1075, 411, 1076, 413, 414, 415, 0, 0, - 417, 418, 419, 420, 0, 0, 422, 1077, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 2165, 435, 436, 437, 0, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 0, 451, 0, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1078, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 0, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 2166, 509, 510, 511, 512, 513, - 1080, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 0, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1081, - 1082, 0, 0, 541, 542, 0, 544, 0, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 0, 1083, 2167, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 1061, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 589, 590, 591, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 2274, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 0, 1062, 251, 1063, 1064, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 1065, 1066, 264, 0, 265, 266, 267, 268, 0, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 1067, 1068, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 1069, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 0, 327, 328, 329, 0, 0, 331, - 0, 332, 333, 1070, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 0, 0, - 0, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 2162, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 2163, 369, 370, 371, 372, - 1072, 1073, 0, 1074, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 0, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 1075, 411, 1076, 413, 414, 415, - 0, 0, 417, 418, 419, 420, 0, 0, 422, 1077, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 2165, 435, 436, 437, 0, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 0, 451, 0, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 1078, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 0, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 2166, 509, 510, 511, - 512, 513, 1080, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 0, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 1081, 1082, 0, 0, 541, 542, 0, 544, 0, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 0, 1083, 2167, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 0, 228, 1216, 660, 1217, 1218, 1219, 721, - 1220, 0, 0, 589, 590, 591, 0, 0, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 0, 0, 0, 3344, 1221, 0, 0, 240, 241, 0, - 242, 243, 244, 245, 246, 247, 248, 249, 1222, 251, - 1223, 1224, 0, 254, 255, 256, 257, 258, 259, 1225, - 1226, 260, 261, 1227, 1228, 264, 0, 265, 266, 267, - 268, 1229, 0, 1230, 0, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 0, 280, 281, 282, 283, 284, - 285, 0, 286, 287, 288, 289, 1231, 1232, 1233, 1234, - 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, 1238, - 1239, 299, 1240, 300, 0, 301, 302, 303, 304, 305, - 306, 0, 307, 308, 309, 310, 0, 0, 311, 312, - 1069, 314, 315, 0, 316, 317, 318, 0, 319, 320, - 321, 0, 322, 323, 324, 325, 1241, 327, 328, 329, - 1242, 1243, 331, 0, 332, 333, 1244, 335, 0, 336, - 0, 337, 338, 0, 339, 340, 341, 342, 343, 0, - 344, 1245, 0, 1246, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 0, 359, 360, - 361, 362, 363, 364, 365, 0, 366, 367, 368, 369, - 370, 371, 372, 1247, 1248, 0, 1249, 0, 376, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 0, 0, - 386, 1250, 388, 389, 390, 0, 391, 392, 393, 1251, - 1252, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 1253, 411, 1254, - 413, 414, 415, 416, 1255, 417, 418, 419, 420, 1256, - 1257, 422, 1258, 424, 425, 426, 0, 427, 428, 0, - 0, 1259, 430, 431, 0, 0, 432, 433, 434, 435, - 436, 437, 1260, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 0, 0, 448, 449, 1261, 451, 452, 453, - 454, 455, 0, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 1262, 467, 468, 469, 470, 0, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 0, 483, 484, 485, 486, 487, 488, 489, 490, - 1263, 492, 493, 494, 495, 496, 497, 498, 499, 500, - 41, 501, 502, 503, 504, 505, 1264, 506, 507, 508, - 509, 510, 511, 512, 513, 1265, 515, 0, 516, 517, - 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, - 1266, 0, 529, 530, 45, 531, 532, 533, 534, 535, - 536, 537, 0, 538, 1267, 1268, 0, 0, 541, 542, - 1269, 544, 1270, 1271, 546, 547, 548, 549, 550, 551, - 552, 0, 1272, 553, 554, 555, 556, 557, 1273, 0, - 558, 559, 560, 561, 562, 1147, 1274, 0, 565, 566, - 567, 568, 569, 570, 0, 0, 571, 0, 50, 572, - 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, 1278, - 583, 1279, 1280, 1281, 1282, 588, 589, 590, 591, 1283, - 0, 51, 0, 0, 0, 0, 1284, 1285, 0, 0, - 0, 0, 0, 0, 0, 1287, 228, 1216, 660, 1217, - 1218, 1219, 721, 1220, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 1221, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 1222, 251, 1223, 1224, 2773, 254, 255, 256, 257, - 258, 259, 1225, 1226, 260, 261, 1227, 1228, 264, 0, - 265, 266, 267, 268, 1229, 0, 1230, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 1231, - 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, 293, 294, - 295, 296, 1238, 1239, 299, 1240, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 1069, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 1241, - 327, 328, 329, 1242, 1243, 331, 0, 332, 333, 1244, - 335, 0, 336, 0, 337, 338, 2774, 339, 340, 341, - 342, 343, 0, 344, 1245, 0, 1246, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 1247, 1248, 0, 1249, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 2775, 386, 1250, 388, 389, 390, 0, 391, - 392, 393, 1251, 1252, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 1253, 411, 1254, 413, 414, 415, 416, 1255, 417, 418, - 419, 420, 1256, 1257, 422, 1258, 424, 425, 426, 0, - 427, 428, 0, 0, 1259, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 1260, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 1261, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 1262, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 1263, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 1264, - 506, 507, 508, 509, 510, 511, 512, 513, 1265, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 1266, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 1267, 1268, 0, - 2776, 541, 542, 1269, 544, 1270, 1271, 546, 547, 548, - 549, 550, 551, 552, 0, 1272, 553, 554, 555, 556, - 557, 1273, 0, 558, 559, 560, 561, 562, 563, 1274, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 1275, - 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, 589, - 590, 591, 1283, 0, 0, 0, 0, 0, 0, 1284, - 1285, 0, 0, 0, 0, 0, 0, 0, 1287, 228, - 1216, 660, 1217, 1218, 1219, 721, 1220, 0, 0, 0, - 0, 0, 0, 0, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 0, 0, 0, 0, - 1221, 0, 0, 240, 241, 0, 242, 243, 244, 245, - 246, 247, 248, 249, 1222, 251, 1223, 1224, 0, 254, - 255, 256, 257, 258, 259, 1225, 1226, 260, 261, 1227, - 1228, 264, 0, 265, 266, 267, 268, 1229, 0, 1230, - 0, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 0, 280, 281, 282, 283, 284, 285, 0, 286, 287, - 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, - 292, 293, 294, 295, 296, 1238, 1239, 299, 1240, 300, - 0, 301, 302, 303, 304, 305, 306, 0, 307, 308, - 309, 310, 0, 0, 311, 312, 1069, 314, 315, 0, - 316, 317, 318, 0, 319, 320, 321, 0, 322, 323, - 324, 325, 1241, 327, 328, 329, 1242, 1243, 331, 0, - 332, 333, 1244, 335, 0, 336, 0, 337, 338, 0, - 339, 340, 341, 342, 343, 0, 344, 1245, 0, 1246, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, - 365, 0, 366, 367, 368, 369, 370, 371, 372, 1247, - 1248, 0, 1249, 0, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 0, 0, 386, 1250, 388, 389, - 390, 0, 391, 392, 393, 1251, 1252, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 1253, 411, 1254, 413, 414, 415, 416, - 1255, 417, 418, 419, 420, 1256, 1257, 422, 1258, 424, - 425, 426, 0, 427, 428, 0, 0, 1259, 430, 431, - 0, 0, 432, 433, 434, 435, 436, 437, 1260, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 0, 0, - 448, 449, 1261, 451, 452, 453, 454, 455, 0, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 1262, - 467, 468, 469, 470, 0, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 0, 483, 484, - 485, 486, 487, 488, 489, 490, 1263, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 0, 501, 502, 503, - 504, 505, 1264, 506, 507, 508, 509, 510, 511, 512, - 513, 1265, 515, 0, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 1266, 0, 529, 530, - 0, 531, 532, 533, 534, 535, 536, 537, 0, 538, - 1267, 1268, 0, 0, 541, 542, 1269, 544, 1270, 1271, - 546, 547, 548, 549, 550, 551, 552, 0, 1272, 553, - 554, 555, 556, 557, 1273, 0, 558, 559, 560, 561, - 562, 563, 1274, 0, 565, 566, 567, 568, 569, 570, - 0, 0, 571, 0, 0, 572, 573, 574, 575, 576, - 577, 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, - 1282, 588, 589, 590, 591, 1283, 0, 0, 0, 0, - 0, 0, 1284, 1285, 0, 0, 0, 0, 0, 1984, - 2728, 1287, 228, 1216, 660, 1217, 1218, 1219, 721, 1220, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 1221, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 1222, 251, 1223, - 1224, 0, 254, 255, 256, 257, 258, 259, 1225, 1226, - 260, 261, 1227, 1228, 264, 0, 265, 266, 267, 268, - 1229, 0, 1230, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 1231, 1232, 1233, 1234, 1235, - 1236, 1237, 291, 292, 293, 294, 295, 296, 1238, 1239, - 299, 1240, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 1069, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 1241, 327, 328, 329, 1242, - 1243, 331, 0, 332, 333, 1244, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 1245, 0, 1246, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 1247, 1248, 0, 1249, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 1250, 388, 389, 390, 0, 391, 392, 393, 1251, 1252, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 1253, 411, 1254, 413, - 414, 415, 416, 1255, 417, 418, 419, 420, 1256, 1257, - 422, 1258, 424, 425, 426, 0, 427, 428, 0, 0, - 1259, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 1260, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 1261, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 1262, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 1263, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 1264, 506, 507, 508, 509, - 510, 511, 512, 513, 1265, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 1266, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 1267, 1268, 0, 0, 541, 542, 1269, - 544, 1270, 1271, 546, 547, 548, 549, 550, 551, 552, - 0, 1272, 553, 554, 555, 556, 557, 1273, 0, 558, - 559, 560, 561, 562, 563, 1274, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 1275, 1276, 1277, 1278, 583, - 1279, 1280, 1281, 1282, 588, 589, 590, 591, 1283, 0, - 0, 0, 0, 0, 0, 1284, 1285, 1286, 0, 0, - 0, 0, 0, 0, 1287, 228, 1216, 660, 1217, 1218, - 1219, 721, 1220, 0, 0, 0, 0, 0, 0, 0, - 229, 230, 231, 232, 233, 234, 235, 236, 2131, 237, - 238, 239, 0, 0, 0, 0, 1221, 0, 0, 240, - 241, 0, 242, 243, 244, 245, 246, 247, 248, 249, - 1222, 251, 1223, 1224, 0, 254, 255, 256, 257, 258, - 259, 1225, 1226, 260, 261, 1227, 1228, 264, 0, 265, - 266, 267, 268, 1229, 0, 1230, 0, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 0, 280, 281, 282, - 283, 284, 285, 0, 286, 287, 288, 289, 1231, 1232, - 1233, 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, - 296, 1238, 1239, 299, 1240, 300, 0, 301, 302, 303, - 304, 305, 306, 0, 307, 308, 309, 310, 0, 0, - 311, 312, 1069, 314, 315, 0, 316, 317, 318, 0, - 319, 320, 321, 0, 322, 323, 324, 325, 1241, 327, - 328, 329, 1242, 1243, 331, 0, 332, 333, 1244, 335, - 0, 336, 0, 337, 338, 0, 339, 340, 341, 342, - 343, 0, 344, 1245, 0, 1246, 347, 348, 0, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 0, - 359, 360, 361, 362, 363, 364, 365, 0, 366, 367, - 368, 369, 370, 371, 372, 1247, 1248, 0, 1249, 0, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 0, 0, 386, 1250, 388, 389, 390, 0, 391, 392, - 393, 1251, 1252, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 1253, - 411, 1254, 413, 414, 415, 416, 1255, 417, 418, 419, - 420, 1256, 1257, 422, 1258, 424, 425, 426, 0, 427, - 428, 0, 0, 1259, 430, 431, 0, 0, 432, 433, - 434, 435, 436, 437, 1260, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 0, 0, 448, 449, 1261, 451, - 452, 453, 454, 455, 0, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 1262, 467, 468, 469, 470, - 0, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 0, 483, 484, 485, 486, 487, 488, - 489, 490, 1263, 492, 493, 494, 495, 496, 497, 498, - 499, 500, 0, 501, 502, 503, 504, 505, 1264, 506, - 507, 508, 509, 510, 511, 512, 513, 1265, 515, 0, - 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 1266, 0, 529, 530, 0, 531, 532, 533, - 534, 535, 536, 537, 0, 538, 1267, 1268, 0, 0, - 541, 542, 1269, 544, 1270, 1271, 546, 547, 548, 549, - 550, 551, 552, 0, 1272, 553, 554, 555, 556, 557, - 1273, 0, 558, 559, 560, 561, 562, 563, 1274, 0, - 565, 566, 567, 568, 569, 570, 0, 0, 571, 0, - 0, 572, 573, 574, 575, 576, 577, 578, 1275, 1276, - 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, 589, 590, - 591, 1283, 0, 0, 0, 0, 0, 0, 1284, 1285, - 0, 0, 0, 0, 0, 0, 0, 1287, 228, 1216, - 660, 1217, 1218, 1219, 721, 1220, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 1221, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 1222, 251, 1223, 1224, 0, 254, 255, - 256, 257, 258, 259, 1225, 1226, 260, 261, 1227, 1228, - 264, 0, 265, 266, 267, 268, 1229, 0, 1230, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, - 293, 294, 295, 296, 1238, 1239, 299, 1240, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 1241, 327, 328, 329, 1242, 1243, 331, 0, 332, - 333, 1244, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 1245, 0, 1246, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 1247, 1248, - 0, 1249, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 1250, 388, 389, 390, - 0, 391, 392, 393, 1251, 1252, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1253, 411, 1254, 413, 414, 415, 416, 1255, - 417, 418, 419, 420, 1256, 1257, 422, 1258, 424, 425, - 426, 0, 427, 428, 0, 0, 1259, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 1260, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 1261, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1262, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 1263, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 1264, 506, 507, 508, 509, 510, 511, 512, 513, - 1265, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 1266, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1267, - 1268, 0, 0, 541, 542, 1269, 544, 1270, 1271, 546, - 547, 548, 549, 550, 551, 552, 0, 1272, 553, 554, - 555, 556, 557, 1273, 0, 558, 559, 560, 561, 562, - 563, 1274, 3222, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, - 588, 589, 590, 591, 1283, 0, 0, 0, 0, 0, - 0, 1284, 1285, 0, 0, 0, 0, 0, 0, 0, - 1287, 228, 1216, 660, 1217, 1218, 1219, 721, 1220, 0, - 0, 0, 0, 0, 0, 0, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 0, 0, - 0, 0, 1221, 0, 0, 240, 241, 0, 242, 243, - 244, 245, 246, 247, 248, 249, 1222, 251, 1223, 1224, - 0, 254, 255, 256, 257, 258, 259, 1225, 1226, 260, - 261, 1227, 1228, 264, 0, 265, 266, 267, 268, 1229, - 0, 1230, 0, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 0, 280, 281, 282, 283, 284, 285, 0, - 286, 287, 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, - 1237, 291, 292, 293, 294, 295, 296, 1238, 1239, 299, - 1240, 300, 0, 301, 302, 303, 304, 305, 306, 0, - 307, 308, 309, 310, 0, 0, 311, 312, 1069, 314, - 315, 0, 316, 317, 318, 0, 319, 320, 321, 0, - 322, 323, 324, 325, 1241, 327, 328, 329, 1242, 1243, - 331, 0, 332, 333, 1244, 335, 0, 336, 0, 337, - 338, 2774, 339, 340, 341, 342, 343, 0, 344, 1245, - 0, 1246, 347, 348, 0, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, - 363, 364, 365, 0, 366, 367, 368, 369, 370, 371, - 372, 1247, 1248, 0, 1249, 0, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 0, 0, 386, 1250, - 388, 389, 390, 0, 391, 392, 393, 1251, 1252, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 1253, 411, 1254, 413, 414, - 415, 416, 1255, 417, 418, 419, 420, 1256, 1257, 422, - 1258, 424, 425, 426, 0, 427, 428, 0, 0, 1259, - 430, 431, 0, 0, 432, 433, 434, 435, 436, 437, - 1260, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 0, 0, 448, 449, 1261, 451, 452, 453, 454, 455, - 0, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 1262, 467, 468, 469, 470, 0, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 0, - 483, 484, 485, 486, 487, 488, 489, 490, 1263, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 0, 501, - 502, 503, 504, 505, 1264, 506, 507, 508, 509, 510, - 511, 512, 513, 1265, 515, 0, 516, 517, 518, 519, - 520, 521, 522, 523, 524, 525, 526, 527, 1266, 0, - 529, 530, 0, 531, 532, 533, 534, 535, 536, 537, - 0, 538, 1267, 1268, 0, 0, 541, 542, 1269, 544, - 1270, 1271, 546, 547, 548, 549, 550, 551, 552, 0, - 1272, 553, 554, 555, 556, 557, 1273, 0, 558, 559, - 560, 561, 562, 563, 1274, 0, 565, 566, 567, 568, - 569, 570, 0, 0, 571, 0, 0, 572, 573, 574, - 575, 576, 577, 578, 1275, 1276, 1277, 1278, 583, 1279, - 1280, 1281, 1282, 588, 589, 590, 591, 1283, 0, 0, - 0, 0, 0, 0, 1284, 1285, 0, 0, 0, 0, - 0, 0, 0, 1287, 228, 1216, 660, 1217, 1218, 1219, - 721, 1220, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 1221, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 1222, - 251, 1223, 1224, 0, 254, 255, 256, 257, 258, 259, - 1225, 1226, 260, 261, 1227, 1228, 264, 0, 265, 266, - 267, 268, 1229, 0, 1230, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 1231, 1232, 1233, - 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, - 1238, 1239, 299, 1240, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 1069, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 1241, 327, 328, - 329, 1242, 1243, 331, 0, 332, 333, 1244, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 1245, 0, 1246, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 1247, 1248, 0, 1249, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 1250, 388, 389, 390, 0, 391, 392, 393, - 1251, 1252, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 1253, 411, - 1254, 413, 414, 415, 416, 1255, 417, 418, 419, 420, - 1256, 1257, 422, 1258, 424, 425, 426, 0, 427, 428, - 0, 0, 1259, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 1260, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 1261, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 1262, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 1263, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 1264, 506, 507, - 508, 509, 510, 511, 512, 513, 1265, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 1266, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 1267, 1268, 0, 0, 541, - 542, 1269, 544, 1270, 1271, 546, 547, 548, 549, 550, - 551, 552, 0, 1272, 553, 554, 555, 556, 557, 1273, - 0, 558, 559, 560, 561, 562, 563, 1274, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, - 1278, 583, 1279, 1280, 1281, 1282, 588, 589, 590, 591, - 1283, 0, 0, 0, 0, 0, 0, 1284, 1285, 0, - 0, 0, 0, 0, 0, 0, 1287, 228, 1216, 660, - 1217, 1218, 1219, 721, 1220, 0, 0, 0, 0, 0, - 0, 0, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 0, 0, 0, 0, 1221, 0, - 0, 240, 241, 0, 242, 243, 244, 245, 246, 247, - 248, 249, 1222, 251, 1223, 1224, 0, 254, 255, 256, - 257, 258, 259, 1225, 1226, 260, 261, 1227, 1228, 264, - 0, 265, 266, 267, 268, 1229, 0, 1230, 0, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 0, 280, - 281, 282, 283, 284, 285, 0, 286, 287, 288, 289, - 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, 293, - 294, 295, 296, 1238, 1239, 299, 1240, 300, 0, 301, - 302, 303, 304, 305, 306, 0, 307, 308, 309, 310, - 0, 0, 311, 312, 1069, 314, 315, 0, 316, 317, - 318, 0, 319, 320, 321, 0, 322, 323, 324, 325, - 1241, 327, 328, 329, 1242, 1243, 331, 0, 332, 333, - 1244, 335, 0, 336, 0, 337, 338, 0, 339, 340, - 341, 342, 343, 0, 344, 1245, 0, 1246, 347, 348, - 0, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 0, 359, 360, 361, 362, 363, 364, 365, 0, - 366, 367, 368, 369, 370, 371, 372, 1247, 1248, 0, - 1249, 0, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 0, 0, 386, 1250, 388, 389, 390, 0, - 391, 392, 393, 1251, 1252, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 1253, 411, 1254, 413, 414, 415, 416, 1255, 417, - 418, 419, 420, 1256, 1257, 422, 1258, 424, 425, 426, - 0, 427, 428, 0, 0, 1259, 430, 431, 0, 0, - 432, 433, 434, 435, 436, 437, 1260, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 0, 0, 448, 449, - 1261, 451, 452, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 1262, 467, 468, - 469, 470, 0, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 0, 483, 484, 485, 486, - 487, 488, 489, 490, 1263, 492, 493, 494, 495, 496, - 497, 498, 499, 500, 0, 501, 502, 503, 504, 505, - 1264, 506, 507, 508, 509, 510, 511, 512, 513, 1265, - 515, 0, 516, 517, 518, 519, 520, 521, 522, 523, - 524, 525, 526, 527, 1266, 0, 529, 530, 0, 531, - 532, 533, 534, 535, 536, 537, 0, 538, 1267, 1268, - 0, 0, 541, 542, 1269, 544, 1270, 1271, 546, 547, - 548, 549, 550, 551, 552, 0, 1272, 553, 554, 555, - 556, 557, 1273, 0, 558, 559, 560, 561, 562, 563, - 1274, 0, 565, 566, 567, 568, 569, 570, 0, 0, - 571, 0, 0, 572, 573, 574, 575, 576, 577, 578, - 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, - 589, 590, 591, 1283, 0, 0, 0, 0, 0, 0, - 2134, 2135, 0, 0, 0, 0, 0, 0, 0, 1287, - 228, 2894, 660, 1217, 1218, 1219, 721, 1220, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 1221, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 1222, 251, 1223, 1224, 0, - 254, 255, 256, 257, 258, 259, 1225, 1226, 260, 261, - 1227, 1228, 264, 0, 265, 266, 267, 268, 1229, 0, - 1230, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 291, 292, 293, 294, 295, 296, 1238, 1239, 299, 1240, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 1069, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 1241, 327, 328, 329, 1242, 1243, 331, - 0, 332, 333, 1244, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 1245, 0, - 1246, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 1247, 1248, 0, 1249, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 1250, 388, - 389, 390, 0, 391, 392, 393, 1251, 1252, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 1253, 411, 1254, 413, 414, 415, - 416, 1255, 417, 418, 419, 420, 1256, 1257, 422, 1258, - 424, 425, 426, 0, 427, 428, 0, 0, 1259, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 1260, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 1261, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 1262, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 1263, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 1264, 506, 507, 508, 509, 510, 511, - 512, 513, 1265, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 1266, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 1267, 1268, 0, 0, 541, 542, 1269, 544, 1270, - 1271, 546, 547, 548, 549, 550, 551, 552, 0, 1272, - 553, 554, 555, 556, 557, 1273, 0, 558, 559, 560, - 561, 562, 563, 1274, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, - 1281, 1282, 588, 589, 590, 591, 1283, 0, 0, 0, - 0, 0, 0, 1284, 1285, 0, 0, 0, 0, 0, - 0, 0, 1287, 228, 1216, 660, 1217, 1218, 1219, 721, - 1220, 0, 0, 0, 0, 0, 0, 0, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 0, 0, 0, 0, 1221, 0, 0, 240, 241, 0, - 242, 243, 244, 245, 246, 247, 248, 249, 1222, 251, - 1223, 1224, 0, 254, 255, 256, 257, 258, 259, 1225, - 1226, 260, 261, 1227, 1228, 264, 0, 265, 266, 267, - 268, 1229, 0, 1230, 0, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 0, 280, 281, 282, 283, 284, - 285, 0, 286, 287, 288, 4143, 1231, 1232, 1233, 1234, - 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, 1238, - 1239, 299, 1240, 300, 0, 301, 302, 303, 304, 305, - 306, 0, 307, 308, 309, 310, 0, 0, 311, 312, - 1069, 314, 315, 0, 316, 317, 318, 0, 319, 320, - 321, 0, 322, 323, 324, 325, 1241, 327, 328, 329, - 1242, 1243, 331, 0, 332, 333, 1244, 335, 0, 336, - 0, 337, 338, 0, 339, 340, 341, 342, 343, 0, - 344, 1245, 0, 1246, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 0, 359, 360, - 361, 362, 363, 364, 365, 0, 366, 367, 368, 369, - 370, 371, 372, 1247, 1248, 0, 1249, 0, 376, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 0, 0, - 386, 1250, 388, 389, 390, 0, 391, 392, 393, 1251, - 1252, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 1253, 411, 1254, - 413, 414, 415, 416, 1255, 417, 418, 419, 420, 1256, - 1257, 422, 1258, 424, 425, 426, 0, 427, 428, 0, - 0, 1259, 430, 431, 0, 0, 432, 433, 434, 435, - 436, 437, 1260, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 0, 0, 448, 449, 1261, 451, 452, 453, - 454, 455, 0, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 1262, 467, 468, 469, 470, 0, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 0, 483, 484, 485, 486, 487, 488, 489, 490, - 1263, 492, 493, 494, 495, 496, 497, 498, 499, 500, - 0, 501, 502, 503, 504, 505, 1264, 506, 507, 508, - 509, 510, 511, 512, 513, 1265, 515, 0, 516, 517, - 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, - 1266, 0, 529, 530, 0, 531, 532, 533, 534, 535, - 536, 537, 0, 538, 1267, 1268, 0, 0, 541, 542, - 1269, 544, 1270, 1271, 546, 547, 548, 549, 550, 551, - 552, 0, 1272, 553, 554, 555, 556, 557, 1273, 0, - 558, 559, 560, 561, 562, 563, 1274, 0, 565, 566, - 567, 568, 569, 570, 0, 0, 571, 0, 0, 572, - 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, 1278, - 583, 1279, 1280, 1281, 1282, 588, 589, 590, 591, 1283, - 0, 0, 0, 0, 0, 0, 1284, 1285, 0, 0, - 0, 0, 0, 0, 0, 1287, 228, 1216, 660, 1217, - 1218, 1219, 721, 1220, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 1221, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 1222, 251, 1223, 1224, 0, 254, 255, 256, 257, - 258, 259, 1225, 1226, 260, 261, 1227, 1228, 264, 0, - 265, 266, 267, 268, 1229, 0, 1230, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 1231, - 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, 293, 294, - 295, 296, 1238, 1239, 299, 1240, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 1069, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 1241, - 327, 328, 329, 1242, 1243, 331, 0, 332, 333, 1244, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 1245, 0, 1246, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 1247, 1248, 0, 1249, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 1250, 388, 389, 390, 0, 391, - 392, 393, 1251, 1252, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 1253, 411, 1254, 413, 414, 415, 416, 1255, 417, 418, - 419, 420, 1256, 1257, 422, 1258, 424, 425, 426, 0, - 427, 428, 0, 0, 1259, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 1260, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 1261, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 1262, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 1263, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 1264, - 506, 507, 508, 509, 510, 511, 512, 513, 1265, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 1266, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 1267, 1268, 0, - 0, 541, 542, 1269, 544, 1270, 1271, 546, 547, 548, - 549, 550, 551, 552, 0, 1272, 553, 554, 555, 556, - 557, 1273, 0, 558, 559, 560, 561, 562, 563, 1274, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 4475, 1275, - 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, 589, - 590, 591, 1283, 0, 0, 0, 0, 0, 0, 1284, - 1285, 0, 0, 0, 0, 0, 0, 0, 1287, 228, - 1216, 660, 1217, 1218, 1219, 721, 1220, 0, 0, 0, - 0, 0, 0, 0, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 0, 0, 0, 0, - 1221, 0, 0, 240, 241, 0, 242, 243, 244, 245, - 246, 247, 248, 249, 1222, 251, 1223, 1224, 0, 254, - 255, 256, 257, 258, 259, 1225, 1226, 260, 261, 1227, - 1228, 264, 0, 265, 266, 267, 268, 1229, 0, 1230, - 0, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 0, 280, 281, 282, 283, 284, 285, 0, 286, 287, - 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, - 292, 293, 294, 295, 296, 1238, 1239, 299, 1240, 300, - 0, 301, 302, 303, 304, 305, 306, 0, 307, 308, - 309, 310, 0, 0, 311, 312, 1069, 314, 315, 0, - 316, 317, 318, 0, 319, 320, 321, 0, 322, 323, - 324, 325, 1241, 327, 328, 329, 1242, 1243, 331, 0, - 332, 333, 1244, 335, 0, 336, 0, 337, 338, 0, - 339, 340, 341, 342, 343, 0, 344, 1245, 0, 1246, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, - 365, 0, 366, 367, 368, 369, 370, 371, 372, 1247, - 1248, 0, 1249, 0, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 0, 0, 386, 1250, 388, 389, - 390, 0, 391, 392, 393, 1251, 1252, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 1253, 411, 1254, 413, 414, 4484, 416, - 1255, 417, 418, 419, 420, 1256, 1257, 422, 1258, 424, - 425, 426, 0, 427, 428, 0, 0, 1259, 430, 431, - 0, 0, 432, 433, 434, 435, 436, 437, 1260, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 0, 0, - 448, 449, 1261, 451, 452, 453, 454, 455, 0, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 1262, - 467, 468, 469, 470, 0, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 0, 483, 484, - 485, 486, 487, 488, 489, 490, 1263, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 0, 501, 502, 503, - 504, 505, 1264, 506, 507, 508, 509, 510, 511, 512, - 513, 1265, 515, 0, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 1266, 0, 529, 530, - 0, 531, 532, 533, 534, 535, 536, 537, 0, 538, - 1267, 1268, 0, 0, 541, 542, 1269, 544, 1270, 1271, - 546, 547, 548, 549, 550, 551, 552, 0, 1272, 553, - 554, 555, 556, 557, 1273, 0, 558, 559, 560, 561, - 562, 563, 1274, 0, 565, 566, 567, 568, 569, 570, - 0, 0, 571, 0, 0, 572, 573, 574, 575, 576, - 577, 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, - 1282, 588, 589, 590, 591, 1283, 0, 0, 0, 0, - 0, 0, 1284, 1285, 0, 0, 0, 0, 0, 0, - 0, 1287, 228, 1216, 660, 1217, 1218, 1219, 721, 1220, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 1221, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 1222, 251, 1223, - 1224, 0, 254, 255, 256, 257, 258, 259, 1225, 1226, - 260, 261, 1227, 1228, 264, 0, 265, 266, 267, 268, - 1229, 0, 1230, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 4792, 289, 1231, 1232, 1233, 1234, 1235, - 1236, 1237, 291, 292, 293, 294, 295, 296, 1238, 1239, - 299, 1240, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 1069, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 1241, 327, 328, 329, 1242, - 1243, 331, 0, 332, 333, 1244, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 1245, 0, 4793, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 1247, 1248, 0, 1249, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 1250, 388, 389, 390, 0, 391, 392, 393, 1251, 1252, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 1253, 411, 1254, 413, - 414, 415, 416, 1255, 417, 418, 419, 420, 1256, 1257, - 422, 1258, 424, 425, 426, 0, 427, 428, 0, 0, - 1259, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 1260, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 1261, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 1262, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 4794, 489, 490, 1263, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 1264, 506, 507, 508, 509, - 510, 511, 512, 513, 1265, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 1266, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 1267, 1268, 0, 0, 541, 542, 1269, - 544, 1270, 1271, 546, 547, 548, 549, 550, 551, 552, - 0, 1272, 553, 554, 555, 556, 557, 1273, 0, 558, - 559, 560, 561, 562, 563, 1274, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 1275, 1276, 1277, 1278, 583, - 1279, 1280, 1281, 1282, 588, 589, 590, 591, 1283, 0, - 0, 0, 0, 0, 0, 1284, 1285, 0, 0, 0, - 0, 0, 0, 0, 4795, 228, 1216, 660, 1217, 1218, - 1219, 721, 1220, 0, 0, 0, 0, 0, 0, 0, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 0, 0, 0, 0, 1221, 0, 0, 240, - 241, 0, 242, 243, 244, 245, 246, 247, 248, 5270, - 1222, 251, 1223, 1224, 0, 254, 255, 256, 257, 258, - 259, 1225, 1226, 260, 261, 1227, 1228, 264, 0, 265, - 266, 267, 268, 1229, 0, 1230, 0, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 0, 280, 281, 282, - 283, 284, 285, 0, 286, 287, 288, 5271, 1231, 1232, - 1233, 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, - 296, 1238, 1239, 299, 1240, 300, 0, 301, 302, 303, - 304, 305, 306, 0, 307, 308, 309, 310, 0, 0, - 311, 312, 1069, 314, 315, 0, 316, 317, 318, 0, - 319, 320, 321, 0, 322, 323, 324, 325, 1241, 327, - 328, 329, 1242, 1243, 331, 0, 332, 333, 1244, 335, - 0, 336, 0, 337, 338, 0, 339, 340, 341, 342, - 343, 0, 344, 1245, 0, 1246, 347, 348, 0, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 0, - 359, 360, 361, 362, 363, 364, 365, 0, 366, 367, - 368, 369, 370, 371, 372, 1247, 1248, 0, 1249, 0, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 0, 0, 386, 1250, 388, 389, 390, 0, 391, 392, - 393, 1251, 1252, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 1253, - 411, 1254, 413, 414, 415, 416, 1255, 417, 418, 419, - 420, 1256, 1257, 422, 1258, 424, 425, 426, 0, 427, - 428, 0, 0, 1259, 430, 431, 0, 0, 432, 433, - 434, 435, 436, 437, 1260, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 0, 0, 448, 449, 1261, 451, - 452, 453, 454, 455, 0, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 1262, 467, 468, 469, 470, - 0, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 0, 483, 484, 485, 486, 487, 488, - 489, 490, 1263, 492, 493, 494, 495, 496, 497, 498, - 499, 500, 0, 501, 502, 503, 504, 505, 1264, 506, - 507, 508, 509, 510, 511, 512, 513, 1265, 515, 0, - 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 1266, 0, 529, 530, 0, 531, 532, 533, - 534, 535, 536, 537, 0, 538, 1267, 1268, 0, 0, - 541, 542, 1269, 544, 1270, 1271, 546, 547, 548, 549, - 5272, 551, 552, 0, 1272, 553, 554, 555, 556, 557, - 1273, 0, 558, 559, 560, 561, 562, 563, 1274, 0, - 565, 566, 567, 568, 569, 570, 0, 0, 571, 0, - 0, 572, 573, 574, 575, 576, 577, 578, 1275, 1276, - 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, 589, 590, - 591, 1283, 0, 0, 0, 0, 0, 0, 1284, 1285, - 0, 0, 0, 0, 0, 0, 0, 1287, 228, 1216, - 660, 1217, 1218, 1219, 721, 1220, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 1221, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 1222, 251, 1223, 1224, 0, 254, 255, - 256, 257, 258, 259, 1225, 1226, 260, 261, 1227, 1228, - 264, 0, 265, 266, 267, 268, 1229, 0, 1230, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 5271, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, - 293, 294, 295, 296, 1238, 1239, 299, 1240, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 1241, 327, 328, 329, 1242, 1243, 331, 0, 332, - 333, 1244, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 1245, 0, 1246, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 1247, 1248, - 0, 1249, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 1250, 388, 389, 390, - 0, 391, 392, 393, 1251, 1252, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1253, 411, 1254, 413, 414, 415, 416, 1255, - 417, 418, 419, 420, 1256, 1257, 422, 1258, 424, 425, - 426, 0, 427, 428, 0, 0, 1259, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 1260, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 1261, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1262, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 1263, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 1264, 506, 507, 508, 509, 510, 511, 512, 513, - 1265, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 1266, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1267, - 1268, 0, 0, 541, 542, 1269, 544, 1270, 1271, 546, - 547, 548, 549, 5272, 551, 552, 0, 1272, 553, 554, - 555, 556, 557, 1273, 0, 558, 559, 560, 561, 562, - 563, 1274, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, - 588, 589, 590, 591, 1283, 0, 0, 0, 0, 0, - 0, 1284, 1285, 0, 0, 0, 0, 0, 0, 0, - 1287, 228, 1216, 660, 1217, 1218, 1219, 721, 1220, 0, - 0, 0, 0, 0, 0, 0, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 0, 0, - 0, 0, 1221, 0, 0, 240, 241, 0, 242, 243, - 244, 245, 246, 247, 248, 249, 1222, 251, 1223, 1224, - 0, 254, 255, 256, 257, 258, 259, 1225, 1226, 260, - 261, 1227, 1228, 264, 0, 265, 266, 267, 268, 1229, - 0, 1230, 0, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 0, 280, 281, 282, 283, 284, 285, 0, - 286, 287, 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, - 1237, 291, 292, 293, 294, 295, 296, 1238, 1239, 299, - 4987, 300, 0, 301, 302, 303, 304, 305, 306, 0, - 307, 308, 309, 310, 0, 0, 311, 312, 1069, 314, - 315, 0, 316, 317, 318, 0, 319, 320, 321, 0, - 322, 323, 324, 325, 1241, 327, 328, 329, 1242, 1243, - 331, 0, 332, 333, 1244, 335, 0, 336, 0, 337, - 338, 0, 339, 340, 341, 342, 343, 0, 344, 1245, - 0, 1246, 347, 348, 0, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, - 363, 364, 365, 0, 366, 367, 368, 369, 370, 371, - 372, 1247, 1248, 0, 1249, 0, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 0, 0, 386, 1250, - 388, 389, 390, 0, 391, 392, 393, 1251, 1252, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 1253, 411, 1254, 413, 414, - 415, 416, 0, 417, 418, 419, 420, 1256, 1257, 422, - 1258, 424, 425, 426, 0, 427, 428, 0, 0, 1259, - 430, 431, 0, 0, 432, 433, 434, 435, 436, 437, - 1260, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 0, 0, 448, 449, 1261, 451, 452, 453, 454, 455, - 0, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 1262, 467, 468, 469, 470, 0, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 0, - 483, 484, 485, 486, 487, 488, 489, 490, 2759, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 0, 501, - 502, 503, 504, 505, 1264, 506, 507, 508, 509, 510, - 511, 512, 513, 1265, 515, 0, 516, 517, 518, 519, - 520, 521, 522, 523, 524, 525, 526, 527, 1266, 0, - 529, 530, 0, 531, 532, 533, 534, 535, 536, 537, - 0, 538, 1267, 1268, 0, 0, 541, 542, 1269, 544, - 1270, 1271, 546, 547, 548, 549, 550, 551, 552, 0, - 0, 553, 554, 555, 556, 557, 1273, 0, 558, 559, - 560, 561, 562, 563, 1274, 0, 565, 566, 567, 568, - 569, 570, 0, 0, 571, 0, 0, 572, 573, 574, - 575, 576, 577, 578, 1275, 1276, 1277, 1278, 583, 1279, - 1280, 1281, 1282, 588, 589, 590, 591, 0, 0, 0, - 0, 0, 0, 0, 2760, 2761, 0, 0, 0, 0, - 0, 0, 0, 2762, 228, 1216, 660, 1217, 1218, 1219, - 721, 1220, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 1221, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, -2636, 1222, - 251, 1223, 1224, 0, 254, 255, 256, 257, 258, 259, - 1225, 1226, 260, 261, 1227, 1228, 264, 0, 265, 266, - 267, 268, 1229, 0, 1230, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 5271, 1231, 1232, 1233, - 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, - 1238, 1239, 299, 1240, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 1069, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 1241, 327, 328, - 329, 1242, 1243, 331, 0, 332, 333, 1244, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 1245, 0, 1246, 347, 348, 0, 349, 350, - 351, 352, 353, -2636, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 1247, 1248, 0, 1249, 0, 376, - 0, 0, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 1250, 388, 389, -2636, 0, 391, 392, 393, - 1251, 1252, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 1253, 411, - 1254, 413, 414, 415, 416, 1255, 417, 418, 0, 420, - 1256, 1257, 422, 1258, 424, 425, 426, 0, 427, 428, - 0, 0, 1259, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 1260, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 1261, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 1262, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 1263, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 1264, 506, 507, - 508, 509, 510, -2636, 512, 513, 1265, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 1266, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 1267, 1268, 0, 0, 541, - 542, 1269, 544, 1270, 1271, 546, 547, 548, 549, 5272, - 551, 552, 0, 1272, 553, 554, 555, 556, 557, 1273, - 0, 558, 559, 560, 561, 562, 563, 1274, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, - 1278, 583, 1279, 1280, 1281, 1282, 588, 589, 590, 591, - -2636, 0, 0, 0, 0, 0, 0, 1284, 1285, 0, - 0, 0, 0, 0, 0, 0, 1287, 228, 1216, 660, - 1217, 1218, 1219, 721, 1220, 0, 0, 0, 0, 0, - 0, 0, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 0, 0, 0, 0, 1221, 0, - 0, 240, 241, 0, 242, 243, 244, 245, 246, 247, - 248, 249, 1222, 251, 1223, 1224, 0, 254, 255, 256, - 257, 258, 259, 1225, 1226, 260, 261, 1227, 1228, 264, - 0, 265, 266, 267, 268, 1229, 0, 1230, 0, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 0, 280, - 281, 282, 283, 284, 285, 0, 286, 287, 288, 289, - 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, 293, - 294, 295, 296, 1238, 1239, 299, 0, 300, 0, 301, - 302, 303, 304, 305, 306, 0, 307, 308, 309, 310, - 0, 0, 311, 312, 1069, 314, 315, 0, 316, 317, - 318, 0, 319, 320, 321, 0, 322, 323, 324, 325, - 1241, 327, 328, 329, 1242, 1243, 331, 0, 332, 333, - 1244, 335, 0, 336, 0, 337, 338, 0, 339, 340, - 341, 342, 343, 0, 344, 1245, 0, 1246, 347, 348, - 0, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 0, 359, 360, 361, 362, 363, 364, 365, 0, - 366, 367, 368, 369, 370, 371, 372, 1247, 1248, 0, - 1249, 0, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 0, 0, 386, 1250, 388, 389, 390, 0, - 391, 392, 393, 1251, 1252, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 1253, 411, 1254, 413, 414, 415, 416, 0, 417, - 418, 419, 420, 1256, 1257, 422, 1258, 424, 425, 426, - 0, 427, 428, 0, 0, 1259, 430, 431, 0, 0, - 432, 433, 434, 435, 436, 437, 1260, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 0, 0, 448, 449, - 1261, 451, 452, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 1262, 467, 468, - 469, 470, 0, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 0, 483, 484, 485, 486, - 487, 488, 489, 490, 2759, 492, 493, 494, 495, 496, - 497, 498, 499, 500, 0, 501, 502, 503, 504, 505, - 1264, 506, 507, 508, 509, 510, 511, 512, 513, 1265, - 515, 0, 516, 517, 518, 519, 520, 521, 522, 523, - 524, 525, 526, 527, 1266, 0, 529, 530, 0, 531, - 532, 533, 534, 535, 536, 537, 0, 538, 1267, 1268, - 0, 0, 541, 542, 1269, 544, 1270, 1271, 546, 547, - 548, 549, 550, 551, 552, 0, 0, 553, 554, 555, - 556, 557, 1273, 0, 558, 559, 560, 561, 562, 563, - 1274, 0, 565, 566, 567, 568, 569, 570, 0, 0, - 571, 0, 0, 572, 573, 574, 575, 576, 577, 578, - 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, - 589, 590, 591, 0, 0, 0, 0, 0, 0, 0, - 2760, 2761, 0, 0, 228, 1216, 660, 1217, 1218, 2762, - 721, 1220, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 1221, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 1222, - 251, 1223, 1224, 0, 254, 255, 256, 257, 258, 259, - 1225, 1226, 260, 261, 1227, 1228, 264, 0, 265, 266, - 267, 268, 1229, 0, 1230, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 1231, 1232, 1233, - 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, - 1238, 1239, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 1069, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 1241, 327, 328, - 329, 1242, 1243, 331, 0, 332, 333, 1244, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 1245, 0, 1246, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 1247, 1248, 0, 1249, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 1250, 388, 389, 390, 0, 391, 392, 393, - 1251, 1252, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 1253, 411, - 1254, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 1256, 1257, 422, 1258, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 1260, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 1261, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 1262, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 2883, 2884, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 1264, 506, 507, - 508, 509, 510, 511, 512, 513, 1265, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 1266, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 1267, 1268, 0, 0, 541, - 542, 1269, 544, 1270, 1271, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 1273, - 0, 558, 559, 560, 561, 562, 563, 1274, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, - 1278, 583, 1279, 1280, 1281, 1282, 588, 589, 590, 591, - 0, 0, 0, 0, 0, 0, 0, 2885, 2886, 0, - 0, 0, 0, 0, 0, 0, 2762, 228, 1216, 660, - 1217, 1218, 1219, 721, 1220, 0, 0, 0, 0, 0, - 0, 0, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 0, 0, 0, 0, 1221, 0, - 0, 240, 241, 0, 242, 243, 244, 245, 246, 247, - 248, 249, 1222, 251, 1223, 1224, 0, 254, 255, 256, - 257, 258, 259, 1225, 1226, 260, 261, 1227, 1228, 264, - 0, 265, 266, 267, 268, 1229, 0, 1230, 0, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 0, 280, - 281, 282, 283, 284, 285, 0, 286, 287, 288, 289, - 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, 293, - 294, 295, 296, 1238, 1239, 299, 0, 300, 0, 301, - 302, 303, 304, 305, 306, 0, 307, 308, 309, 310, - 0, 0, 311, 312, 1069, 314, 315, 0, 316, 317, - 318, 0, 319, 320, 321, 0, 322, 323, 324, 325, - 1241, 327, 328, 329, 1242, 1243, 331, 0, 332, 333, - 1244, 335, 0, 336, 0, 337, 338, 0, 339, 340, - 341, 342, 343, 0, 344, 1245, 0, 1246, 347, 348, - 0, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 0, 359, 360, 361, 362, 363, 364, 365, 0, - 366, 367, 368, 369, 370, 371, 372, 1247, 1248, 0, - 1249, 0, 376, 0, 378, 379, 380, 381, 382, 383, - 384, 385, 0, 0, 386, 1250, 388, 389, 390, 0, - 391, 392, 393, 1251, 1252, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 1253, 411, 1254, 413, 414, 415, 416, 0, 417, - 418, 419, 420, 1256, 1257, 422, 1258, 424, 425, 426, - 0, 427, 428, 0, 0, 1259, 430, 431, 0, 0, - 432, 433, 434, 435, 436, 437, 1260, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 0, 0, 448, 449, - 1261, 451, 452, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 1262, 467, 468, - 469, 470, 0, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 0, 483, 484, 485, 486, - 487, 488, 489, 490, 2759, 492, 493, 494, 495, 496, - 497, 498, 499, 500, 0, 501, 502, 503, 504, 505, - 1264, 506, 507, 508, 509, 510, 511, 512, 513, 1265, - 515, 0, 516, 517, 518, 519, 520, 521, 522, 523, - 524, 525, 526, 527, 1266, 0, 529, 530, 0, 531, - 532, 533, 534, 535, 536, 537, 0, 538, 1267, 1268, - 0, 0, 541, 542, 1269, 544, 1270, 1271, 546, 547, - 548, 549, 550, 551, 552, 0, 0, 553, 554, 555, - 556, 557, 1273, 0, 558, 559, 560, 561, 562, 563, - 1274, 0, 565, 566, 567, 568, 569, 570, 0, 0, - 571, 0, 0, 572, 573, 574, 575, 576, 577, 578, - 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, 588, - 589, 590, 591, 0, 0, 0, 0, 0, 0, 0, - 2760, 2761, 0, 0, 228, 1216, 660, 1217, 1218, 2762, - 721, 1220, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 1221, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 1222, - 251, 1223, 1224, 0, 254, 255, 256, 257, 258, 259, - 1225, 1226, 260, 261, 1227, 1228, 264, 0, 265, 266, - 267, 268, 1229, 0, 1230, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 1231, 1232, 1233, - 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, - 1238, 1239, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 1069, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 1241, 327, 328, - 329, 1242, 1243, 331, 0, 332, 333, 1244, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 1245, 0, 1246, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 1247, 1248, 0, 1249, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 1250, 388, 389, 390, 0, 391, 392, 393, - 1251, 1252, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 1253, 411, - 1254, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 1256, 1257, 422, 1258, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 1260, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 1261, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 1262, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 2759, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 1264, 506, 507, - 508, 509, 510, 511, 512, 513, 1265, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 1266, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 1267, 1268, 0, 0, 541, - 542, 1269, 544, 1270, 1271, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 1273, - 0, 558, 559, 560, 561, 562, 563, 1274, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, - 1278, 583, 1279, 1280, 1281, 1282, 588, 589, 590, 591, - 0, 0, 228, 1216, 660, 1217, 1218, 0, 721, 1220, - 0, 0, 0, 0, 0, 0, 2762, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 1221, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 1222, 251, 1223, - 1224, 0, 4053, 255, 256, 257, 258, 259, 1225, 1226, - 260, 261, 1227, 1228, 264, 0, 265, 266, 267, 268, - 1229, 0, 1230, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 1231, 1232, 1233, 1234, 1235, - 1236, 1237, 291, 292, 293, 294, 295, 296, 1238, 1239, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 1069, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 1241, 327, 328, 329, 1242, - 1243, 331, 0, 332, 333, 1244, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 1245, 0, 1246, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 1247, 1248, 0, 1249, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 1250, 388, 389, 390, 0, 391, 392, 393, 1251, 1252, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 1253, 411, 1254, 413, - 414, 415, 416, 0, 417, 418, 419, 420, 1256, 1257, - 422, 1258, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 1260, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 1261, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 1262, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 2759, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 1264, 506, 507, 508, 509, - 510, 511, 512, 513, 1265, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 1266, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 1267, 1268, 0, 0, 541, 542, 1269, - 544, 1270, 1271, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 1273, 0, 558, - 559, 560, 561, 562, 563, 1274, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 1275, 1276, 1277, 1278, 583, - 1279, 1280, 1281, 1282, 588, 589, 590, 591, 0, 0, - 228, 1216, 660, 1217, 1218, 0, 721, 1220, 0, 0, - 0, 0, 0, 0, 2762, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 1221, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 1222, 251, 1223, 1224, 0, - 254, 255, 256, 257, 258, 259, 1225, 1226, 260, 261, - 1227, 1228, 264, 0, 265, 266, 267, 268, 1229, 0, - 1230, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 291, 292, 293, 294, 295, 296, 1238, 1239, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 1069, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 1241, 327, 328, 329, 1242, 1243, 331, - 0, 332, 333, 1244, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 1245, 0, - 1246, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 1247, 1248, 0, 1249, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 1250, 388, - 389, 390, 0, 391, 392, 393, 1251, 1252, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 1253, 411, 1254, 413, 414, 415, - 416, 0, 417, 418, 419, 420, 1256, 1257, 422, 1258, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 1260, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 1261, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 1262, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 2759, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 1264, 506, 507, 508, 509, 510, 511, - 512, 513, 1265, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 1266, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 1267, 1268, 0, 0, 541, 542, 1269, 544, 1270, - 1271, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 1273, 0, 558, 559, 560, - 561, 562, 563, 1274, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 1275, 1276, 1277, 1278, 4515, 1279, 1280, - 1281, 1282, 588, 589, 590, 591, 0, 0, 228, 1216, - 660, 1217, 1218, 1219, 721, 1220, 0, 0, 0, 0, - 0, 0, 2762, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 1221, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 0, 1222, 251, 1223, 1224, 0, 254, 255, - 256, 257, 258, 259, 1225, 1226, 260, 261, 1227, 1228, - 264, 0, 265, 266, 267, 268, 1229, 0, 1230, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, - 293, 294, 295, 296, 1238, 1239, 299, 1240, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 0, 321, 0, 322, 323, 324, - 325, 1241, 327, 328, 329, 1242, 1243, 331, 0, 332, - 333, 1244, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 1245, 0, 1246, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 1247, 1248, - 0, 1249, 0, 376, 0, 0, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 1250, 388, 389, 0, - 0, 391, 392, 393, 1251, 1252, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1253, 411, 1254, 413, 414, 415, 416, 1255, - 417, 418, 0, 420, 1256, 1257, 422, 1258, 424, 425, - 426, 0, 427, 428, 0, 0, 1259, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 1260, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 1261, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1262, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 1263, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 1264, 506, 507, 508, 509, 510, 0, 512, 513, - 1265, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 1266, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1267, - 1268, 0, 0, 541, 542, 1269, 544, 1270, 1271, 546, - 547, 548, 549, 550, 551, 552, 0, 1272, 553, 554, - 555, 556, 557, 1273, 0, 558, 559, 560, 561, 562, - 563, 1274, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, - 588, 589, 590, 591, 0, 0, 228, 0, 0, 0, - 0, 1284, 1285, 0, 0, 0, 0, 0, 0, 0, - 1287, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 1226, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 1229, 0, 1230, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 1231, - 1232, 1233, 1234, 1235, 1236, 1237, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 1242, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 1245, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 3572, 0, 386, 1250, 388, 389, 390, 0, 391, - 392, 393, 1251, 1252, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 0, 417, 418, - 419, 420, 0, 1257, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 813, 429, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 1260, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 1261, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 491, 3573, 493, 494, 495, 496, 497, - 498, 499, 500, 41, 501, 502, 503, 504, 505, 1264, - 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 1266, 0, 529, 530, 45, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 1269, 544, 1270, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 1273, 0, 558, 559, 560, 561, 562, 1147, 564, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 50, 572, 573, 574, 575, 576, 577, 578, 1275, - 1276, 1277, 1278, 583, 1279, 1280, 1281, 1282, 3574, 589, - 590, 591, 0, 0, 51, 228, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3575, 0, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 0, 0, 0, 0, 0, 0, 0, 240, - 241, 0, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 0, 254, 255, 256, 257, 258, - 259, 0, 1226, 260, 261, 262, 263, 264, 0, 265, - 266, 267, 268, 1229, 0, 1230, 0, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 0, 280, 281, 282, - 283, 284, 285, 0, 286, 287, 288, 289, 1231, 1232, - 1233, 1234, 1235, 1236, 1237, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 0, 300, 0, 301, 302, 303, - 304, 305, 306, 0, 307, 308, 309, 310, 0, 0, - 311, 312, 313, 314, 315, 0, 316, 317, 318, 0, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 1242, 0, 331, 0, 332, 333, 334, 335, - 0, 336, 0, 337, 338, 0, 339, 340, 341, 342, - 343, 0, 344, 1245, 0, 346, 347, 348, 0, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 0, - 359, 360, 361, 362, 363, 364, 365, 0, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 0, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 3572, 0, 386, 1250, 388, 389, 390, 0, 391, 392, - 393, 1251, 1252, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, 414, 415, 416, 0, 417, 418, 419, - 420, 0, 1257, 422, 423, 424, 425, 426, 0, 427, - 428, 0, 813, 429, 430, 431, 0, 0, 432, 433, - 434, 435, 436, 437, 1260, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 0, 0, 448, 449, 1261, 451, - 452, 453, 454, 455, 0, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 0, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 0, 483, 484, 485, 486, 487, 488, - 489, 490, 491, 3573, 493, 494, 495, 496, 497, 498, - 499, 500, 0, 501, 502, 503, 504, 505, 1264, 506, - 507, 508, 509, 510, 511, 512, 513, 514, 515, 0, - 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 1266, 0, 529, 530, 0, 531, 532, 533, - 534, 535, 536, 537, 0, 538, 539, 540, 0, 0, - 541, 542, 1269, 544, 1270, 0, 546, 547, 548, 549, - 550, 551, 552, 0, 0, 553, 554, 555, 556, 557, - 1273, 0, 558, 559, 560, 561, 562, 563, 564, 0, - 565, 566, 567, 568, 569, 570, 0, 0, 571, 0, - 0, 572, 573, 574, 575, 576, 577, 578, 1275, 1276, - 1277, 1278, 583, 1279, 1280, 1281, 1282, 3574, 589, 590, - 591, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3575, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 0, 0, 0, 0, 0, 0, 0, 240, 241, 0, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 0, 254, 255, 256, 257, 258, 259, 0, - 1226, 260, 261, 262, 263, 264, 0, 265, 266, 267, - 268, 1229, 0, 1230, 0, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 0, 280, 281, 282, 283, 284, - 285, 0, 286, 287, 288, 289, 1231, 1232, 1233, 1234, - 1235, 1236, 1237, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 0, 300, 0, 301, 302, 303, 304, 305, - 306, 0, 307, 308, 309, 310, 0, 0, 311, 312, - 313, 314, 315, 0, 316, 317, 318, 0, 319, 320, - 321, 0, 322, 323, 324, 325, 326, 327, 328, 329, - 1242, 0, 331, 0, 332, 333, 334, 335, 0, 336, - 0, 337, 338, 0, 339, 340, 341, 342, 343, 0, - 344, 1245, 0, 346, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 0, 359, 360, - 361, 362, 363, 364, 365, 0, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 0, 375, 0, 376, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 0, 0, - 386, 1250, 388, 389, 390, 0, 391, 392, 393, 1251, - 1252, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 0, 417, 418, 419, 420, 0, - 1257, 422, 423, 424, 425, 426, 0, 427, 428, 0, - 0, 429, 430, 431, 0, 0, 432, 433, 434, 435, - 436, 437, 1260, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 0, 0, 448, 449, 1261, 451, 452, 453, - 454, 455, 0, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 0, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 0, 483, 484, 485, 486, 487, 488, 489, 490, - 491, 3573, 493, 494, 495, 496, 497, 498, 499, 500, - 0, 501, 502, 503, 504, 505, 1264, 506, 507, 508, - 509, 510, 511, 512, 513, 514, 515, 0, 516, 517, - 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, - 1266, 0, 529, 530, 0, 531, 532, 533, 534, 535, - 536, 537, 0, 538, 539, 540, 0, 0, 541, 542, - 1269, 544, 1270, 0, 546, 547, 548, 549, 550, 551, - 552, 0, 0, 553, 554, 555, 556, 557, 1273, 0, - 558, 559, 560, 561, 562, 563, 564, 0, 565, 566, - 567, 568, 569, 570, 0, 0, 571, 0, 0, 572, - 573, 574, 575, 576, 577, 578, 1275, 1276, 1277, 1278, - 583, 1279, 1280, 1281, 1282, 3574, 589, 590, 591, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 52, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 0, 0, - 0, 0, 0, 0, 0, 240, 241, 0, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 0, 254, 255, 256, 257, 258, 259, 0, 1226, 260, - 261, 262, 263, 264, 0, 265, 266, 267, 268, 1229, - 0, 1230, 0, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 0, 280, 281, 282, 283, 284, 285, 0, - 286, 287, 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, - 1237, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 0, 300, 0, 301, 302, 303, 304, 305, 306, 0, - 307, 308, 309, 310, 0, 0, 311, 312, 313, 314, - 315, 0, 316, 317, 318, 0, 319, 320, 321, 0, - 322, 323, 324, 325, 326, 327, 328, 329, 1242, 0, - 331, 0, 332, 333, 334, 335, 0, 336, 0, 337, - 338, 0, 339, 340, 341, 342, 343, 0, 344, 1245, - 0, 346, 347, 348, 0, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, - 363, 364, 365, 0, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 0, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 0, 0, 386, 1250, - 388, 389, 390, 0, 391, 392, 393, 1251, 1252, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 0, 417, 418, 419, 420, 0, 1257, 422, - 423, 424, 425, 426, 0, 427, 428, 0, 0, 429, - 430, 431, 0, 0, 432, 433, 434, 435, 436, 437, - 1260, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 0, 0, 448, 449, 1261, 451, 452, 453, 454, 455, - 0, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 0, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 0, - 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 0, 501, - 502, 503, 504, 505, 1264, 506, 507, 508, 509, 510, - 511, 512, 513, 514, 515, 0, 516, 517, 518, 519, - 520, 521, 522, 523, 524, 525, 526, 527, 1266, 0, - 529, 530, 0, 531, 532, 533, 534, 535, 536, 537, - 0, 538, 539, 540, 0, 0, 541, 542, 1269, 544, - 1270, 0, 546, 547, 548, 549, 550, 551, 552, 0, - 0, 553, 554, 555, 556, 557, 1273, 0, 558, 559, - 560, 561, 562, 563, 564, 0, 565, 566, 567, 568, - 569, 570, 0, 0, 571, 0, 0, 572, 573, 574, - 575, 576, 577, 578, 1275, 1276, 1277, 1278, 583, 1279, - 1280, 1281, 1282, 588, 589, 590, 591, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4172, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 0, 0, 0, 0, - 0, 0, 0, 240, 241, 0, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 0, 254, - 255, 256, 257, 258, 259, 0, 1226, 260, 261, 262, - 263, 264, 0, 265, 266, 267, 268, 1229, 0, 1230, - 0, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 0, 280, 281, 282, 283, 284, 285, 0, 286, 287, - 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 0, 300, - 0, 301, 302, 303, 304, 305, 306, 0, 307, 308, - 309, 310, 0, 0, 311, 312, 313, 314, 315, 0, - 316, 317, 318, 0, 319, 320, 321, 0, 322, 323, - 324, 325, 326, 327, 328, 329, 1242, 0, 331, 0, - 332, 333, 334, 335, 0, 336, 0, 337, 338, 0, - 339, 340, 341, 342, 343, 0, 344, 1245, 0, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, - 365, 0, 366, 367, 368, 369, 370, 371, 372, 373, - 374, 0, 375, 0, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 0, 0, 386, 1250, 388, 389, - 390, 0, 391, 392, 393, 1251, 1252, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, - 0, 417, 418, 419, 420, 0, 1257, 422, 423, 424, - 425, 426, 0, 427, 428, 0, 0, 429, 430, 431, - 0, 0, 432, 433, 434, 435, 436, 437, 1260, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 0, 0, - 448, 449, 1261, 451, 452, 453, 454, 455, 0, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 0, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 0, 483, 484, - 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 0, 501, 502, 503, - 504, 505, 1264, 506, 507, 508, 509, 510, 511, 512, - 513, 514, 515, 0, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 1266, 0, 529, 530, - 0, 531, 532, 533, 534, 535, 536, 537, 0, 538, - 539, 540, 0, 0, 541, 542, 1269, 544, 1270, 0, - 546, 547, 548, 549, 550, 551, 552, 0, 0, 553, - 554, 555, 556, 557, 1273, 0, 558, 559, 560, 561, - 562, 563, 564, 0, 565, 566, 567, 568, 569, 570, - 0, 0, 571, 0, 0, 572, 573, 574, 575, 576, - 577, 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, 1281, - 1282, 588, 589, 590, 591, 0, 0, 866, 1499, 660, - 0, 0, 0, 721, 0, 0, 0, 0, 0, 0, - 0, 5253, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 0, 0, 0, 0, 0, 0, - 0, 240, 241, 0, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 0, 254, 255, 256, - 257, 258, 259, 0, 0, 260, 261, 262, 263, 264, - 0, 265, 266, 267, 268, 269, 0, 270, 0, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 0, 280, - 281, 282, 283, 284, 285, 0, 286, 287, 288, 289, - 0, 0, 0, 290, 0, 0, 0, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 0, 300, 0, 301, - 302, 303, 304, 305, 306, 0, 307, 308, 309, 310, - 0, 0, 311, 312, 313, 314, 315, 0, 316, 317, - 318, 0, 319, 320, 321, 0, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 1915, 331, 0, 332, 333, - 334, 335, 0, 336, 0, 337, 338, 0, 339, 340, - 341, 342, 343, 0, 344, 345, 0, 346, 347, 348, - 0, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 0, 359, 360, 361, 362, 363, 364, 365, 0, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 0, - 375, 0, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 0, 0, 386, 387, 388, 389, 390, 0, - 391, 392, 393, 0, 0, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 0, 417, - 418, 419, 420, 0, 421, 422, 423, 424, 425, 426, - 0, 427, 428, 1916, 0, 429, 430, 431, 0, 0, - 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 0, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 0, 483, 484, 485, 486, - 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, - 497, 498, 499, 500, 0, 501, 502, 503, 504, 505, - 0, 506, 507, 508, 509, 510, 511, 512, 513, 514, - 515, 0, 516, 517, 518, 519, 520, 521, 522, 523, - 524, 525, 526, 527, 528, 0, 529, 530, 0, 531, - 532, 533, 534, 535, 536, 537, 0, 538, 539, 540, - 0, 0, 541, 542, 543, 544, 545, 1917, 546, 547, - 548, 549, 550, 551, 552, 0, 0, 553, 554, 555, - 556, 557, 0, 0, 558, 559, 560, 561, 562, 563, - 564, 0, 565, 566, 567, 568, 569, 570, 0, 0, - 571, 0, 0, 572, 573, 574, 575, 576, 577, 578, - 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 591, 0, 0, 866, 0, 0, 0, 0, - 1500, 1501, 5068, 0, 0, 0, 0, 0, 0, 5069, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 3, 4, 0, 0, 0, 0, 0, 240, - 241, 0, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 0, 254, 255, 256, 257, 258, - 259, 0, 0, 260, 261, 262, 263, 264, 0, 265, - 266, 267, 268, 269, 0, 270, 0, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 0, 280, 281, 282, - 283, 284, 285, 0, 286, 287, 288, 289, 0, 0, - 0, 290, 0, 0, 0, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 0, 300, 0, 301, 302, 303, - 304, 305, 306, 0, 307, 308, 309, 310, 0, 0, - 311, 312, 313, 314, 315, 0, 316, 317, 318, 0, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 0, 332, 333, 334, 335, - 0, 336, 0, 337, 338, 0, 339, 340, 341, 342, - 343, 0, 344, 345, 0, 346, 347, 348, 0, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 0, - 359, 360, 361, 362, 363, 364, 365, 0, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 0, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 0, 0, 386, 387, 388, 389, 390, 0, 391, 392, - 393, 0, 0, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, 414, 415, 416, 0, 417, 418, 419, - 420, 0, 421, 422, 423, 424, 425, 426, 0, 427, - 428, 0, 0, 429, 430, 431, 0, 0, 432, 433, - 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 0, 0, 448, 449, 450, 451, - 452, 453, 454, 455, 0, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 0, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 0, 483, 484, 485, 486, 487, 488, - 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, - 499, 500, 41, 501, 502, 503, 504, 505, 0, 506, - 507, 508, 509, 510, 511, 512, 513, 514, 515, 0, - 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 528, 0, 529, 530, 45, 531, 532, 533, - 534, 535, 536, 537, 0, 538, 539, 540, 0, 0, - 541, 542, 543, 544, 545, 0, 546, 547, 548, 549, - 550, 551, 552, 0, 0, 553, 554, 555, 556, 557, - 0, 0, 558, 559, 560, 561, 562, 1147, 564, 0, - 565, 566, 567, 568, 569, 570, 0, 0, 571, 0, - 50, 572, 573, 574, 575, 576, 577, 578, 579, 580, - 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, - 591, 0, 0, 51, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 52, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 0, 0, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4844, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 41, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 45, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 1147, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 50, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 0, 0, - 51, 599, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 52, 0, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 0, 0, - 0, 0, 0, 0, 0, 240, 241, 0, 242, 243, - 244, 0, 246, 247, 248, 249, 250, 0, 252, 253, - 0, 254, 255, 256, 257, 258, 259, 0, 0, 260, - 261, 262, 263, 264, 0, 265, 266, 267, 268, 269, - 0, 0, 0, 271, 272, 273, 274, 275, 0, 277, - 278, 279, 0, 280, 281, 282, 283, 284, 285, 0, - 0, 287, 288, 289, 0, 0, 0, 0, 0, 0, - 0, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 0, 300, 0, 301, 302, 303, 304, 305, 306, 0, - 307, 308, 309, 310, 0, 0, 311, 312, 313, 314, - 315, 0, 316, 317, 318, 0, 319, 320, 321, 0, - 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, - 331, 0, 332, 333, 334, 335, 0, 336, 0, 337, - 0, 0, 0, 340, 341, 342, 343, 0, 344, 345, - 0, 346, 347, 348, 0, 349, 350, 351, 352, 353, - 0, 355, 356, 357, 358, 0, 359, 360, 361, 362, - 363, 364, 365, 0, 366, 0, 368, 369, 370, 371, - 372, 373, 374, 0, 375, 0, 376, 0, 0, 379, - 0, 381, 382, 383, 384, 385, 0, 0, 386, 387, - 0, 389, 0, 0, 391, 392, 393, 0, 0, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 0, 412, 413, 414, - 415, 416, 0, 417, 418, 0, 420, 0, 421, 422, - 423, 424, 425, 426, 0, 427, 428, 0, 0, 429, - 430, 431, 0, 0, 432, 433, 434, 0, 436, 0, - 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 0, 0, 448, 449, 450, 451, 452, 453, 454, 455, - 0, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 0, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 0, - 483, 484, 0, 486, 487, 488, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 0, 501, - 502, 503, 504, 505, 0, 506, 507, 508, 509, 510, - 0, 512, 513, 514, 515, 0, 516, 517, 518, 519, - 520, 521, 522, 523, 524, 525, 526, 527, 528, 0, - 529, 530, 0, 531, 0, 533, 534, 535, 536, 537, - 0, 538, 539, 540, 0, 0, 541, 542, 543, 544, - 545, 0, 546, 547, 548, 549, 550, 551, 552, 0, - 0, 553, 554, 555, 556, 557, 0, 0, 558, 559, - 560, 561, 562, 563, 564, 0, 565, 0, 567, 568, - 569, 570, 0, 0, 571, 0, 0, 572, 573, 574, - 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, - 585, 586, 587, 588, 589, 590, 591, 0, 0, 599, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1345, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 0, 0, 0, 0, - 0, 0, 0, 240, 241, 0, 242, 243, 244, 0, - 246, 247, 248, 249, 250, 0, 252, 253, 0, 254, - 255, 256, 257, 258, 259, 0, 0, 260, 261, 262, - 263, 264, 0, 265, 266, 267, 268, 269, 0, 0, - 0, 271, 272, 273, 274, 275, 0, 277, 278, 279, - 0, 280, 281, 282, 283, 284, 285, 0, 0, 287, - 288, 289, 0, 0, 0, 0, 0, 0, 0, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 0, 300, - 0, 301, 302, 303, 304, 305, 306, 0, 307, 308, - 309, 310, 0, 0, 311, 312, 313, 314, 315, 0, - 316, 317, 318, 0, 319, 320, 321, 0, 322, 323, - 324, 325, 326, 327, 328, 329, 330, 0, 331, 0, - 332, 333, 334, 335, 0, 336, 0, 337, 0, 0, - 0, 340, 341, 342, 343, 0, 344, 345, 0, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 0, 355, - 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, - 365, 0, 366, 0, 368, 369, 370, 371, 372, 373, - 374, 0, 375, 0, 376, 0, 0, 379, 0, 381, - 382, 383, 384, 385, 0, 0, 386, 387, 0, 389, - 0, 0, 391, 392, 393, 0, 0, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 0, 412, 413, 414, 415, 416, - 0, 417, 418, 0, 420, 0, 421, 422, 423, 424, - 425, 426, 0, 427, 428, 0, 0, 429, 430, 431, - 0, 0, 432, 433, 434, 0, 436, 0, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 0, 0, - 448, 449, 450, 451, 452, 453, 454, 455, 0, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 0, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 0, 483, 484, - 0, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 0, 501, 502, 503, - 504, 505, 0, 506, 507, 508, 509, 510, 0, 512, - 513, 514, 515, 0, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 528, 0, 529, 530, - 0, 531, 0, 533, 534, 535, 536, 537, 0, 538, - 539, 540, 0, 0, 541, 542, 543, 544, 545, 0, - 546, 547, 548, 549, 550, 551, 552, 0, 0, 553, - 554, 555, 556, 557, 0, 0, 558, 559, 560, 561, - 562, 563, 564, 0, 565, 0, 567, 568, 569, 570, - 0, 0, 571, 0, 0, 572, 573, 574, 575, 576, - 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, - 587, 588, 589, 590, 591, 0, 0, 599, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2916, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 0, 0, 0, 0, 0, 0, - 0, 240, 241, 0, 242, 243, 244, 0, 246, 247, - 248, 249, 250, 0, 252, 253, 0, 254, 255, 256, - 257, 258, 259, 0, 0, 260, 261, 262, 263, 264, - 0, 265, 266, 267, 268, 269, 0, 0, 0, 271, - 272, 273, 274, 275, 0, 277, 278, 279, 0, 280, - 281, 282, 283, 284, 285, 0, 0, 287, 288, 289, - 0, 0, 0, 0, 0, 0, 0, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 0, 300, 0, 301, - 302, 303, 304, 305, 306, 0, 307, 308, 309, 310, - 0, 0, 311, 312, 313, 314, 315, 0, 316, 317, - 318, 0, 319, 320, 321, 0, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 0, 331, 0, 332, 333, - 334, 335, 0, 336, 0, 337, 0, 0, 0, 340, - 341, 342, 343, 0, 344, 345, 0, 346, 347, 348, - 0, 349, 350, 351, 352, 353, 0, 355, 356, 357, - 358, 0, 359, 360, 361, 362, 363, 364, 365, 0, - 366, 0, 368, 369, 370, 371, 372, 373, 374, 0, - 375, 0, 376, 0, 0, 379, 0, 381, 382, 383, - 384, 385, 0, 0, 386, 387, 0, 389, 0, 0, - 391, 392, 393, 0, 0, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 412, 413, 414, 415, 416, 0, 417, - 418, 0, 420, 0, 421, 422, 423, 424, 425, 426, - 0, 427, 428, 0, 0, 429, 430, 431, 0, 0, - 432, 433, 434, 0, 436, 0, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 0, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 0, 483, 484, 0, 486, - 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, - 497, 498, 499, 500, 0, 501, 502, 503, 504, 505, - 0, 506, 507, 508, 509, 510, 0, 512, 513, 514, - 515, 0, 516, 517, 518, 519, 520, 521, 522, 523, - 524, 525, 526, 527, 528, 0, 529, 530, 0, 531, - 0, 533, 534, 535, 536, 537, 0, 538, 539, 540, - 0, 0, 541, 542, 543, 544, 545, 0, 546, 547, - 548, 549, 550, 551, 552, 0, 0, 553, 554, 555, - 556, 557, 0, 0, 558, 559, 560, 561, 562, 563, - 564, 0, 565, 0, 567, 568, 569, 570, 0, 0, - 571, 0, 0, 572, 573, 574, 575, 576, 577, 578, - 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 591, 0, 0, 599, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4088, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 0, 0, 0, 0, 0, 0, 0, 240, - 241, 0, 242, 243, 244, 0, 246, 247, 248, 249, - 250, 0, 252, 253, 0, 254, 255, 256, 257, 258, - 259, 0, 0, 260, 261, 262, 263, 264, 0, 265, - 266, 267, 268, 269, 0, 0, 0, 271, 272, 273, - 274, 275, 0, 277, 278, 279, 0, 280, 281, 282, - 283, 284, 285, 0, 0, 287, 288, 289, 0, 0, - 0, 0, 0, 0, 0, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 0, 300, 0, 301, 302, 303, - 304, 305, 306, 0, 307, 308, 309, 310, 0, 0, - 311, 312, 313, 314, 315, 0, 316, 317, 318, 0, - 319, 320, 321, 0, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 0, 331, 0, 332, 333, 334, 335, - 0, 336, 0, 337, 0, 0, 0, 340, 341, 342, - 343, 0, 344, 345, 0, 346, 347, 348, 0, 349, - 350, 351, 352, 353, 0, 355, 356, 357, 358, 0, - 359, 360, 361, 362, 363, 364, 365, 0, 366, 0, - 368, 369, 370, 371, 372, 373, 374, 0, 375, 0, - 376, 0, 0, 379, 0, 381, 382, 383, 384, 385, - 0, 0, 386, 387, 0, 389, 0, 0, 391, 392, - 393, 0, 0, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 0, 412, 413, 414, 415, 416, 0, 417, 418, 0, - 420, 0, 421, 422, 423, 424, 425, 426, 0, 427, - 428, 0, 0, 429, 430, 431, 0, 0, 432, 433, - 434, 0, 436, 0, 438, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 0, 0, 448, 449, 450, 451, - 452, 453, 454, 455, 0, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 0, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 0, 483, 484, 0, 486, 487, 488, - 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, - 499, 500, 0, 501, 502, 503, 504, 505, 0, 506, - 507, 508, 509, 510, 0, 512, 513, 514, 515, 0, - 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 528, 0, 529, 530, 0, 531, 0, 533, - 534, 535, 536, 537, 0, 538, 539, 540, 0, 0, - 541, 542, 543, 544, 545, 0, 546, 547, 548, 549, - 550, 551, 552, 0, 0, 553, 554, 555, 556, 557, - 0, 0, 558, 559, 560, 561, 562, 563, 564, 0, - 565, 0, 567, 568, 569, 570, 0, 0, 571, 0, - 0, 572, 573, 574, 575, 576, 577, 578, 579, 580, - 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, - 591, 0, 0, 0, 0, 0, 1061, 1499, 660, 0, - 0, 880, 721, 0, 0, 0, 0, 4532, 881, 882, - 883, 229, 230, 231, 232, 233, 234, 235, 236, 1629, - 237, 238, 239, 1630, 1631, 1632, 1633, 1634, 1635, 1636, - 240, 241, 1637, 242, 243, 244, 245, 246, 247, 248, - 0, 1062, 251, 1063, 1064, 1638, 254, 255, 256, 257, - 258, 259, 1639, 1640, 260, 261, 1065, 1066, 264, 1641, - 265, 266, 267, 268, 0, 1642, 270, 1643, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 1644, 280, 281, - 282, 283, 284, 285, 1645, 286, 287, 288, 289, 1646, - 1647, 1648, 290, 1649, 1650, 1651, 291, 292, 293, 294, - 295, 296, 1067, 1068, 299, 1652, 300, 1653, 301, 302, - 303, 304, 305, 306, 1654, 307, 308, 309, 310, 1655, - 1656, 311, 312, 1069, 314, 315, 1657, 316, 317, 318, - 1658, 319, 320, 321, 1659, 322, 323, 324, 325, 0, - 327, 328, 329, 0, 1660, 331, 1661, 332, 333, 1070, - 335, 1662, 336, 1663, 337, 338, 1664, 339, 340, 341, - 342, 343, 1665, 344, 0, 1666, 0, 347, 348, 1667, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 1668, 359, 360, 361, 362, 363, 364, 365, 1669, 366, - 367, 0, 369, 370, 371, 372, 1072, 1073, 1670, 1074, - 1671, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 1672, 1673, 386, 0, 388, 389, 390, 1674, 391, - 392, 393, 1675, 1676, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 1075, 411, 1076, 413, 414, 415, 3839, 1677, 417, 418, - 419, 420, 1678, 0, 422, 1077, 424, 425, 426, 1679, - 427, 428, 1680, 1681, 3840, 430, 431, 1682, 1683, 432, - 433, 0, 435, 436, 437, 0, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 1684, 448, 449, 0, - 451, 0, 453, 454, 455, 1685, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 1078, 467, 468, 469, - 470, 1686, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 1687, 483, 484, 485, 486, 487, - 488, 489, 490, 0, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 1688, 501, 502, 503, 504, 505, 1689, - 506, 507, 2166, 509, 510, 511, 512, 513, 1080, 515, - 1690, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 0, 1691, 529, 530, 1692, 531, 532, - 533, 534, 535, 536, 537, 1693, 538, 1081, 1082, 1694, - 1695, 541, 542, 0, 544, 0, 1696, 546, 547, 548, - 549, 550, 551, 552, 1697, 1698, 553, 554, 555, 556, - 557, 1699, 1700, 558, 559, 560, 561, 562, 0, 1083, - 1701, 565, 566, 567, 568, 569, 570, 1702, 1703, 571, - 1704, 1705, 572, 573, 574, 575, 576, 577, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 589, - 590, 591, 0, 0, 0, 886, 887, 888, 0, 3841, - 3842, 891, 892, 893, 894, 1061, 1499, 660, 0, 0, - 880, 721, 0, 0, 0, 0, 0, 881, 882, 883, - 229, 230, 231, 232, 233, 234, 235, 236, 1629, 237, - 238, 239, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 240, - 241, 1637, 242, 243, 244, 245, 246, 247, 248, 0, - 1062, 251, 1063, 1064, 1638, 254, 255, 256, 257, 258, - 259, 1639, 1640, 260, 261, 1065, 1066, 264, 1641, 265, - 266, 267, 268, 0, 1642, 270, 1643, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 1644, 280, 281, 282, - 283, 284, 285, 1645, 286, 287, 288, 289, 1646, 1647, - 1648, 290, 1649, 1650, 1651, 291, 292, 293, 294, 295, - 296, 1067, 1068, 299, 1652, 300, 1653, 301, 302, 303, - 304, 305, 306, 1654, 307, 308, 309, 310, 1655, 1656, - 311, 312, 1069, 314, 315, 1657, 316, 317, 318, 1658, - 319, 320, 321, 1659, 322, 323, 324, 325, 0, 327, - 328, 329, 0, 1660, 331, 1661, 332, 333, 1070, 335, - 1662, 336, 1663, 337, 338, 1664, 339, 340, 341, 342, - 343, 1665, 344, 0, 1666, 0, 347, 348, 1667, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 1668, - 359, 360, 361, 362, 363, 364, 365, 1669, 366, 367, - 0, 369, 370, 371, 372, 1072, 1073, 1670, 1074, 1671, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 1672, 1673, 386, 0, 388, 389, 390, 1674, 391, 392, - 393, 1675, 1676, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 1075, - 411, 1076, 413, 414, 415, 4264, 1677, 417, 418, 419, - 420, 1678, 0, 422, 1077, 424, 425, 426, 1679, 427, - 428, 1680, 1681, 3840, 430, 431, 1682, 1683, 432, 433, - 0, 435, 436, 437, 0, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 0, 1684, 448, 449, 0, 451, - 0, 453, 454, 455, 1685, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 1078, 467, 468, 469, 470, - 1686, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 1687, 483, 484, 485, 486, 487, 488, - 489, 490, 0, 492, 493, 494, 495, 496, 497, 498, - 499, 500, 1688, 501, 502, 503, 504, 505, 1689, 506, - 507, 2166, 509, 510, 511, 512, 513, 1080, 515, 1690, - 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 0, 1691, 529, 530, 1692, 531, 532, 533, - 534, 535, 536, 537, 1693, 538, 1081, 1082, 1694, 1695, - 541, 542, 0, 544, 0, 1696, 546, 547, 548, 549, - 550, 551, 552, 1697, 1698, 553, 554, 555, 556, 557, - 1699, 1700, 558, 559, 560, 561, 562, 0, 1083, 1701, - 565, 566, 567, 568, 569, 570, 1702, 1703, 571, 1704, - 1705, 572, 573, 574, 575, 576, 577, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 589, 590, - 591, 0, 599, 0, 886, 887, 888, 880, 3841, 3842, - 891, 892, 893, 894, 881, 882, 883, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 884, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 885, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 0, 599, - 0, 886, 887, 888, 880, 889, 890, 891, 892, 893, - 894, 881, 882, 883, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 0, 0, 0, 0, - 0, 0, 0, 240, 241, 0, 242, 243, 244, 0, - 246, 247, 248, 249, 250, 0, 252, 253, 0, 254, - 255, 256, 257, 258, 259, 0, 0, 260, 261, 262, - 263, 264, 0, 265, 1011, 267, 268, 269, 0, 0, - 0, 271, 272, 273, 274, 275, 0, 277, 278, 279, - 0, 280, 281, 282, 283, 284, 285, 0, 0, 287, - 288, 289, 0, 0, 0, 0, 0, 0, 0, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 0, 300, - 0, 301, 302, 303, 304, 305, 306, 0, 307, 308, - 309, 310, 0, 0, 311, 312, 313, 314, 315, 0, - 316, 317, 318, 0, 319, 320, 321, 0, 322, 323, - 324, 325, 326, 327, 328, 329, 330, 0, 1012, 0, - 332, 333, 334, 335, 0, 336, 0, 337, 0, 0, - 0, 340, 341, 342, 343, 0, 344, 345, 0, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 0, 355, - 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, - 365, 0, 366, 0, 368, 369, 370, 371, 372, 373, - 374, 0, 375, 0, 376, 0, 0, 379, 0, 381, - 382, 383, 384, 385, 0, 0, 386, 387, 0, 389, - 0, 0, 391, 392, 393, 0, 0, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 0, 412, 413, 414, 415, 416, - 0, 417, 418, 0, 420, 0, 421, 422, 423, 424, - 425, 426, 0, 427, 428, 0, 0, 429, 430, 431, - 0, 0, 432, 433, 434, 0, 436, 0, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 0, 0, - 448, 449, 450, 451, 452, 453, 454, 455, 0, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 0, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 0, 483, 484, - 0, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 0, 501, 502, 503, - 504, 505, 0, 506, 507, 508, 509, 510, 0, 512, - 513, 514, 515, 0, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 528, 0, 529, 530, - 0, 531, 0, 533, 534, 535, 536, 537, 0, 538, - 539, 540, 0, 0, 541, 542, 543, 544, 545, 0, - 546, 547, 548, 549, 550, 551, 552, 0, 0, 553, - 554, 555, 556, 557, 0, 0, 558, 559, 560, 561, - 562, 563, 564, 0, 565, 0, 567, 568, 569, 570, - 0, 0, 571, 0, 0, 572, 573, 574, 575, 576, - 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, - 587, 588, 589, 590, 591, 0, 599, 0, 886, 887, - 888, 880, 889, 890, 891, 892, 893, 894, 881, 882, - 883, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 1111, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 1112, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 1113, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 0, 599, 0, 886, 887, 888, 880, 889, - 890, 891, 892, 893, 894, 881, 882, 883, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 0, 0, 0, 0, 0, 0, 0, 240, 241, 0, - 242, 243, 244, 0, 246, 247, 248, 249, 250, 0, - 252, 253, 0, 254, 255, 256, 257, 258, 259, 0, - 0, 260, 261, 262, 263, 264, 0, 265, 1728, 267, - 268, 269, 0, 0, 0, 271, 272, 273, 274, 275, - 0, 277, 278, 279, 0, 280, 281, 282, 283, 284, - 285, 0, 0, 287, 288, 289, 0, 0, 0, 0, - 0, 0, 0, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 0, 300, 0, 301, 302, 303, 304, 305, - 306, 0, 307, 308, 309, 310, 0, 0, 311, 312, - 313, 314, 315, 0, 316, 317, 318, 0, 319, 320, - 321, 0, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 0, 1729, 0, 332, 333, 334, 335, 0, 336, - 0, 337, 0, 0, 0, 340, 341, 342, 343, 0, - 344, 345, 0, 346, 347, 348, 0, 349, 350, 351, - 352, 353, 0, 355, 356, 357, 358, 0, 359, 360, - 361, 362, 363, 364, 365, 0, 366, 0, 368, 369, - 370, 371, 372, 373, 374, 0, 375, 0, 376, 0, - 0, 379, 0, 381, 382, 383, 384, 385, 0, 0, - 386, 387, 0, 389, 0, 0, 391, 392, 393, 0, - 0, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 0, 412, - 413, 414, 415, 416, 0, 417, 418, 0, 420, 0, - 421, 422, 423, 424, 425, 426, 0, 427, 428, 0, - 0, 429, 430, 431, 0, 0, 432, 433, 434, 0, - 436, 0, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 0, 0, 448, 449, 450, 451, 452, 453, - 454, 455, 0, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 0, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 0, 483, 484, 0, 486, 487, 488, 489, 490, - 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, - 0, 501, 502, 503, 504, 505, 0, 506, 507, 508, - 509, 510, 0, 512, 513, 514, 515, 0, 516, 517, - 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, - 528, 0, 529, 530, 0, 531, 0, 533, 534, 535, - 536, 537, 0, 538, 539, 540, 0, 0, 541, 542, - 543, 544, 545, 0, 546, 547, 548, 549, 550, 551, - 552, 0, 0, 553, 554, 555, 556, 557, 0, 0, - 558, 559, 560, 561, 562, 563, 564, 0, 565, 0, - 567, 568, 569, 570, 0, 0, 571, 0, 0, 572, - 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, - 583, 584, 585, 586, 587, 588, 589, 590, 591, 0, - 599, 0, 886, 887, 888, 880, 889, 890, 891, 892, - 893, 894, 881, 882, 883, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 0, 599, 0, 886, - 887, 888, 880, 889, 890, 891, 892, 893, 894, 881, - 882, 883, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 0, 0, 0, 0, 0, 0, - 0, 240, 241, 0, 242, 243, 244, 0, 246, 247, - 248, 249, 250, 0, 252, 253, 0, 254, 255, 256, - 257, 258, 259, 0, 0, 260, 261, 262, 263, 264, - 0, 265, 2994, 267, 268, 269, 0, 0, 0, 271, - 272, 273, 274, 275, 0, 277, 278, 279, 0, 280, - 281, 282, 283, 284, 285, 0, 0, 287, 288, 289, - 0, 0, 0, 0, 0, 0, 0, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 0, 300, 0, 301, - 302, 303, 304, 305, 306, 0, 307, 308, 309, 310, - 0, 0, 311, 312, 313, 314, 315, 0, 316, 317, - 318, 0, 319, 320, 321, 0, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 0, 2995, 0, 332, 333, - 334, 335, 0, 336, 0, 337, 0, 0, 0, 340, - 341, 342, 343, 0, 344, 345, 0, 346, 347, 348, - 0, 349, 350, 351, 352, 353, 0, 355, 356, 357, - 358, 0, 359, 360, 361, 362, 363, 364, 365, 0, - 366, 0, 368, 369, 370, 371, 372, 373, 374, 0, - 375, 0, 376, 0, 0, 379, 0, 381, 382, 383, - 384, 385, 0, 0, 386, 387, 0, 389, 0, 0, - 391, 392, 393, 0, 0, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 0, 412, 413, 414, 415, 416, 0, 417, - 418, 0, 420, 0, 421, 422, 423, 424, 425, 426, - 0, 427, 428, 0, 0, 429, 430, 431, 0, 0, - 432, 433, 434, 0, 436, 0, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 0, 0, 448, 449, - 450, 451, 452, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 0, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 0, 483, 484, 0, 486, - 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, - 497, 498, 499, 500, 0, 501, 502, 503, 504, 505, - 0, 506, 507, 508, 509, 510, 0, 512, 513, 514, - 515, 0, 516, 517, 518, 519, 520, 521, 522, 523, - 524, 525, 526, 527, 528, 0, 529, 530, 0, 531, - 0, 533, 534, 535, 536, 537, 0, 538, 539, 540, - 0, 0, 541, 542, 543, 544, 545, 0, 546, 547, - 548, 549, 550, 551, 552, 0, 0, 553, 554, 555, - 556, 557, 0, 0, 558, 559, 560, 561, 562, 563, - 564, 0, 565, 0, 567, 568, 569, 570, 0, 0, - 571, 0, 0, 572, 573, 574, 575, 576, 577, 578, - 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 591, 0, 599, 0, 886, 887, 888, 880, - 889, 890, 891, 892, 893, 894, 881, 882, 883, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 4821, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 1628, 0, 0, 886, 887, 888, 0, 889, 890, 891, - 892, 893, 894, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 1629, 237, 238, 239, 1630, 1631, 1632, - 1633, 1634, 1635, 1636, 240, 241, 1637, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 1638, - 254, 255, 256, 257, 258, 259, 1639, 1640, 260, 261, - 262, 263, 264, 1641, 265, 266, 267, 268, 269, 1642, - 270, 1643, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 1644, 280, 281, 282, 283, 284, 285, 1645, 286, - 287, 288, 289, 1646, 1647, 1648, 290, 1649, 1650, 1651, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 1652, - 300, 1653, 301, 302, 303, 304, 305, 306, 1654, 307, - 308, 309, 310, 1655, 1656, 311, 312, 313, 314, 315, - 1657, 316, 317, 318, 1658, 319, 320, 321, 1659, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 1660, 331, - 1661, 332, 333, 334, 335, 1662, 336, 1663, 337, 338, - 1664, 339, 340, 341, 342, 343, 1665, 344, 345, 1666, - 346, 347, 348, 1667, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 1668, 359, 360, 361, 362, 363, - 364, 365, 1669, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 1670, 375, 1671, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 1672, 1673, 386, 387, 388, - 389, 390, 1674, 391, 392, 393, 1675, 1676, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 1677, 417, 418, 419, 420, 1678, 421, 422, 423, - 424, 425, 426, 1679, 427, 428, 1680, 1681, 429, 430, - 431, 1682, 1683, 432, 433, 434, 435, 436, 437, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 1684, 448, 449, 450, 451, 452, 453, 454, 455, 1685, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 1686, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 1687, 483, - 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 1688, 501, 502, - 503, 504, 505, 1689, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 1690, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 1691, 529, - 530, 1692, 531, 532, 533, 534, 535, 536, 537, 1693, - 538, 539, 540, 1694, 1695, 541, 542, 543, 544, 545, - 1696, 546, 547, 548, 549, 550, 551, 552, 1697, 1698, - 553, 554, 555, 556, 557, 1699, 1700, 558, 559, 560, - 561, 562, 563, 564, 1701, 565, 566, 567, 568, 569, - 570, 1702, 1703, 571, 1704, 1705, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 1706, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 818, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 1061, 0, - 0, 0, 0, 0, 0, 0, 0, 5220, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 0, 1062, 251, 1063, 1064, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 1065, 1066, - 264, 0, 265, 266, 267, 268, 0, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 1067, 1068, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 0, 327, 328, 329, 0, 0, 331, 0, 332, - 333, 1070, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 0, 0, 0, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 2162, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 2163, 369, 370, 371, 372, 1072, 1073, - 0, 1074, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 0, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1075, 411, 1076, 413, 414, 415, 0, 0, - 417, 418, 419, 420, 0, 0, 422, 1077, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 2164, 432, 433, 2165, 435, 436, 437, 0, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 0, 451, 0, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1078, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 0, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 2166, 509, 510, 511, 512, 513, - 1080, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 0, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1081, - 1082, 0, 0, 541, 542, 0, 544, 0, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 0, 1083, 2167, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 2484, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 589, 590, 591, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 2168, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 0, 1062, 251, 1063, 1064, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 1065, 1066, 264, 0, 265, 266, 267, 268, 0, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 1067, 1068, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 1069, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 0, 327, 328, 329, 0, 0, 331, - 0, 332, 333, 1070, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 0, 0, - 0, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 2162, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 2163, 369, 370, 371, 372, - 1072, 1073, 0, 1074, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 0, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 1075, 411, 1076, 413, 414, 415, - 0, 0, 417, 418, 419, 420, 0, 0, 422, 1077, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 2164, 432, 433, 2165, 435, 436, 437, 0, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 0, 451, 0, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 1078, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 0, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 2166, 509, 510, 511, - 512, 513, 1080, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 0, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 1081, 1082, 0, 0, 541, 542, 0, 544, 0, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 0, 1083, 2167, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 866, 1499, 660, 0, 0, 0, 721, 0, - 0, 0, 0, 589, 590, 591, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 2168, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 270, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 0, 0, 0, 290, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 2093, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 1915, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 388, 389, 390, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 0, 417, 418, 419, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 1916, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 511, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 1917, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 866, 1499, - 660, 0, 0, 0, 721, 1500, 1501, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 2098, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 1915, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 0, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 1916, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 1917, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 866, 1499, 660, 0, 0, 0, - 721, 1500, 1501, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 1915, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 1916, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 1917, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 866, 0, 660, 0, 0, 0, 721, 1500, 1501, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 2948, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 1915, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 0, 417, 418, 419, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 1916, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 1917, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 721, 733, 734, 0, 0, 0, 0, 0, - 0, 229, 722, 231, 232, 233, 234, 235, 236, 723, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 724, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 725, 334, - 335, 0, 336, 0, 726, 0, 727, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 728, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 729, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 730, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 731, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 732, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 1628, 5430, 660, 0, 0, 0, 721, 733, - 734, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 1629, 237, 238, 239, 1630, - 1631, 1632, 1633, 1634, 1635, 1636, 240, 241, 1637, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 1638, 254, 255, 256, 257, 258, 259, 1639, 1640, - 260, 261, 262, 263, 264, 1641, 265, 266, 267, 268, - 269, 1642, 270, 1643, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 1644, 280, 281, 282, 283, 284, 285, - 1645, 286, 287, 288, 289, 1646, 1647, 1648, 290, 1649, - 1650, 1651, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 1652, 300, 1653, 301, 302, 303, 304, 305, 306, - 1654, 307, 308, 309, 310, 1655, 1656, 311, 312, 313, - 314, 315, 1657, 316, 317, 318, 1658, 319, 320, 321, - 1659, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 1660, 331, 1661, 332, 333, 334, 335, 1662, 336, 1663, - 337, 338, 1664, 339, 340, 341, 342, 343, 1665, 344, - 345, 1666, 346, 347, 348, 1667, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 1668, 359, 360, 361, - 362, 363, 364, 365, 1669, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 1670, 375, 1671, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 1672, 1673, 386, - 387, 388, 389, 390, 1674, 391, 392, 393, 1675, 1676, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 1677, 417, 418, 419, 420, 1678, 421, - 422, 423, 424, 425, 426, 1679, 427, 428, 1680, 1681, - 429, 430, 431, 1682, 1683, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 1684, 448, 449, 450, 451, 452, 453, 454, - 455, 1685, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 1686, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 1687, 483, 484, 485, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 1688, - 501, 502, 503, 504, 505, 1689, 506, 507, 508, 509, - 510, 511, 512, 513, 514, 515, 1690, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 1691, 529, 530, 1692, 531, 532, 533, 534, 535, 536, - 537, 1693, 538, 539, 540, 1694, 1695, 541, 542, 543, - 544, 545, 1696, 546, 547, 548, 549, 550, 551, 552, - 1697, 1698, 553, 554, 555, 556, 557, 1699, 1700, 558, - 559, 560, 561, 562, 563, 564, 1701, 565, 566, 567, - 568, 569, 570, 1702, 1703, 571, 1704, 1705, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 1628, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 1629, 237, 238, 239, 1630, 1631, 1632, 1633, 1634, - 1635, 1636, 240, 241, 1637, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 1638, 254, 255, - 256, 257, 258, 259, 1639, 1640, 260, 261, 262, 263, - 264, 1641, 265, 266, 267, 268, 269, 1642, 270, 1643, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 1644, - 280, 281, 282, 283, 284, 285, 1645, 286, 287, 288, - 289, 1646, 1647, 1648, 290, 1649, 1650, 1651, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 1652, 300, 1653, - 301, 302, 303, 304, 305, 306, 1654, 307, 308, 309, - 310, 1655, 1656, 311, 312, 313, 314, 315, 1657, 316, - 317, 318, 1658, 319, 320, 321, 1659, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 1660, 331, 1661, 332, - 333, 334, 335, 1662, 336, 1663, 337, 338, 1664, 339, - 340, 341, 342, 343, 1665, 344, 345, 1666, 346, 347, - 348, 1667, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 1668, 359, 360, 361, 362, 363, 364, 365, - 1669, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 1670, 375, 1671, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 1672, 1673, 386, 387, 388, 389, 390, - 1674, 391, 392, 393, 1675, 1676, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 1677, - 417, 418, 419, 420, 1678, 421, 422, 423, 424, 425, - 426, 1679, 427, 428, 1680, 1681, 429, 430, 431, 1682, - 1683, 432, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 1684, 448, - 449, 450, 451, 452, 453, 454, 455, 1685, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 1686, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 1687, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 1688, 501, 502, 503, 504, - 505, 1689, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 1690, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 1691, 529, 530, 1692, - 531, 532, 533, 534, 535, 536, 537, 1693, 538, 539, - 540, 1694, 1695, 541, 542, 543, 544, 545, 1696, 546, - 547, 548, 549, 550, 551, 552, 1697, 1698, 553, 554, - 555, 556, 557, 1699, 1700, 558, 559, 560, 561, 562, - 563, 564, 1701, 565, 566, 567, 568, 569, 570, 1702, - 1703, 571, 1704, 1705, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 1628, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 3066, 234, 235, 236, 1629, 237, 238, - 239, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 240, 241, - 1637, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 1638, 254, 255, 256, 257, 258, 259, - 1639, 1640, 260, 261, 262, 263, 264, 1641, 265, 266, - 267, 268, 269, 1642, 270, 1643, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 1644, 280, 281, 282, 283, - 284, 285, 1645, 286, 287, 288, 289, 1646, 1647, 1648, - 290, 1649, 1650, 1651, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 1652, 300, 1653, 301, 302, 303, 304, - 305, 306, 1654, 307, 308, 309, 310, 1655, 1656, 311, - 312, 313, 3067, 315, 1657, 316, 317, 318, 1658, 319, - 320, 321, 1659, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 1660, 331, 1661, 332, 333, 334, 335, 1662, - 336, 1663, 337, 338, 1664, 339, 340, 341, 342, 343, - 1665, 344, 345, 1666, 346, 347, 348, 1667, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 1668, 359, - 360, 361, 362, 363, 364, 365, 1669, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 1670, 375, 1671, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 1672, - 1673, 386, 387, 388, 389, 390, 1674, 391, 392, 393, - 1675, 1676, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 1677, 417, 418, 419, 420, - 1678, 421, 422, 423, 424, 425, 426, 1679, 427, 428, - 1680, 1681, 429, 430, 431, 1682, 1683, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 1684, 448, 449, 450, 451, 452, - 453, 454, 455, 1685, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 1686, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 1687, 483, 484, 485, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 1688, 501, 502, 503, 504, 505, 1689, 3068, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 1690, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 1691, 529, 530, 1692, 531, 532, 533, 534, - 535, 536, 537, 1693, 538, 539, 540, 1694, 1695, 541, - 542, 543, 544, 545, 1696, 546, 547, 548, 549, 550, - 551, 552, 1697, 1698, 553, 554, 555, 556, 557, 1699, - 1700, 558, 559, 560, 561, 562, 563, 564, 1701, 565, - 566, 567, 568, 569, 570, 1702, 1703, 571, 1704, 1705, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 1226, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 1229, 0, - 1230, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 1242, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 1245, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 1250, 388, - 389, 390, 0, 391, 392, 393, 1251, 1252, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 0, 417, 418, 419, 420, 0, 1257, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 1260, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 1261, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 1264, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 1266, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 1269, 544, 1270, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 1273, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 1275, 1276, 1277, 1278, 583, 1279, 1280, - 1281, 1282, 588, 589, 590, 591, 866, 0, 660, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 270, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 0, - 0, 0, 290, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 1915, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 388, 389, 390, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 0, 417, 418, - 419, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 1916, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 1917, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 866, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 904, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 270, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 0, 0, 0, 290, 0, - 0, 867, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 388, 389, 390, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 0, 417, 418, 419, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 868, 506, 507, 508, 509, - 510, 511, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 866, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 924, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 867, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 925, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 0, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 868, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 866, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 867, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 868, 506, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 2427, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 866, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 867, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 345, 3418, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 0, 417, 418, 419, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 868, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 866, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 270, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 0, - 0, 0, 290, 0, 0, 867, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 388, 389, 390, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 0, 417, 418, - 419, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 868, - 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 866, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 270, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 0, 0, 0, 290, 0, - 0, 867, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 388, 389, 390, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 1030, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 0, 417, 418, 419, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 868, 506, 507, 508, 509, - 510, 511, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 866, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 867, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 1106, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 0, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 868, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 866, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 867, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 1119, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 868, 506, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 866, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 867, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 1131, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 1132, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 0, 417, 418, 419, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 868, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 866, 0, 660, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 270, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 0, - 0, 0, 290, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 2078, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 388, 389, 390, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 0, 417, 418, - 419, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 866, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 3, - 4, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 270, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 0, 0, 0, 290, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 388, 389, 390, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 0, 417, 418, 419, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 511, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 866, 0, - 660, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 0, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 866, 0, 660, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 1901, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 0, 417, 418, 419, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 228, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 270, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 0, - 0, 0, 290, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 1053, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 388, 389, 390, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 0, 417, 418, - 419, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 270, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 0, 0, 0, 290, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 1103, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 388, 389, 390, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 0, 417, 418, 419, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 511, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 1117, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 0, - 417, 418, 419, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 511, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 1121, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 0, 417, 418, 419, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 511, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 866, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 0, 417, 418, 419, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 435, 436, 437, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 2202, - 265, 266, 267, 268, 269, 0, 0, 2281, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 2203, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 2282, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 2205, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 2283, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 2206, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 2207, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 2202, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 2203, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 2282, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 2205, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 3277, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 2206, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 2207, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 781, 235, - 236, 740, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 741, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 782, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 742, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 743, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 740, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 741, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 2955, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 742, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 743, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 2202, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 2203, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 2282, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 2205, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 2206, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 2207, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 740, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 741, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 742, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 743, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 1942, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 1943, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 1944, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 1945, - 337, 0, 0, 0, 1946, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 1947, 1948, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 1949, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 1950, 490, 491, - 492, 493, 494, 1951, 496, 497, 498, 499, 500, 0, - 1952, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 1953, 531, 0, 1954, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 1955, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 741, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 742, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 743, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 917, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 918, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 813, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 3047, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 3048, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 3060, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 3061, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 600, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 651, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 652, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 773, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 774, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 775, 540, 0, 0, 776, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 807, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 808, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 809, 540, 0, 0, 810, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 813, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 875, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 876, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 1045, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 773, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 1190, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 1320, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 1331, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 793, 261, 262, 263, 1332, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 796, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 797, 487, 488, 489, 490, 491, - 492, 493, 494, 798, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 1324, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 800, 540, 0, 0, 801, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 802, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 1445, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 813, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 1504, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 1505, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 2846, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 2847, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 2848, 531, 0, 533, 2849, 535, 2850, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 2851, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 660, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 721, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 4109, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 4123, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 759, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 771, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 793, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 794, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 795, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 796, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 797, 487, 488, 489, 490, 491, 492, 493, 494, 798, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 799, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 800, - 540, 0, 0, 801, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 802, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 824, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 900, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 910, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 928, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 995, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 1001, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 1018, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 1021, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 1023, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 1059, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 1123, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 1125, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 1135, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 1138, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 1141, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 793, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 796, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 797, 487, 488, 489, - 490, 491, 492, 493, 494, 798, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 1324, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 800, 540, 0, 0, 801, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 802, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 1762, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 1800, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 1802, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 1873, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 1875, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 1877, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 1978, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 2155, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 0, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 793, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 796, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 797, 487, 488, 489, 490, 491, 492, 493, 494, 798, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 1324, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 2189, 534, 535, 536, 537, 0, 538, 800, - 540, 0, 0, 801, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 802, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 793, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 796, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 797, 487, 488, 489, - 490, 491, 492, 493, 494, 2266, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 2267, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 800, 540, 0, 0, 2268, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 802, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 793, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 796, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 797, 487, 488, 489, 490, 491, 492, 493, - 494, 2345, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 2267, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 800, 540, 0, 0, 2268, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 802, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 793, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 796, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 797, 487, - 488, 489, 490, 491, 492, 493, 494, 2362, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 2267, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 800, 540, 0, - 0, 2268, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 802, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 2564, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 2568, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 2640, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 2966, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 793, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 796, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 797, 487, - 488, 489, 490, 491, 492, 493, 494, 798, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 2267, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 800, 540, 0, - 0, 2268, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 802, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 3035, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 599, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 0, 246, - 247, 248, 249, 250, 0, 252, 253, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 262, 263, - 264, 0, 265, 266, 267, 268, 269, 0, 0, 0, - 271, 272, 273, 274, 275, 0, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 0, 287, 288, - 289, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 313, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 0, 331, 0, 332, - 333, 334, 335, 0, 336, 0, 337, 0, 0, 0, - 340, 341, 342, 343, 0, 344, 345, 0, 346, 347, - 348, 0, 349, 350, 351, 352, 3050, 0, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 0, 368, 369, 370, 371, 372, 373, 374, - 0, 375, 0, 376, 0, 0, 379, 0, 381, 382, - 383, 384, 385, 0, 0, 386, 387, 0, 389, 0, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 0, 412, 413, 414, 415, 416, 0, - 417, 418, 0, 420, 0, 421, 422, 423, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 434, 0, 436, 0, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 450, 451, 452, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 0, - 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 508, 509, 510, 0, 512, 513, - 514, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 0, 529, 530, 0, - 531, 0, 533, 534, 535, 536, 537, 0, 538, 539, - 540, 0, 0, 541, 542, 543, 544, 545, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 563, 564, 0, 565, 0, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 599, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 0, 246, 247, 248, 249, 250, - 0, 252, 253, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 262, 263, 264, 0, 265, 266, - 267, 268, 269, 0, 0, 0, 271, 272, 273, 274, - 275, 0, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 0, 287, 288, 289, 0, 0, 0, - 0, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 0, 331, 0, 332, 333, 334, 335, 0, - 336, 0, 337, 0, 0, 0, 340, 341, 342, 343, - 0, 344, 345, 0, 346, 347, 348, 0, 349, 350, - 351, 352, 3052, 0, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 0, 368, - 369, 370, 371, 372, 373, 374, 0, 375, 0, 376, - 0, 0, 379, 0, 381, 382, 383, 384, 385, 0, - 0, 386, 387, 0, 389, 0, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 0, - 412, 413, 414, 415, 416, 0, 417, 418, 0, 420, - 0, 421, 422, 423, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 434, - 0, 436, 0, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 450, 451, 452, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 0, 486, 487, 488, 489, - 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 508, 509, 510, 0, 512, 513, 514, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 0, 529, 530, 0, 531, 0, 533, 534, - 535, 536, 537, 0, 538, 539, 540, 0, 0, 541, - 542, 543, 544, 545, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 563, 564, 0, 565, - 0, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 347, 348, 0, 349, 350, 351, 352, 3195, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 599, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 249, 250, 0, 252, 253, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 262, 263, 264, 0, - 265, 266, 267, 268, 269, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 3231, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 0, 331, 0, 332, 333, 334, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 345, 0, 346, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 368, 369, 370, 371, 372, 373, 374, 0, 375, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 387, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 0, 412, 413, 414, 415, 416, 0, 417, 418, - 0, 420, 0, 421, 422, 423, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 434, 0, 436, 0, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 450, - 451, 452, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 508, 509, 510, 0, 512, 513, 514, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 539, 540, 0, - 0, 541, 542, 543, 544, 545, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 563, 564, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 599, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 0, 246, 247, 248, 249, 250, 0, 252, - 253, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 262, 263, 264, 0, 265, 266, 267, 268, - 269, 0, 0, 0, 271, 272, 273, 274, 275, 0, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 0, 287, 288, 289, 0, 0, 0, 0, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 313, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 0, 331, 0, 332, 333, 334, 335, 0, 336, 0, - 337, 0, 0, 0, 340, 341, 342, 343, 0, 344, - 345, 0, 346, 347, 348, 0, 349, 350, 351, 352, - 4380, 0, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 0, 368, 369, 370, - 371, 372, 373, 374, 0, 375, 0, 376, 0, 0, - 379, 0, 381, 382, 383, 384, 385, 0, 0, 386, - 387, 0, 389, 0, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 412, 413, - 414, 415, 416, 0, 417, 418, 0, 420, 0, 421, - 422, 423, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 434, 0, 436, - 0, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 450, 451, 452, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 0, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 508, 509, - 510, 0, 512, 513, 514, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 0, 529, 530, 0, 531, 0, 533, 534, 535, 536, - 537, 0, 538, 539, 540, 0, 0, 541, 542, 543, - 544, 545, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 563, 564, 0, 565, 0, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 1061, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 0, 1062, 251, 1063, 1064, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 1065, 1066, - 264, 0, 265, 266, 267, 268, 0, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 1067, 1068, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 0, 327, 328, 329, 0, 0, 331, 0, 332, - 333, 1070, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 0, 0, 0, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 2162, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 2163, 369, 370, 371, 372, 1072, 1073, - 0, 1074, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 0, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1075, 411, 1076, 413, 414, 415, 0, 0, - 417, 418, 419, 420, 0, 0, 422, 1077, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 2165, 435, 436, 437, 0, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 0, 451, 0, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1078, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 0, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 2166, 509, 510, 511, 512, 513, - 1080, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 0, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1081, - 1082, 0, 0, 541, 542, 0, 544, 0, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 0, 1083, 2167, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 589, 590, 591, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 0, 246, 247, 248, 249, 250, 0, 252, 253, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 262, 263, 264, 0, 265, 266, 267, 268, 269, 0, - 0, 0, 271, 272, 273, 274, 275, 0, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 0, - 287, 288, 289, 0, 0, 0, 0, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 313, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 0, 331, - 0, 332, 333, 334, 335, 0, 336, 0, 337, 0, - 0, 0, 340, 341, 342, 343, 0, 344, 345, 0, - 346, 0, 348, 0, 349, 350, 351, 352, 353, 0, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 0, 368, 369, 370, 371, 372, - 373, 374, 0, 375, 0, 376, 0, 0, 379, 0, - 381, 382, 383, 384, 385, 0, 0, 386, 387, 0, - 389, 0, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 0, 412, 413, 414, 415, - 416, 0, 417, 418, 0, 420, 0, 421, 422, 423, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 434, 0, 436, 0, 438, - 439, 440, 441, 442, 443, 444, 0, 446, 447, 0, - 0, 448, 449, 450, 451, 452, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 0, 465, - 466, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 0, 486, 487, 488, 489, 490, 491, 0, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 508, 509, 510, 0, - 512, 513, 514, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 528, 0, 529, - 530, 0, 531, 0, 533, 534, 535, 536, 537, 0, - 538, 539, 540, 0, 0, 541, 542, 543, 544, 545, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 563, 564, 0, 565, 0, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 1061, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 0, 1062, 251, 1063, 1064, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 1065, 1066, 264, 0, - 265, 266, 267, 268, 0, 0, 270, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 0, - 0, 0, 290, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 1067, 1068, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 1069, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 0, - 327, 328, 329, 0, 0, 331, 0, 332, 333, 1070, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 0, 0, 0, 347, 348, 0, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 0, 369, 370, 371, 372, 1072, 1073, 0, 1074, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 0, 388, 389, 390, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 1075, 411, 1076, 413, 414, 415, 0, 0, 417, 418, - 419, 420, 2262, 0, 422, 1077, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 0, 435, 436, 437, 0, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 0, - 451, 0, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 1078, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 0, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 2166, 509, 510, 511, 512, 513, 1080, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 0, 0, 529, 530, 3946, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 1081, 1082, 0, - 0, 541, 542, 0, 544, 0, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 0, 1083, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 1061, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 589, - 590, 591, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 0, 1062, 251, 1063, 1064, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 1065, 1066, - 264, 0, 265, 266, 267, 268, 0, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 1067, 1068, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 0, 327, 328, 329, 0, 0, 331, 0, 332, - 333, 1070, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 0, 0, 0, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 0, 369, 370, 371, 372, 1072, 1073, - 0, 1074, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 0, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1075, 411, 1076, 413, 414, 415, 2334, 0, - 417, 418, 419, 420, 0, 0, 422, 1077, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 0, 435, 436, 437, 0, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 0, 451, 0, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1078, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 0, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 1079, 509, 510, 511, 512, 513, - 1080, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 0, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1081, - 1082, 0, 0, 541, 542, 0, 544, 0, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 0, 1083, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 1061, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 589, 590, 591, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 0, 1062, 251, 1063, 1064, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 1065, 1066, 264, 0, 265, 266, 267, 268, 0, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 1067, 1068, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 1069, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 0, 327, 328, 329, 0, 0, 331, - 0, 332, 333, 1070, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 0, 0, - 0, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 0, 369, 370, 371, 372, - 1072, 1073, 0, 1074, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 0, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 1075, 411, 1076, 413, 414, 415, - 3753, 0, 417, 418, 419, 420, 0, 0, 422, 1077, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 0, 435, 436, 437, 0, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 0, 451, 0, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 1078, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 0, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 1079, 509, 510, 511, - 512, 513, 1080, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 0, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 1081, 1082, 0, 0, 541, 542, 0, 544, 0, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 0, 1083, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 1061, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 589, 590, 591, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 0, 1062, 251, 1063, - 1064, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 1065, 1066, 264, 0, 265, 266, 267, 268, - 0, 0, 270, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 0, 0, 0, 290, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 1067, 1068, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 1069, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 0, 327, 328, 329, 0, - 0, 331, 0, 332, 333, 1070, 335, 5285, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 0, 0, 0, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 0, 369, 370, - 371, 372, 1072, 1073, 0, 1074, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 0, 388, 389, 390, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 1075, 411, 1076, 413, - 414, 415, 0, 0, 417, 418, 419, 420, 0, 0, - 422, 1077, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 0, 435, 436, - 437, 0, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 0, 451, 0, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 1078, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 0, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 1079, 509, - 510, 511, 512, 513, 1080, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 0, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 1081, 1082, 0, 0, 541, 542, 0, - 544, 0, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 0, 1083, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 1061, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 589, 590, 591, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 0, 1062, - 251, 1063, 1064, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 1065, 1066, 264, 0, 265, 266, - 267, 268, 0, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 1067, 1068, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 1069, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 0, 327, 328, - 329, 0, 0, 331, 0, 332, 333, 1070, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 0, 0, 0, 347, 348, 0, 349, 350, - 351, 352, 1071, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 0, - 369, 370, 371, 372, 1072, 1073, 0, 1074, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 0, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 1075, 411, - 1076, 413, 414, 415, 0, 0, 417, 418, 419, 420, - 0, 0, 422, 1077, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 0, - 435, 436, 437, 0, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 0, 451, 0, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 1078, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 0, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 1079, 509, 510, 511, 512, 513, 1080, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 0, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 1081, 1082, 0, 0, 541, - 542, 0, 544, 0, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 0, 1083, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 1061, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 589, 590, 591, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 245, 246, 247, 248, - 0, 1062, 251, 1063, 1064, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 1065, 1066, 264, 0, - 265, 266, 267, 268, 0, 0, 270, 0, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 286, 287, 288, 289, 0, - 0, 0, 290, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 1067, 1068, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 1069, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 0, - 327, 328, 329, 0, 0, 331, 0, 332, 333, 1070, - 335, 0, 336, 0, 337, 338, 0, 339, 340, 341, - 342, 343, 0, 344, 0, 0, 0, 347, 348, 0, - 349, 350, 351, 352, 1129, 354, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 367, 0, 369, 370, 371, 372, 1072, 1073, 0, 1074, - 0, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 0, 0, 386, 0, 388, 389, 390, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 1075, 411, 1076, 413, 414, 415, 0, 0, 417, 418, - 419, 420, 0, 0, 422, 1077, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 0, 435, 436, 437, 0, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 0, - 451, 0, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 1078, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 485, 486, 487, - 488, 489, 490, 0, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 1079, 509, 510, 511, 512, 513, 1080, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 0, 0, 529, 530, 0, 531, 532, - 533, 534, 535, 536, 537, 0, 538, 1081, 1082, 0, - 0, 541, 542, 0, 544, 0, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 0, 1083, - 0, 565, 566, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 1061, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 589, - 590, 591, 0, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 0, 0, 0, 0, 0, - 0, 0, 240, 241, 0, 242, 243, 244, 245, 246, - 247, 248, 0, 1062, 251, 1063, 1064, 0, 254, 255, - 256, 257, 258, 259, 0, 0, 260, 261, 1065, 1066, - 264, 0, 265, 266, 267, 268, 0, 0, 270, 0, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 0, - 280, 281, 282, 283, 284, 285, 0, 286, 287, 288, - 289, 0, 0, 0, 290, 0, 0, 0, 291, 292, - 293, 294, 295, 296, 1067, 1068, 299, 0, 300, 0, - 301, 302, 303, 304, 305, 306, 0, 307, 308, 309, - 310, 0, 0, 311, 312, 1069, 314, 315, 0, 316, - 317, 318, 0, 319, 320, 321, 0, 322, 323, 324, - 325, 0, 327, 328, 329, 0, 0, 331, 0, 332, - 333, 1070, 335, 0, 336, 0, 337, 338, 0, 339, - 340, 341, 342, 343, 0, 344, 0, 0, 0, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, - 0, 366, 367, 0, 369, 370, 371, 372, 1072, 1073, - 0, 1074, 0, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 0, 0, 386, 0, 388, 389, 390, - 0, 391, 392, 393, 0, 0, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 1075, 411, 1076, 413, 414, 415, 0, 0, - 417, 418, 419, 420, 0, 0, 422, 1077, 424, 425, - 426, 0, 427, 428, 0, 0, 429, 430, 431, 0, - 0, 432, 433, 0, 435, 436, 437, 0, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 0, 0, 448, - 449, 0, 451, 0, 453, 454, 455, 0, 456, 457, - 458, 459, 460, 461, 462, 463, 464, 465, 1078, 467, - 468, 469, 470, 0, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 0, 483, 484, 485, - 486, 487, 488, 489, 490, 0, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 0, 501, 502, 503, 504, - 505, 0, 506, 507, 1079, 509, 510, 511, 512, 513, - 1080, 515, 0, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 0, 0, 529, 530, 0, - 531, 532, 533, 534, 535, 536, 537, 0, 538, 1081, - 1082, 0, 0, 541, 542, 0, 544, 0, 0, 546, - 547, 548, 549, 550, 551, 552, 0, 0, 553, 554, - 555, 556, 557, 0, 0, 558, 559, 560, 561, 562, - 0, 1083, 0, 565, 566, 567, 568, 569, 570, 0, - 0, 571, 0, 0, 572, 573, 574, 575, 576, 577, - 1061, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 589, 590, 591, 0, 229, 230, 231, 232, 233, - 234, 235, 236, 0, 237, 238, 239, 0, 0, 0, - 0, 0, 0, 0, 240, 241, 0, 242, 243, 244, - 245, 246, 247, 248, 0, 1062, 251, 1063, 1064, 0, - 254, 255, 256, 257, 258, 259, 0, 0, 260, 261, - 1065, 1066, 264, 0, 265, 266, 267, 268, 0, 0, - 270, 0, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 0, 280, 281, 282, 283, 284, 285, 0, 286, - 287, 288, 289, 0, 0, 0, 290, 0, 0, 0, - 291, 292, 293, 294, 295, 296, 1067, 1068, 299, 0, - 300, 0, 301, 302, 303, 304, 305, 306, 0, 307, - 308, 309, 310, 0, 0, 311, 312, 1069, 314, 315, - 0, 316, 317, 318, 0, 319, 320, 321, 0, 322, - 323, 324, 325, 0, 327, 328, 329, 0, 0, 331, - 0, 332, 333, 1070, 335, 0, 336, 0, 337, 338, - 0, 339, 340, 341, 342, 343, 0, 344, 0, 0, - 0, 347, 348, 0, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, - 364, 365, 0, 366, 367, 0, 369, 370, 371, 372, - 1072, 1073, 0, 1074, 0, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 0, 0, 386, 0, 388, - 389, 390, 0, 391, 392, 393, 0, 0, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 1075, 411, 1076, 413, 414, 415, - 0, 0, 417, 418, 419, 420, 0, 0, 422, 1077, - 424, 425, 426, 0, 427, 428, 0, 0, 429, 430, - 431, 0, 0, 432, 433, 0, 435, 436, 437, 0, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 0, - 0, 448, 449, 0, 451, 0, 453, 454, 455, 0, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 1078, 467, 468, 469, 470, 0, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 0, 483, - 484, 485, 486, 487, 488, 489, 490, 0, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 0, 501, 502, - 503, 504, 505, 0, 506, 507, 2166, 509, 510, 511, - 512, 513, 1080, 515, 0, 516, 517, 518, 519, 520, - 521, 522, 523, 524, 525, 526, 527, 0, 0, 529, - 530, 0, 531, 532, 533, 534, 535, 536, 537, 0, - 538, 1081, 1082, 0, 0, 541, 542, 0, 544, 0, - 0, 546, 547, 548, 549, 550, 551, 552, 0, 0, - 553, 554, 555, 556, 557, 0, 0, 558, 559, 560, - 561, 562, 0, 1083, 0, 565, 566, 567, 568, 569, - 570, 0, 0, 571, 0, 0, 572, 573, 574, 575, - 576, 577, 1061, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 589, 590, 591, 0, 229, 230, 231, - 232, 233, 234, 235, 236, 0, 237, 238, 239, 0, - 0, 0, 0, 0, 0, 0, 240, 241, 0, 242, - 243, 244, 245, 246, 247, 248, 0, 1062, 251, 1063, - 1064, 0, 254, 255, 256, 257, 258, 259, 0, 0, - 260, 261, 1065, 1066, 264, 0, 265, 266, 267, 268, - 0, 0, 270, 0, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 0, 280, 281, 282, 283, 284, 285, - 0, 286, 287, 288, 289, 0, 0, 0, 290, 0, - 0, 0, 291, 292, 293, 294, 295, 296, 1067, 1068, - 299, 0, 300, 0, 301, 302, 303, 304, 305, 306, - 0, 307, 308, 309, 310, 0, 0, 311, 312, 1069, - 314, 315, 0, 316, 317, 318, 0, 319, 320, 321, - 0, 322, 323, 324, 325, 0, 327, 328, 329, 0, - 0, 331, 0, 332, 333, 1070, 335, 0, 336, 0, - 337, 338, 0, 339, 340, 341, 342, 343, 0, 344, - 0, 0, 0, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, - 362, 363, 364, 365, 0, 366, 367, 0, 369, 370, - 371, 372, 1072, 1073, 0, 1074, 0, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 0, 0, 386, - 0, 388, 389, 390, 0, 391, 392, 393, 0, 0, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 1075, 411, 1076, 413, - 414, 415, 0, 0, 417, 418, 419, 420, 0, 0, - 422, 1077, 424, 425, 426, 0, 427, 428, 0, 0, - 429, 430, 431, 0, 0, 432, 433, 0, 435, 436, - 437, 0, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 0, 0, 448, 449, 0, 451, 0, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 1078, 467, 468, 469, 470, 0, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 0, 483, 484, 485, 486, 487, 488, 489, 490, 0, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 0, - 501, 502, 503, 504, 505, 0, 506, 507, 0, 509, - 510, 511, 512, 513, 1080, 515, 0, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 0, - 0, 529, 530, 0, 531, 532, 533, 534, 535, 536, - 537, 0, 538, 1081, 1082, 0, 0, 541, 542, 0, - 544, 0, 0, 546, 547, 548, 549, 550, 551, 552, - 0, 0, 553, 554, 555, 556, 557, 0, 0, 558, - 559, 560, 561, 562, 0, 1083, 0, 565, 566, 567, - 568, 569, 570, 0, 0, 571, 0, 0, 572, 573, - 574, 575, 576, 577, 1061, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 589, 590, 591, 0, 229, - 230, 231, 232, 233, 234, 235, 236, 0, 237, 238, - 239, 0, 0, 0, 0, 0, 0, 0, 240, 241, - 0, 242, 243, 244, 245, 246, 247, 248, 0, 0, - 251, 0, 0, 0, 254, 255, 256, 257, 258, 259, - 0, 0, 260, 261, 0, 0, 264, 0, 265, 266, - 267, 268, 0, 0, 270, 0, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 0, 280, 281, 282, 283, - 284, 285, 0, 286, 287, 288, 289, 0, 0, 0, - 290, 0, 0, 0, 291, 292, 293, 294, 295, 296, - 0, 0, 299, 0, 300, 0, 301, 302, 303, 304, - 305, 306, 0, 307, 308, 309, 310, 0, 0, 311, - 312, 313, 314, 315, 0, 316, 317, 318, 0, 319, - 320, 321, 0, 322, 323, 324, 325, 0, 327, 328, - 329, 0, 0, 331, 0, 332, 333, 0, 335, 0, - 336, 0, 337, 338, 0, 339, 340, 341, 342, 343, - 0, 344, 0, 0, 0, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 0, 359, - 360, 361, 362, 363, 364, 365, 0, 366, 367, 0, - 369, 370, 371, 372, 0, 0, 0, 0, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 0, - 0, 386, 0, 388, 389, 390, 0, 391, 392, 393, - 0, 0, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 0, 411, - 0, 413, 414, 415, 0, 0, 417, 418, 419, 420, - 0, 0, 422, 0, 424, 425, 426, 0, 427, 428, - 0, 0, 429, 430, 431, 0, 0, 432, 433, 0, - 435, 436, 437, 0, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 0, 0, 448, 449, 0, 451, 0, - 453, 454, 455, 0, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 0, 467, 468, 469, 470, 0, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 0, 483, 484, 485, 486, 487, 488, 489, - 490, 0, 492, 493, 494, 495, 496, 497, 498, 499, - 500, 0, 501, 502, 503, 504, 505, 0, 506, 507, - 0, 509, 510, 511, 512, 513, 0, 515, 0, 516, - 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, - 527, 0, 0, 529, 530, 0, 531, 532, 533, 534, - 535, 536, 537, 0, 538, 0, 0, 0, 0, 541, - 542, 0, 544, 0, 0, 546, 547, 548, 549, 550, - 551, 552, 0, 0, 553, 554, 555, 556, 557, 0, - 0, 558, 559, 560, 561, 562, 0, 0, 0, 565, - 566, 567, 568, 569, 570, 0, 0, 571, 0, 0, - 572, 573, 574, 575, 576, 577, 4943, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 589, 590, 591, - 0, 229, 230, 231, 232, 233, 234, 235, 236, 0, - 237, 238, 239, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 242, 243, 244, 0, 246, 247, 248, - 0, 0, 0, 0, 0, 0, 254, 255, 256, 257, - 258, 259, 0, 0, 260, 261, 0, 0, 264, 0, - 265, 266, 267, 268, 0, 0, 0, 0, 271, 272, - 273, 274, 275, 0, 277, 278, 279, 0, 280, 281, - 282, 283, 284, 285, 0, 0, 287, 288, 289, 0, - 0, 0, 0, 0, 0, 0, 291, 292, 293, 294, - 295, 296, 0, 0, 299, 0, 300, 0, 301, 302, - 303, 304, 305, 306, 0, 307, 308, 309, 310, 0, - 0, 311, 312, 313, 314, 315, 0, 316, 317, 318, - 0, 319, 320, 321, 0, 322, 323, 324, 325, 0, - 327, 328, 329, 0, 0, 331, 0, 332, 333, 0, - 335, 0, 336, 0, 337, 0, 0, 0, 340, 341, - 342, 343, 0, 344, 0, 0, 0, 347, 348, 0, - 349, 350, 351, 352, 353, 0, 355, 356, 357, 358, - 0, 359, 360, 361, 362, 363, 364, 365, 0, 366, - 0, 0, 369, 370, 371, 372, 0, 0, 0, 0, - 0, 376, 0, 0, 379, 0, 381, 382, 383, 384, - 385, 0, 0, 386, 0, 0, 389, 0, 0, 391, - 392, 393, 0, 0, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 0, 0, 0, 413, 414, 415, 0, 0, 417, 418, - 0, 420, 0, 0, 422, 0, 424, 425, 426, 0, - 427, 428, 0, 0, 429, 430, 431, 0, 0, 432, - 433, 0, 0, 436, 0, 0, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 0, 0, 448, 449, 0, - 451, 0, 453, 454, 455, 0, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 0, 467, 468, 469, - 470, 0, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 0, 483, 484, 0, 486, 487, - 488, 489, 490, 0, 492, 493, 494, 495, 496, 497, - 498, 499, 500, 0, 501, 502, 503, 504, 505, 0, - 506, 507, 0, 509, 510, 0, 512, 513, 0, 515, - 0, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 0, 0, 529, 530, 0, 531, 0, - 533, 534, 535, 536, 537, 0, 538, 0, 0, 0, - 0, 541, 542, 0, 544, 0, 0, 546, 547, 548, - 549, 550, 551, 552, 0, 0, 553, 554, 555, 556, - 557, 0, 0, 558, 559, 560, 561, 562, 0, 0, - 0, 565, 0, 567, 568, 569, 570, 0, 0, 571, - 0, 0, 572, 573, 574, 575, 576, 577, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 589, - 590, 591 -}; - -static const yytype_int16 yycheck[] = -{ - 6, 911, 45, 0, 205, 1151, 0, 8, 628, 183, - 0, 1109, 0, 940, 15, 0, 1173, 23, 843, 25, - 741, 742, 743, 29, 21, 792, 747, 37, 794, 35, - 36, 37, 927, 39, 1079, 52, 42, 43, 22, 45, - 205, 47, 200, 1431, 28, 912, 1556, 2504, 1468, 852, - 208, 13, 942, 211, 816, 703, 1475, 817, 191, 936, - 2699, 1082, 1024, 2573, 46, 1209, 801, 1481, 2907, 2395, - 2517, 685, 911, 661, 18, 3353, 1796, 2416, 3356, 3012, - 919, 3600, 1067, 1068, 2675, 699, 1714, 1475, 1618, 6, - 929, 938, 1077, 3263, 3039, 3697, 1984, 210, 2916, 3066, - 2858, 3068, 864, 998, 708, 661, 619, 1002, 170, 2170, - 2171, 224, 1007, 23, 3645, 3546, 3328, 3641, 3938, 3309, - 3575, 698, 1017, 1967, 2881, 3581, 3255, 37, 683, 4516, - 3925, 686, 3935, 3645, 3263, 1013, 1031, 4177, 2072, 0, - 0, 42, 4407, 2028, 4410, 0, 1408, 0, 0, 185, - 3340, 1029, 3881, 709, 51, 0, 2333, 2005, 671, 0, - 2790, 36, 21, 0, 4567, 1579, 0, 2135, 43, 185, - 0, 0, 2105, 1460, 0, 0, 219, 2926, 1492, 1899, - 2113, 1809, 4361, 945, 2137, 191, 192, 193, 194, 862, - 196, 4725, 1065, 1066, 200, 3924, 202, 840, 4532, 205, - 4534, 840, 208, 1076, 3326, 211, 3509, 0, 214, 797, - 216, 3621, 0, 219, 5, 0, 11, 223, 57, 225, - 0, 9, 0, 0, 4587, 114, 9, 4634, 4635, 902, - 4409, 9, 1519, 3580, 907, 3582, 5, 5, 26, 4713, - 72, 797, 5, 5, 5, 13, 14, 1268, 26, 1536, - 13, 14, 42, 1238, 1239, 5, 5, 5, 42, 5, - 39, 5, 5, 5, 4627, 13, 14, 1616, 1617, 990, - 74, 1585, 1586, 1258, 5, 22, 4921, 823, 163, 35, - 84, 112, 158, 57, 4667, 5, 107, 5, 1423, 22, - 2920, 49, 4825, 4826, 138, 1098, 3, 4, 5, 145, - 133, 39, 9, 26, 105, 4, 11, 163, 105, 105, - 9, 3014, 57, 4659, 207, 9, 57, 4860, 5, 79, - 163, 112, 211, 112, 163, 144, 264, 175, 4, 144, - 2507, 267, 87, 9, 269, 40, 57, 4002, 4003, 5, - 4005, 4006, 4007, 4008, 4009, 270, 252, 5, 275, 74, - 289, 289, 24, 158, 1227, 1228, 27, 57, 179, 57, - 275, 3, 172, 309, 169, 254, 357, 72, 5270, 301, - 163, 163, 163, 45, 270, 163, 105, 57, 163, 57, - 57, 1254, 187, 163, 131, 163, 163, 22, 30, 31, - 358, 22, 114, 28, 187, 335, 112, 28, 131, 187, - 396, 158, 187, 116, 252, 112, 70, 187, 419, 187, - 187, 32, 1374, 4, 5, 3274, 91, 26, 9, 240, - 255, 285, 243, 312, 84, 273, 2460, 429, 2462, 11, - 115, 11, 2466, 440, 2468, 2469, 440, 324, 2615, 165, - 2617, 398, 11, 2477, 2478, 2479, 438, 4830, 4714, 464, - 4715, 5, 163, 476, 461, 4789, 479, 461, 1348, 1336, - 40, 163, 477, 628, 475, 254, 398, 311, 475, 26, - 357, 40, 198, 475, 4948, 26, 33, 5122, 418, 4842, - 163, 1408, 33, 479, 441, 66, 74, 479, 479, 26, - 72, 11, 72, 357, 169, 208, 33, 1542, 183, 206, - 131, 74, 1116, 72, 74, 344, 11, 475, 164, 441, - 2855, 84, 5414, 626, 20, 680, 74, 126, 1384, 632, - 162, 228, 164, 252, 145, 335, 1288, 348, 333, 475, - 202, 202, 645, 170, 105, 163, 475, 475, 285, 475, - 475, 360, 4888, 259, 119, 360, 1134, 443, 26, 1153, - 475, 457, 479, 396, 1316, 344, 330, 215, 354, 8, - 151, 142, 2907, 3733, 479, 1179, 15, 16, 17, 326, - 3273, 117, 259, 187, 329, 423, 29, 324, 1134, 160, - 1470, 1195, 417, 384, 105, 330, 479, 384, 434, 330, - 479, 430, 396, 259, 479, 1151, 1210, 1143, 105, 475, - 606, 434, 381, 267, 3733, 396, 612, 1446, 614, 330, - 357, 617, 396, 619, 611, 621, 5019, 611, 29, 475, - 1755, 611, 628, 611, 357, 1213, 611, 633, 3757, 635, - 330, 475, 330, 464, 424, 456, 642, 5020, 144, 117, - 424, 473, 5025, 381, 4075, 477, 4102, 1525, 5181, 409, - 330, 713, 330, 330, 5061, 5129, 1551, 1213, 4113, 1554, - 666, 384, 4117, 607, 5207, 671, 428, 1506, 259, 843, - 676, 396, 4938, 464, 680, 422, 471, 683, 466, 467, - 686, 163, 4947, 5328, 417, 478, 477, 479, 466, 467, - 478, 474, 709, 478, 1572, 1562, 702, 440, 478, 421, - 478, 478, 3892, 3648, 473, 479, 475, 475, 477, 440, - 753, 708, 475, 475, 475, 1363, 4019, 475, 461, 475, - 2069, 302, 3934, 201, 479, 475, 475, 475, 5262, 475, - 461, 475, 475, 475, 479, 736, 396, 1614, 722, 438, - 724, 1287, 726, 1331, 475, 707, 4156, 753, 732, 1392, - 756, 757, 758, 1392, 4101, 475, 4103, 475, 479, 466, - 467, 962, 461, 769, 475, 771, 471, 466, 467, 1616, - 1617, 1618, 466, 467, 817, 1331, 5250, 479, 4818, 479, - 1937, 479, 2959, 1339, 1340, 791, 792, 429, 794, 795, - 466, 467, 4457, 799, 1467, 831, 479, 962, 1623, 479, - 958, 479, 479, 4405, 847, 1903, 964, 813, 396, 967, - 367, 817, 403, 384, 947, 831, 367, 823, 861, 475, - 374, 375, 271, 396, 5158, 1752, 396, 5190, 26, 835, - 367, 412, 3158, 3, 340, 5, 833, 2251, 396, 833, - 5203, 847, 479, 833, 419, 833, 1944, 1520, 833, 66, - 709, 479, 1398, 3300, 360, 861, 3978, 1955, 5123, 5125, - 5334, 81, 2281, 384, 1537, 479, 5, 84, 2929, 1747, - 2931, 417, 350, 879, 327, 466, 467, 384, 884, 885, - 1865, 756, 757, 758, 3633, 175, 466, 467, 468, 469, - 470, 471, 163, 1513, 795, 429, 264, 120, 799, 468, - 469, 470, 471, 123, 304, 3838, 3851, 878, 289, 915, - 916, 114, 2760, 2761, 396, 2329, 327, 2765, 2886, 2449, - 2182, 289, 112, 5397, 5103, 142, 36, 824, 5, 340, - 3, 342, 938, 939, 2887, 5338, 5339, 107, 2871, 417, - 5303, 947, 117, 160, 107, 5124, 466, 467, 468, 469, - 470, 471, 958, 269, 2802, 2803, 962, 316, 964, 112, - 175, 967, 821, 468, 469, 470, 471, 1840, 1841, 106, - 757, 240, 833, 833, 164, 4704, 982, 2862, 833, 5366, - 833, 833, 464, 2917, 2271, 5251, 22, 5252, 833, 3619, - 401, 124, 833, 854, 116, 477, 833, 340, 1004, 833, - 3757, 134, 4514, 833, 833, 1011, 1012, 833, 833, 179, - 83, 121, 252, 462, 463, 464, 179, 466, 467, 468, - 469, 470, 471, 26, 117, 3958, 201, 1033, 1034, 1035, - 2874, 1037, 4563, 1039, 1040, 5438, 164, 252, 4550, 340, - 915, 916, 4473, 160, 22, 250, 2556, 174, 81, 2195, - 28, 4563, 756, 34, 191, 3914, 259, 117, 38, 3236, - 3237, 4517, 135, 268, 3903, 255, 4521, 287, 5333, 114, - 240, 4526, 431, 243, 4529, 475, 155, 240, 163, 348, - 243, 30, 31, 384, 1805, 302, 208, 722, 47, 724, - 123, 726, 84, 1983, 475, 131, 294, 732, 733, 734, - 1044, 324, 187, 1109, 81, 1111, 1112, 475, 201, 2036, - 4905, 724, 725, 726, 165, 264, 729, 730, 731, 344, - 259, 2166, 357, 126, 3, 396, 739, 384, 275, 916, - 283, 112, 475, 423, 157, 2025, 4956, 1143, 217, 2005, - 289, 201, 91, 4946, 22, 4940, 123, 2013, 4426, 106, - 28, 2571, 285, 131, 352, 1156, 1153, 1158, 231, 1160, - 288, 1162, 111, 1164, 1165, 1166, 211, 1173, 1174, 389, - 1171, 115, 1178, 264, 1180, 4904, 168, 269, 348, 66, - 1151, 2071, 259, 423, 311, 348, 1952, 1953, 4400, 26, - 388, 324, 390, 112, 3255, 412, 145, 350, 289, 191, - 1206, 3235, 3263, 1209, 4394, 185, 1212, 344, 423, 254, - 4939, 915, 285, 4725, 341, 357, 5256, 5257, 475, 1225, - 271, 155, 2069, 182, 5, 112, 4171, 3572, 187, 419, - 3575, 384, 284, 112, 191, 363, 228, 57, 3, 183, - 77, 81, 417, 878, 479, 4212, 383, 384, 85, 1255, - 475, 163, 117, 131, 287, 2182, 81, 1871, 1906, 2125, - 2022, 180, 1839, 4, 5, 224, 131, 312, 9, 3, - 1287, 1885, 425, 179, 297, 187, 113, 1283, 1284, 1285, - 167, 1287, 274, 123, 1898, 438, 456, 1833, 95, 3350, - 350, 22, 4816, 456, 275, 1943, 1358, 340, 123, 1947, - 3645, 1307, 166, 1951, 153, 357, 1954, 285, 461, 1913, - 287, 404, 475, 1868, 387, 1828, 389, 251, 83, 1896, - 4751, 366, 475, 2170, 417, 376, 475, 5130, 1883, 476, - 4785, 1886, 479, 141, 240, 254, 4154, 479, 475, 1345, - 4942, 1377, 1378, 180, 1380, 153, 324, 258, 1513, 83, - 158, 1394, 58, 438, 2357, 192, 389, 417, 1914, 5399, - 66, 1377, 1378, 1334, 1380, 172, 301, 254, 1339, 1340, - 135, 320, 259, 1379, 417, 254, 225, 1383, 1384, 357, - 259, 473, 2148, 2003, 475, 477, 2313, 344, 1394, 1395, - 1396, 1946, 1398, 143, 1949, 1950, 388, 205, 390, 438, - 131, 350, 136, 362, 435, 115, 3997, 285, 419, 401, - 151, 2338, 389, 4844, 1420, 302, 384, 225, 4849, 4850, - 412, 141, 126, 415, 128, 165, 383, 384, 2431, 284, - 284, 318, 252, 4603, 299, 384, 1982, 3947, 1984, 189, - 479, 2280, 348, 307, 1990, 252, 324, 287, 479, 1455, - 1996, 1997, 1998, 364, 1460, 5258, 342, 2367, 266, 193, - 2006, 2007, 287, 398, 475, 2011, 231, 275, 1474, 1475, - 2397, 22, 4984, 183, 4603, 339, 425, 1448, 1484, 357, - 429, 1487, 5013, 464, 22, 205, 396, 1458, 352, 438, - 328, 4703, 473, 104, 475, 476, 477, 238, 479, 1443, - 241, 5013, 357, 5022, 5023, 66, 441, 1513, 237, 1515, - 330, 72, 461, 1519, 2612, 401, 1151, 285, 259, 357, - 285, 385, 228, 84, 84, 412, 475, 292, 2367, 5332, - 1536, 271, 1538, 1576, 2412, 1541, 373, 357, 438, 376, - 5343, 1154, 273, 3869, 1157, 141, 1159, 234, 1161, 389, - 1163, 112, 112, 114, 1167, 275, 324, 291, 3903, 324, - 264, 2400, 145, 328, 389, 213, 285, 49, 175, 479, - 1576, 2498, 1543, 3461, 3913, 1546, 1547, 438, 3904, 479, - 131, 1587, 1588, 1589, 1590, 1591, 393, 2347, 2348, 357, - 112, 2351, 357, 131, 2433, 5398, 187, 328, 329, 1605, - 461, 320, 2449, 411, 252, 324, 167, 29, 1527, 3029, - 1616, 1617, 1618, 1532, 168, 5127, 83, 214, 2443, 2444, - 2445, 103, 387, 114, 389, 153, 357, 238, 168, 225, - 241, 53, 3142, 5436, 195, 2513, 158, 275, 357, 2195, - 3488, 3489, 3490, 3491, 326, 252, 3494, 3495, 3496, 3497, - 3498, 3499, 3500, 3501, 3502, 3503, 5459, 124, 2536, 2537, - 2538, 2539, 403, 396, 2278, 473, 1527, 134, 476, 477, - 2548, 1532, 3733, 438, 228, 2188, 410, 153, 285, 1880, - 3400, 1600, 158, 237, 418, 1604, 3216, 421, 228, 284, - 1823, 411, 3222, 254, 254, 342, 3757, 225, 259, 1334, - 387, 292, 3550, 3551, 1339, 1340, 324, 475, 1714, 347, - 1716, 1869, 360, 164, 1879, 1880, 4661, 324, 200, 234, - 211, 4215, 1728, 1729, 383, 466, 467, 4221, 415, 4562, - 4920, 464, 324, 324, 285, 398, 4569, 328, 266, 1600, - 165, 302, 4954, 1604, 477, 1751, 197, 285, 3162, 225, - 5262, 438, 2512, 440, 401, 1726, 438, 318, 126, 418, - 128, 212, 357, 254, 1770, 357, 357, 350, 4113, 417, - 252, 222, 4117, 324, 292, 114, 316, 5296, 396, 461, - 1786, 1787, 1788, 1789, 168, 340, 324, 342, 475, 86, - 266, 3825, 3969, 1799, 3971, 3829, 3830, 479, 3832, 4600, - 1806, 384, 22, 1809, 4737, 475, 357, 2964, 28, 159, - 328, 5342, 4451, 1448, 1820, 254, 423, 1823, 285, 357, - 259, 312, 1828, 1458, 126, 5337, 128, 1833, 285, 344, - 5342, 128, 4691, 126, 388, 128, 390, 285, 2003, 357, - 2353, 4642, 425, 193, 228, 2566, 401, 438, 388, 151, - 390, 412, 340, 320, 2781, 438, 195, 324, 151, 5137, - 2787, 415, 1868, 1869, 346, 1500, 1501, 324, 1520, 4836, - 461, 310, 387, 1879, 1880, 415, 324, 1883, 461, 158, - 1886, 306, 285, 334, 372, 1537, 254, 91, 4, 419, - 357, 431, 475, 9, 2760, 2761, 264, 1903, 1904, 2765, - 415, 0, 181, 4360, 1910, 329, 1912, 111, 1543, 357, - 5441, 1546, 1547, 252, 312, 254, 1913, 342, 4557, 1962, - 4559, 324, 1923, 438, 1925, 440, 1927, 325, 1929, 5441, - 1931, 1937, 4379, 357, 1935, 3481, 2802, 2803, 1944, 478, - 1946, 145, 4399, 1949, 1950, 475, 1952, 1953, 285, 1955, - 316, 401, 2937, 4, 357, 353, 1962, 259, 9, 166, - 475, 254, 264, 1969, 3510, 1975, 259, 43, 1974, 1975, - 1967, 264, 1978, 1967, 399, 4733, 1982, 1967, 1984, 1967, - 405, 11, 1967, 1989, 1990, 351, 2532, 324, 2576, 65, - 1996, 1997, 1998, 2601, 2602, 2603, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 388, 2011, 390, 2013, 2014, 24, - 40, 2017, 114, 3861, 2662, 4192, 4193, 92, 384, 3333, - 2576, 3649, 3336, 479, 104, 4351, 2032, 2033, 2034, 2035, - 45, 415, 2857, 2039, 2040, 4968, 2237, 1981, 2044, 2585, - 304, 2047, 72, 2631, 2050, 2051, 2052, 2053, 2054, 2055, - 2056, 2057, 2058, 316, 2060, 1914, 158, 213, 350, 4918, - 2066, 2067, 153, 2069, 1974, 431, 431, 158, 255, 256, - 2076, 158, 2237, 328, 5264, 2631, 4935, 2235, 347, 159, - 2238, 2239, 5027, 440, 5, 438, 263, 4926, 351, 164, - 11, 1726, 384, 195, 181, 2228, 252, 215, 19, 2105, - 285, 403, 357, 2109, 461, 475, 361, 2113, 461, 2115, - 403, 413, 4971, 193, 285, 273, 320, 38, 475, 2125, - 413, 384, 197, 906, 2927, 2860, 479, 285, 2134, 2135, - 1774, 285, 339, 425, 225, 269, 401, 212, 345, 324, - 274, 924, 2148, 328, 927, 352, 350, 222, 3015, 2155, - 252, 2157, 254, 324, 1798, 474, 312, 3314, 238, 2153, - 479, 241, 158, 350, 2277, 438, 324, 3324, 431, 4514, - 324, 239, 357, 248, 3041, 266, 4521, 3016, 385, 475, - 384, 4526, 2188, 475, 4529, 181, 357, 2197, 461, 2199, - 388, 2197, 390, 2199, 3704, 3915, 74, 384, 2818, 74, - 407, 256, 1837, 357, 360, 4550, 84, 2250, 470, 84, - 2216, 2195, 1847, 475, 1849, 477, 2762, 401, 4563, 473, - 1855, 425, 2228, 477, 2230, 2231, 326, 1862, 2774, 2235, - 347, 2237, 2238, 2239, 438, 2241, 476, 2243, 425, 479, - 237, 2247, 5187, 2356, 2250, 4571, 5105, 2106, 2107, 5439, - 234, 438, 141, 3092, 5012, 63, 64, 461, 474, 334, - 2806, 417, 237, 479, 153, 2271, 1056, 3681, 473, 158, - 475, 475, 430, 470, 461, 2281, 3695, 4, 475, 4876, - 477, 4878, 9, 2289, 2290, 4882, 88, 4884, 475, 92, - 4324, 2297, 4326, 4327, 1084, 350, 4330, 3441, 2844, 2773, - 2306, 2775, 2776, 141, 2347, 2348, 2954, 2863, 2351, 3937, - 475, 191, 477, 269, 1104, 153, 205, 2430, 274, 476, - 158, 2327, 479, 3737, 1114, 902, 2332, 2333, 1118, 384, - 907, 239, 1122, 4930, 1124, 3262, 225, 2951, 2952, 181, - 1130, 2347, 2348, 401, 3306, 2351, 1136, 2353, 2354, 1139, - 80, 3372, 3373, 5298, 30, 31, 476, 1992, 1993, 479, - 344, 164, 431, 234, 1999, 2000, 388, 205, 390, 3216, - 425, 2377, 3267, 476, 2380, 3222, 479, 266, 5153, 5154, - 4725, 3308, 3260, 438, 350, 5244, 275, 225, 3702, 438, - 3704, 440, 2027, 2981, 197, 2401, 2402, 53, 476, 476, - 2371, 479, 479, 387, 476, 347, 461, 479, 2379, 212, - 2416, 2382, 2418, 2419, 476, 13, 14, 479, 384, 222, - 475, 476, 215, 478, 476, 2981, 476, 479, 266, 479, - 473, 415, 475, 475, 477, 477, 476, 275, 5383, 479, - 4785, 2447, 2448, 2449, 438, 248, 440, 2453, 476, 4959, - 475, 479, 476, 2459, 438, 479, 440, 476, 35, 425, - 479, 2467, 5276, 5277, 2470, 283, 269, 5326, 9, 2512, - 2476, 8, 438, 344, 11, 340, 341, 54, 15, 16, - 17, 269, 2488, 476, 2490, 476, 479, 475, 479, 3646, - 3647, 475, 344, 4819, 476, 461, 3110, 479, 2504, 2134, - 2135, 2507, 4828, 2509, 476, 4682, 2512, 479, 476, 475, - 2516, 479, 479, 2519, 476, 3129, 387, 479, 340, 341, - 3940, 8, 411, 475, 11, 2531, 2532, 104, 15, 16, - 17, 334, 350, 5392, 3922, 476, 5294, 476, 479, 53, - 479, 5180, 4603, 2549, 415, 476, 476, 476, 479, 479, - 479, 2709, 431, 2559, 2712, 2561, 2518, 2715, 476, 476, - 2195, 479, 479, 429, 2558, 476, 384, 438, 479, 440, - 2703, 476, 3293, 411, 479, 476, 43, 8, 479, 2585, - 11, 4926, 340, 341, 15, 16, 17, 340, 341, 476, - 476, 8, 479, 479, 11, 234, 3523, 458, 15, 16, - 17, 32, 476, 211, 475, 479, 2612, 425, 2614, 2615, - 2616, 2617, 4646, 190, 476, 32, 419, 479, 477, 272, - 438, 4469, 3488, 3489, 3490, 3491, 272, 269, 3494, 3495, - 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 158, 4984, - 3530, 476, 396, 461, 479, 3630, 2652, 476, 5406, 476, - 479, 269, 479, 2818, 2289, 3521, 476, 475, 458, 479, - 476, 238, 272, 479, 241, 3425, 4727, 388, 5013, 390, - 3284, 476, 3286, 2015, 479, 252, 2018, 234, 388, 141, - 390, 3269, 43, 3271, 3550, 3551, 476, 2693, 458, 479, - 476, 153, 476, 479, 2665, 479, 158, 2703, 476, 476, - 187, 479, 479, 2709, 211, 344, 2712, 284, 476, 2715, - 5468, 479, 162, 3269, 3591, 3271, 2881, 4227, 2724, 479, - 476, 476, 209, 479, 479, 476, 2732, 476, 479, 3, - 479, 2737, 476, 468, 271, 479, 2371, 476, 3628, 476, - 479, 475, 479, 205, 2379, 2762, 429, 2382, 387, 23, - 476, 476, 329, 479, 2760, 2761, 2762, 476, 476, 2765, - 479, 3349, 476, 225, 53, 479, 3414, 2773, 2774, 2775, - 2776, 438, 476, 440, 351, 479, 415, 476, 209, 478, - 2786, 163, 5127, 2789, 271, 2791, 5243, 344, 476, 2806, - 478, 4210, 209, 3349, 371, 476, 2802, 2803, 479, 438, - 2806, 440, 207, 476, 266, 3732, 479, 3734, 3703, 83, - 475, 475, 2818, 275, 2820, 477, 2822, 476, 2824, 476, - 479, 837, 479, 839, 3586, 476, 3440, 475, 479, 3756, - 387, 476, 476, 442, 479, 479, 475, 4118, 2844, 4120, - 271, 476, 2848, 476, 479, 475, 479, 476, 3775, 2855, - 479, 324, 0, 476, 271, 187, 479, 477, 415, 146, - 234, 476, 136, 476, 479, 2871, 479, 2849, 2850, 2851, - 3673, 476, 2878, 476, 479, 476, 479, 2874, 479, 476, - 2874, 438, 479, 440, 2874, 476, 2874, 2893, 479, 2874, - 476, 475, 2863, 479, 2911, 476, 146, 476, 479, 476, - 479, 2907, 4750, 476, 476, 2911, 479, 479, 2914, 476, - 2916, 476, 479, 187, 479, 269, 187, 5262, 475, 193, - 476, 476, 324, 479, 479, 462, 463, 464, 0, 466, - 467, 468, 469, 470, 471, 269, 476, 3483, 2855, 479, - 3835, 476, 476, 91, 479, 479, 3813, 476, 146, 411, - 479, 2957, 476, 2959, 476, 479, 187, 479, 2964, 146, - 269, 234, 158, 2598, 2599, 324, 146, 223, 114, 2604, - 344, 3517, 419, 269, 239, 462, 463, 464, 475, 466, - 467, 468, 469, 470, 471, 2991, 401, 2993, 2994, 2995, - 2907, 8, 5337, 141, 11, 3861, 3821, 5342, 15, 16, - 17, 263, 431, 347, 158, 153, 215, 476, 66, 475, - 158, 254, 35, 387, 254, 163, 3562, 291, 35, 91, - 4065, 169, 442, 475, 172, 269, 158, 254, 176, 43, - 2665, 462, 463, 464, 43, 466, 467, 468, 469, 470, - 471, 415, 234, 254, 406, 462, 463, 464, 254, 466, - 467, 468, 469, 470, 471, 83, 285, 205, 431, 6, - 431, 335, 234, 158, 438, 80, 440, 305, 146, 141, - 146, 344, 475, 146, 475, 428, 298, 225, 475, 146, - 34, 153, 475, 146, 1874, 442, 158, 146, 479, 146, - 3255, 163, 1882, 146, 146, 146, 5441, 169, 3263, 146, - 172, 475, 3108, 146, 176, 146, 146, 146, 382, 158, - 146, 146, 1902, 269, 387, 384, 35, 475, 266, 223, - 22, 269, 269, 475, 158, 22, 28, 275, 158, 5, - 5, 28, 475, 205, 475, 475, 410, 158, 475, 4987, - 475, 5, 415, 5, 418, 234, 475, 421, 475, 475, - 475, 475, 344, 225, 475, 8, 475, 475, 11, 475, - 475, 5, 15, 16, 17, 438, 5, 440, 70, 475, - 475, 475, 344, 70, 8, 475, 475, 11, 475, 32, - 475, 475, 475, 331, 475, 475, 439, 475, 281, 207, - 35, 95, 209, 479, 266, 387, 479, 269, 223, 35, - 479, 158, 475, 275, 266, 158, 40, 357, 264, 344, - 3216, 396, 4369, 47, 396, 387, 3222, 396, 120, 396, - 430, 344, 124, 415, 344, 3231, 2861, 124, 2863, 131, - 3236, 3237, 134, 396, 131, 477, 384, 134, 72, 4105, - 4130, 396, 8, 415, 191, 11, 438, 225, 440, 328, - 2885, 2886, 396, 200, 271, 344, 396, 159, 396, 331, - 4150, 208, 159, 411, 211, 464, 438, 84, 440, 3275, - 3276, 3277, 3886, 3887, 40, 344, 146, 269, 269, 349, - 220, 47, 396, 475, 3255, 396, 3292, 435, 259, 437, - 438, 193, 3263, 396, 418, 387, 193, 269, 387, 289, - 3343, 269, 340, 475, 264, 139, 72, 475, 3314, 3315, - 396, 396, 384, 180, 2104, 475, 84, 479, 3324, 3325, - 3326, 4709, 285, 146, 3330, 473, 415, 187, 476, 477, - 478, 3979, 3980, 3981, 3982, 3983, 419, 3343, 419, 411, - 269, 396, 396, 106, 269, 3339, 396, 384, 182, 438, - 252, 440, 254, 187, 396, 252, 209, 254, 384, 53, - 53, 245, 264, 435, 396, 437, 438, 264, 3362, 396, - 273, 273, 396, 139, 396, 344, 273, 396, 4145, 309, - 396, 387, 3425, 285, 3558, 396, 475, 42, 285, 396, - 224, 396, 396, 396, 396, 396, 289, 289, 3404, 396, - 396, 473, 42, 396, 476, 477, 478, 344, 479, 396, - 396, 476, 480, 209, 269, 209, 182, 209, 271, 3425, - 209, 187, 324, 269, 209, 327, 328, 324, 209, 442, - 327, 328, 269, 209, 269, 3441, 209, 271, 209, 438, - 396, 406, 475, 35, 146, 462, 463, 464, 24, 466, - 467, 468, 469, 470, 471, 357, 269, 3463, 224, 146, - 357, 254, 112, 438, 419, 146, 3472, 146, 430, 146, - 269, 231, 3478, 264, 3480, 254, 254, 3483, 35, 3450, - 254, 475, 3488, 3489, 3490, 3491, 158, 35, 3494, 3495, - 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 215, 346, - 34, 3507, 3508, 394, 394, 271, 4052, 473, 475, 473, - 396, 3517, 146, 396, 396, 3521, 475, 396, 4138, 3525, - 422, 5369, 5370, 146, 419, 422, 146, 3533, 362, 146, - 3536, 419, 3538, 146, 263, 396, 258, 163, 434, 3556, - 475, 3547, 245, 11, 3550, 3551, 245, 479, 475, 3555, - 3556, 394, 475, 172, 3560, 396, 3562, 154, 3575, 163, - 398, 479, 476, 3569, 3570, 3571, 3572, 475, 3733, 3575, - 3576, 180, 180, 205, 3580, 3581, 3582, 360, 4425, 479, - 213, 3587, 3564, 3565, 3566, 3567, 270, 419, 35, 278, - 479, 53, 3757, 4207, 344, 476, 362, 475, 419, 213, - 259, 213, 259, 4469, 239, 3611, 396, 475, 396, 462, - 463, 464, 4478, 466, 467, 468, 469, 470, 471, 3625, - 3255, 3627, 431, 347, 396, 459, 401, 158, 3263, 215, - 259, 4352, 466, 467, 468, 469, 470, 471, 148, 3645, - 3646, 3647, 269, 3649, 43, 4293, 4294, 366, 4296, 254, - 148, 223, 3287, 223, 49, 3572, 223, 340, 3575, 396, - 3666, 3667, 3668, 3669, 267, 479, 387, 614, 35, 269, - 4284, 269, 4829, 148, 148, 324, 181, 35, 354, 275, - 396, 396, 312, 209, 419, 419, 215, 54, 267, 3695, - 476, 191, 308, 459, 464, 464, 146, 158, 93, 264, - 466, 467, 468, 469, 470, 471, 431, 35, 3714, 160, - 385, 264, 354, 475, 309, 146, 5226, 475, 146, 666, - 146, 264, 254, 118, 4651, 438, 35, 4873, 3645, 676, - 254, 269, 269, 215, 3369, 178, 683, 104, 178, 686, - 135, 158, 35, 476, 139, 473, 458, 458, 243, 476, - 476, 215, 354, 476, 348, 158, 476, 269, 35, 23, - 4655, 254, 3733, 4377, 159, 187, 4864, 162, 4866, 187, - 479, 187, 187, 187, 479, 442, 170, 54, 479, 475, - 3764, 396, 177, 163, 242, 438, 3757, 479, 269, 163, - 53, 2581, 263, 384, 401, 431, 215, 475, 2588, 479, - 167, 281, 476, 3809, 6, 476, 476, 476, 476, 163, - 476, 476, 476, 476, 476, 3450, 476, 8, 2608, 458, - 11, 290, 396, 190, 15, 16, 17, 104, 2618, 475, - 475, 2621, 475, 2623, 2624, 280, 435, 2627, 4384, 460, - 270, 32, 417, 2633, 475, 2635, 270, 3853, 2638, 40, - 475, 3857, 233, 3859, 435, 3861, 47, 425, 269, 53, - 269, 269, 3868, 464, 259, 272, 191, 146, 3874, 475, - 199, 238, 267, 396, 241, 396, 442, 396, 3884, 396, - 259, 72, 475, 8, 4750, 252, 11, 146, 254, 273, - 15, 16, 17, 3899, 357, 349, 146, 3903, 146, 223, - 349, 349, 191, 148, 464, 396, 419, 3913, 479, 4775, - 225, 2701, 416, 190, 4680, 310, 3922, 284, 291, 291, - 5077, 5078, 235, 5069, 396, 8, 396, 3933, 11, 396, - 396, 3937, 15, 16, 17, 3941, 3942, 235, 3932, 235, - 396, 396, 344, 396, 4564, 4770, 344, 344, 344, 32, - 396, 269, 396, 254, 396, 396, 357, 146, 396, 396, - 42, 238, 329, 3969, 241, 3971, 209, 396, 476, 476, - 476, 474, 3978, 4138, 209, 252, 209, 209, 175, 3, - 476, 406, 476, 3, 351, 158, 3903, 479, 43, 191, - 4604, 182, 326, 105, 4614, 479, 187, 476, 200, 201, - 947, 158, 475, 269, 371, 4011, 208, 284, 210, 211, - 267, 958, 35, 146, 3985, 146, 4022, 964, 209, 210, - 967, 396, 224, 158, 476, 175, 419, 419, 146, 144, - 344, 272, 344, 224, 344, 474, 344, 344, 474, 144, - 209, 476, 209, 354, 209, 479, 4052, 209, 209, 209, - 209, 209, 329, 473, 163, 11, 4062, 4063, 137, 281, - 158, 5218, 430, 4069, 4070, 475, 257, 479, 4074, 163, - 476, 476, 476, 4079, 351, 435, 4082, 4083, 163, 479, - 271, 4087, 4088, 274, 209, 476, 476, 4093, 4094, 4095, - 4096, 4097, 1039, 1040, 371, 4101, 4102, 4103, 3733, 4105, - 4106, 479, 461, 4109, 475, 172, 476, 4113, 331, 82, - 475, 4117, 8, 4960, 476, 11, 270, 4123, 424, 476, - 406, 4987, 3757, 158, 35, 419, 209, 419, 215, 3764, - 4778, 396, 4138, 199, 53, 387, 146, 475, 167, 4145, - 5067, 4789, 373, 4149, 40, 406, 271, 396, 4154, 349, - 396, 47, 396, 4147, 4148, 476, 344, 396, 396, 4169, - 344, 324, 438, 4169, 53, 425, 4172, 5313, 387, 158, - 475, 362, 476, 476, 148, 72, 72, 2967, 146, 5089, - 105, 406, 209, 209, 209, 476, 4192, 4193, 271, 306, - 209, 475, 213, 194, 475, 396, 4113, 269, 319, 479, - 4117, 476, 442, 35, 4210, 479, 3841, 3842, 289, 4755, - 78, 387, 479, 475, 406, 396, 354, 169, 4224, 475, - 4868, 479, 476, 474, 105, 163, 209, 163, 317, 476, - 4214, 53, 436, 475, 281, 5162, 212, 436, 475, 4223, - 476, 279, 476, 139, 386, 212, 476, 475, 4219, 4795, - 479, 53, 476, 176, 475, 264, 464, 406, 276, 396, - 163, 3051, 8, 3053, 438, 11, 72, 4273, 459, 193, - 188, 462, 463, 464, 181, 466, 467, 468, 469, 470, - 471, 259, 259, 53, 464, 387, 182, 66, 479, 4295, - 396, 187, 479, 479, 40, 5161, 396, 396, 146, 35, - 209, 47, 201, 5024, 4310, 4861, 476, 475, 165, 163, - 35, 210, 112, 187, 264, 419, 419, 4873, 54, 475, - 354, 35, 254, 160, 158, 224, 72, 264, 224, 53, - 438, 438, 354, 35, 4340, 163, 269, 462, 463, 464, - 158, 466, 467, 468, 469, 470, 471, 4995, 4354, 475, - 3985, 196, 272, 163, 4360, 207, 475, 317, 370, 475, - 424, 289, 476, 4369, 437, 476, 212, 84, 104, 105, - 127, 269, 318, 35, 475, 271, 112, 146, 4384, 462, - 463, 464, 475, 466, 467, 468, 469, 470, 471, 475, - 396, 4397, 476, 4399, 396, 475, 158, 119, 476, 4564, - 3190, 5021, 4396, 35, 475, 475, 3196, 475, 259, 180, - 475, 236, 614, 4614, 5280, 475, 475, 191, 475, 306, - 476, 475, 105, 4429, 626, 354, 146, 132, 35, 434, - 632, 167, 476, 273, 406, 4981, 182, 341, 4603, 341, - 476, 187, 368, 645, 53, 53, 368, 35, 75, 4614, - 180, 479, 4998, 424, 190, 4613, 5002, 387, 5004, 661, - 475, 475, 475, 4469, 666, 419, 362, 475, 5395, 158, - 672, 475, 4478, 387, 676, 677, 252, 475, 224, 269, - 476, 683, 387, 685, 686, 5, 152, 442, 475, 4495, - 4496, 145, 66, 4499, 475, 272, 698, 699, 66, 4657, - 317, 127, 238, 5369, 5370, 241, 475, 709, 4514, 424, - 423, 4517, 475, 5069, 479, 4521, 252, 438, 254, 35, - 4526, 438, 357, 4529, 4530, 271, 4532, 163, 4534, 5456, - 4536, 4537, 387, 315, 132, 193, 259, 269, 269, 354, - 475, 35, 4543, 35, 4550, 5472, 4552, 306, 284, 188, - 165, 272, 165, 272, 53, 435, 340, 4563, 4564, 4565, - 4566, 4567, 117, 459, 476, 475, 396, 475, 417, 5, - 466, 467, 468, 469, 470, 471, 476, 340, 479, 4214, - 142, 476, 354, 475, 4219, 276, 325, 475, 4223, 791, - 792, 475, 21, 329, 479, 797, 475, 4514, 3388, 32, - 3390, 479, 3392, 259, 4521, 475, 145, 4613, 4614, 4526, - 396, 3401, 4529, 4248, 4249, 351, 362, 163, 4253, 4254, - 277, 823, 340, 75, 306, 368, 368, 438, 475, 438, - 165, 165, 4603, 4550, 2516, 371, 1340, 373, 833, 2863, - 376, 0, 1603, 870, 2322, 3041, 4563, 3706, 2400, 3732, - 5209, 4657, 3442, 5209, 4660, 5386, 5205, 3837, 2425, 3253, - 4886, 5067, 5313, 3884, 4709, 8, 4672, 4679, 11, 4675, - 2958, 2652, 4342, 4563, 4680, 5186, 4682, 5300, 5097, 5096, - 5228, 4724, 5337, 4689, 2962, 3933, 3917, 5031, 3875, 2501, - 4684, 2501, 3727, 3067, 3304, 912, 3900, 40, 2495, 4705, - 4686, 3316, 4695, 4709, 47, 4378, 5315, 5472, 5456, 4672, - 3262, 3257, 5241, 459, 4616, 4847, 5040, 4723, 4724, 4725, - 466, 467, 468, 469, 470, 471, 28, 626, 4722, 72, - 3988, 4619, 91, 632, 1765, 4815, 938, 939, 940, 475, - 5403, 2171, 2936, 3940, 4750, 947, 645, 4753, 1180, 4755, - 1811, 4960, 954, 1879, 1820, 696, 958, 5313, 1970, 3194, - 3756, 3308, 964, 1196, 1971, 967, 992, 1970, 662, 4775, - 3775, 5267, 5444, 812, 3920, 4781, 1427, 979, 4795, 4785, - 1914, 2114, 141, 4789, 0, 2115, 2106, 4546, 4149, 4795, - 5179, 3625, 994, 1362, 153, 1317, 139, 2878, 4804, 158, - 2151, 2893, 1387, 1386, 163, 21, 3590, 5171, 4725, 5006, - 169, 2125, 4135, 172, 2150, 3575, 1389, 176, 4102, 4119, - 4786, 4827, 4984, 4829, 3572, 3626, 4983, 3572, 5450, 5284, - 1394, 5373, 5161, 4753, 1844, 3525, 52, 1039, 1040, 182, - 5174, 2064, 5175, 4540, 187, 2823, 205, 2453, 4854, 2733, - 2821, 2067, -1, -1, -1, -1, 5021, -1, 4864, 4865, - 4866, 4867, -1, -1, -1, -1, 225, -1, 4785, -1, - -1, -1, -1, 1820, -1, -1, 1823, 1079, -1, -1, - -1, 224, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4902, -1, -1, -1, - -1, -1, 4873, -1, -1, -1, -1, 266, -1, -1, - 269, -1, -1, -1, 1116, -1, 275, 4923, -1, -1, - 4926, 1868, 1869, -1, -1, -1, -1, -1, 271, -1, - -1, -1, 1134, -1, -1, -1, 1883, -1, -1, 1886, - -1, 1143, 4936, -1, -1, -1, -1, -1, -1, 1151, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4603, 185, - -1, -1, 331, -1, -1, 4981, -1, 1179, 4984, -1, - -1, 4987, -1, -1, -1, 4991, -1, -1, -1, -1, - -1, 1193, 4998, 1195, -1, -1, 5002, -1, 5004, 1946, - 5006, -1, 1949, 1950, -1, -1, -1, 5013, 1210, 4926, - -1, 1213, -1, 5019, -1, 5021, 5010, -1, -1, 362, - -1, -1, -1, 1225, 8, 384, 5032, 11, -1, -1, - -1, 15, 16, 17, -1, -1, 5194, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 411, 1255, -1, -1, 40, -1, -1, -1, - -1, -1, -1, 47, -1, -1, -1, 4984, -1, -1, - -1, 5077, 5078, -1, -1, -1, 435, -1, 437, 438, - -1, 1283, 1284, 1285, -1, 1287, -1, -1, 72, -1, - -1, -1, -1, -1, -1, -1, 5013, -1, -1, -1, - -1, -1, 5108, -1, -1, 1307, -1, -1, -1, 5115, - 5268, 5269, -1, 5119, 473, -1, 459, 476, 477, 478, - -1, 5127, -1, 466, 467, 468, 469, 470, 471, 1331, - -1, -1, -1, -1, -1, -1, -1, 1339, 1340, -1, - 8, -1, -1, 11, -1, -1, 5152, 5153, 5154, -1, - -1, -1, 5158, -1, -1, 5161, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 5171, -1, -1, 5174, -1, - -1, -1, 40, 5179, -1, -1, -1, 1379, -1, 47, - -1, 1383, 1384, 3973, -1, -1, -1, 3977, 5194, -1, - -1, -1, -1, -1, -1, -1, 1398, -1, 182, -1, - 1402, -1, -1, 187, 72, 5211, 1408, -1, -1, -1, - 5127, -1, 5218, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4859, 4860, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 5243, 4873, -1, - 224, -1, 5248, -1, -1, -1, -1, 5253, 5242, -1, - -1, -1, -1, -1, -1, -1, 5262, -1, -1, -1, - -1, -1, 5268, 5269, 5270, -1, 1468, -1, -1, -1, - 5267, 139, -1, 5267, 5280, -1, -1, 5267, 5284, 5267, - -1, 2228, 5267, -1, -1, -1, -1, 271, 2235, -1, - -1, 2238, 2239, -1, -1, -1, -1, -1, -1, 5305, - -1, -1, -1, -1, -1, -1, -1, 1509, -1, -1, - -1, -1, -1, -1, 182, 8, 5474, 5475, 11, 187, - -1, -1, 15, 16, 17, -1, -1, -1, 5345, -1, - -1, 5337, 5338, 5339, -1, -1, 5342, 56, -1, -1, - 1542, -1, -1, -1, -1, 5262, -1, -1, 5345, -1, - -1, 5345, -1, -1, -1, 5345, 224, 5345, -1, -1, - 5345, -1, -1, 5369, 5370, 8, -1, -1, 11, -1, - -1, 90, -1, -1, -1, 5381, -1, -1, 362, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 611, -1, 40, 4188, 1601, - -1, 120, -1, 271, 47, -1, -1, -1, 5414, -1, - -1, -1, -1, -1, 1616, 1617, 1618, -1, 5424, -1, - 5337, -1, -1, -1, 5059, 5342, -1, -1, -1, 72, - 149, -1, 5438, -1, -1, 5441, -1, -1, -1, -1, - 4230, 4231, -1, -1, 5450, -1, -1, 5444, 5454, -1, - 5444, -1, -1, -1, 5444, -1, 5444, -1, -1, 5444, - -1, -1, -1, -1, -1, 184, -1, -1, 5474, 5475, - -1, -1, -1, -1, -1, 459, -1, -1, 462, 463, - 464, -1, 466, 467, 468, 469, 470, 471, -1, -1, - -1, -1, 708, 709, 362, -1, 139, -1, -1, -1, - -1, 220, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 209, 1719, -1, -1, - -1, -1, -1, -1, 5441, -1, 4316, 4317, -1, -1, - -1, -1, -1, -1, 1736, 254, -1, -1, -1, 182, - -1, -1, -1, 1745, 187, -1, -1, -1, -1, -1, - 1752, -1, -1, -1, -1, 1757, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 285, 286, -1, -1, - 5205, -1, 5207, 292, 1776, -1, -1, -1, 271, -1, - -1, 224, 1784, -1, -1, -1, -1, -1, -1, -1, - -1, 459, -1, -1, 1796, -1, -1, -1, 466, 467, - 468, 469, 470, 471, -1, 324, -1, -1, -1, 328, - -1, 1813, -1, 332, -1, 831, -1, 833, 1820, -1, - -1, 1823, 341, -1, -1, 1827, -1, -1, 271, -1, - 349, 1833, -1, -1, -1, -1, -1, 1839, 357, -1, - -1, -1, 4432, -1, 4434, 4435, -1, -1, -1, 1851, - 369, -1, -1, -1, -1, -1, -1, -1, 377, -1, - 4450, -1, -1, -1, -1, -1, 1868, 1869, -1, 1871, - 1872, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1883, -1, 1885, 1886, -1, -1, -1, -1, -1, - -1, -1, -1, 1895, 1896, -1, 1898, 1899, -1, -1, - -1, -1, 1601, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1914, -1, 433, -1, -1, -1, -1, 362, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1946, -1, -1, 1949, 1950, -1, - -1, 5386, -1, -1, -1, -1, 2703, -1, -1, -1, - 5395, -1, 2709, -1, -1, 2712, -1, -1, 2715, 462, - 463, 464, -1, 466, 467, 468, 469, 470, 471, -1, - 1982, -1, 1984, -1, -1, -1, -1, 1989, 1990, -1, - -1, -1, -1, -1, 1996, 1997, 1998, -1, -1, -1, - 2002, -1, 2004, 2005, 2006, 2007, 2008, 2009, -1, 2011, - -1, 2013, 2014, -1, -1, 2017, 459, -1, -1, -1, - -1, 5456, -1, 466, 467, 468, 469, 470, 471, 2031, - 2032, 2033, 2034, 2035, 2036, -1, -1, 5472, 2040, -1, - -1, -1, 2044, -1, -1, 2047, -1, -1, 2050, 2051, - 2052, 2053, 2054, 2055, 2056, 2057, 2058, -1, 2060, -1, - -1, -1, -1, 20, -1, 2067, 8, 2069, 25, 11, - -1, -1, -1, 15, 16, 17, -1, 1776, -1, -1, - 37, -1, -1, -1, -1, 1784, -1, -1, -1, -1, - 32, -1, -1, -1, -1, -1, -1, 1796, 40, -1, - -1, -1, -1, 60, -1, 47, -1, 2109, 2855, -1, - -1, -1, -1, -1, -1, -1, 73, -1, -1, -1, - -1, -1, -1, 2125, -1, -1, -1, -1, -1, -1, - 72, 88, 2134, 2135, -1, -1, -1, 1153, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 106, - -1, -1, -1, -1, -1, -1, 4746, 2159, -1, -1, - 2907, -1, -1, -1, 2166, -1, -1, -1, 2170, 2171, - -1, -1, 129, 1872, -1, 2177, -1, -1, -1, -1, - 2182, 2183, -1, 140, -1, 2187, -1, -1, -1, -1, - -1, 148, -1, 2195, -1, -1, -1, -1, -1, -1, - 1899, -1, -1, 160, -1, 1221, -1, -1, 165, -1, - -1, 2213, -1, -1, 2216, 172, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1241, 2228, 4817, -1, -1, - 2232, -1, -1, 2235, 191, -1, 2238, 2239, -1, -1, - 182, -1, -1, -1, 2246, 187, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1272, 2259, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 209, 210, -1, - -1, 1287, -1, -1, -1, 2277, 2278, -1, -1, 4869, - 237, -1, 224, -1, 2286, -1, -1, 3, -1, -1, - -1, -1, 8, -1, -1, 11, -1, -1, -1, 15, - 16, 17, -1, 56, -1, -1, -1, 2309, 2310, -1, - -1, 2313, -1, -1, 271, 257, 32, -1, -1, 35, - -1, -1, 25, -1, 40, -1, -1, 284, -1, 271, - -1, 47, 274, -1, 2336, -1, 2338, 90, 295, -1, - -1, 2343, -1, -1, -1, -1, -1, 2349, 305, 306, - -1, -1, 309, -1, 2356, -1, 72, -1, 2360, -1, - -1, 1377, 1378, 2365, 1380, -1, -1, 120, -1, -1, - -1, 74, -1, -1, -1, -1, -1, -1, 335, -1, - -1, 338, -1, 2385, -1, 342, -1, 344, 2390, -1, - -1, -1, 2394, -1, 351, 2397, 149, 354, -1, -1, - -1, -1, -1, 106, -1, 2407, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 373, -1, 2420, -1, - 362, -1, 379, -1, -1, -1, 129, 384, 2430, -1, - 387, 184, -1, -1, 391, -1, -1, 140, -1, -1, - -1, -1, 399, -1, 401, 2447, 2448, 2449, -1, 406, - -1, 2453, -1, -1, -1, -1, -1, 160, -1, -1, - 2159, 418, 165, -1, -1, -1, 182, 220, -1, -1, - -1, 187, -1, -1, 431, -1, -1, -1, 2177, -1, - -1, -1, -1, -1, 2183, -1, 2488, 2489, 2187, -1, - -1, -1, -1, 209, 210, -1, 2498, -1, -1, -1, - -1, 254, -1, -1, -1, -1, -1, -1, 224, -1, - -1, -1, -1, 216, 2213, -1, -1, 459, -1, -1, - 462, 463, 464, -1, 466, 467, 468, 469, 470, 471, - 2532, -1, 285, 286, 237, -1, -1, 479, -1, 292, - -1, 257, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 271, -1, -1, 274, -1, - 2259, -1, -1, -1, -1, -1, -1, -1, -1, 2571, - -1, 324, -1, -1, 2576, 328, -1, -1, 2277, 332, - -1, -1, -1, 2585, -1, -1, -1, -1, 341, -1, - -1, 8, -1, -1, 11, -1, 349, -1, 15, 16, - 17, -1, 305, 306, 357, -1, 309, -1, -1, -1, - -1, 2310, -1, -1, -1, 32, 369, -1, -1, -1, - -1, -1, -1, 40, 377, -1, -1, -1, -1, 2631, - 47, -1, 335, -1, -1, 338, -1, 2336, -1, -1, - -1, 344, -1, -1, 2343, -1, 362, 17, 351, -1, - 2349, -1, -1, -1, -1, 72, 26, 2356, -1, -1, - -1, 2360, -1, -1, -1, -1, 2365, -1, -1, -1, - 8, 2673, -1, 11, -1, -1, 379, 15, 16, 17, - 433, 384, -1, -1, 387, -1, 2385, 2689, -1, 2691, - -1, 2390, -1, -1, 32, 2394, -1, 2699, -1, -1, - -1, 2703, 40, 406, 2706, 5295, -1, 2709, 2407, 47, - 2712, -1, -1, 2715, -1, -1, -1, -1, -1, 2721, - -1, 2420, -1, -1, -1, -1, -1, -1, 431, -1, - 2732, 2430, -1, -1, 72, 2737, -1, -1, -1, -1, - -1, -1, -1, 459, -1, -1, 462, 463, 464, -1, - 466, 467, 468, 469, 470, 471, -1, -1, 2760, 2761, - 2762, -1, -1, 2765, -1, 182, -1, -1, -1, -1, - 187, 2773, 2774, 2775, 2776, -1, -1, -1, -1, 2781, - -1, -1, -1, -1, 2786, 2787, -1, 2789, -1, 2791, - -1, -1, 209, 210, -1, -1, -1, -1, -1, -1, - 2802, 2803, -1, -1, 2806, -1, -1, 224, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2820, -1, - 2822, -1, 2824, -1, -1, 3572, 20, -1, 3575, -1, - -1, 25, -1, -1, -1, -1, -1, -1, -1, -1, - 257, -1, 2844, -1, 182, -1, -1, -1, -1, 187, - -1, -1, -1, 2855, 271, -1, 8, 274, -1, 11, - -1, 2863, -1, 15, 16, 17, 60, -1, -1, -1, - -1, 209, 210, -1, -1, -1, 2878, -1, -1, 73, - 32, -1, -1, -1, -1, -1, 224, -1, 40, -1, - -1, 2893, -1, -1, 88, 47, -1, 1913, 3645, -1, - -1, -1, -1, -1, -1, 2907, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 257, - 72, -1, -1, -1, 2926, -1, -1, 2929, -1, 2931, - -1, -1, -1, 271, 2936, 129, 274, -1, -1, -1, - -1, -1, -1, -1, -1, 362, 140, -1, -1, 2951, - 2952, 1967, -1, -1, -1, 2957, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 160, -1, -1, -1, - -1, 165, -1, -1, 2673, -1, 2978, -1, -1, 2981, - -1, -1, -1, 2985, -1, -1, -1, -1, -1, -1, - -1, -1, 2691, -1, -1, -1, -1, -1, -1, -1, - 2699, -1, 3004, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 362, 2041, -1, 3029, -1, -1, - 182, -1, -1, -1, -1, 187, -1, -1, -1, -1, - -1, -1, 459, 237, -1, 462, 463, 464, -1, 466, - 467, 468, 469, 470, 471, -1, -1, 209, 210, 476, - -1, -1, -1, -1, 3066, 3067, 3068, -1, -1, -1, - -1, -1, 224, -1, -1, -1, -1, 271, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3090, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3100, -1, - 3102, -1, -1, -1, -1, 257, -1, -1, 3110, -1, - -1, 305, 306, -1, -1, -1, -1, -1, -1, 271, - -1, 459, 274, -1, 462, 463, 464, 3129, 466, 467, - 468, 469, 470, 471, -1, -1, -1, 2153, 476, -1, - -1, -1, -1, -1, 338, -1, -1, -1, -1, -1, - 344, -1, -1, -1, -1, -1, 3903, 351, -1, 8, - 354, -1, 11, -1, -1, -1, 15, 16, 17, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 32, -1, -1, -1, -1, -1, 3191, - 384, 40, -1, 8, -1, -1, 11, 391, 47, -1, - 15, 16, 17, -1, -1, 399, -1, -1, -1, 3211, - 362, -1, 406, -1, 3216, -1, -1, 32, -1, -1, - 3222, -1, -1, 72, -1, 40, -1, -1, 3230, -1, - -1, -1, 47, -1, -1, -1, -1, 431, 608, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3255, -1, -1, -1, 72, -1, -1, - 3262, 3263, -1, -1, -1, -1, -1, 3269, -1, 3271, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 2978, - -1, -1, 3284, -1, 3286, -1, -1, -1, -1, -1, - -1, 661, 662, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3308, 459, -1, -1, - 462, 463, 464, -1, 466, 467, 468, 469, 470, 471, - -1, -1, -1, -1, 476, -1, -1, -1, -1, -1, - 3332, -1, -1, 182, -1, -1, -1, -1, 187, -1, - -1, -1, -1, -1, -1, -1, -1, 3349, 3350, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 209, 210, 3364, -1, -1, -1, 4113, 182, -1, -1, - 4117, -1, 187, -1, -1, 224, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 759, - -1, 3090, -1, -1, 209, 210, -1, -1, 3400, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 257, 224, - -1, -1, -1, -1, -1, 785, 3418, -1, -1, -1, - -1, -1, 271, 793, -1, 274, 796, 797, 798, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3440, -1, - -1, 3443, 257, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 35, -1, 271, -1, -1, 274, - -1, 3463, -1, -1, 3466, -1, -1, -1, -1, -1, - 3472, -1, -1, -1, -1, 56, 3478, -1, 3480, -1, - -1, 3483, -1, -1, -1, 3487, 3488, 3489, 3490, 3491, - -1, -1, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, - 3502, 3503, -1, -1, -1, 3507, 3508, -1, -1, 90, - 3512, -1, 3211, 362, -1, 3517, -1, -1, -1, 3521, - -1, 3523, -1, 3525, -1, -1, -1, -1, -1, -1, - -1, 3533, -1, -1, 3536, -1, 3538, -1, -1, -1, - -1, -1, 2558, -1, 3546, 3547, -1, 362, 3550, 3551, - -1, -1, -1, 3555, 3556, -1, -1, -1, -1, -1, - 3562, -1, -1, -1, -1, -1, -1, -1, 149, -1, - 3572, -1, -1, 3575, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 3587, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, - -1, -1, -1, 184, 28, -1, -1, 4354, -1, 3611, - 459, 35, -1, 462, 463, 464, -1, 466, 467, 468, - 469, 470, 471, -1, -1, 3627, -1, 476, -1, -1, - 54, 3633, -1, -1, 215, -1, -1, -1, -1, 220, - -1, -1, -1, 3645, 459, -1, 70, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, -1, -1, -1, - -1, 476, -1, 8, -1, -1, 11, -1, -1, -1, - 15, 16, 17, 254, 3676, -1, -1, -1, -1, -1, - 104, -1, -1, -1, -1, -1, -1, 32, -1, -1, - -1, -1, -1, -1, -1, 40, -1, -1, -1, -1, - 124, 3400, 47, -1, -1, 286, -1, 131, -1, -1, - 134, 292, -1, -1, -1, -1, -1, -1, -1, 3418, - -1, -1, -1, -1, -1, 3727, -1, 72, -1, -1, - 3732, 3733, 3734, -1, -1, 159, -1, -1, -1, -1, - -1, -1, -1, -1, 3443, -1, 2762, 328, -1, -1, - -1, 332, -1, -1, 3756, 3757, -1, -1, -1, -1, - 341, -1, -1, -1, 1134, -1, 190, 4514, 349, 193, - -1, -1, -1, 3775, 4521, -1, 357, -1, -1, 4526, - -1, 1151, 4529, 4530, -1, -1, -1, -1, 369, 3791, - 2806, -1, 3794, -1, -1, -1, 377, -1, -1, -1, - -1, -1, -1, 4550, -1, -1, -1, 2823, -1, -1, - -1, -1, -1, -1, 238, 1185, 4563, 241, 399, -1, - -1, -1, -1, 2839, -1, -1, -1, -1, 252, -1, - 254, -1, -1, -1, -1, -1, -1, 182, -1, 2855, - 264, -1, 187, 1213, -1, -1, -1, -1, -1, 273, - -1, -1, 433, -1, -1, -1, 437, -1, 2874, 3861, - 284, 285, -1, -1, 209, 210, 4613, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 224, - -1, -1, -1, -1, 3886, 3887, -1, -1, 3890, -1, - -1, 2907, -1, -1, 3896, 2911, -1, -1, -1, -1, - 324, 3903, -1, 327, 328, 329, -1, -1, -1, -1, - 4657, -1, 257, 3915, -1, -1, -1, -1, -1, 1289, - 35, -1, -1, -1, -1, -1, 271, 351, 1298, 274, - -1, -1, -1, 357, -1, -1, -1, -1, 3940, 3941, - 3942, 56, 1312, -1, -1, -1, -1, 371, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1331, -1, -1, 1334, 1335, -1, -1, -1, 1339, - 1340, -1, -1, 8, -1, 90, 11, 3676, 4725, -1, - 15, 16, 17, -1, -1, 56, 3988, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 32, 422, -1, - -1, -1, -1, -1, -1, 40, -1, -1, -1, 4011, - -1, -1, 47, -1, -1, -1, -1, 362, -1, 90, - 4022, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 149, -1, -1, 72, 4785, -1, - -1, -1, -1, -1, 8, -1, -1, 11, -1, -1, - 4052, 15, 16, 17, -1, -1, -1, -1, -1, -1, - 4062, 4063, -1, 4065, -1, -1, -1, 4069, 4070, 184, - -1, -1, 4074, 4075, -1, -1, 40, 4079, 149, -1, - 4082, 4083, 22, 47, -1, 4087, -1, -1, 28, -1, - -1, 4093, 3791, -1, -1, 3794, -1, -1, -1, -1, - 215, 41, -1, 4105, -1, 220, -1, -1, 72, -1, - -1, 4113, -1, 184, 459, 4117, -1, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, -1, -1, -1, - 70, 476, -1, -1, -1, -1, -1, -1, -1, 254, - -1, -1, -1, 4145, -1, -1, -1, 182, -1, 220, - -1, -1, 187, -1, -1, 4902, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4172, 286, -1, -1, 209, 210, -1, 292, -1, 4926, - 120, -1, -1, 254, 124, -1, -1, -1, 4190, 224, - 1560, 131, -1, -1, 134, -1, 1566, 3896, -1, -1, - -1, -1, -1, -1, -1, 4207, -1, -1, -1, -1, - 4212, -1, -1, 328, -1, 286, 3915, 332, 182, 159, - -1, 292, 257, 187, -1, -1, 341, 4229, -1, -1, - -1, -1, -1, -1, 349, -1, 271, 4984, -1, 274, - -1, -1, 357, 4245, -1, 209, 210, -1, 4250, -1, - -1, -1, -1, 193, 369, 4257, -1, 328, -1, 330, - 224, 332, 377, -1, -1, -1, 5013, -1, -1, -1, - 341, 4273, -1, -1, -1, -1, -1, -1, 349, -1, - -1, -1, 4284, -1, 399, -1, 357, -1, -1, 3988, - -1, -1, -1, 257, -1, -1, -1, -1, 369, -1, - -1, -1, -1, -1, -1, -1, 377, 271, -1, -1, - -1, -1, 252, 4315, 254, -1, -1, -1, 433, -1, - -1, -1, 437, 3339, 264, -1, -1, 362, -1, -1, - -1, -1, -1, 273, -1, -1, -1, -1, 4340, -1, - -1, -1, -1, -1, 672, 285, 3362, -1, -1, -1, - -1, 8, 4354, -1, 11, -1, -1, -1, 15, 16, - 17, -1, 433, -1, -1, -1, -1, -1, -1, -1, - 698, -1, -1, -1, -1, 4377, -1, -1, -1, -1, - 5127, -1, 4384, 40, 324, -1, -1, 327, 328, -1, - 47, -1, -1, -1, -1, -1, -1, -1, 362, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1779, - -1, -1, -1, 1783, -1, 72, -1, 357, -1, -1, - -1, -1, -1, 4425, 459, 4427, -1, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, -1, -1, -1, - -1, 476, -1, -1, -1, -1, -1, 5194, -1, 4451, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 22, 4469, -1, -1, - -1, 4473, 28, -1, -1, -1, 4478, -1, -1, -1, - -1, -1, 422, -1, -1, 41, -1, -1, -1, -1, - -1, -1, -1, 4495, 4496, 459, -1, 4499, 462, 463, - 464, 5248, 466, 467, 468, 469, 470, 471, -1, -1, - -1, -1, 4514, -1, 70, 5262, -1, -1, -1, 4521, - -1, 5268, 5269, -1, 4526, 182, -1, 4529, 4530, -1, - 187, -1, -1, -1, 4536, 4537, -1, -1, -1, -1, - 3556, -1, -1, -1, -1, -1, 4245, -1, 4550, -1, - 4552, -1, 209, 210, -1, 4557, 3572, 4559, 4257, 3575, - -1, 4563, -1, -1, -1, -1, 122, 224, 124, -1, - -1, -1, -1, -1, -1, 131, -1, -1, 134, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 5337, -1, -1, -1, -1, 5342, -1, -1, -1, -1, - 257, 4603, 4604, 159, -1, -1, -1, -1, -1, -1, - -1, 4613, -1, 0, 271, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1995, 954, -1, -1, -1, - -1, 18, -1, -1, -1, -1, -1, 193, -1, -1, - -1, 28, -1, 30, 31, -1, -1, -1, -1, 4651, - -1, 979, -1, -1, -1, 4657, -1, -1, -1, 46, - -1, -1, -1, -1, -1, -1, 994, -1, 55, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 67, -1, 69, 70, -1, -1, -1, -1, -1, 76, - -1, 78, -1, -1, 5441, -1, 252, -1, 254, -1, - -1, -1, 89, -1, 91, 362, -1, 5454, 264, -1, - 4712, -1, -1, -1, -1, -1, 2086, 273, -1, -1, - -1, 108, -1, 4725, 111, 4727, -1, 5474, 5475, 285, - -1, -1, -1, -1, -1, -1, -1, -1, 125, -1, - 127, -1, -1, -1, 131, -1, -1, -1, 4750, 4751, - 137, 4753, 4451, 4755, -1, -1, -1, -1, 145, -1, - 147, -1, -1, -1, -1, -1, 153, -1, 324, -1, - -1, 327, 328, 4775, -1, -1, -1, -1, -1, 4781, - -1, -1, 169, 4785, -1, -1, -1, -1, -1, 4791, - -1, -1, -1, 4795, -1, -1, -1, -1, -1, 186, - -1, 357, 459, -1, -1, 462, 463, 464, -1, 466, - 467, 468, 469, 470, 471, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 2195, -1, -1, -1, -1, - -1, -1, -1, -1, 4836, -1, -1, -1, -1, 226, - 227, -1, 4844, -1, -1, 232, -1, 4849, 4850, -1, - -1, -1, 4854, -1, -1, -1, -1, 244, 4557, 4861, - 4559, -1, -1, -1, -1, 1193, 422, -1, -1, 256, - -1, 4873, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3903, -1, -1, - -1, -1, -1, -1, -1, -1, 2266, -1, -1, -1, - 4902, -1, -1, -1, -1, 292, -1, -1, -1, -1, - -1, -1, -1, 300, -1, -1, 3932, -1, -1, -1, - -1, -1, -1, -1, 4926, -1, -1, 314, -1, -1, - -1, -1, -1, 320, 321, -1, 323, -1, -1, -1, - -1, 328, -1, -1, -1, -1, 333, -1, -1, 336, - -1, -1, -1, -1, -1, -1, 343, -1, 4960, 4961, - -1, -1, 349, 350, -1, -1, -1, -1, -1, -1, - 357, -1, -1, -1, 361, 2345, -1, -1, -1, 4981, - -1, -1, 4984, -1, 371, 4987, -1, -1, -1, -1, - -1, -1, 2362, -1, -1, -1, 4998, 384, -1, -1, - 5002, -1, 5004, -1, 5006, -1, -1, -1, -1, -1, - -1, 5013, -1, -1, -1, -1, -1, 404, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 414, -1, -1, - 5032, -1, -1, 420, -1, -1, -1, -1, 425, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 438, -1, 2423, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 5067, -1, 5069, -1, -1, - -1, -1, -1, -1, 461, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2457, 475, -1, - 2460, 478, 2462, -1, -1, -1, 2466, 4113, 2468, 2469, - -1, 4117, -1, -1, -1, -1, -1, 2477, 2478, 2479, - -1, -1, -1, -1, 8, 8, -1, 5119, 11, -1, - 14, 15, 15, 16, 17, 5127, 20, -1, 22, -1, - -1, 4147, 4148, -1, 28, -1, -1, 31, -1, 32, - -1, -1, -1, 22, -1, -1, -1, 40, -1, 28, - 5152, 5153, 5154, -1, 47, -1, 50, 51, -1, 5161, - 5162, -1, 41, 5165, -1, 2535, -1, -1, -1, 5171, - -1, -1, -1, -1, -1, -1, -1, -1, 5180, 72, - -1, 1509, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 70, 5194, -1, -1, 8, -1, 2567, 11, -1, - -1, -1, 15, 16, 17, -1, 2576, 5209, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, - -1, -1, -1, -1, -1, -1, -1, 40, -1, -1, - -1, -1, -1, -1, 47, -1, -1, -1, -1, -1, - -1, -1, -1, 122, -1, 124, 5248, -1, -1, -1, - -1, 5253, 131, -1, -1, 134, -1, -1, -1, 72, - 5262, 2631, -1, -1, -1, -1, 5268, 5269, 5270, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 5280, -1, - 159, -1, -1, -1, -1, -1, -1, -1, -1, 182, - -1, -1, -1, -1, 187, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 198, -1, -1, -1, -1, -1, - -1, 5313, 206, -1, 193, 209, 209, 210, 212, 213, - -1, 215, -1, 217, -1, -1, 220, -1, 222, -1, - -1, 224, -1, -1, -1, 5337, -1, -1, -1, -1, - 5342, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 257, 22, -1, 5369, 5370, 182, - -1, 28, -1, 252, 187, 254, -1, -1, 271, 5381, - 4396, 274, -1, -1, -1, 264, -1, -1, -1, 22, - -1, 1719, -1, 5395, 273, 28, 209, 210, -1, -1, - -1, -1, -1, -1, -1, -1, 285, -1, 1736, -1, - -1, 224, 5414, 70, -1, -1, -1, -1, -1, -1, - -1, -1, 5424, -1, -1, -1, -1, -1, -1, 1757, - -1, -1, -1, -1, -1, -1, -1, 70, -1, 5441, - -1, -1, -1, -1, 257, 324, -1, -1, 327, 328, - -1, -1, 5454, -1, 5456, -1, -1, -1, 271, -1, - -1, 274, -1, -1, -1, -1, -1, 124, -1, 362, - 5472, -1, 5474, 5475, 131, -1, -1, 134, 357, -1, - -1, 5180, -1, -1, -1, 1813, -1, -1, -1, -1, - -1, 124, -1, 2863, -1, -1, -1, -1, 131, 1827, - -1, 134, 159, -1, -1, 4521, -1, -1, -1, -1, - 4526, 1839, -1, 4529, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1851, -1, -1, 159, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 193, -1, -1, -1, - -1, -1, -1, 422, -1, -1, -1, -1, 8, 362, - -1, 11, -1, -1, -1, 15, 16, 17, -1, -1, - 193, -1, -1, -1, -1, -1, 459, 1895, 1896, 462, - 463, 464, 32, 466, 467, 468, 469, 470, 471, -1, - 40, -1, -1, 476, -1, -1, -1, 47, -1, -1, - -1, -1, -1, -1, -1, 252, -1, 254, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 264, -1, -1, - -1, 2981, 72, -1, -1, -1, 273, -1, -1, 252, - -1, 254, -1, -1, -1, -1, -1, -1, 285, -1, - -1, 264, -1, -1, -1, -1, -1, -1, -1, -1, - 273, -1, -1, -1, -1, -1, 459, -1, -1, 462, - 463, 464, 285, 466, 467, 468, 469, 470, 471, -1, - -1, -1, -1, 476, -1, -1, 8, 324, 4684, 11, - 327, 328, -1, 15, 16, 17, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 32, 324, -1, -1, 327, 328, -1, -1, 40, -1, - 357, -1, 3072, 2031, -1, 47, 4722, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, - -1, 615, 182, -1, 357, 28, -1, 187, -1, 623, - 72, -1, -1, -1, -1, -1, 630, 631, -1, -1, - 634, -1, 636, 637, -1, -1, -1, 641, -1, 209, - 210, -1, -1, -1, -1, -1, -1, 3127, 652, -1, - -1, -1, -1, -1, 224, 422, -1, 70, -1, 4785, - -1, -1, -1, 667, -1, -1, -1, -1, -1, 4795, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 422, - -1, -1, -1, -1, -1, -1, -1, 257, 692, -1, - 694, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 704, 271, -1, -1, 274, -1, -1, -1, -1, -1, - -1, 124, -1, 3193, -1, -1, -1, -1, 131, -1, - -1, 134, -1, -1, -1, -1, -1, -1, -1, -1, - 182, -1, 736, -1, -1, 187, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 159, -1, -1, -1, - -1, -1, -1, -1, -1, 3235, -1, 209, 210, -1, - -1, -1, -1, -1, -1, -1, 770, -1, -1, 3249, - -1, -1, 224, -1, -1, 3255, -1, -1, -1, 8, - 193, -1, 11, 3263, -1, -1, 15, 16, 17, 3269, - -1, 3271, 362, -1, 2232, -1, -1, -1, -1, -1, - 4926, -1, -1, 32, -1, 257, -1, -1, 2246, -1, - 4936, 40, -1, -1, -1, -1, -1, -1, 47, 271, - 824, -1, 274, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3317, -1, 252, - -1, 254, -1, 72, -1, -1, -1, -1, 2286, -1, - -1, 264, -1, -1, 858, -1, -1, -1, -1, -1, - 273, -1, -1, -1, -1, -1, -1, -1, 3348, 3349, - -1, -1, 285, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 5010, -1, -1, -1, -1, 459, - -1, -1, 462, 463, 464, -1, 466, 467, 468, 469, - 470, 471, -1, -1, -1, -1, 476, -1, -1, -1, - 362, 324, -1, -1, 327, 328, -1, -1, -1, -1, - -1, 22, 8, -1, -1, 11, 930, 28, -1, 15, - 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 357, -1, 32, 951, -1, -1, - -1, -1, -1, 182, 40, -1, -1, -1, 187, 963, - -1, 47, -1, -1, 968, -1, -1, -1, -1, 70, - -1, -1, -1, -1, 978, -1, -1, -1, -1, 983, - 209, 210, -1, -1, -1, -1, 72, 991, -1, -1, - -1, -1, -1, 997, -1, 224, 1000, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 459, -1, 422, - 462, 463, 464, -1, 466, 467, 468, 469, 470, 471, - -1, -1, -1, 124, 476, -1, -1, -1, 257, -1, - 131, -1, -1, 134, -1, -1, -1, 1041, -1, -1, - -1, -1, 271, -1, -1, 274, -1, -1, -1, -1, - -1, 2489, 3532, -1, -1, -1, -1, -1, 159, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 8, -1, -1, 11, -1, -1, -1, 15, 16, 17, - -1, -1, 193, -1, -1, -1, 182, -1, -1, -1, - -1, 187, -1, -1, 32, -1, -1, -1, -1, -1, - -1, -1, 40, -1, -1, -1, 5242, -1, -1, 47, - -1, -1, -1, 209, 210, -1, -1, -1, -1, -1, - -1, -1, -1, 362, -1, -1, -1, -1, 224, -1, - -1, 5267, -1, -1, 72, -1, -1, -1, -1, -1, - -1, 252, 1156, 254, 1158, -1, 1160, -1, 1162, -1, - 1164, 1165, 1166, 264, -1, -1, -1, 1171, -1, -1, - -1, 257, 273, -1, -1, 192, 193, -1, 1182, 196, - -1, -1, -1, -1, 285, 271, -1, -1, 274, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 216, - -1, -1, -1, -1, -1, -1, 223, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 5345, - -1, -1, -1, 324, -1, -1, 327, 328, -1, -1, - 459, -1, -1, 462, 463, 464, -1, 466, 467, 468, - 469, 470, 471, -1, -1, -1, -1, 476, -1, -1, - -1, 2689, 22, 3733, 182, -1, 357, 22, 28, 187, - -1, -1, -1, 28, -1, -1, -1, -1, 2706, -1, - 35, -1, -1, -1, -1, -1, 362, 3757, -1, -1, - -1, 209, 210, 2721, -1, 3765, -1, -1, 3768, 54, - 3770, -1, -1, -1, -1, -1, 224, -1, -1, -1, - 70, -1, -1, -1, -1, 70, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 5444, -1, - -1, 422, -1, -1, -1, -1, -1, -1, -1, 257, - -1, -1, 3812, -1, -1, -1, -1, -1, -1, 104, - -1, -1, -1, 271, -1, 3825, 274, -1, -1, 3829, - 3830, -1, 3832, -1, 124, -1, -1, 3837, 1362, 124, - -1, 131, -1, -1, 134, -1, 131, -1, -1, 134, - -1, -1, -1, 459, -1, -1, 462, 463, 464, -1, - 466, 467, 468, 469, 470, 471, -1, -1, -1, 159, - 476, -1, -1, -1, 159, -1, -1, 8, -1, -1, - 11, -1, -1, -1, 15, 16, 17, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 32, -1, 193, -1, 190, -1, -1, 193, 40, - -1, -1, -1, -1, 362, -1, 47, -1, -1, -1, - 1444, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3936, -1, -1, -1, - -1, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 238, -1, -1, 241, -1, -1, -1, - -1, -1, 252, -1, 254, -1, -1, 252, -1, 254, - -1, -1, -1, -1, 264, -1, -1, -1, -1, 264, - -1, -1, -1, 273, -1, -1, -1, -1, 273, -1, - 1514, -1, -1, -1, -1, 285, -1, -1, -1, 284, - 285, 4001, 4002, 4003, -1, 4005, 4006, 4007, 4008, 4009, - -1, 459, -1, -1, 462, 463, 464, -1, 466, 467, - 468, 469, 470, 471, -1, -1, 8, 2985, 476, 11, - -1, -1, -1, 15, 16, 17, -1, 327, 328, 324, - -1, -1, 327, 328, 329, -1, 3004, -1, -1, -1, - 32, 182, -1, -1, -1, -1, 187, -1, 40, -1, - -1, -1, -1, -1, -1, 47, 351, 357, -1, -1, - -1, -1, 357, -1, -1, -1, -1, -1, 209, 210, - 617, -1, -1, -1, 621, -1, 371, -1, -1, -1, - 72, -1, -1, 224, -1, -1, -1, -1, 635, -1, - -1, -1, -1, -1, -1, 642, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 257, -1, -1, -1, - -1, -1, 422, -1, 4134, -1, 4136, 422, -1, -1, - 271, -1, 3100, 274, 3102, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 8, -1, -1, 11, -1, - -1, -1, 15, 16, 17, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, - -1, -1, -1, -1, -1, -1, -1, 40, -1, -1, - -1, -1, -1, -1, 47, -1, -1, -1, -1, -1, - 182, -1, -1, -1, -1, 187, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 8, -1, -1, 11, 72, - -1, -1, 15, 16, 17, -1, -1, 209, 210, -1, - -1, 362, -1, 3191, -1, -1, -1, 1761, -1, 32, - -1, -1, 224, -1, -1, -1, -1, 40, -1, -1, - -1, -1, -1, -1, 47, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3230, -1, -1, 257, -1, -1, -1, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 271, - -1, -1, 274, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 4313, 4314, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4324, -1, 4326, 4327, 459, 182, - 4330, 462, 463, 464, 187, 466, 467, 468, 469, 470, - 471, -1, -1, -1, -1, 476, -1, 884, 885, -1, - -1, -1, -1, -1, -1, -1, 209, 210, -1, -1, - -1, -1, -1, -1, 1888, -1, 1890, 200, 201, -1, - -1, 224, -1, -1, 3332, 208, -1, 210, 211, -1, - 362, -1, -1, 1907, -1, 1909, -1, -1, -1, 182, - 4390, 224, -1, -1, 187, -1, -1, -1, -1, 1923, - -1, 1925, -1, 1927, 257, 1929, 3364, 1931, -1, -1, - -1, 1935, -1, -1, -1, -1, 209, 210, 271, -1, - -1, 274, -1, -1, 4424, -1, -1, -1, -1, -1, - -1, 224, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 982, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 4457, -1, -1, - -1, -1, -1, -1, 257, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1011, 1012, -1, 459, 271, -1, - 462, 463, 464, -1, 466, 467, 468, 469, 470, 471, - -1, -1, -1, -1, 476, -1, -1, -1, -1, -1, - 1037, -1, -1, -1, -1, -1, -1, -1, 3466, 362, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3487, - -1, -1, 8, -1, -1, 11, -1, -1, -1, 15, - 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3512, -1, 32, -1, -1, -1, - -1, -1, -1, -1, 40, -1, -1, -1, -1, 362, - -1, 47, -1, -1, 1111, 1112, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3546, -1, - -1, -1, -1, -1, -1, -1, 72, -1, -1, -1, - -1, -1, -1, 4603, -1, -1, 459, -1, -1, 462, - 463, 464, -1, 466, 467, 468, 469, 470, 471, -1, - -1, -1, -1, 476, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2160, 2161, -1, -1, - -1, -1, -1, -1, -1, -1, 4646, -1, -1, -1, - -1, -1, -1, -1, -1, 2179, 2180, -1, -1, -1, - 2184, 2185, -1, -1, -1, 2189, 459, -1, -1, 462, - 463, 464, -1, 466, 467, 468, 469, 470, 471, 2203, - -1, -1, -1, -1, -1, -1, 2210, -1, -1, -1, - 2214, 2215, -1, -1, 2218, 2219, -1, -1, -1, -1, - -1, 2225, -1, -1, -1, -1, 182, -1, -1, -1, - -1, 187, -1, -1, -1, -1, 2240, -1, 2242, -1, - -1, 22, -1, -1, -1, -1, -1, 28, -1, -1, - -1, -1, -1, 209, 210, -1, -1, 2261, -1, -1, - -1, -1, 2266, -1, -1, -1, -1, -1, 224, -1, - -1, -1, -1, -1, -1, 2279, -1, -1, -1, -1, - -1, -1, -1, -1, 2288, -1, -1, 2291, -1, 70, - 2294, 2295, 2296, -1, -1, -1, -1, 2301, 2302, -1, - -1, 257, -1, -1, -1, -1, -1, 2311, -1, -1, - -1, -1, 2316, 626, -1, 271, -1, 2321, 274, 632, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 645, 2337, -1, -1, -1, -1, -1, -1, - 2344, 2345, -1, 124, -1, -1, 2350, -1, 661, -1, - 131, -1, -1, 134, -1, -1, -1, 2361, 2362, -1, - -1, -1, 2366, 676, 677, -1, -1, -1, -1, -1, - 683, -1, 685, 686, 2378, -1, -1, 2381, 159, 4859, - 4860, -1, 2386, -1, -1, -1, 699, 2391, 2392, -1, - -1, -1, 2396, 4873, -1, 2399, 709, 4877, -1, 2403, - 2404, 2405, 2406, -1, 2408, -1, 362, 4887, -1, -1, - -1, -1, 193, -1, -1, -1, -1, 2421, 2422, -1, - 2424, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2434, 2435, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3890, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1487, 252, -1, 254, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 264, 797, -1, -1, -1, -1, -1, - -1, -1, 273, -1, -1, 2499, -1, -1, -1, -1, - -1, -1, -1, 459, 285, -1, 462, 463, 464, -1, - 466, 467, 468, 469, 470, 471, -1, -1, -1, -1, - 476, -1, -1, 2527, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 324, -1, -1, 327, 328, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1587, 1588, 1589, 1590, -1, -1, 357, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 5069, - -1, -1, -1, 5073, -1, 5075, -1, -1, -1, 5079, - 5080, -1, -1, -1, 8, -1, -1, 11, -1, -1, - -1, 15, 16, 17, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, -1, -1, 11, 940, 32, -1, - 15, 16, 17, -1, -1, -1, 40, 4075, -1, -1, - -1, 422, -1, 47, -1, 958, -1, 32, -1, -1, - -1, 964, -1, -1, 967, 40, -1, -1, -1, -1, - -1, -1, 47, -1, -1, -1, -1, -1, 72, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 72, -1, -1, - 2694, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1728, 1729, -1, -1, -1, -1, -1, -1, -1, - -1, 2725, -1, -1, -1, 5205, -1, 5207, -1, -1, - -1, -1, -1, -1, 1751, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 202, -1, -1, -1, -1, -1, - -1, -1, 4190, -1, -1, -1, 214, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 225, -1, 1786, - 1787, 1788, 1789, -1, -1, -1, -1, -1, 182, -1, - -1, -1, -1, 187, -1, -1, -1, -1, -1, -1, - -1, 4229, -1, -1, -1, -1, -1, 182, -1, -1, - -1, -1, 187, 1116, -1, 209, 210, -1, -1, -1, - -1, -1, 4250, -1, -1, -1, -1, -1, -1, -1, - 224, 1134, -1, -1, 209, 210, -1, -1, -1, -1, - -1, -1, -1, 5313, -1, -1, -1, -1, 1151, 224, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 257, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1179, 271, -1, -1, - 274, -1, 257, -1, -1, -1, -1, 4315, -1, -1, - -1, -1, 1195, -1, -1, -1, 271, 1904, -1, 274, - -1, -1, -1, 1910, -1, -1, -1, 1210, -1, -1, - 1213, -1, 201, -1, -1, -1, 5386, -1, -1, -1, - -1, 210, -1, -1, -1, 5395, 56, -1, -1, -1, - -1, -1, -1, -1, -1, 224, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 90, -1, -1, -1, -1, -1, -1, -1, 362, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 2979, 5456, 362, -1, 2983, - 120, -1, -1, -1, -1, 2989, -1, -1, -1, 4427, - -1, -1, 5472, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3007, 3008, -1, -1, -1, 3012, 149, - -1, -1, -1, 3017, 3018, 3019, -1, 3021, 1331, -1, - -1, -1, 2039, -1, -1, -1, 1339, 1340, -1, -1, - -1, -1, -1, -1, -1, 4473, -1, -1, -1, -1, - 3044, -1, -1, -1, 184, -1, -1, -1, -1, -1, - 3054, 3055, 3056, 3057, -1, 459, -1, -1, 462, 463, - 464, -1, 466, 467, 468, 469, 470, 471, -1, -1, - -1, -1, 476, -1, 459, -1, -1, 462, 463, 464, - 220, 466, 467, 468, 469, 470, 471, 3091, -1, 474, - 3094, 3095, 3096, -1, -1, 1408, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3112, -1, - -1, -1, -1, -1, 254, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3132, -1, - -1, -1, -1, 8, -1, -1, 11, -1, -1, -1, - 15, 16, 17, -1, -1, 285, 286, -1, 606, -1, - -1, -1, 292, -1, 612, -1, -1, 32, -1, -1, - -1, 36, -1, -1, -1, 40, -1, -1, -1, -1, - -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 324, -1, -1, -1, 328, -1, - -1, -1, 332, -1, -1, -1, -1, 72, -1, -1, - 3204, 341, -1, -1, -1, -1, -1, -1, 3212, 349, - -1, -1, -1, 2230, 2231, -1, -1, 357, -1, -1, - -1, -1, -1, -1, 2241, -1, 2243, -1, -1, 369, - 2247, -1, -1, -1, -1, -1, -1, 377, -1, 3243, - -1, -1, -1, -1, -1, -1, 121, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3270, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1601, -1, - -1, -1, -1, 433, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 182, -1, -1, - -1, 769, 187, 4751, -1, -1, -1, -1, 3322, -1, - -1, -1, -1, 3327, -1, -1, -1, 626, -1, -1, - -1, -1, -1, 632, 209, 210, 794, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 645, -1, -1, 224, - -1, -1, -1, 4791, 3358, 813, -1, -1, -1, -1, - 2377, -1, 661, 2380, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 835, 677, -1, - -1, -1, 257, -1, -1, -1, 685, -1, -1, -1, - -1, -1, -1, 3397, -1, 3399, 271, -1, -1, 274, - 699, -1, -1, -1, -1, -1, 4844, -1, -1, -1, - 709, 4849, 4850, -1, -1, -1, -1, -1, -1, -1, - -1, 879, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1752, - -1, -1, 2459, -1, -1, -1, -1, -1, -1, -1, - 2467, -1, -1, 2470, -1, -1, -1, -1, -1, 2476, - -1, -1, -1, 1776, -1, -1, -1, -1, -1, -1, - -1, 1784, -1, 2490, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1796, -1, -1, -1, 362, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 8, 797, -1, - 11, -1, -1, -1, 15, 16, 17, -1, -1, -1, - -1, -1, -1, -1, 2531, -1, -1, -1, -1, -1, - -1, 32, -1, 4961, -1, -1, -1, -1, -1, 40, - -1, -1, -1, -1, -1, -1, 47, -1, -1, -1, - -1, -1, 2559, -1, 419, -1, 1004, -1, -1, -1, - -1, -1, -1, -1, -1, 1868, 1869, -1, 1871, 1872, - -1, 72, -1, -1, -1, -1, -1, -1, -1, -1, - 1883, -1, 1885, 1886, -1, 1033, 1034, 1035, -1, -1, - -1, -1, -1, -1, 459, 1898, 1899, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, 2614, -1, 2616, - -1, 1914, -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, 1946, -1, -1, 1949, 1950, -1, -1, - -1, 940, -1, -1, -1, -1, -1, 158, 3652, -1, - 3654, -1, 163, -1, -1, -1, -1, 3661, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 182, -1, 3677, -1, -1, 187, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3693, - -1, -1, -1, -1, -1, -1, -1, -1, 209, 210, - -1, -1, -1, -1, -1, -1, -1, 2724, 3712, -1, - -1, -1, -1, 224, -1, -1, -1, -1, -1, -1, - 1178, -1, -1, 2036, -1, -1, 3730, 5165, -1, -1, - -1, -1, -1, -1, -1, -1, 3740, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 257, -1, -1, -1, - -1, 1209, -1, -1, -1, 3759, -1, -1, -1, -1, - 271, -1, -1, 274, -1, -1, -1, -1, 3772, 3773, - 3774, -1, -1, -1, -1, 3779, 3780, 3781, 3782, -1, - -1, -1, 3786, 3787, -1, -1, -1, -1, 3792, 3793, - -1, 3795, 3796, 3797, 3798, 3799, 3800, -1, 3802, -1, - -1, -1, -1, -1, -1, -1, -1, 3811, -1, -1, - 3814, 3815, -1, -1, -1, -1, -1, 1116, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, 3838, 1134, 11, -1, -1, -1, - 15, 16, 17, -1, -1, -1, 2159, -1, -1, -1, - -1, 362, 1151, -1, -1, -1, 3860, 32, -1, -1, - -1, -1, -1, -1, 2177, 40, -1, -1, -1, 2182, - 2183, -1, 47, -1, 2187, -1, -1, -1, -1, -1, - 1179, -1, 2195, -1, -1, -1, -1, 1345, -1, -1, - -1, -1, -1, -1, -1, -1, 1195, 72, -1, -1, - 2213, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1210, -1, -1, 1213, -1, -1, -1, -1, -1, - -1, -1, 2235, -1, -1, 2238, 2239, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1395, -1, -1, - -1, -1, -1, -1, -1, -1, 2259, -1, 459, -1, - -1, 462, 463, 464, 3958, 466, 467, 468, 469, 470, - 471, -1, -1, 8, 2277, 2278, 11, -1, -1, -1, - 15, 16, 17, -1, 2991, -1, 2993, 2994, 2995, -1, - -1, -1, -1, -1, -1, -1, -1, 32, 3992, -1, - -1, -1, -1, -1, -1, 40, 2309, 2310, -1, -1, - 2313, -1, 47, -1, -1, -1, -1, 182, -1, -1, - -1, -1, 187, -1, -1, -1, 1474, -1, -1, -1, - -1, -1, -1, 2336, -1, 2338, 1484, 72, -1, -1, - 2343, -1, 1331, -1, 209, 210, 2349, -1, -1, -1, - 1339, 1340, -1, 2356, -1, -1, -1, 2360, -1, 224, - -1, -1, 2365, -1, -1, -1, -1, 1515, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2385, -1, -1, -1, -1, 2390, -1, -1, - 1538, 2394, 257, 1541, 2397, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2407, -1, 271, -1, -1, 274, - -1, -1, -1, -1, -1, -1, -1, 2420, -1, 1408, - -1, -1, 157, -1, -1, -1, -1, 2430, -1, -1, - -1, -1, -1, -1, 299, -1, -1, -1, -1, -1, - -1, -1, -1, 1591, -1, -1, -1, 182, -1, -1, - -1, -1, 187, -1, -1, -1, -1, 1605, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 209, 210, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 224, - -1, -1, -1, -1, -1, 2498, -1, 362, -1, -1, - -1, -1, -1, -1, 4198, -1, -1, -1, 4202, 4203, - 4204, 4205, -1, 378, 4208, -1, -1, -1, -1, -1, - -1, -1, 257, -1, 3231, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 271, -1, -1, 274, - -1, -1, -1, -1, -1, -1, 4240, 4241, 4242, -1, - 4244, -1, 4246, 4247, -1, -1, -1, -1, -1, -1, - -1, -1, 297, -1, 4258, 4259, -1, -1, 1716, -1, - -1, -1, -1, 2576, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4285, -1, -1, 459, -1, -1, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, -1, -1, -1, - -1, -1, 1601, -1, 4308, -1, -1, -1, -1, -1, - -1, -1, 1770, 8, -1, -1, 11, 362, 2631, -1, - 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 32, -1, -1, - 35, 1799, -1, -1, -1, 40, -1, -1, 1806, -1, - -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, - 2673, -1, -1, -1, -1, -1, -1, -1, -1, 791, - 792, -1, -1, -1, -1, -1, -1, 72, 2691, 4383, - -1, -1, -1, -1, -1, -1, 2699, 3404, -1, -1, - -1, -1, -1, -1, -1, -1, 2709, -1, -1, 2712, - -1, -1, 2715, -1, -1, -1, -1, -1, 4412, -1, - -1, -1, -1, -1, 459, -1, -1, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, -1, -1, -1, - -1, -1, -1, 4437, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1752, 1912, -1, -1, 8, -1, -1, - 11, -1, -1, -1, 15, 16, 17, -1, 2781, -1, - -1, -1, -1, -1, 2787, -1, -1, 1776, -1, -1, - -1, 32, -1, -1, -1, 1784, -1, 182, -1, 40, - -1, -1, 187, -1, 1952, 1953, 47, 1796, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1969, -1, -1, 209, 210, 938, 939, -1, -1, - -1, 72, -1, -1, -1, -1, -1, -1, -1, 224, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4543, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2863, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 257, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1871, 1872, -1, -1, 271, -1, -1, 274, - -1, -1, -1, -1, -1, -1, 1885, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1898, - 1899, 4605, -1, -1, -1, -1, -1, -1, 2066, -1, - -1, -1, -1, -1, -1, 1914, -1, -1, 2076, 4623, - -1, -1, -1, -1, 4628, 4629, -1, -1, -1, -1, - -1, 182, -1, -1, -1, -1, 187, -1, 2951, 2952, - -1, -1, -1, -1, -1, -1, -1, 2105, -1, 3666, - 3667, 3668, 3669, -1, -1, 2113, -1, 2115, 209, 210, - -1, -1, -1, -1, -1, 2978, -1, 362, 2981, -1, - -1, -1, -1, 224, -1, -1, -1, 4681, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2148, -1, -1, -1, -1, -1, -1, 4701, -1, -1, - -1, -1, -1, -1, -1, -1, 257, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 672, - 271, -1, -1, 274, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 4737, -1, -1, -1, 2036, -1, -1, - 4744, -1, 293, -1, -1, 698, -1, -1, -1, -1, - -1, -1, -1, 3066, 3067, 3068, -1, -1, -1, -1, - -1, -1, -1, -1, 459, -1, -1, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, 3090, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3110, -1, -1, - -1, -1, -1, 1225, -1, -1, 4810, -1, -1, -1, - -1, 362, -1, -1, -1, -1, 3129, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4832, -1, - -1, -1, 2290, 1255, -1, -1, 3853, -1, -1, 4843, - -1, -1, 3859, -1, -1, -1, -1, -1, 2306, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2159, 1283, 1284, 1285, -1, 1287, -1, -1, -1, 2327, - -1, -1, -1, -1, -1, -1, -1, -1, 2177, -1, - -1, -1, -1, 2182, 2183, 1307, -1, -1, 2187, -1, - -1, -1, -1, -1, -1, -1, 2195, -1, 3211, -1, - -1, -1, 4906, -1, -1, -1, -1, -1, 459, -1, - -1, 462, 463, 464, 2213, 466, 467, 468, 469, 470, - 471, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2401, 2402, -1, -1, -1, -1, 3262, - -1, -1, -1, -1, -1, -1, 3269, 1379, 3271, -1, - 2259, 1383, 1384, -1, 4968, -1, -1, -1, -1, -1, - -1, 3284, -1, 3286, -1, -1, -1, -1, 2277, 2278, - -1, -1, -1, -1, -1, 938, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 3308, 8, -1, -1, 11, - -1, 954, -1, 15, 16, 17, -1, -1, -1, -1, - 2309, 2310, -1, -1, 2313, -1, -1, -1, -1, -1, - 32, -1, -1, 35, -1, 5029, 979, -1, 40, -1, - -1, -1, -1, -1, -1, 47, 3349, 2336, -1, 2338, - 5044, 994, -1, -1, 2343, -1, -1, -1, -1, -1, - 2349, 2509, -1, -1, -1, -1, -1, 2356, -1, -1, - 72, 2360, -1, -1, -1, -1, 2365, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2385, 3400, -1, -1, - -1, 2390, -1, -1, 5098, 2394, -1, -1, 2397, -1, - -1, -1, -1, -1, -1, 3418, -1, -1, 2407, 5113, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2420, -1, 672, -1, -1, 1079, 3440, -1, -1, - 3443, 2430, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 8, -1, -1, 11, 698, - -1, -1, 15, 16, 17, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, - 182, -1, -1, -1, -1, 187, -1, 40, -1, -1, - -1, -1, -1, -1, 47, -1, -1, -1, -1, 5193, - -1, -1, -1, -1, 1616, 1617, 1618, 209, 210, 2498, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, - 3523, -1, 224, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 5238, 2693, -1, -1, -1, -1, - 1193, -1, -1, -1, -1, 257, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 271, - -1, -1, 274, 8, -1, -1, 11, -1, -1, -1, - 15, 16, 17, -1, -1, -1, -1, 2576, 4295, -1, - -1, -1, -1, -1, -1, -1, -1, 32, -1, -1, - 35, -1, -1, 4310, -1, 40, -1, -1, -1, -1, - 163, -1, 47, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 182, - -1, 5325, -1, -1, 187, -1, -1, 72, -1, -1, - -1, -1, 2631, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 209, 210, -1, -1, - 362, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 224, -1, 3676, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2673, -1, -1, -1, -1, -1, - 4397, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2848, -1, 2691, -1, 257, -1, -1, -1, -1, -1, - 2699, -1, -1, -1, -1, 954, -1, -1, 271, -1, - -1, 274, -1, 2871, 3727, -1, -1, -1, -1, 3732, - -1, 3734, -1, -1, -1, -1, -1, -1, -1, -1, - 979, -1, -1, -1, -1, -1, -1, 182, -1, -1, - -1, -1, 187, 3756, -1, 994, -1, 459, -1, 1402, - 462, 463, 464, -1, 466, 467, 468, 469, 470, 471, - -1, -1, 3775, -1, 209, 210, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3791, 224, - -1, 3794, 2781, -1, -1, -1, -1, -1, 2787, -1, - -1, -1, -1, -1, -1, 8, -1, -1, 11, 362, - -1, -1, 15, 16, 17, -1, -1, -1, -1, -1, - -1, -1, 257, -1, -1, 1468, -1, -1, -1, 32, - -1, -1, -1, -1, -1, -1, 271, 40, -1, 274, - 1079, -1, -1, -1, 47, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4565, 4566, - 4567, -1, -1, -1, -1, -1, 1509, -1, -1, 72, - -1, -1, -1, -1, 2863, -1, -1, 1989, -1, -1, - -1, -1, -1, 3886, 3887, -1, -1, -1, -1, -1, - 2002, -1, 2004, 3896, -1, 2007, 2008, 2009, -1, 1542, - -1, -1, 2014, -1, -1, 2017, 459, -1, -1, 462, - 463, 464, 3915, 466, 467, 468, 469, 470, 471, -1, - 2032, 2033, 2034, 2035, -1, -1, -1, 362, 2040, -1, - -1, -1, 2044, -1, -1, 2047, -1, -1, 2050, 2051, - 2052, 2053, 2054, 2055, 2056, 2057, 2058, -1, 2060, -1, - -1, -1, -1, -1, 1193, 2067, -1, 2069, -1, -1, - 3108, -1, 2951, 2952, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1616, 1617, 1618, -1, -1, -1, 182, - -1, -1, -1, -1, 187, 3988, -1, 672, -1, 2978, - -1, -1, 2981, -1, -1, -1, -1, 2109, -1, -1, - -1, -1, -1, -1, -1, -1, 209, 210, -1, -1, - -1, -1, -1, 698, -1, -1, 4723, -1, -1, -1, - -1, 224, 2134, 2135, 459, -1, -1, 462, 463, 464, - -1, 466, 467, 468, 469, 470, 471, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 257, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 271, -1, - -1, 274, -1, -1, -1, -1, 1719, 3066, 3067, 3068, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1736, -1, 1334, -1, -1, -1, -1, - -1, 3090, 1745, -1, 2216, -1, -1, -1, -1, 8, - -1, -1, 11, -1, 1757, -1, 15, 16, 17, -1, - -1, 3110, -1, -1, -1, -1, -1, 3275, 3276, 3277, - -1, -1, -1, 32, -1, -1, 35, -1, -1, -1, - 3129, 40, -1, -1, 3292, -1, -1, -1, 47, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4865, 362, - 4867, -1, -1, 1402, -1, -1, -1, 3315, -1, -1, - 1813, -1, -1, 72, -1, -1, -1, 3325, 3326, -1, - -1, -1, 3330, -1, 1827, -1, -1, -1, -1, 392, - -1, -1, -1, -1, -1, -1, 1839, -1, -1, -1, - -1, -1, -1, -1, 4207, -1, -1, -1, 1851, 4212, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3211, -1, -1, -1, -1, -1, -1, 1468, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4245, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1895, 1896, 4257, -1, 459, -1, -1, 462, - 463, 464, -1, 466, 467, 468, 469, 470, 471, 954, - 1509, -1, -1, 3262, -1, -1, -1, -1, -1, -1, - 3269, 4284, 3271, 182, -1, -1, -1, -1, 187, -1, - -1, -1, -1, 3441, 979, 3284, -1, 3286, -1, -1, - -1, -1, -1, 1542, -1, -1, -1, -1, -1, 994, - 209, 210, 5019, -1, -1, -1, -1, -1, -1, 3308, - -1, -1, -1, -1, -1, 224, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 2447, 2448, 2449, -1, -1, - -1, 2453, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 257, -1, - 3349, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 271, -1, 4377, 274, 2488, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2031, -1, - -1, -1, -1, -1, 1079, -1, -1, -1, -1, -1, - -1, 5108, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3400, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3569, 3570, 3571, -1, -1, 2069, -1, -1, 3418, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4451, -1, - 8, 3440, -1, 11, 3443, -1, -1, 15, 16, 17, - -1, -1, -1, 362, -1, -1, -1, 20, -1, -1, - -1, -1, 25, -1, 32, -1, -1, -1, -1, -1, - 1719, -1, 40, -1, 37, -1, -1, -1, -1, 47, - -1, -1, -1, -1, -1, -1, -1, 1736, -1, -1, - -1, -1, -1, -1, 5211, -1, 1745, 60, 1193, -1, - -1, -1, -1, -1, 72, -1, -1, -1, 1757, -1, - 73, -1, -1, 2166, -1, -1, -1, 2170, 2171, -1, - -1, 84, -1, -1, 3523, 88, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 106, 4557, -1, 4559, -1, -1, 112, - 459, -1, -1, 462, 463, 464, -1, 466, 467, 468, - 469, 470, 471, -1, 1813, -1, 129, -1, 672, -1, - -1, -1, -1, -1, -1, -1, -1, 140, 1827, 2232, - -1, -1, -1, -1, -1, 148, -1, -1, 5305, -1, - 1839, 4604, -1, 2246, 698, -1, -1, 160, -1, -1, - 4613, -1, 1851, -1, -1, 168, -1, -1, -1, 172, - 2732, -1, -1, -1, 182, 2737, -1, -1, -1, 187, - -1, 5338, 5339, -1, -1, -1, -1, -1, 191, -1, - -1, -1, -1, 2286, -1, -1, -1, -1, 4651, -1, - 2762, 209, 210, -1, 4657, -1, 1895, 1896, -1, -1, - -1, 2773, -1, 2775, 2776, -1, 224, -1, -1, -1, - -1, -1, -1, -1, 2786, 228, -1, 2789, -1, 2791, - -1, -1, -1, -1, 237, -1, -1, 3676, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 257, - -1, -1, -1, -1, -1, -1, -1, -1, 2820, 3857, - 2822, -1, 2824, 271, -1, -1, 274, 1402, 271, -1, - 3868, 274, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 5438, -1, -1, -1, -1, -1, -1, 3727, -1, - -1, -1, 295, 3732, -1, 3734, -1, -1, -1, -1, - -1, 3899, -1, -1, -1, -1, 309, -1, -1, -1, - -1, -1, -1, 316, -1, -1, 2878, 3756, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2893, 335, 1468, -1, 3933, 3775, -1, -1, -1, - -1, 344, 2031, -1, -1, -1, -1, -1, 351, -1, - -1, 354, 3791, -1, 362, 3794, 2449, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 373, -1, -1, -1, 1509, -1, 379, -1, -1, -1, - 3978, 384, -1, 4836, 387, 388, 25, 390, 391, -1, - -1, -1, -1, -1, -1, 2957, 2489, -1, 401, -1, - -1, -1, -1, 406, -1, -1, -1, 1542, 4861, 412, - 954, -1, 415, -1, -1, 418, -1, -1, -1, -1, - 4873, -1, -1, -1, -1, -1, -1, -1, 431, -1, - -1, -1, -1, -1, 73, 979, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3886, 3887, 88, - 994, 459, -1, -1, 462, 463, 464, 3896, 466, 467, - 468, 469, 470, 471, -1, -1, -1, 106, -1, -1, - -1, -1, -1, 112, -1, -1, 3915, 2166, 2571, -1, - -1, 2170, 2171, -1, -1, -1, -1, -1, -1, -1, - 129, -1, -1, -1, -1, -1, 4094, 4095, 4096, 4097, - -1, 140, -1, -1, -1, -1, -1, -1, -1, 148, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 160, -1, -1, -1, -1, 165, -1, -1, -1, - -1, -1, -1, 172, -1, 1079, -1, -1, -1, -1, - -1, -1, -1, 2232, -1, -1, -1, -1, -1, 3988, - -1, -1, 191, -1, -1, -1, -1, 2246, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 216, -1, -1, - -1, -1, -1, -1, 1719, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2689, 2286, 237, -1, - -1, 1736, -1, -1, -1, -1, -1, 672, -1, -1, - 1745, -1, -1, 2706, 5067, -1, 5069, -1, -1, -1, - -1, -1, 1757, -1, -1, -1, -1, -1, 2721, -1, - -1, -1, 271, 698, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1193, - -1, -1, -1, -1, 3216, -1, 295, -1, -1, -1, - 3222, -1, -1, -1, -1, -1, 305, 306, -1, -1, - 309, -1, -1, -1, -1, -1, -1, -1, 1813, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1827, -1, -1, -1, 335, -1, -1, 338, - -1, -1, -1, 342, 1839, 344, -1, -1, -1, 5162, - -1, -1, 351, -1, -1, 354, 1851, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 5180, -1, -1, - -1, -1, -1, -1, 373, -1, -1, -1, -1, -1, - 379, 5194, -1, -1, 383, 384, -1, -1, 387, -1, - -1, -1, 391, -1, -1, -1, 5209, -1, -1, -1, - 1895, 1896, 401, -1, -1, -1, -1, 406, 4207, -1, - -1, -1, -1, 4212, -1, -1, -1, -1, -1, 418, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 431, -1, -1, -1, -1, -1, -1, -1, - 2489, -1, -1, -1, -1, -1, 4245, -1, -1, -1, - -1, -1, -1, -1, -1, 5268, 5269, -1, 4257, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4429, -1, 2926, -1, -1, 2929, -1, 2931, -1, - -1, -1, -1, 2936, -1, 4284, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1402, -1, - 5313, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2571, -1, -1, -1, -1, -1, -1, 954, - -1, -1, 2985, -1, -1, -1, 2031, -1, -1, -1, - -1, 3463, -1, -1, -1, -1, -1, -1, -1, -1, - 3472, 3004, -1, -1, 979, -1, 3478, -1, 3480, -1, - -1, -1, -1, -1, 1468, -1, -1, -1, -1, 994, - -1, -1, -1, -1, -1, -1, 3029, -1, 4377, -1, - -1, -1, 5395, -1, -1, 3507, 3508, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3525, -1, 1509, -1, -1, -1, -1, - -1, 3533, -1, -1, 3536, -1, 3538, -1, -1, -1, - -1, -1, -1, -1, -1, 3547, -1, -1, -1, -1, - -1, -1, -1, 3555, 3556, -1, -1, -1, 1542, -1, - 2689, -1, -1, 5456, -1, -1, -1, 3100, -1, 3102, - -1, -1, 4451, -1, 1079, -1, -1, 2706, -1, 5472, - -1, 5474, 5475, -1, -1, 3587, -1, -1, -1, -1, - -1, 2166, 2721, -1, -1, 2170, 2171, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3611, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4660, -1, -1, 3627, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 672, 4675, -1, -1, - -1, -1, 4680, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2232, 3191, -1, - -1, -1, 698, -1, -1, -1, -1, 4705, -1, -1, - -1, 2246, -1, -1, -1, -1, -1, -1, 4557, -1, - 4559, -1, -1, 3216, -1, -1, -1, -1, 1193, 3222, - -1, -1, -1, -1, -1, -1, -1, 3230, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2286, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3255, -1, -1, 4604, -1, -1, -1, -1, - 3263, -1, -1, -1, -1, 1719, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1736, -1, -1, -1, -1, -1, -1, -1, - -1, 1745, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4651, 1757, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4827, - -1, -1, -1, -1, -1, -1, -1, 2926, -1, 3332, - 2929, -1, 2931, -1, -1, -1, -1, 2936, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3350, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1813, - -1, 3364, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1827, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1839, 2985, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1851, -1, -1, - -1, -1, -1, -1, -1, 3004, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4923, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1402, -1, -1, - 3029, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1895, 1896, -1, 2489, -1, -1, -1, 954, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3466, -1, -1, -1, -1, -1, 3941, - 3942, -1, -1, 979, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3487, -1, -1, 4836, 994, -1, - -1, -1, -1, 1468, -1, -1, -1, -1, -1, -1, - -1, 3100, -1, 3102, -1, -1, -1, -1, -1, 3512, - -1, -1, 4861, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4873, -1, 2571, -1, -1, -1, - -1, -1, -1, -1, 1509, -1, -1, -1, -1, 4011, - -1, -1, -1, 3546, -1, -1, -1, -1, -1, -1, - 4022, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1542, -1, -1, - -1, -1, -1, 1079, -1, -1, -1, 2031, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4062, 4063, 3191, -1, -1, -1, -1, 4069, 4070, -1, - -1, -1, 4074, -1, -1, -1, -1, 4079, -1, -1, - 4082, 4083, -1, -1, -1, 4087, -1, -1, -1, -1, - -1, 4093, -1, -1, -1, -1, -1, -1, -1, -1, - 3633, 3230, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2689, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3255, -1, -1, -1, - -1, 2706, -1, -1, 3263, -1, -1, -1, -1, -1, - -1, -1, -1, 4145, -1, -1, 2721, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1193, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4172, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2166, -1, -1, -1, 2170, 2171, 5067, -1, - 5069, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 3733, -1, -1, 3332, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1719, -1, -1, -1, -1, -1, - -1, 3350, -1, -1, 3757, -1, -1, -1, -1, -1, - -1, 1736, -1, -1, -1, 3364, -1, -1, -1, -1, - 1745, -1, -1, -1, -1, -1, -1, -1, 2232, -1, - -1, -1, 1757, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2246, -1, -1, -1, -1, -1, -1, -1, - -1, 4273, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 5162, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 5180, 2286, -1, -1, -1, -1, -1, 1813, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1827, -1, -1, -1, -1, -1, -1, -1, - 5209, -1, -1, -1, 1839, -1, -1, 3466, 4340, -1, - -1, -1, -1, -1, -1, -1, 1851, -1, -1, -1, - -1, 2926, -1, -1, 2929, -1, 2931, 3890, 3487, -1, - -1, 2936, -1, -1, -1, -1, 1402, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3512, -1, -1, -1, -1, -1, -1, - 1895, 1896, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3940, -1, -1, - 2985, -1, -1, -1, -1, -1, -1, 3546, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3004, - -1, -1, 1468, -1, 5313, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3029, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1509, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 4495, 4496, -1, -1, 4499, -1, -1, - -1, -1, -1, -1, 3633, 2489, 1542, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 5395, -1, -1, -1, - -1, -1, -1, 672, -1, 3100, 2031, 3102, -1, -1, - -1, -1, 4065, -1, 4536, 4537, -1, -1, -1, -1, - -1, -1, 4075, -1, -1, -1, -1, -1, -1, 698, - 4552, -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, 5456, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2571, -1, -1, - -1, -1, -1, 5472, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3733, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3191, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 672, 3757, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, - -1, -1, -1, 25, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 698, -1, 3230, -1, 4190, -1, -1, - -1, 2166, -1, -1, -1, 2170, 2171, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 60, -1, - 3255, -1, -1, 1719, -1, -1, -1, -1, 3263, -1, - -1, 73, 74, -1, -1, -1, 4229, -1, -1, -1, - 1736, -1, 84, -1, -1, 2689, 88, -1, -1, 1745, - -1, -1, -1, -1, -1, -1, -1, 4250, -1, -1, - -1, 1757, 2706, -1, 106, -1, -1, 2232, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2721, -1, -1, - -1, 2246, -1, -1, -1, -1, -1, 129, -1, -1, - -1, 4753, -1, -1, -1, -1, -1, 3332, 140, -1, - -1, 3890, -1, -1, -1, -1, 148, -1, -1, -1, - -1, -1, -1, -1, -1, 3350, -1, 1813, 160, 4781, - -1, 2286, 4315, 165, -1, -1, -1, -1, -1, 3364, - -1, 1827, -1, 4795, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1839, -1, 954, -1, -1, -1, 191, - -1, 3940, -1, -1, -1, 1851, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 979, -1, -1, -1, 216, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 994, -1, -1, -1, -1, - -1, -1, 4854, -1, -1, 237, -1, -1, -1, 1895, - 1896, -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, 271, - -1, 3466, 4425, -1, 4427, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 954, - -1, -1, 3487, 295, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 305, 306, -1, -1, 309, -1, -1, - 1079, -1, -1, -1, 979, -1, 4065, 3512, -1, -1, - 4473, -1, 2926, -1, -1, 2929, 4075, 2931, -1, 994, - -1, -1, 2936, 335, -1, -1, 338, -1, -1, -1, - 342, -1, 344, -1, -1, -1, -1, -1, -1, 351, - -1, 3546, 354, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2489, -1, -1, -1, -1, -1, - -1, 373, -1, -1, -1, 2031, -1, 379, -1, -1, - -1, 2985, 384, -1, 5006, 387, -1, -1, -1, 391, - -1, -1, -1, -1, -1, -1, -1, 399, -1, 401, - 3004, -1, -1, -1, 406, -1, -1, -1, -1, -1, - 5032, -1, -1, -1, 1079, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1193, 3029, -1, -1, -1, 431, - -1, -1, -1, -1, -1, -1, -1, -1, 3633, -1, - -1, 4190, -1, -1, -1, -1, 2571, -1, -1, -1, - 4603, -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, - 4229, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3100, 5119, 3102, -1, - -1, 4250, -1, -1, -1, -1, -1, -1, -1, -1, - 2166, -1, -1, -1, 2170, 2171, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1193, -1, - 5152, 5153, 5154, -1, -1, -1, -1, -1, 3733, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 5171, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3757, -1, 2689, -1, 4315, -1, -1, -1, - -1, -1, -1, -1, 4727, -1, 2232, -1, -1, -1, - -1, 2706, -1, -1, -1, -1, -1, 3191, -1, -1, - 2246, -1, -1, -1, -1, -1, 2721, -1, 4751, -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, 3230, -1, -1, -1, - 2286, 5253, -1, 1402, -1, -1, -1, -1, 4791, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 5270, -1, - -1, 3255, -1, -1, -1, -1, -1, -1, -1, 3263, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4427, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4844, -1, -1, -1, 3890, 4849, 4850, -1, 1468, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4473, -1, -1, -1, 3332, -1, - -1, -1, -1, -1, -1, -1, -1, 1402, -1, -1, - 1509, -1, -1, -1, -1, 3940, 3350, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 5381, - 3364, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1542, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 5414, -1, -1, -1, -1, -1, -1, -1, - -1, 2926, 5424, 1468, 2929, -1, 2931, 4960, 4961, -1, - -1, 2936, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2489, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1509, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4603, -1, -1, -1, -1, -1, - 2985, -1, 3466, -1, -1, -1, -1, -1, -1, -1, - 4065, -1, -1, -1, -1, -1, -1, 1542, -1, 3004, - 4075, -1, -1, 3487, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3029, -1, -1, -1, 3512, -1, - -1, -1, -1, -1, -1, 2571, -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, 3546, -1, -1, -1, -1, -1, -1, -1, - 1719, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1736, -1, -1, - -1, -1, -1, -1, -1, 3100, 1745, 3102, 4727, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1757, -1, - -1, -1, -1, -1, -1, 4190, -1, -1, -1, -1, - -1, -1, 4751, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 5165, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3633, - -1, -1, -1, 2689, 4229, -1, -1, -1, -1, -1, - -1, -1, 4791, -1, 1813, -1, -1, -1, -1, -1, - 2706, -1, -1, -1, 1719, 4250, -1, -1, 1827, -1, - -1, -1, -1, -1, -1, 2721, 3191, -1, -1, -1, - 1839, 1736, -1, -1, -1, -1, -1, -1, -1, -1, - 1745, -1, 1851, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1757, -1, -1, 4844, -1, -1, -1, -1, - 4849, 4850, -1, -1, -1, 3230, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4315, -1, -1, -1, -1, -1, 1895, 1896, -1, 3733, - 3255, -1, -1, -1, -1, -1, -1, -1, 3263, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1813, -1, - -1, -1, -1, 3757, -1, -1, -1, -1, -1, -1, - -1, -1, 1827, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1839, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1851, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3332, -1, -1, - -1, -1, 4961, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 3350, -1, -1, -1, -1, - 1895, 1896, 4427, -1, -1, -1, -1, -1, -1, 3364, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2031, -1, -1, -1, -1, -1, -1, -1, - 2926, -1, -1, 2929, -1, 2931, -1, -1, 4473, -1, - 2936, -1, -1, -1, -1, -1, 3890, -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, 2985, - -1, -1, -1, -1, -1, -1, 3940, -1, -1, -1, - -1, 3466, -1, -1, -1, -1, -1, -1, 3004, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3487, -1, -1, -1, 2031, -1, -1, -1, - -1, -1, -1, 3029, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3512, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2166, -1, -1, - -1, 2170, 2171, -1, -1, -1, -1, -1, 4603, -1, - -1, -1, -1, -1, -1, -1, 5165, -1, -1, -1, - -1, 3546, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3100, -1, 3102, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4065, -1, 2232, -1, -1, -1, -1, -1, -1, - -1, 4075, -1, -1, -1, -1, 1299, 2246, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2166, -1, -1, -1, 2170, 2171, -1, 3633, -1, - -1, -1, -1, -1, -1, -1, -1, 2286, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4727, -1, -1, 3191, 1359, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4751, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2232, -1, -1, - -1, -1, -1, -1, 3230, -1, -1, -1, -1, -1, - -1, 2246, -1, -1, -1, -1, 4190, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4791, -1, -1, 3255, - -1, -1, -1, -1, -1, -1, -1, 3263, 3733, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2286, -1, -1, -1, 4229, -1, -1, -1, -1, - -1, -1, 3757, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4250, -1, -1, 4844, - -1, -1, -1, -1, 4849, 4850, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3332, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3350, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3364, -1, - -1, 4315, -1, -1, -1, -1, -1, -1, -1, -1, - 2489, -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, 3890, 4961, -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, 1622, - -1, -1, 2571, 1626, -1, -1, -1, -1, -1, -1, - 3466, -1, -1, -1, -1, 3940, -1, -1, -1, -1, - -1, -1, -1, 4427, 2489, -1, -1, -1, -1, -1, - -1, 3487, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3512, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4473, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 3546, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2571, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2689, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2706, -1, -1, - 4065, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4075, -1, 2721, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 5165, -1, -1, -1, -1, -1, -1, 3633, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4603, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2689, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2706, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2721, -1, -1, -1, - -1, -1, -1, -1, -1, 4190, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3733, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3757, -1, -1, 4229, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 4727, -1, 4250, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 4751, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2926, -1, -1, - 2929, -1, 2931, -1, 1987, -1, -1, 2936, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2001, -1, - -1, -1, 2005, -1, -1, -1, -1, 4791, -1, -1, - 4315, -1, -1, -1, -1, -1, 2019, 2020, 2021, -1, - 2023, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2985, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3890, 3004, -1, -1, -1, -1, - 4844, -1, 2065, -1, -1, 4849, 4850, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 3029, 2926, -1, -1, 2929, -1, 2931, -1, -1, -1, - -1, 2936, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3940, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2121, -1, - -1, -1, 4427, -1, -1, -1, -1, -1, -1, -1, - 2133, -1, -1, -1, -1, 2138, -1, -1, -1, -1, - 2985, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3100, -1, 3102, -1, -1, -1, -1, -1, 3004, - -1, -1, -1, -1, -1, -1, -1, -1, 4473, -1, - -1, -1, -1, -1, -1, -1, -1, 4961, -1, -1, - -1, -1, -1, -1, 3029, -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, 4065, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4075, - -1, -1, 3191, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 3100, -1, 3102, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3230, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4603, -1, - -1, -1, -1, -1, -1, -1, 3255, -1, -1, -1, - -1, -1, -1, -1, 3263, -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, 3191, -1, -1, -1, - -1, -1, -1, -1, 4190, -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, 5165, -1, 3332, -1, 3230, -1, -1, -1, -1, - -1, -1, -1, 4229, -1, -1, -1, -1, -1, -1, - -1, 3350, -1, -1, -1, -1, -1, -1, -1, -1, - 3255, -1, -1, -1, 4250, 3364, -1, -1, 3263, -1, - -1, -1, 4727, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4751, -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, 4315, - -1, -1, -1, -1, -1, -1, 4791, 3332, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 3350, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3466, -1, 3364, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3487, 4844, - -1, -1, -1, -1, 4849, 4850, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3512, -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, 4427, -1, -1, -1, -1, -1, 3546, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3466, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 4473, -1, -1, - -1, -1, 3487, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4961, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3512, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3633, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3546, -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, 2735, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2755, -1, 2757, -1, -1, 2760, 2761, -1, - 2763, -1, 2765, -1, -1, -1, 2769, 4603, -1, 2772, - -1, -1, -1, -1, 2777, -1, -1, -1, -1, -1, - 2783, -1, -1, -1, 3733, 2788, -1, -1, 3633, -1, - -1, -1, 2795, 2796, 2797, 2798, -1, -1, -1, 2802, - 2803, -1, 2805, -1, -1, -1, -1, -1, 3757, -1, - -1, -1, -1, -1, 2817, -1, 2819, -1, -1, -1, - -1, -1, -1, 2826, 2827, 2828, 2829, 2830, 2831, 2832, - 2833, 2834, 2835, -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, - 5165, -1, -1, -1, -1, -1, -1, -1, -1, 2872, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3733, -1, - -1, 4727, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3757, -1, -1, 4751, -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, 3890, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4791, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 2972, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3940, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4844, -1, - -1, -1, -1, 4849, 4850, -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, 3890, -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, -1, 3940, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4065, -1, -1, -1, - -1, -1, -1, -1, -1, 4961, 4075, -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, -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, 3220, 3221, -1, - 4065, -1, 3225, -1, -1, -1, -1, -1, -1, -1, - 4075, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4190, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 3258, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4229, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4250, -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, 5165, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4190, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4315, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4229, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4250, -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, -1, -1, -1, -1, -1, 3462, - -1, -1, -1, -1, -1, 3468, -1, -1, -1, -1, - 4315, -1, -1, -1, -1, -1, -1, -1, 4427, -1, - -1, 3484, 3485, -1, -1, 3488, 3489, 3490, 3491, -1, - -1, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, - 3503, 3504, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3526, 4473, -1, 3529, -1, 3531, -1, - -1, 3534, 3535, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 3549, 3550, 3551, 3552, - -1, 3554, -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, 4427, -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, 4473, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3642, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4603, -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, -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, -1, -1, -1, -1, -1, -1, -1, 4603, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4727, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4751, -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, 4791, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3861, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4727, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4844, -1, -1, -1, -1, - 4849, 4850, -1, -1, -1, -1, 4751, -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, 4791, -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, -1, -1, -1, -1, 4844, - -1, -1, -1, -1, 4849, 4850, -1, -1, -1, 4012, - -1, -1, 4961, 4016, 4017, 4018, -1, -1, -1, -1, - -1, 4024, 4025, 4026, 4027, -1, -1, -1, -1, 4032, - 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, - 4043, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4068, -1, -1, 4071, -1, - 4073, -1, -1, -1, 4077, -1, -1, 4080, 4081, -1, - -1, 4084, 4085, -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, 4961, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4131, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4144, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4157, -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, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 5165, -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, -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, -1, -1, -1, -1, -1, -1, -1, - 5165, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4343, -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, -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, 4422, - 4423, -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, - 4463, -1, -1, -1, -1, 4468, 4469, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4483, -1, 4485, -1, -1, -1, 4489, 4490, 4491, -1, - -1, 4494, -1, -1, 4497, 4498, -1, -1, -1, 4502, - -1, -1, -1, 4506, -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, -1, -1, -1, -1, -1, -1, 4561, -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, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4624, -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, 4662, - -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, -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, 4749, 4750, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4765, 4766, 4767, -1, -1, -1, -1, -1, - -1, -1, 4775, -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, 4802, - 4803, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4814, -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, - -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, -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, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4973, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4987, -1, -1, 4990, -1, -1, - -1, 4994, -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, - 5043, -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, -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, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 5159, -1, 5161, -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, 5192, - -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, -1, -1, - -1, -1, -1, -1, 5247, -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, - 5273, -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, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 5335, -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, 5369, 5370, -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, -1, 5420, 5421, -1, - -1, -1, 5425, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, - 9, 10, -1, -1, -1, -1, -1, -1, 5451, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, -1, -1, -1, -1, 34, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, 126, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, -1, 412, 413, 414, 415, 416, 417, 418, - -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, -1, -1, -1, -1, -1, -1, 466, 467, 468, - -1, -1, -1, -1, -1, -1, 475, 476, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, 34, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, -1, 412, 413, 414, - 415, 416, 417, 418, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, -1, 461, -1, -1, -1, - -1, 466, 467, -1, -1, -1, -1, -1, -1, -1, - 475, 476, 3, 4, 5, 6, 7, 8, 9, 10, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, 34, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - -1, 412, 413, 414, 415, 416, 417, 418, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 459, -1, - -1, -1, -1, -1, -1, 466, 467, -1, -1, -1, - -1, -1, -1, -1, 475, 476, 3, 4, 5, 6, - 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, 34, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, 221, 222, 223, 224, -1, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, -1, 412, 413, 414, 415, 416, - 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, -1, -1, -1, -1, -1, -1, 466, - 467, -1, -1, -1, -1, -1, -1, -1, 475, 476, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, 34, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, -1, 412, - 413, 414, 415, 416, 417, 418, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, -1, -1, 3, - -1, -1, -1, 466, 467, -1, -1, -1, -1, -1, - -1, -1, 475, 476, 18, 19, 20, 21, 22, 23, - 24, 25, -1, 27, 28, 29, -1, -1, -1, -1, - -1, 35, -1, 37, 38, -1, 40, 41, 42, -1, - 44, 45, 46, 47, 48, -1, 50, 51, -1, 53, - 54, 55, 56, 57, 58, -1, -1, 61, 62, 63, - 64, 65, -1, 67, 68, 69, 70, 71, -1, -1, - -1, 75, 76, 77, 78, 79, -1, 81, 82, 83, - -1, 85, 86, 87, 88, 89, 90, -1, 92, 93, - 94, 95, -1, -1, -1, -1, -1, -1, -1, 103, - 104, 105, 106, 107, 108, 109, 110, 111, -1, 113, - -1, 115, 116, 117, 118, 119, 120, -1, 122, 123, - 124, 125, -1, -1, 128, 129, 130, 131, 132, -1, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, 145, 146, 147, 148, 149, 150, -1, 152, -1, - 154, 155, 156, 157, -1, 159, -1, 161, -1, -1, - 164, 165, 166, 167, 168, -1, 170, 171, -1, 173, - 174, 175, -1, 177, 178, 179, 180, 181, -1, 183, - 184, 185, 186, -1, 188, 189, 190, 191, 192, 193, - 194, -1, 196, 197, 198, 199, 200, 201, 202, 203, - 204, -1, 206, -1, 208, -1, -1, 211, 212, 213, - 214, 215, 216, 217, -1, -1, 220, 221, 222, 223, - -1, -1, 226, 227, 228, -1, -1, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - -1, 255, 256, -1, 258, -1, 260, 261, 262, 263, - 264, 265, -1, 267, 268, -1, -1, 271, 272, 273, - -1, -1, 276, 277, 278, -1, 280, -1, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, -1, -1, - 294, 295, 296, 297, 298, 299, 300, 301, -1, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, -1, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, -1, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, -1, 351, 352, 353, - 354, 355, -1, 357, 358, 359, 360, 361, -1, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 377, 378, 379, 380, -1, 382, 383, - -1, 385, -1, 387, 388, 389, 390, 391, -1, 393, - 394, 395, -1, -1, 398, 399, 400, 401, 402, -1, - 404, 405, 406, 407, 408, 409, 410, -1, -1, 413, - 414, 415, 416, 417, -1, -1, 420, 421, 422, 423, - 424, 425, 426, -1, 428, -1, 430, 431, 432, 433, - -1, -1, 436, -1, -1, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, -1, -1, -1, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 476, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, -1, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, -1, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, -1, 147, 148, 149, -1, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, -1, -1, -1, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, -1, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, -1, -1, - 255, 256, 257, 258, -1, -1, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, -1, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, -1, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, -1, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, -1, 401, -1, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 456, 457, 458, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, 476, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, -1, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, -1, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, -1, 147, 148, 149, -1, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, -1, -1, - -1, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, -1, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - -1, -1, 255, 256, 257, 258, -1, -1, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, -1, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, -1, 297, -1, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, -1, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, -1, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, -1, 401, -1, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, -1, 3, 4, 5, 6, 7, 8, 9, - 10, -1, -1, 456, 457, 458, -1, -1, 18, 19, - 20, 21, 22, 23, 24, 25, -1, 27, 28, 29, - -1, -1, -1, 476, 34, -1, -1, 37, 38, -1, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, -1, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, -1, 67, 68, 69, - 70, 71, -1, 73, -1, 75, 76, 77, 78, 79, - 80, 81, 82, 83, -1, 85, 86, 87, 88, 89, - 90, -1, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, -1, 115, 116, 117, 118, 119, - 120, -1, 122, 123, 124, 125, -1, -1, 128, 129, - 130, 131, 132, -1, 134, 135, 136, -1, 138, 139, - 140, -1, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, -1, 154, 155, 156, 157, -1, 159, - -1, 161, 162, -1, 164, 165, 166, 167, 168, -1, - 170, 171, -1, 173, 174, 175, -1, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, -1, 188, 189, - 190, 191, 192, 193, 194, -1, 196, 197, 198, 199, - 200, 201, 202, 203, 204, -1, 206, -1, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, -1, -1, - 220, 221, 222, 223, 224, -1, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, -1, 267, 268, -1, - -1, 271, 272, 273, -1, -1, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, - 300, 301, -1, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, -1, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, -1, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, -1, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, -1, 382, 383, 384, 385, 386, 387, 388, 389, - 390, 391, -1, 393, 394, 395, -1, -1, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, -1, 412, 413, 414, 415, 416, 417, 418, -1, - 420, 421, 422, 423, 424, 425, 426, -1, 428, 429, - 430, 431, 432, 433, -1, -1, 436, -1, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - -1, 461, -1, -1, -1, -1, 466, 467, -1, -1, - -1, -1, -1, -1, -1, 475, 3, 4, 5, 6, - 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, 34, -1, -1, - 37, 38, -1, 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, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, 163, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, 219, 220, 221, 222, 223, 224, -1, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, -1, 412, 413, 414, 415, 416, - 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, -1, -1, -1, -1, -1, -1, 466, - 467, -1, -1, -1, -1, -1, -1, -1, 475, 3, - 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, - -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, - 24, 25, -1, 27, 28, 29, -1, -1, -1, -1, - 34, -1, -1, 37, 38, -1, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, -1, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, -1, 67, 68, 69, 70, 71, -1, 73, - -1, 75, 76, 77, 78, 79, 80, 81, 82, 83, - -1, 85, 86, 87, 88, 89, 90, -1, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - -1, 115, 116, 117, 118, 119, 120, -1, 122, 123, - 124, 125, -1, -1, 128, 129, 130, 131, 132, -1, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, -1, - 154, 155, 156, 157, -1, 159, -1, 161, 162, -1, - 164, 165, 166, 167, 168, -1, 170, 171, -1, 173, - 174, 175, -1, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, -1, 188, 189, 190, 191, 192, 193, - 194, -1, 196, 197, 198, 199, 200, 201, 202, 203, - 204, -1, 206, -1, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, -1, -1, 220, 221, 222, 223, - 224, -1, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, -1, 267, 268, -1, -1, 271, 272, 273, - -1, -1, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, -1, -1, - 294, 295, 296, 297, 298, 299, 300, 301, -1, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, -1, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, -1, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, -1, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 377, 378, 379, 380, -1, 382, 383, - -1, 385, 386, 387, 388, 389, 390, 391, -1, 393, - 394, 395, -1, -1, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, -1, 412, 413, - 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, - 424, 425, 426, -1, 428, 429, 430, 431, 432, 433, - -1, -1, 436, -1, -1, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, -1, -1, -1, -1, - -1, -1, 466, 467, -1, -1, -1, -1, -1, 473, - 474, 475, 3, 4, 5, 6, 7, 8, 9, 10, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, 34, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - -1, 412, 413, 414, 415, 416, 417, 418, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 459, -1, - -1, -1, -1, -1, -1, 466, 467, 468, -1, -1, - -1, -1, -1, -1, 475, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, -1, -1, -1, -1, 34, -1, -1, 37, - 38, -1, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, -1, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, -1, 67, - 68, 69, 70, 71, -1, 73, -1, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, - 88, 89, 90, -1, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, -1, 115, 116, 117, - 118, 119, 120, -1, 122, 123, 124, 125, -1, -1, - 128, 129, 130, 131, 132, -1, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, -1, 154, 155, 156, 157, - -1, 159, -1, 161, 162, -1, 164, 165, 166, 167, - 168, -1, 170, 171, -1, 173, 174, 175, -1, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, -1, - 188, 189, 190, 191, 192, 193, 194, -1, 196, 197, - 198, 199, 200, 201, 202, 203, 204, -1, 206, -1, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - -1, -1, 220, 221, 222, 223, 224, -1, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, -1, 267, - 268, -1, -1, 271, 272, 273, -1, -1, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, -1, -1, 294, 295, 296, 297, - 298, 299, 300, 301, -1, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - -1, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, -1, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, - 348, 349, -1, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, -1, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, -1, 382, 383, -1, 385, 386, 387, - 388, 389, 390, 391, -1, 393, 394, 395, -1, -1, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, -1, 412, 413, 414, 415, 416, 417, - 418, -1, 420, 421, 422, 423, 424, 425, 426, -1, - 428, 429, 430, 431, 432, 433, -1, -1, 436, -1, - -1, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, - 458, 459, -1, -1, -1, -1, -1, -1, 466, 467, - -1, -1, -1, -1, -1, -1, -1, 475, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, 34, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, -1, 412, 413, 414, - 415, 416, 417, 418, -1, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, -1, -1, -1, -1, -1, - -1, 466, 467, -1, -1, -1, -1, -1, -1, -1, - 475, 3, 4, 5, 6, 7, 8, 9, 10, -1, - -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, - 22, 23, 24, 25, -1, 27, 28, 29, -1, -1, - -1, -1, 34, -1, -1, 37, 38, -1, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - -1, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, -1, 67, 68, 69, 70, 71, - -1, 73, -1, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, 85, 86, 87, 88, 89, 90, -1, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, -1, 115, 116, 117, 118, 119, 120, -1, - 122, 123, 124, 125, -1, -1, 128, 129, 130, 131, - 132, -1, 134, 135, 136, -1, 138, 139, 140, -1, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, -1, 154, 155, 156, 157, -1, 159, -1, 161, - 162, 163, 164, 165, 166, 167, 168, -1, 170, 171, - -1, 173, 174, 175, -1, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, -1, 188, 189, 190, 191, - 192, 193, 194, -1, 196, 197, 198, 199, 200, 201, - 202, 203, 204, -1, 206, -1, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, -1, -1, 220, 221, - 222, 223, 224, -1, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, -1, 267, 268, -1, -1, 271, - 272, 273, -1, -1, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, - -1, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, -1, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, -1, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, 344, 345, 346, 347, 348, 349, -1, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, -1, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, -1, - 382, 383, -1, 385, 386, 387, 388, 389, 390, 391, - -1, 393, 394, 395, -1, -1, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, -1, - 412, 413, 414, 415, 416, 417, 418, -1, 420, 421, - 422, 423, 424, 425, 426, -1, 428, 429, 430, 431, - 432, 433, -1, -1, 436, -1, -1, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, -1, -1, - -1, -1, -1, -1, 466, 467, -1, -1, -1, -1, - -1, -1, -1, 475, 3, 4, 5, 6, 7, 8, - 9, 10, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, 34, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, -1, 412, 413, 414, 415, 416, 417, 418, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, -1, -1, -1, -1, -1, -1, 466, 467, -1, - -1, -1, -1, -1, -1, -1, 475, 3, 4, 5, - 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, - -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, - -1, 27, 28, 29, -1, -1, -1, -1, 34, -1, - -1, 37, 38, -1, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, -1, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - -1, 67, 68, 69, 70, 71, -1, 73, -1, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, -1, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, -1, 115, - 116, 117, 118, 119, 120, -1, 122, 123, 124, 125, - -1, -1, 128, 129, 130, 131, 132, -1, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, -1, 154, 155, - 156, 157, -1, 159, -1, 161, 162, -1, 164, 165, - 166, 167, 168, -1, 170, 171, -1, 173, 174, 175, - -1, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, -1, 188, 189, 190, 191, 192, 193, 194, -1, - 196, 197, 198, 199, 200, 201, 202, 203, 204, -1, - 206, -1, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, -1, -1, 220, 221, 222, 223, 224, -1, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, -1, -1, 271, 272, 273, -1, -1, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, -1, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, -1, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, -1, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, -1, 382, 383, -1, 385, - 386, 387, 388, 389, 390, 391, -1, 393, 394, 395, - -1, -1, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, -1, 412, 413, 414, 415, - 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, - 426, -1, 428, 429, 430, 431, 432, 433, -1, -1, - 436, -1, -1, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, 459, -1, -1, -1, -1, -1, -1, - 466, 467, -1, -1, -1, -1, -1, -1, -1, 475, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, 34, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, -1, 412, - 413, 414, 415, 416, 417, 418, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, -1, -1, -1, - -1, -1, -1, 466, 467, -1, -1, -1, -1, -1, - -1, -1, 475, 3, 4, 5, 6, 7, 8, 9, - 10, -1, -1, -1, -1, -1, -1, -1, 18, 19, - 20, 21, 22, 23, 24, 25, -1, 27, 28, 29, - -1, -1, -1, -1, 34, -1, -1, 37, 38, -1, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, -1, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, -1, 67, 68, 69, - 70, 71, -1, 73, -1, 75, 76, 77, 78, 79, - 80, 81, 82, 83, -1, 85, 86, 87, 88, 89, - 90, -1, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, -1, 115, 116, 117, 118, 119, - 120, -1, 122, 123, 124, 125, -1, -1, 128, 129, - 130, 131, 132, -1, 134, 135, 136, -1, 138, 139, - 140, -1, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, -1, 154, 155, 156, 157, -1, 159, - -1, 161, 162, -1, 164, 165, 166, 167, 168, -1, - 170, 171, -1, 173, 174, 175, -1, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, -1, 188, 189, - 190, 191, 192, 193, 194, -1, 196, 197, 198, 199, - 200, 201, 202, 203, 204, -1, 206, -1, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, -1, -1, - 220, 221, 222, 223, 224, -1, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, -1, 267, 268, -1, - -1, 271, 272, 273, -1, -1, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, - 300, 301, -1, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, -1, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, -1, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - -1, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, -1, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, -1, 382, 383, -1, 385, 386, 387, 388, 389, - 390, 391, -1, 393, 394, 395, -1, -1, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, -1, 412, 413, 414, 415, 416, 417, 418, -1, - 420, 421, 422, 423, 424, 425, 426, -1, 428, 429, - 430, 431, 432, 433, -1, -1, 436, -1, -1, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - -1, -1, -1, -1, -1, -1, 466, 467, -1, -1, - -1, -1, -1, -1, -1, 475, 3, 4, 5, 6, - 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, 34, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, 221, 222, 223, 224, -1, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, -1, 412, 413, 414, 415, 416, - 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 459, -1, -1, -1, -1, -1, -1, 466, - 467, -1, -1, -1, -1, -1, -1, -1, 475, 3, - 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, - -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, - 24, 25, -1, 27, 28, 29, -1, -1, -1, -1, - 34, -1, -1, 37, 38, -1, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, -1, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, -1, 67, 68, 69, 70, 71, -1, 73, - -1, 75, 76, 77, 78, 79, 80, 81, 82, 83, - -1, 85, 86, 87, 88, 89, 90, -1, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - -1, 115, 116, 117, 118, 119, 120, -1, 122, 123, - 124, 125, -1, -1, 128, 129, 130, 131, 132, -1, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, -1, - 154, 155, 156, 157, -1, 159, -1, 161, 162, -1, - 164, 165, 166, 167, 168, -1, 170, 171, -1, 173, - 174, 175, -1, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, -1, 188, 189, 190, 191, 192, 193, - 194, -1, 196, 197, 198, 199, 200, 201, 202, 203, - 204, -1, 206, -1, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, -1, -1, 220, 221, 222, 223, - 224, -1, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, -1, 267, 268, -1, -1, 271, 272, 273, - -1, -1, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, -1, -1, - 294, 295, 296, 297, 298, 299, 300, 301, -1, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, -1, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, -1, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, -1, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 377, 378, 379, 380, -1, 382, 383, - -1, 385, 386, 387, 388, 389, 390, 391, -1, 393, - 394, 395, -1, -1, 398, 399, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, -1, 412, 413, - 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, - 424, 425, 426, -1, 428, 429, 430, 431, 432, 433, - -1, -1, 436, -1, -1, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, -1, -1, -1, -1, - -1, -1, 466, 467, -1, -1, -1, -1, -1, -1, - -1, 475, 3, 4, 5, 6, 7, 8, 9, 10, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, 34, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - -1, 412, 413, 414, 415, 416, 417, 418, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 459, -1, - -1, -1, -1, -1, -1, 466, 467, -1, -1, -1, - -1, -1, -1, -1, 475, 3, 4, 5, 6, 7, - 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, - 18, 19, 20, 21, 22, 23, 24, 25, -1, 27, - 28, 29, -1, -1, -1, -1, 34, -1, -1, 37, - 38, -1, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, -1, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, -1, 67, - 68, 69, 70, 71, -1, 73, -1, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, - 88, 89, 90, -1, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, -1, 115, 116, 117, - 118, 119, 120, -1, 122, 123, 124, 125, -1, -1, - 128, 129, 130, 131, 132, -1, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, -1, 154, 155, 156, 157, - -1, 159, -1, 161, 162, -1, 164, 165, 166, 167, - 168, -1, 170, 171, -1, 173, 174, 175, -1, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, -1, - 188, 189, 190, 191, 192, 193, 194, -1, 196, 197, - 198, 199, 200, 201, 202, 203, 204, -1, 206, -1, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - -1, -1, 220, 221, 222, 223, 224, -1, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, -1, 267, - 268, -1, -1, 271, 272, 273, -1, -1, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, -1, -1, 294, 295, 296, 297, - 298, 299, 300, 301, -1, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - -1, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, -1, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, - 348, 349, -1, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, -1, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, -1, 382, 383, -1, 385, 386, 387, - 388, 389, 390, 391, -1, 393, 394, 395, -1, -1, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, -1, 412, 413, 414, 415, 416, 417, - 418, -1, 420, 421, 422, 423, 424, 425, 426, -1, - 428, 429, 430, 431, 432, 433, -1, -1, 436, -1, - -1, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, - 458, 459, -1, -1, -1, -1, -1, -1, 466, 467, - -1, -1, -1, -1, -1, -1, -1, 475, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, 34, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, -1, 412, 413, 414, - 415, 416, 417, 418, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, -1, -1, -1, -1, -1, - -1, 466, 467, -1, -1, -1, -1, -1, -1, -1, - 475, 3, 4, 5, 6, 7, 8, 9, 10, -1, - -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, - 22, 23, 24, 25, -1, 27, 28, 29, -1, -1, - -1, -1, 34, -1, -1, 37, 38, -1, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - -1, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, -1, 67, 68, 69, 70, 71, - -1, 73, -1, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, 85, 86, 87, 88, 89, 90, -1, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, -1, 115, 116, 117, 118, 119, 120, -1, - 122, 123, 124, 125, -1, -1, 128, 129, 130, 131, - 132, -1, 134, 135, 136, -1, 138, 139, 140, -1, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, -1, 154, 155, 156, 157, -1, 159, -1, 161, - 162, -1, 164, 165, 166, 167, 168, -1, 170, 171, - -1, 173, 174, 175, -1, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, -1, 188, 189, 190, 191, - 192, 193, 194, -1, 196, 197, 198, 199, 200, 201, - 202, 203, 204, -1, 206, -1, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, -1, -1, 220, 221, - 222, 223, 224, -1, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, -1, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, -1, 267, 268, -1, -1, 271, - 272, 273, -1, -1, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, - -1, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, -1, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, -1, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, 344, 345, 346, 347, 348, 349, -1, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, -1, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, -1, - 382, 383, -1, 385, 386, 387, 388, 389, 390, 391, - -1, 393, 394, 395, -1, -1, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, -1, - -1, 413, 414, 415, 416, 417, 418, -1, 420, 421, - 422, 423, 424, 425, 426, -1, 428, 429, 430, 431, - 432, 433, -1, -1, 436, -1, -1, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, -1, -1, -1, - -1, -1, -1, -1, 466, 467, -1, -1, -1, -1, - -1, -1, -1, 475, 3, 4, 5, 6, 7, 8, - 9, 10, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, 34, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, -1, 258, - 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, -1, 412, 413, 414, 415, 416, 417, 418, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, -1, -1, -1, -1, -1, -1, 466, 467, -1, - -1, -1, -1, -1, -1, -1, 475, 3, 4, 5, - 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, - -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, - -1, 27, 28, 29, -1, -1, -1, -1, 34, -1, - -1, 37, 38, -1, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, -1, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - -1, 67, 68, 69, 70, 71, -1, 73, -1, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, -1, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, -1, 113, -1, 115, - 116, 117, 118, 119, 120, -1, 122, 123, 124, 125, - -1, -1, 128, 129, 130, 131, 132, -1, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, -1, 154, 155, - 156, 157, -1, 159, -1, 161, 162, -1, 164, 165, - 166, 167, 168, -1, 170, 171, -1, 173, 174, 175, - -1, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, -1, 188, 189, 190, 191, 192, 193, 194, -1, - 196, 197, 198, 199, 200, 201, 202, 203, 204, -1, - 206, -1, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, -1, -1, 220, 221, 222, 223, 224, -1, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, -1, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, -1, -1, 271, 272, 273, -1, -1, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, -1, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, -1, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, -1, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, -1, 382, 383, -1, 385, - 386, 387, 388, 389, 390, 391, -1, 393, 394, 395, - -1, -1, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, -1, -1, 413, 414, 415, - 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, - 426, -1, 428, 429, 430, 431, 432, 433, -1, -1, - 436, -1, -1, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, -1, -1, -1, -1, -1, -1, -1, - 466, 467, -1, -1, 3, 4, 5, 6, 7, 475, - 9, 10, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, 34, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, 418, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - -1, -1, -1, -1, -1, -1, -1, 466, 467, -1, - -1, -1, -1, -1, -1, -1, 475, 3, 4, 5, - 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, - -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, - -1, 27, 28, 29, -1, -1, -1, -1, 34, -1, - -1, 37, 38, -1, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, -1, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - -1, 67, 68, 69, 70, 71, -1, 73, -1, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, -1, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, -1, 113, -1, 115, - 116, 117, 118, 119, 120, -1, 122, 123, 124, 125, - -1, -1, 128, 129, 130, 131, 132, -1, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, -1, 154, 155, - 156, 157, -1, 159, -1, 161, 162, -1, 164, 165, - 166, 167, 168, -1, 170, 171, -1, 173, 174, 175, - -1, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, -1, 188, 189, 190, 191, 192, 193, 194, -1, - 196, 197, 198, 199, 200, 201, 202, 203, 204, -1, - 206, -1, 208, -1, 210, 211, 212, 213, 214, 215, - 216, 217, -1, -1, 220, 221, 222, 223, 224, -1, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, -1, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, -1, -1, 271, 272, 273, -1, -1, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, -1, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, -1, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, -1, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, -1, 382, 383, -1, 385, - 386, 387, 388, 389, 390, 391, -1, 393, 394, 395, - -1, -1, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, -1, -1, 413, 414, 415, - 416, 417, 418, -1, 420, 421, 422, 423, 424, 425, - 426, -1, 428, 429, 430, 431, 432, 433, -1, -1, - 436, -1, -1, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, -1, -1, -1, -1, -1, -1, -1, - 466, 467, -1, -1, 3, 4, 5, 6, 7, 475, - 9, 10, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, 34, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, 418, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - -1, -1, 3, 4, 5, 6, 7, -1, 9, 10, - -1, -1, -1, -1, -1, -1, 475, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, 34, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, -1, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, 418, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, -1, -1, - 3, 4, 5, 6, 7, -1, 9, 10, -1, -1, - -1, -1, -1, -1, 475, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, 34, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, 418, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, -1, -1, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, - -1, -1, 475, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, 34, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, -1, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, -1, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, -1, - -1, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, -1, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, -1, 412, 413, 414, - 415, 416, 417, 418, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, -1, -1, 3, -1, -1, -1, - -1, 466, 467, -1, -1, -1, -1, -1, -1, -1, - 475, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, 60, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, -1, 220, 221, 222, 223, 224, -1, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, -1, 255, 256, - 257, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, 270, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, 438, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, -1, -1, 461, 3, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 475, -1, - 18, 19, 20, 21, 22, 23, 24, 25, -1, 27, - 28, 29, -1, -1, -1, -1, -1, -1, -1, 37, - 38, -1, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, -1, 53, 54, 55, 56, 57, - 58, -1, 60, 61, 62, 63, 64, 65, -1, 67, - 68, 69, 70, 71, -1, 73, -1, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, - 88, 89, 90, -1, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, -1, 113, -1, 115, 116, 117, - 118, 119, 120, -1, 122, 123, 124, 125, -1, -1, - 128, 129, 130, 131, 132, -1, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, 145, 146, 147, - 148, 149, 150, -1, 152, -1, 154, 155, 156, 157, - -1, 159, -1, 161, 162, -1, 164, 165, 166, 167, - 168, -1, 170, 171, -1, 173, 174, 175, -1, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, -1, - 188, 189, 190, 191, 192, 193, 194, -1, 196, 197, - 198, 199, 200, 201, 202, 203, 204, -1, 206, -1, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, -1, 220, 221, 222, 223, 224, -1, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, -1, 255, 256, 257, - 258, -1, 260, 261, 262, 263, 264, 265, -1, 267, - 268, -1, 270, 271, 272, 273, -1, -1, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, -1, -1, 294, 295, 296, 297, - 298, 299, 300, 301, -1, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - -1, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, -1, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, - 348, 349, -1, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, -1, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, -1, 382, 383, -1, 385, 386, 387, - 388, 389, 390, 391, -1, 393, 394, 395, -1, -1, - 398, 399, 400, 401, 402, -1, 404, 405, 406, 407, - 408, 409, 410, -1, -1, 413, 414, 415, 416, 417, - 418, -1, 420, 421, 422, 423, 424, 425, 426, -1, - 428, 429, 430, 431, 432, 433, -1, -1, 436, -1, - -1, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, - 458, -1, -1, 3, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 475, 18, 19, - 20, 21, 22, 23, 24, 25, -1, 27, 28, 29, - -1, -1, -1, -1, -1, -1, -1, 37, 38, -1, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, -1, 53, 54, 55, 56, 57, 58, -1, - 60, 61, 62, 63, 64, 65, -1, 67, 68, 69, - 70, 71, -1, 73, -1, 75, 76, 77, 78, 79, - 80, 81, 82, 83, -1, 85, 86, 87, 88, 89, - 90, -1, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, -1, 113, -1, 115, 116, 117, 118, 119, - 120, -1, 122, 123, 124, 125, -1, -1, 128, 129, - 130, 131, 132, -1, 134, 135, 136, -1, 138, 139, - 140, -1, 142, 143, 144, 145, 146, 147, 148, 149, - 150, -1, 152, -1, 154, 155, 156, 157, -1, 159, - -1, 161, 162, -1, 164, 165, 166, 167, 168, -1, - 170, 171, -1, 173, 174, 175, -1, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, -1, 188, 189, - 190, 191, 192, 193, 194, -1, 196, 197, 198, 199, - 200, 201, 202, 203, 204, -1, 206, -1, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, -1, -1, - 220, 221, 222, 223, 224, -1, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, -1, 255, 256, 257, 258, -1, - 260, 261, 262, 263, 264, 265, -1, 267, 268, -1, - -1, 271, 272, 273, -1, -1, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, - 300, 301, -1, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, -1, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, -1, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - -1, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, -1, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, -1, 382, 383, -1, 385, 386, 387, 388, 389, - 390, 391, -1, 393, 394, 395, -1, -1, 398, 399, - 400, 401, 402, -1, 404, 405, 406, 407, 408, 409, - 410, -1, -1, 413, 414, 415, 416, 417, 418, -1, - 420, 421, 422, 423, 424, 425, 426, -1, 428, 429, - 430, 431, 432, 433, -1, -1, 436, -1, -1, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, -1, - -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 475, 18, 19, 20, 21, - 22, 23, 24, 25, -1, 27, 28, 29, -1, -1, - -1, -1, -1, -1, -1, 37, 38, -1, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - -1, 53, 54, 55, 56, 57, 58, -1, 60, 61, - 62, 63, 64, 65, -1, 67, 68, 69, 70, 71, - -1, 73, -1, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, 85, 86, 87, 88, 89, 90, -1, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - -1, 113, -1, 115, 116, 117, 118, 119, 120, -1, - 122, 123, 124, 125, -1, -1, 128, 129, 130, 131, - 132, -1, 134, 135, 136, -1, 138, 139, 140, -1, - 142, 143, 144, 145, 146, 147, 148, 149, 150, -1, - 152, -1, 154, 155, 156, 157, -1, 159, -1, 161, - 162, -1, 164, 165, 166, 167, 168, -1, 170, 171, - -1, 173, 174, 175, -1, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, -1, 188, 189, 190, 191, - 192, 193, 194, -1, 196, 197, 198, 199, 200, 201, - 202, 203, 204, -1, 206, -1, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, -1, -1, 220, 221, - 222, 223, 224, -1, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, -1, 255, 256, 257, 258, -1, 260, 261, - 262, 263, 264, 265, -1, 267, 268, -1, -1, 271, - 272, 273, -1, -1, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, - -1, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, -1, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, -1, - 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 343, 344, 345, 346, 347, 348, 349, -1, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, -1, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, -1, - 382, 383, -1, 385, 386, 387, 388, 389, 390, 391, - -1, 393, 394, 395, -1, -1, 398, 399, 400, 401, - 402, -1, 404, 405, 406, 407, 408, 409, 410, -1, - -1, 413, 414, 415, 416, 417, 418, -1, 420, 421, - 422, 423, 424, 425, 426, -1, 428, 429, 430, 431, - 432, 433, -1, -1, 436, -1, -1, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, -1, -1, 3, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 475, 18, 19, 20, 21, 22, 23, - 24, 25, -1, 27, 28, 29, -1, -1, -1, -1, - -1, -1, -1, 37, 38, -1, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, -1, 53, - 54, 55, 56, 57, 58, -1, 60, 61, 62, 63, - 64, 65, -1, 67, 68, 69, 70, 71, -1, 73, - -1, 75, 76, 77, 78, 79, 80, 81, 82, 83, - -1, 85, 86, 87, 88, 89, 90, -1, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, -1, 113, - -1, 115, 116, 117, 118, 119, 120, -1, 122, 123, - 124, 125, -1, -1, 128, 129, 130, 131, 132, -1, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, 145, 146, 147, 148, 149, 150, -1, 152, -1, - 154, 155, 156, 157, -1, 159, -1, 161, 162, -1, - 164, 165, 166, 167, 168, -1, 170, 171, -1, 173, - 174, 175, -1, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, -1, 188, 189, 190, 191, 192, 193, - 194, -1, 196, 197, 198, 199, 200, 201, 202, 203, - 204, -1, 206, -1, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, -1, -1, 220, 221, 222, 223, - 224, -1, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - -1, 255, 256, 257, 258, -1, 260, 261, 262, 263, - 264, 265, -1, 267, 268, -1, -1, 271, 272, 273, - -1, -1, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, -1, -1, - 294, 295, 296, 297, 298, 299, 300, 301, -1, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, -1, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, -1, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, -1, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 377, 378, 379, 380, -1, 382, 383, - -1, 385, 386, 387, 388, 389, 390, 391, -1, 393, - 394, 395, -1, -1, 398, 399, 400, 401, 402, -1, - 404, 405, 406, 407, 408, 409, 410, -1, -1, 413, - 414, 415, 416, 417, 418, -1, 420, 421, 422, 423, - 424, 425, 426, -1, 428, 429, 430, 431, 432, 433, - -1, -1, 436, -1, -1, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, -1, -1, 3, 4, 5, - -1, -1, -1, 9, -1, -1, -1, -1, -1, -1, - -1, 475, 18, 19, 20, 21, 22, 23, 24, 25, - -1, 27, 28, 29, -1, -1, -1, -1, -1, -1, - -1, 37, 38, -1, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, -1, 53, 54, 55, - 56, 57, 58, -1, -1, 61, 62, 63, 64, 65, - -1, 67, 68, 69, 70, 71, -1, 73, -1, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, -1, 92, 93, 94, 95, - -1, -1, -1, 99, -1, -1, -1, 103, 104, 105, - 106, 107, 108, 109, 110, 111, -1, 113, -1, 115, - 116, 117, 118, 119, 120, -1, 122, 123, 124, 125, - -1, -1, 128, 129, 130, 131, 132, -1, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, -1, 154, 155, - 156, 157, -1, 159, -1, 161, 162, -1, 164, 165, - 166, 167, 168, -1, 170, 171, -1, 173, 174, 175, - -1, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, -1, 188, 189, 190, 191, 192, 193, 194, -1, - 196, 197, 198, 199, 200, 201, 202, 203, 204, -1, - 206, -1, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, -1, -1, 220, 221, 222, 223, 224, -1, - 226, 227, 228, -1, -1, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, -1, 255, - 256, 257, 258, -1, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, -1, 271, 272, 273, -1, -1, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, -1, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, -1, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, -1, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - -1, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, -1, 382, 383, -1, 385, - 386, 387, 388, 389, 390, 391, -1, 393, 394, 395, - -1, -1, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, -1, -1, 413, 414, 415, - 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, - 426, -1, 428, 429, 430, 431, 432, 433, -1, -1, - 436, -1, -1, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, -1, -1, 3, -1, -1, -1, -1, - 466, 467, 468, -1, -1, -1, -1, -1, -1, 475, - 18, 19, 20, 21, 22, 23, 24, 25, -1, 27, - 28, 29, 30, 31, -1, -1, -1, -1, -1, 37, - 38, -1, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, -1, 53, 54, 55, 56, 57, - 58, -1, -1, 61, 62, 63, 64, 65, -1, 67, - 68, 69, 70, 71, -1, 73, -1, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, - 88, 89, 90, -1, 92, 93, 94, 95, -1, -1, - -1, 99, -1, -1, -1, 103, 104, 105, 106, 107, - 108, 109, 110, 111, -1, 113, -1, 115, 116, 117, - 118, 119, 120, -1, 122, 123, 124, 125, -1, -1, - 128, 129, 130, 131, 132, -1, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, 145, 146, 147, - 148, 149, 150, -1, 152, -1, 154, 155, 156, 157, - -1, 159, -1, 161, 162, -1, 164, 165, 166, 167, - 168, -1, 170, 171, -1, 173, 174, 175, -1, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, -1, - 188, 189, 190, 191, 192, 193, 194, -1, 196, 197, - 198, 199, 200, 201, 202, 203, 204, -1, 206, -1, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - -1, -1, 220, 221, 222, 223, 224, -1, 226, 227, - 228, -1, -1, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, -1, 255, 256, 257, - 258, -1, 260, 261, 262, 263, 264, 265, -1, 267, - 268, -1, -1, 271, 272, 273, -1, -1, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, -1, -1, 294, 295, 296, 297, - 298, 299, 300, 301, -1, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - -1, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, -1, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, -1, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, -1, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, -1, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, -1, 393, 394, 395, -1, -1, - 398, 399, 400, 401, 402, -1, 404, 405, 406, 407, - 408, 409, 410, -1, -1, 413, 414, 415, 416, 417, - -1, -1, 420, 421, 422, 423, 424, 425, 426, -1, - 428, 429, 430, 431, 432, 433, -1, -1, 436, -1, - 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, - 458, -1, -1, 461, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 475, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 475, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, -1, -1, - 461, 3, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 475, -1, 18, 19, 20, 21, - 22, 23, 24, 25, -1, 27, 28, 29, -1, -1, - -1, -1, -1, -1, -1, 37, 38, -1, 40, 41, - 42, -1, 44, 45, 46, 47, 48, -1, 50, 51, - -1, 53, 54, 55, 56, 57, 58, -1, -1, 61, - 62, 63, 64, 65, -1, 67, 68, 69, 70, 71, - -1, -1, -1, 75, 76, 77, 78, 79, -1, 81, - 82, 83, -1, 85, 86, 87, 88, 89, 90, -1, - -1, 93, 94, 95, -1, -1, -1, -1, -1, -1, - -1, 103, 104, 105, 106, 107, 108, 109, 110, 111, - -1, 113, -1, 115, 116, 117, 118, 119, 120, -1, - 122, 123, 124, 125, -1, -1, 128, 129, 130, 131, - 132, -1, 134, 135, 136, -1, 138, 139, 140, -1, - 142, 143, 144, 145, 146, 147, 148, 149, 150, -1, - 152, -1, 154, 155, 156, 157, -1, 159, -1, 161, - -1, -1, -1, 165, 166, 167, 168, -1, 170, 171, - -1, 173, 174, 175, -1, 177, 178, 179, 180, 181, - -1, 183, 184, 185, 186, -1, 188, 189, 190, 191, - 192, 193, 194, -1, 196, -1, 198, 199, 200, 201, - 202, 203, 204, -1, 206, -1, 208, -1, -1, 211, - -1, 213, 214, 215, 216, 217, -1, -1, 220, 221, - -1, 223, -1, -1, 226, 227, 228, -1, -1, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, -1, 249, 250, 251, - 252, 253, -1, 255, 256, -1, 258, -1, 260, 261, - 262, 263, 264, 265, -1, 267, 268, -1, -1, 271, - 272, 273, -1, -1, 276, 277, 278, -1, 280, -1, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, - -1, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, -1, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, -1, - 332, 333, -1, 335, 336, 337, 338, 339, 340, 341, - 342, 343, 344, 345, 346, 347, 348, 349, -1, 351, - 352, 353, 354, 355, -1, 357, 358, 359, 360, 361, - -1, 363, 364, 365, 366, -1, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, -1, - 382, 383, -1, 385, -1, 387, 388, 389, 390, 391, - -1, 393, 394, 395, -1, -1, 398, 399, 400, 401, - 402, -1, 404, 405, 406, 407, 408, 409, 410, -1, - -1, 413, 414, 415, 416, 417, -1, -1, 420, 421, - 422, 423, 424, 425, 426, -1, 428, -1, 430, 431, - 432, 433, -1, -1, 436, -1, -1, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, -1, -1, 3, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 475, 18, 19, 20, 21, 22, 23, - 24, 25, -1, 27, 28, 29, -1, -1, -1, -1, - -1, -1, -1, 37, 38, -1, 40, 41, 42, -1, - 44, 45, 46, 47, 48, -1, 50, 51, -1, 53, - 54, 55, 56, 57, 58, -1, -1, 61, 62, 63, - 64, 65, -1, 67, 68, 69, 70, 71, -1, -1, - -1, 75, 76, 77, 78, 79, -1, 81, 82, 83, - -1, 85, 86, 87, 88, 89, 90, -1, -1, 93, - 94, 95, -1, -1, -1, -1, -1, -1, -1, 103, - 104, 105, 106, 107, 108, 109, 110, 111, -1, 113, - -1, 115, 116, 117, 118, 119, 120, -1, 122, 123, - 124, 125, -1, -1, 128, 129, 130, 131, 132, -1, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, 145, 146, 147, 148, 149, 150, -1, 152, -1, - 154, 155, 156, 157, -1, 159, -1, 161, -1, -1, - -1, 165, 166, 167, 168, -1, 170, 171, -1, 173, - 174, 175, -1, 177, 178, 179, 180, 181, -1, 183, - 184, 185, 186, -1, 188, 189, 190, 191, 192, 193, - 194, -1, 196, -1, 198, 199, 200, 201, 202, 203, - 204, -1, 206, -1, 208, -1, -1, 211, -1, 213, - 214, 215, 216, 217, -1, -1, 220, 221, -1, 223, - -1, -1, 226, 227, 228, -1, -1, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, -1, 249, 250, 251, 252, 253, - -1, 255, 256, -1, 258, -1, 260, 261, 262, 263, - 264, 265, -1, 267, 268, -1, -1, 271, 272, 273, - -1, -1, 276, 277, 278, -1, 280, -1, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, -1, -1, - 294, 295, 296, 297, 298, 299, 300, 301, -1, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, -1, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, -1, 332, 333, - -1, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, -1, 351, 352, 353, - 354, 355, -1, 357, 358, 359, 360, 361, -1, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 377, 378, 379, 380, -1, 382, 383, - -1, 385, -1, 387, 388, 389, 390, 391, -1, 393, - 394, 395, -1, -1, 398, 399, 400, 401, 402, -1, - 404, 405, 406, 407, 408, 409, 410, -1, -1, 413, - 414, 415, 416, 417, -1, -1, 420, 421, 422, 423, - 424, 425, 426, -1, 428, -1, 430, 431, 432, 433, - -1, -1, 436, -1, -1, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, -1, -1, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 475, 18, 19, 20, 21, 22, 23, 24, 25, - -1, 27, 28, 29, -1, -1, -1, -1, -1, -1, - -1, 37, 38, -1, 40, 41, 42, -1, 44, 45, - 46, 47, 48, -1, 50, 51, -1, 53, 54, 55, - 56, 57, 58, -1, -1, 61, 62, 63, 64, 65, - -1, 67, 68, 69, 70, 71, -1, -1, -1, 75, - 76, 77, 78, 79, -1, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, -1, -1, 93, 94, 95, - -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, - 106, 107, 108, 109, 110, 111, -1, 113, -1, 115, - 116, 117, 118, 119, 120, -1, 122, 123, 124, 125, - -1, -1, 128, 129, 130, 131, 132, -1, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, 145, - 146, 147, 148, 149, 150, -1, 152, -1, 154, 155, - 156, 157, -1, 159, -1, 161, -1, -1, -1, 165, - 166, 167, 168, -1, 170, 171, -1, 173, 174, 175, - -1, 177, 178, 179, 180, 181, -1, 183, 184, 185, - 186, -1, 188, 189, 190, 191, 192, 193, 194, -1, - 196, -1, 198, 199, 200, 201, 202, 203, 204, -1, - 206, -1, 208, -1, -1, 211, -1, 213, 214, 215, - 216, 217, -1, -1, 220, 221, -1, 223, -1, -1, - 226, 227, 228, -1, -1, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, -1, 249, 250, 251, 252, 253, -1, 255, - 256, -1, 258, -1, 260, 261, 262, 263, 264, 265, - -1, 267, 268, -1, -1, 271, 272, 273, -1, -1, - 276, 277, 278, -1, 280, -1, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, -1, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, -1, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, -1, 332, 333, -1, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - -1, 357, 358, 359, 360, 361, -1, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, -1, 382, 383, -1, 385, - -1, 387, 388, 389, 390, 391, -1, 393, 394, 395, - -1, -1, 398, 399, 400, 401, 402, -1, 404, 405, - 406, 407, 408, 409, 410, -1, -1, 413, 414, 415, - 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, - 426, -1, 428, -1, 430, 431, 432, 433, -1, -1, - 436, -1, -1, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, -1, -1, 3, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 475, - 18, 19, 20, 21, 22, 23, 24, 25, -1, 27, - 28, 29, -1, -1, -1, -1, -1, -1, -1, 37, - 38, -1, 40, 41, 42, -1, 44, 45, 46, 47, - 48, -1, 50, 51, -1, 53, 54, 55, 56, 57, - 58, -1, -1, 61, 62, 63, 64, 65, -1, 67, - 68, 69, 70, 71, -1, -1, -1, 75, 76, 77, - 78, 79, -1, 81, 82, 83, -1, 85, 86, 87, - 88, 89, 90, -1, -1, 93, 94, 95, -1, -1, - -1, -1, -1, -1, -1, 103, 104, 105, 106, 107, - 108, 109, 110, 111, -1, 113, -1, 115, 116, 117, - 118, 119, 120, -1, 122, 123, 124, 125, -1, -1, - 128, 129, 130, 131, 132, -1, 134, 135, 136, -1, - 138, 139, 140, -1, 142, 143, 144, 145, 146, 147, - 148, 149, 150, -1, 152, -1, 154, 155, 156, 157, - -1, 159, -1, 161, -1, -1, -1, 165, 166, 167, - 168, -1, 170, 171, -1, 173, 174, 175, -1, 177, - 178, 179, 180, 181, -1, 183, 184, 185, 186, -1, - 188, 189, 190, 191, 192, 193, 194, -1, 196, -1, - 198, 199, 200, 201, 202, 203, 204, -1, 206, -1, - 208, -1, -1, 211, -1, 213, 214, 215, 216, 217, - -1, -1, 220, 221, -1, 223, -1, -1, 226, 227, - 228, -1, -1, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - -1, 249, 250, 251, 252, 253, -1, 255, 256, -1, - 258, -1, 260, 261, 262, 263, 264, 265, -1, 267, - 268, -1, -1, 271, 272, 273, -1, -1, 276, 277, - 278, -1, 280, -1, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, -1, -1, 294, 295, 296, 297, - 298, 299, 300, 301, -1, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - -1, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, -1, 332, 333, -1, 335, 336, 337, - 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, - 348, 349, -1, 351, 352, 353, 354, 355, -1, 357, - 358, 359, 360, 361, -1, 363, 364, 365, 366, -1, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, -1, 382, 383, -1, 385, -1, 387, - 388, 389, 390, 391, -1, 393, 394, 395, -1, -1, - 398, 399, 400, 401, 402, -1, 404, 405, 406, 407, - 408, 409, 410, -1, -1, 413, 414, 415, 416, 417, - -1, -1, 420, 421, 422, 423, 424, 425, 426, -1, - 428, -1, 430, 431, 432, 433, -1, -1, 436, -1, - -1, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, - 458, -1, -1, -1, -1, -1, 3, 4, 5, -1, - -1, 8, 9, -1, -1, -1, -1, 475, 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, - -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, -1, 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, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, -1, - 147, 148, 149, -1, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, -1, 172, -1, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, -1, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, -1, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, -1, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, -1, 279, 280, 281, -1, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, 293, 294, 295, -1, - 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, - 337, 338, 339, -1, 341, 342, 343, 344, 345, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, -1, 381, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, -1, 401, -1, 403, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, - 417, 418, 419, 420, 421, 422, 423, 424, -1, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 456, - 457, 458, -1, -1, -1, 462, 463, 464, -1, 466, - 467, 468, 469, 470, 471, 3, 4, 5, -1, -1, - 8, 9, -1, -1, -1, -1, -1, 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, -1, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, -1, 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, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, -1, 147, - 148, 149, -1, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, -1, 172, -1, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - -1, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, -1, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, -1, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - -1, 279, 280, 281, -1, 283, 284, 285, 286, 287, - 288, 289, 290, 291, -1, 293, 294, 295, -1, 297, - -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, - 338, 339, -1, 341, 342, 343, 344, 345, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, -1, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, - 398, 399, -1, 401, -1, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, 424, -1, 426, 427, - 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, - 438, 439, 440, 441, 442, 443, 444, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 456, 457, - 458, -1, 3, -1, 462, 463, 464, 8, 466, 467, - 468, 469, 470, 471, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, -1, 3, - -1, 462, 463, 464, 8, 466, 467, 468, 469, 470, - 471, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, -1, 27, 28, 29, -1, -1, -1, -1, - -1, -1, -1, 37, 38, -1, 40, 41, 42, -1, - 44, 45, 46, 47, 48, -1, 50, 51, -1, 53, - 54, 55, 56, 57, 58, -1, -1, 61, 62, 63, - 64, 65, -1, 67, 68, 69, 70, 71, -1, -1, - -1, 75, 76, 77, 78, 79, -1, 81, 82, 83, - -1, 85, 86, 87, 88, 89, 90, -1, -1, 93, - 94, 95, -1, -1, -1, -1, -1, -1, -1, 103, - 104, 105, 106, 107, 108, 109, 110, 111, -1, 113, - -1, 115, 116, 117, 118, 119, 120, -1, 122, 123, - 124, 125, -1, -1, 128, 129, 130, 131, 132, -1, - 134, 135, 136, -1, 138, 139, 140, -1, 142, 143, - 144, 145, 146, 147, 148, 149, 150, -1, 152, -1, - 154, 155, 156, 157, -1, 159, -1, 161, -1, -1, - -1, 165, 166, 167, 168, -1, 170, 171, -1, 173, - 174, 175, -1, 177, 178, 179, 180, 181, -1, 183, - 184, 185, 186, -1, 188, 189, 190, 191, 192, 193, - 194, -1, 196, -1, 198, 199, 200, 201, 202, 203, - 204, -1, 206, -1, 208, -1, -1, 211, -1, 213, - 214, 215, 216, 217, -1, -1, 220, 221, -1, 223, - -1, -1, 226, 227, 228, -1, -1, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, -1, 249, 250, 251, 252, 253, - -1, 255, 256, -1, 258, -1, 260, 261, 262, 263, - 264, 265, -1, 267, 268, -1, -1, 271, 272, 273, - -1, -1, 276, 277, 278, -1, 280, -1, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, -1, -1, - 294, 295, 296, 297, 298, 299, 300, 301, -1, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, -1, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, -1, 332, 333, - -1, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, -1, 351, 352, 353, - 354, 355, -1, 357, 358, 359, 360, 361, -1, 363, - 364, 365, 366, -1, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 377, 378, 379, 380, -1, 382, 383, - -1, 385, -1, 387, 388, 389, 390, 391, -1, 393, - 394, 395, -1, -1, 398, 399, 400, 401, 402, -1, - 404, 405, 406, 407, 408, 409, 410, -1, -1, 413, - 414, 415, 416, 417, -1, -1, 420, 421, 422, 423, - 424, 425, 426, -1, 428, -1, 430, 431, 432, 433, - -1, -1, 436, -1, -1, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, -1, 3, -1, 462, 463, - 464, 8, 466, 467, 468, 469, 470, 471, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, -1, 3, -1, 462, 463, 464, 8, 466, - 467, 468, 469, 470, 471, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, -1, 27, 28, 29, - -1, -1, -1, -1, -1, -1, -1, 37, 38, -1, - 40, 41, 42, -1, 44, 45, 46, 47, 48, -1, - 50, 51, -1, 53, 54, 55, 56, 57, 58, -1, - -1, 61, 62, 63, 64, 65, -1, 67, 68, 69, - 70, 71, -1, -1, -1, 75, 76, 77, 78, 79, - -1, 81, 82, 83, -1, 85, 86, 87, 88, 89, - 90, -1, -1, 93, 94, 95, -1, -1, -1, -1, - -1, -1, -1, 103, 104, 105, 106, 107, 108, 109, - 110, 111, -1, 113, -1, 115, 116, 117, 118, 119, - 120, -1, 122, 123, 124, 125, -1, -1, 128, 129, - 130, 131, 132, -1, 134, 135, 136, -1, 138, 139, - 140, -1, 142, 143, 144, 145, 146, 147, 148, 149, - 150, -1, 152, -1, 154, 155, 156, 157, -1, 159, - -1, 161, -1, -1, -1, 165, 166, 167, 168, -1, - 170, 171, -1, 173, 174, 175, -1, 177, 178, 179, - 180, 181, -1, 183, 184, 185, 186, -1, 188, 189, - 190, 191, 192, 193, 194, -1, 196, -1, 198, 199, - 200, 201, 202, 203, 204, -1, 206, -1, 208, -1, - -1, 211, -1, 213, 214, 215, 216, 217, -1, -1, - 220, 221, -1, 223, -1, -1, 226, 227, 228, -1, - -1, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, -1, 249, - 250, 251, 252, 253, -1, 255, 256, -1, 258, -1, - 260, 261, 262, 263, 264, 265, -1, 267, 268, -1, - -1, 271, 272, 273, -1, -1, 276, 277, 278, -1, - 280, -1, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, - 300, 301, -1, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, -1, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, -1, 332, 333, -1, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - -1, 351, 352, 353, 354, 355, -1, 357, 358, 359, - 360, 361, -1, 363, 364, 365, 366, -1, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, -1, 382, 383, -1, 385, -1, 387, 388, 389, - 390, 391, -1, 393, 394, 395, -1, -1, 398, 399, - 400, 401, 402, -1, 404, 405, 406, 407, 408, 409, - 410, -1, -1, 413, 414, 415, 416, 417, -1, -1, - 420, 421, 422, 423, 424, 425, 426, -1, 428, -1, - 430, 431, 432, 433, -1, -1, 436, -1, -1, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, -1, - 3, -1, 462, 463, 464, 8, 466, 467, 468, 469, - 470, 471, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, -1, 3, -1, 462, - 463, 464, 8, 466, 467, 468, 469, 470, 471, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - -1, 27, 28, 29, -1, -1, -1, -1, -1, -1, - -1, 37, 38, -1, 40, 41, 42, -1, 44, 45, - 46, 47, 48, -1, 50, 51, -1, 53, 54, 55, - 56, 57, 58, -1, -1, 61, 62, 63, 64, 65, - -1, 67, 68, 69, 70, 71, -1, -1, -1, 75, - 76, 77, 78, 79, -1, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, -1, -1, 93, 94, 95, - -1, -1, -1, -1, -1, -1, -1, 103, 104, 105, - 106, 107, 108, 109, 110, 111, -1, 113, -1, 115, - 116, 117, 118, 119, 120, -1, 122, 123, 124, 125, - -1, -1, 128, 129, 130, 131, 132, -1, 134, 135, - 136, -1, 138, 139, 140, -1, 142, 143, 144, 145, - 146, 147, 148, 149, 150, -1, 152, -1, 154, 155, - 156, 157, -1, 159, -1, 161, -1, -1, -1, 165, - 166, 167, 168, -1, 170, 171, -1, 173, 174, 175, - -1, 177, 178, 179, 180, 181, -1, 183, 184, 185, - 186, -1, 188, 189, 190, 191, 192, 193, 194, -1, - 196, -1, 198, 199, 200, 201, 202, 203, 204, -1, - 206, -1, 208, -1, -1, 211, -1, 213, 214, 215, - 216, 217, -1, -1, 220, 221, -1, 223, -1, -1, - 226, 227, 228, -1, -1, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, -1, 249, 250, 251, 252, 253, -1, 255, - 256, -1, 258, -1, 260, 261, 262, 263, 264, 265, - -1, 267, 268, -1, -1, 271, 272, 273, -1, -1, - 276, 277, 278, -1, 280, -1, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, -1, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, -1, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, -1, 332, 333, -1, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - -1, 357, 358, 359, 360, 361, -1, 363, 364, 365, - 366, -1, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, -1, 382, 383, -1, 385, - -1, 387, 388, 389, 390, 391, -1, 393, 394, 395, - -1, -1, 398, 399, 400, 401, 402, -1, 404, 405, - 406, 407, 408, 409, 410, -1, -1, 413, 414, 415, - 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, - 426, -1, 428, -1, 430, 431, 432, 433, -1, -1, - 436, -1, -1, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, -1, 3, -1, 462, 463, 464, 8, - 466, 467, 468, 469, 470, 471, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, 462, 463, 464, -1, 466, 467, 468, - 469, 470, 471, -1, -1, 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, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, 468, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, 468, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, 468, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, -1, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, -1, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, -1, 147, 148, 149, -1, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, -1, -1, -1, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, -1, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, -1, -1, - 255, 256, 257, 258, -1, -1, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - 275, 276, 277, 278, 279, 280, 281, -1, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, -1, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, -1, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, -1, 401, -1, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 456, 457, 458, -1, 18, 19, 20, 21, 22, - 23, 24, 25, 468, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, -1, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, -1, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, -1, 147, 148, 149, -1, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, -1, -1, - -1, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, -1, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - -1, -1, 255, 256, 257, 258, -1, -1, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, 275, 276, 277, 278, 279, 280, 281, -1, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, -1, 297, -1, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, -1, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, -1, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, -1, 401, -1, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 3, 4, 5, -1, -1, -1, 9, -1, - -1, -1, -1, 456, 457, 458, -1, 18, 19, 20, - 21, 22, 23, 24, 25, 468, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, -1, -1, -1, 99, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, -1, 255, 256, 257, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, 269, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, 4, - 5, -1, -1, -1, 9, 466, 467, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, -1, - 255, 256, 257, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, 269, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, 4, 5, -1, -1, -1, - 9, 466, 467, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - 269, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, 5, -1, -1, -1, 9, 466, 467, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, 269, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, 9, 466, 467, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, 163, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, 4, 5, -1, -1, -1, 9, 466, - 467, -1, -1, -1, -1, -1, -1, 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, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, - 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 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, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, - 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, 60, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, 418, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, 5, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, -1, - -1, -1, 99, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, 221, 222, 223, 224, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, -1, 255, 256, - 257, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, 269, -1, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, -1, -1, -1, 99, -1, - -1, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, -1, 255, 256, 257, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, -1, - 255, 256, 257, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, 418, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, 172, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, -1, - -1, -1, 99, -1, -1, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, 221, 222, 223, 224, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, -1, 255, 256, - 257, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, -1, -1, -1, 99, -1, - -1, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, -1, 255, 256, 257, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, -1, - 255, 256, 257, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, 5, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, -1, - -1, -1, 99, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, 221, 222, 223, 224, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, -1, 255, 256, - 257, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, 30, - 31, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, -1, -1, -1, 99, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, -1, 255, 256, 257, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, -1, - 255, 256, 257, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, 5, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, -1, - -1, -1, 99, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, 221, 222, 223, 224, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, -1, 255, 256, - 257, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, -1, -1, -1, 99, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - 221, 222, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, -1, 255, 256, 257, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, 221, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, -1, - 255, 256, 257, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, 221, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, -1, 255, 256, 257, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, 221, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, -1, -1, 74, 75, 76, - 77, 78, 79, -1, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, 160, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, 412, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, 160, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, 412, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, 91, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, 169, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, 91, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - 169, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, 160, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, 412, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, 91, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, 350, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, 160, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, 91, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, 270, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, 418, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, 418, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, 270, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, 270, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, 384, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, 5, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, 9, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - 35, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, 35, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, 35, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, -1, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, -1, 44, - 45, 46, 47, 48, -1, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, 71, -1, -1, -1, - 75, 76, 77, 78, 79, -1, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, -1, 93, 94, - 95, -1, -1, -1, -1, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, 146, 147, 148, 149, 150, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, -1, -1, -1, - 165, 166, 167, 168, -1, 170, 171, -1, 173, 174, - 175, -1, 177, 178, 179, 180, 181, -1, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, -1, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, -1, -1, 211, -1, 213, 214, - 215, 216, 217, -1, -1, 220, 221, -1, 223, -1, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, -1, 249, 250, 251, 252, 253, -1, - 255, 256, -1, 258, -1, 260, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, -1, 280, -1, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, -1, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, -1, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, -1, - 385, -1, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, 400, 401, 402, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - 425, 426, -1, 428, -1, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, -1, 44, 45, 46, 47, 48, - -1, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, 71, -1, -1, -1, 75, 76, 77, 78, - 79, -1, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, -1, 93, 94, 95, -1, -1, -1, - -1, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, 146, 147, 148, - 149, 150, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, -1, -1, -1, 165, 166, 167, 168, - -1, 170, 171, -1, 173, 174, 175, -1, 177, 178, - 179, 180, 181, -1, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, -1, 198, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - -1, -1, 211, -1, 213, 214, 215, 216, 217, -1, - -1, 220, 221, -1, 223, -1, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, -1, - 249, 250, 251, 252, 253, -1, 255, 256, -1, 258, - -1, 260, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, 278, - -1, 280, -1, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, -1, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, -1, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, -1, 382, 383, -1, 385, -1, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, 425, 426, -1, 428, - -1, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, 174, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - 47, 48, -1, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, 71, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, 146, - 147, 148, 149, 150, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, 171, -1, 173, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, 198, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, 221, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, -1, 249, 250, 251, 252, 253, -1, 255, 256, - -1, 258, -1, 260, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, 278, -1, 280, -1, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, -1, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, -1, 44, 45, 46, 47, 48, -1, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - 71, -1, -1, -1, 75, 76, 77, 78, 79, -1, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, 146, 147, 148, 149, 150, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, -1, -1, -1, 165, 166, 167, 168, -1, 170, - 171, -1, 173, 174, 175, -1, 177, 178, 179, 180, - 181, -1, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, -1, 198, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, -1, -1, - 211, -1, 213, 214, 215, 216, 217, -1, -1, 220, - 221, -1, 223, -1, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, -1, 249, 250, - 251, 252, 253, -1, 255, 256, -1, 258, -1, 260, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, 278, -1, 280, - -1, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, -1, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, -1, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - -1, 382, 383, -1, 385, -1, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, 425, 426, -1, 428, -1, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, -1, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, -1, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, -1, 147, 148, 149, -1, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, -1, -1, -1, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, 198, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, -1, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, -1, -1, - 255, 256, 257, 258, -1, -1, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, 278, 279, 280, 281, -1, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, -1, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, -1, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, -1, 401, -1, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 456, 457, 458, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - -1, 44, 45, 46, 47, 48, -1, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, 71, -1, - -1, -1, 75, 76, 77, 78, 79, -1, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, -1, - 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, 146, 147, 148, 149, 150, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, -1, - -1, -1, 165, 166, 167, 168, -1, 170, 171, -1, - 173, -1, 175, -1, 177, 178, 179, 180, 181, -1, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, -1, 198, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, -1, -1, 211, -1, - 213, 214, 215, 216, 217, -1, -1, 220, 221, -1, - 223, -1, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, -1, 249, 250, 251, 252, - 253, -1, 255, 256, -1, 258, -1, 260, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, 278, -1, 280, -1, 282, - 283, 284, 285, 286, 287, 288, -1, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, -1, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, -1, 335, 336, 337, 338, 339, 340, -1, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, -1, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, -1, 382, - 383, -1, 385, -1, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, 425, 426, -1, 428, -1, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - -1, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, -1, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, -1, - -1, -1, 99, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, -1, - 147, 148, 149, -1, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, -1, -1, -1, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, -1, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, -1, 222, 223, 224, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, -1, -1, 255, 256, - 257, 258, 259, -1, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, -1, 279, 280, 281, -1, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, -1, - 297, -1, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, -1, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, -1, -1, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, -1, 401, -1, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 456, - 457, 458, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, -1, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, -1, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, -1, 147, 148, 149, -1, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, -1, -1, -1, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, -1, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, -1, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, -1, - 255, 256, 257, 258, -1, -1, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, -1, 279, 280, 281, -1, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, -1, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, -1, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, -1, 401, -1, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - -1, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 456, 457, 458, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, -1, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, -1, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, -1, 147, 148, 149, -1, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, -1, -1, - -1, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, -1, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, -1, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, -1, 255, 256, 257, 258, -1, -1, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, -1, 279, 280, 281, -1, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, -1, 297, -1, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, -1, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, -1, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, -1, 401, -1, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, -1, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 456, 457, 458, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, -1, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - -1, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, -1, -1, -1, 99, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, -1, 147, 148, 149, -1, - -1, 152, -1, 154, 155, 156, 157, 158, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - -1, -1, -1, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, -1, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - -1, 222, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, -1, -1, 255, 256, 257, 258, -1, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, -1, 279, 280, - 281, -1, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, -1, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, -1, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, -1, - 401, -1, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, -1, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 456, 457, 458, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, -1, 48, - 49, 50, 51, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, 63, 64, 65, -1, 67, 68, - 69, 70, -1, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, -1, 103, 104, 105, 106, 107, 108, - 109, 110, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, -1, 147, 148, - 149, -1, -1, 152, -1, 154, 155, 156, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, -1, -1, -1, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, -1, - 199, 200, 201, 202, 203, 204, -1, 206, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, -1, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, -1, -1, 255, 256, 257, 258, - -1, -1, 261, 262, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, -1, - 279, 280, 281, -1, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, -1, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, -1, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, 394, 395, -1, -1, 398, - 399, -1, 401, -1, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, -1, 426, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 456, 457, 458, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, 43, 44, 45, 46, - -1, 48, 49, 50, 51, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, 63, 64, 65, -1, - 67, 68, 69, 70, -1, -1, 73, -1, 75, 76, - 77, 78, 79, 80, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, 92, 93, 94, 95, -1, - -1, -1, 99, -1, -1, -1, 103, 104, 105, 106, - 107, 108, 109, 110, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, -1, - 147, 148, 149, -1, -1, 152, -1, 154, 155, 156, - 157, -1, 159, -1, 161, 162, -1, 164, 165, 166, - 167, 168, -1, 170, -1, -1, -1, 174, 175, -1, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - 197, -1, 199, 200, 201, 202, 203, 204, -1, 206, - -1, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, -1, -1, 220, -1, 222, 223, 224, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, -1, -1, 255, 256, - 257, 258, -1, -1, 261, 262, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, -1, 279, 280, 281, -1, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, -1, - 297, -1, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, 334, 335, 336, - 337, 338, 339, -1, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, -1, -1, 382, 383, -1, 385, 386, - 387, 388, 389, 390, 391, -1, 393, 394, 395, -1, - -1, 398, 399, -1, 401, -1, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, - -1, 428, 429, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 456, - 457, 458, -1, 18, 19, 20, 21, 22, 23, 24, - 25, -1, 27, 28, 29, -1, -1, -1, -1, -1, - -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, - 45, 46, -1, 48, 49, 50, 51, -1, 53, 54, - 55, 56, 57, 58, -1, -1, 61, 62, 63, 64, - 65, -1, 67, 68, 69, 70, -1, -1, 73, -1, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, 88, 89, 90, -1, 92, 93, 94, - 95, -1, -1, -1, 99, -1, -1, -1, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, 113, -1, - 115, 116, 117, 118, 119, 120, -1, 122, 123, 124, - 125, -1, -1, 128, 129, 130, 131, 132, -1, 134, - 135, 136, -1, 138, 139, 140, -1, 142, 143, 144, - 145, -1, 147, 148, 149, -1, -1, 152, -1, 154, - 155, 156, 157, -1, 159, -1, 161, 162, -1, 164, - 165, 166, 167, 168, -1, 170, -1, -1, -1, 174, - 175, -1, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, -1, 188, 189, 190, 191, 192, 193, 194, - -1, 196, 197, -1, 199, 200, 201, 202, 203, 204, - -1, 206, -1, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, -1, -1, 220, -1, 222, 223, 224, - -1, 226, 227, 228, -1, -1, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, -1, -1, - 255, 256, 257, 258, -1, -1, 261, 262, 263, 264, - 265, -1, 267, 268, -1, -1, 271, 272, 273, -1, - -1, 276, 277, -1, 279, 280, 281, -1, 283, 284, - 285, 286, 287, 288, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, -1, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, -1, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, -1, 332, 333, 334, - 335, 336, 337, 338, 339, -1, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, -1, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, -1, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, -1, -1, 382, 383, -1, - 385, 386, 387, 388, 389, 390, 391, -1, 393, 394, - 395, -1, -1, 398, 399, -1, 401, -1, -1, 404, - 405, 406, 407, 408, 409, 410, -1, -1, 413, 414, - 415, 416, 417, -1, -1, 420, 421, 422, 423, 424, - -1, 426, -1, 428, 429, 430, 431, 432, 433, -1, - -1, 436, -1, -1, 439, 440, 441, 442, 443, 444, - 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 456, 457, 458, -1, 18, 19, 20, 21, 22, - 23, 24, 25, -1, 27, 28, 29, -1, -1, -1, - -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, - 43, 44, 45, 46, -1, 48, 49, 50, 51, -1, - 53, 54, 55, 56, 57, 58, -1, -1, 61, 62, - 63, 64, 65, -1, 67, 68, 69, 70, -1, -1, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, -1, 85, 86, 87, 88, 89, 90, -1, 92, - 93, 94, 95, -1, -1, -1, 99, -1, -1, -1, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - 113, -1, 115, 116, 117, 118, 119, 120, -1, 122, - 123, 124, 125, -1, -1, 128, 129, 130, 131, 132, - -1, 134, 135, 136, -1, 138, 139, 140, -1, 142, - 143, 144, 145, -1, 147, 148, 149, -1, -1, 152, - -1, 154, 155, 156, 157, -1, 159, -1, 161, 162, - -1, 164, 165, 166, 167, 168, -1, 170, -1, -1, - -1, 174, 175, -1, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, -1, 188, 189, 190, 191, 192, - 193, 194, -1, 196, 197, -1, 199, 200, 201, 202, - 203, 204, -1, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, -1, -1, 220, -1, 222, - 223, 224, -1, 226, 227, 228, -1, -1, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - -1, -1, 255, 256, 257, 258, -1, -1, 261, 262, - 263, 264, 265, -1, 267, 268, -1, -1, 271, 272, - 273, -1, -1, 276, 277, -1, 279, 280, 281, -1, - 283, 284, 285, 286, 287, 288, 289, 290, 291, -1, - -1, 294, 295, -1, 297, -1, 299, 300, 301, -1, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, -1, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, -1, 332, - 333, 334, 335, 336, 337, 338, 339, -1, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, -1, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, -1, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, -1, -1, 382, - 383, -1, 385, 386, 387, 388, 389, 390, 391, -1, - 393, 394, 395, -1, -1, 398, 399, -1, 401, -1, - -1, 404, 405, 406, 407, 408, 409, 410, -1, -1, - 413, 414, 415, 416, 417, -1, -1, 420, 421, 422, - 423, 424, -1, 426, -1, 428, 429, 430, 431, 432, - 433, -1, -1, 436, -1, -1, 439, 440, 441, 442, - 443, 444, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 456, 457, 458, -1, 18, 19, 20, - 21, 22, 23, 24, 25, -1, 27, 28, 29, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, - 41, 42, 43, 44, 45, 46, -1, 48, 49, 50, - 51, -1, 53, 54, 55, 56, 57, 58, -1, -1, - 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, - -1, -1, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, - -1, 92, 93, 94, 95, -1, -1, -1, 99, -1, - -1, -1, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, 113, -1, 115, 116, 117, 118, 119, 120, - -1, 122, 123, 124, 125, -1, -1, 128, 129, 130, - 131, 132, -1, 134, 135, 136, -1, 138, 139, 140, - -1, 142, 143, 144, 145, -1, 147, 148, 149, -1, - -1, 152, -1, 154, 155, 156, 157, -1, 159, -1, - 161, 162, -1, 164, 165, 166, 167, 168, -1, 170, - -1, -1, -1, 174, 175, -1, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, -1, 188, 189, 190, - 191, 192, 193, 194, -1, 196, 197, -1, 199, 200, - 201, 202, 203, 204, -1, 206, -1, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, -1, -1, 220, - -1, 222, 223, 224, -1, 226, 227, 228, -1, -1, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, -1, -1, 255, 256, 257, 258, -1, -1, - 261, 262, 263, 264, 265, -1, 267, 268, -1, -1, - 271, 272, 273, -1, -1, 276, 277, -1, 279, 280, - 281, -1, 283, 284, 285, 286, 287, 288, 289, 290, - 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, - 301, -1, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, -1, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, - -1, 332, 333, 334, 335, 336, 337, 338, 339, -1, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, -1, 357, 358, -1, 360, - 361, 362, 363, 364, 365, 366, -1, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, -1, - -1, 382, 383, -1, 385, 386, 387, 388, 389, 390, - 391, -1, 393, 394, 395, -1, -1, 398, 399, -1, - 401, -1, -1, 404, 405, 406, 407, 408, 409, 410, - -1, -1, 413, 414, 415, 416, 417, -1, -1, 420, - 421, 422, 423, 424, -1, 426, -1, 428, 429, 430, - 431, 432, 433, -1, -1, 436, -1, -1, 439, 440, - 441, 442, 443, 444, 3, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 456, 457, 458, -1, 18, - 19, 20, 21, 22, 23, 24, 25, -1, 27, 28, - 29, -1, -1, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, 45, 46, -1, -1, - 49, -1, -1, -1, 53, 54, 55, 56, 57, 58, - -1, -1, 61, 62, -1, -1, 65, -1, 67, 68, - 69, 70, -1, -1, 73, -1, 75, 76, 77, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, - 89, 90, -1, 92, 93, 94, 95, -1, -1, -1, - 99, -1, -1, -1, 103, 104, 105, 106, 107, 108, - -1, -1, 111, -1, 113, -1, 115, 116, 117, 118, - 119, 120, -1, 122, 123, 124, 125, -1, -1, 128, - 129, 130, 131, 132, -1, 134, 135, 136, -1, 138, - 139, 140, -1, 142, 143, 144, 145, -1, 147, 148, - 149, -1, -1, 152, -1, 154, 155, -1, 157, -1, - 159, -1, 161, 162, -1, 164, 165, 166, 167, 168, - -1, 170, -1, -1, -1, 174, 175, -1, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, -1, 188, - 189, 190, 191, 192, 193, 194, -1, 196, 197, -1, - 199, 200, 201, 202, -1, -1, -1, -1, -1, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, -1, - -1, 220, -1, 222, 223, 224, -1, 226, 227, 228, - -1, -1, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, -1, 248, - -1, 250, 251, 252, -1, -1, 255, 256, 257, 258, - -1, -1, 261, -1, 263, 264, 265, -1, 267, 268, - -1, -1, 271, 272, 273, -1, -1, 276, 277, -1, - 279, 280, 281, -1, 283, 284, 285, 286, 287, 288, - 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, - 299, 300, 301, -1, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, -1, 314, 315, 316, 317, -1, - 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, - 329, 330, -1, 332, 333, 334, 335, 336, 337, 338, - 339, -1, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, -1, 357, 358, - -1, 360, 361, 362, 363, 364, -1, 366, -1, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, -1, -1, 382, 383, -1, 385, 386, 387, 388, - 389, 390, 391, -1, 393, -1, -1, -1, -1, 398, - 399, -1, 401, -1, -1, 404, 405, 406, 407, 408, - 409, 410, -1, -1, 413, 414, 415, 416, 417, -1, - -1, 420, 421, 422, 423, 424, -1, -1, -1, 428, - 429, 430, 431, 432, 433, -1, -1, 436, -1, -1, - 439, 440, 441, 442, 443, 444, 3, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 456, 457, 458, - -1, 18, 19, 20, 21, 22, 23, 24, 25, -1, - 27, 28, 29, -1, -1, -1, -1, -1, -1, -1, - 37, 38, -1, 40, 41, 42, -1, 44, 45, 46, - -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, - 57, 58, -1, -1, 61, 62, -1, -1, 65, -1, - 67, 68, 69, 70, -1, -1, -1, -1, 75, 76, - 77, 78, 79, -1, 81, 82, 83, -1, 85, 86, - 87, 88, 89, 90, -1, -1, 93, 94, 95, -1, - -1, -1, -1, -1, -1, -1, 103, 104, 105, 106, - 107, 108, -1, -1, 111, -1, 113, -1, 115, 116, - 117, 118, 119, 120, -1, 122, 123, 124, 125, -1, - -1, 128, 129, 130, 131, 132, -1, 134, 135, 136, - -1, 138, 139, 140, -1, 142, 143, 144, 145, -1, - 147, 148, 149, -1, -1, 152, -1, 154, 155, -1, - 157, -1, 159, -1, 161, -1, -1, -1, 165, 166, - 167, 168, -1, 170, -1, -1, -1, 174, 175, -1, - 177, 178, 179, 180, 181, -1, 183, 184, 185, 186, - -1, 188, 189, 190, 191, 192, 193, 194, -1, 196, - -1, -1, 199, 200, 201, 202, -1, -1, -1, -1, - -1, 208, -1, -1, 211, -1, 213, 214, 215, 216, - 217, -1, -1, 220, -1, -1, 223, -1, -1, 226, - 227, 228, -1, -1, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - -1, -1, -1, 250, 251, 252, -1, -1, 255, 256, - -1, 258, -1, -1, 261, -1, 263, 264, 265, -1, - 267, 268, -1, -1, 271, 272, 273, -1, -1, 276, - 277, -1, -1, 280, -1, -1, 283, 284, 285, 286, - 287, 288, 289, 290, 291, -1, -1, 294, 295, -1, - 297, -1, 299, 300, 301, -1, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, -1, 314, 315, 316, - 317, -1, 319, 320, 321, 322, 323, 324, 325, 326, - 327, 328, 329, 330, -1, 332, 333, -1, 335, 336, - 337, 338, 339, -1, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, -1, - 357, 358, -1, 360, 361, -1, 363, 364, -1, 366, - -1, 368, 369, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, -1, -1, 382, 383, -1, 385, -1, - 387, 388, 389, 390, 391, -1, 393, -1, -1, -1, - -1, 398, 399, -1, 401, -1, -1, 404, 405, 406, - 407, 408, 409, 410, -1, -1, 413, 414, 415, 416, - 417, -1, -1, 420, 421, 422, 423, 424, -1, -1, - -1, 428, -1, 430, 431, 432, 433, -1, -1, 436, - -1, -1, 439, 440, 441, 442, 443, 444, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 456, - 457, 458 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 18, 28, 30, 31, 46, 55, 67, 69, 70, - 76, 78, 89, 91, 108, 111, 125, 127, 131, 137, - 145, 147, 153, 169, 186, 226, 227, 232, 244, 256, - 292, 300, 314, 320, 321, 323, 328, 333, 336, 343, - 349, 350, 357, 361, 371, 384, 404, 414, 420, 425, - 438, 461, 475, 482, 483, 484, 485, 486, 492, 493, - 495, 496, 497, 498, 500, 504, 516, 521, 522, 525, - 526, 527, 550, 553, 554, 570, 614, 615, 618, 621, - 622, 623, 631, 637, 639, 641, 642, 645, 648, 649, - 653, 662, 666, 667, 668, 669, 672, 674, 675, 676, - 677, 685, 686, 705, 709, 711, 712, 713, 723, 725, - 732, 733, 736, 737, 738, 739, 740, 748, 750, 754, - 759, 763, 764, 772, 773, 776, 781, 794, 821, 824, - 825, 826, 831, 834, 836, 838, 840, 841, 846, 847, - 850, 851, 852, 856, 857, 860, 861, 864, 865, 866, - 873, 875, 876, 877, 882, 884, 885, 891, 892, 893, - 894, 895, 896, 897, 899, 900, 902, 903, 905, 908, - 911, 920, 926, 929, 931, 932, 941, 943, 948, 953, - 957, 958, 959, 960, 961, 962, 965, 1000, 398, 441, - 878, 25, 73, 88, 106, 112, 129, 140, 148, 160, - 165, 172, 191, 216, 237, 271, 295, 305, 306, 309, - 335, 338, 342, 344, 351, 354, 373, 379, 383, 384, - 387, 391, 401, 406, 418, 431, 638, 878, 3, 18, - 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, - 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, - 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, - 73, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, - 99, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 113, 115, 116, 117, 118, 119, 120, 122, 123, 124, - 125, 128, 129, 130, 131, 132, 134, 135, 136, 138, - 139, 140, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 152, 154, 155, 156, 157, 159, 161, 162, 164, - 165, 166, 167, 168, 170, 171, 173, 174, 175, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 188, - 189, 190, 191, 192, 193, 194, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 206, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 220, 221, 222, 223, - 224, 226, 227, 228, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 255, 256, 257, - 258, 260, 261, 262, 263, 264, 265, 267, 268, 271, - 272, 273, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 294, 295, - 296, 297, 298, 299, 300, 301, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - 317, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 328, 329, 330, 332, 333, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 351, 352, 353, 354, 355, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, 382, - 383, 385, 386, 387, 388, 389, 390, 391, 393, 394, - 395, 398, 399, 400, 401, 402, 404, 405, 406, 407, - 408, 409, 410, 413, 414, 415, 416, 417, 420, 421, - 422, 423, 424, 425, 426, 428, 429, 430, 431, 432, - 433, 436, 439, 440, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - 457, 458, 1059, 1132, 1140, 1141, 1144, 1145, 1146, 3, - 26, 954, 1126, 1140, 1144, 429, 913, 269, 301, 878, - 49, 475, 561, 20, 25, 37, 60, 73, 84, 106, - 112, 129, 140, 148, 160, 168, 172, 228, 271, 274, - 295, 309, 335, 344, 354, 373, 379, 387, 388, 390, - 391, 401, 406, 412, 415, 418, 571, 620, 728, 782, - 795, 26, 300, 1126, 954, 26, 294, 352, 388, 390, - 5, 215, 832, 833, 1135, 20, 25, 37, 60, 73, - 88, 106, 129, 140, 148, 160, 165, 172, 191, 237, - 271, 284, 295, 306, 309, 335, 338, 342, 344, 351, - 354, 373, 379, 384, 387, 391, 399, 401, 406, 418, - 431, 638, 741, 742, 743, 878, 1126, 91, 429, 475, - 615, 618, 621, 911, 921, 929, 932, 941, 948, 953, - 957, 9, 19, 26, 44, 155, 161, 163, 187, 217, - 251, 303, 322, 466, 467, 760, 761, 954, 1134, 1136, - 26, 91, 318, 350, 765, 766, 767, 1140, 160, 1140, - 1131, 1135, 384, 968, 760, 1140, 328, 357, 361, 398, - 1126, 284, 237, 106, 191, 344, 383, 384, 475, 842, - 843, 343, 1140, 26, 355, 394, 398, 508, 517, 518, - 1140, 23, 169, 765, 766, 301, 878, 1140, 214, 26, - 126, 970, 971, 61, 85, 228, 246, 335, 344, 355, - 394, 398, 444, 505, 506, 507, 508, 26, 355, 394, - 398, 508, 398, 270, 1011, 1124, 1140, 968, 468, 1140, - 164, 475, 914, 475, 316, 963, 964, 1126, 963, 958, - 959, 962, 0, 478, 475, 913, 141, 205, 275, 411, - 972, 973, 958, 960, 961, 117, 201, 417, 479, 811, - 1132, 745, 1140, 745, 1127, 1140, 304, 745, 401, 1126, - 105, 384, 799, 1132, 1140, 1146, 3, 102, 356, 1137, - 1138, 1142, 1144, 1145, 1146, 26, 181, 1124, 263, 431, - 8, 15, 16, 17, 68, 152, 462, 463, 464, 466, - 467, 468, 469, 470, 471, 828, 830, 1088, 1089, 1140, - 181, 1126, 799, 1126, 26, 1137, 1138, 799, 1126, 1126, - 181, 1124, 1126, 745, 1126, 328, 357, 26, 181, 1011, - 1126, 347, 1126, 745, 26, 235, 1137, 1138, 181, 1124, - 215, 114, 211, 254, 312, 879, 880, 881, 475, 473, - 477, 1115, 1117, 1124, 1130, 1140, 20, 25, 60, 73, - 74, 84, 88, 106, 129, 140, 148, 160, 165, 191, - 216, 237, 271, 295, 306, 309, 335, 338, 342, 344, - 351, 354, 373, 379, 384, 387, 391, 399, 401, 406, - 431, 638, 751, 752, 1135, 928, 932, 941, 948, 957, - 1124, 239, 1132, 1126, 475, 181, 745, 401, 1127, 745, - 401, 181, 1126, 105, 384, 388, 390, 1137, 1138, 388, - 390, 68, 152, 828, 326, 1126, 1126, 1137, 181, 501, - 1140, 181, 1126, 181, 745, 1126, 1126, 347, 1126, 745, - 235, 1137, 316, 351, 384, 431, 237, 88, 191, 165, - 306, 342, 399, 405, 632, 26, 1126, 955, 515, 1135, - 1142, 833, 239, 181, 811, 812, 1126, 181, 837, 181, - 1127, 3, 48, 50, 51, 63, 64, 109, 110, 130, - 156, 181, 203, 204, 206, 247, 249, 262, 313, 359, - 365, 394, 395, 426, 747, 1033, 1035, 1037, 1039, 1041, - 1043, 1044, 1045, 1047, 1048, 1049, 1051, 1052, 1141, 1144, - 401, 105, 384, 181, 798, 799, 181, 1138, 1139, 80, - 431, 68, 152, 181, 829, 830, 53, 181, 798, 181, - 1139, 181, 798, 181, 1126, 181, 1126, 347, 837, 181, - 747, 181, 235, 1139, 215, 181, 744, 745, 181, 1125, - 1126, 181, 1126, 475, 930, 571, 921, 425, 911, 922, - 923, 924, 1142, 913, 1136, 761, 762, 26, 762, 1136, - 762, 26, 762, 1136, 762, 762, 762, 1136, 1134, 1134, - 954, 762, 304, 475, 475, 591, 591, 591, 269, 396, - 479, 591, 344, 1011, 1012, 479, 874, 518, 506, 508, - 26, 508, 1135, 475, 927, 53, 431, 429, 844, 845, - 1124, 1126, 1140, 43, 458, 211, 477, 272, 272, 269, - 163, 1135, 396, 158, 755, 269, 4, 6, 7, 8, - 10, 34, 48, 50, 51, 59, 60, 63, 64, 71, - 73, 96, 97, 98, 99, 100, 101, 102, 109, 110, - 112, 146, 150, 151, 156, 171, 173, 203, 204, 206, - 221, 229, 230, 247, 249, 254, 259, 260, 262, 271, - 282, 296, 313, 340, 356, 365, 380, 394, 395, 400, - 402, 403, 412, 418, 426, 446, 447, 448, 449, 451, - 452, 453, 454, 459, 466, 467, 468, 475, 958, 1036, - 1039, 1042, 1043, 1044, 1046, 1047, 1048, 1051, 1052, 1056, - 1058, 1059, 1060, 1062, 1084, 1085, 1086, 1090, 1109, 1114, - 1121, 1122, 1132, 1133, 1134, 1135, 1140, 1120, 1121, 1135, - 26, 523, 1123, 1124, 355, 505, 112, 514, 1135, 515, - 1135, 43, 65, 505, 458, 366, 880, 272, 163, 396, - 464, 43, 458, 211, 881, 475, 1124, 468, 1117, 1012, - 3, 162, 164, 429, 906, 907, 911, 162, 915, 1056, - 1093, 963, 479, 475, 916, 476, 476, 484, 429, 909, - 910, 917, 918, 919, 1124, 26, 126, 969, 969, 53, - 969, 153, 158, 225, 266, 976, 978, 979, 994, 996, - 997, 998, 972, 973, 163, 207, 1011, 1013, 475, 285, - 324, 357, 475, 809, 285, 320, 324, 357, 477, 746, - 285, 324, 357, 3, 83, 135, 231, 285, 292, 324, - 357, 387, 389, 438, 516, 519, 886, 887, 888, 889, - 777, 22, 131, 285, 324, 357, 422, 532, 1126, 22, - 131, 357, 417, 499, 442, 181, 1011, 56, 90, 120, - 149, 184, 220, 254, 285, 286, 324, 332, 341, 349, - 357, 369, 377, 433, 516, 520, 814, 822, 475, 796, - 1117, 324, 499, 187, 146, 22, 28, 41, 70, 120, - 124, 131, 134, 159, 193, 252, 254, 264, 273, 285, - 324, 327, 328, 357, 422, 528, 530, 531, 656, 4, - 466, 467, 629, 1136, 26, 181, 1124, 745, 745, 475, - 827, 285, 357, 477, 146, 269, 120, 285, 324, 357, - 822, 22, 131, 285, 324, 357, 187, 494, 324, 438, - 461, 487, 494, 120, 285, 324, 357, 822, 269, 285, - 324, 146, 35, 54, 104, 190, 238, 241, 252, 284, - 324, 329, 351, 357, 371, 528, 626, 627, 285, 324, - 430, 656, 664, 285, 324, 357, 83, 124, 134, 285, - 320, 324, 357, 518, 506, 187, 146, 41, 122, 324, - 357, 528, 529, 285, 324, 328, 357, 81, 123, 287, - 389, 269, 22, 28, 131, 285, 324, 357, 551, 552, - 494, 158, 324, 487, 494, 146, 324, 357, 528, 1126, - 223, 114, 270, 443, 479, 879, 26, 126, 427, 468, - 476, 804, 1056, 1094, 1095, 1141, 1056, 1116, 3, 26, - 30, 31, 32, 33, 34, 35, 36, 39, 52, 59, - 60, 66, 72, 74, 84, 91, 96, 97, 98, 100, - 101, 102, 112, 114, 121, 126, 127, 133, 137, 141, - 151, 153, 158, 160, 163, 169, 172, 176, 187, 195, - 205, 207, 218, 219, 225, 229, 230, 254, 259, 266, - 269, 270, 274, 275, 293, 302, 318, 331, 350, 356, - 367, 381, 384, 392, 396, 397, 403, 411, 412, 418, - 419, 427, 434, 435, 437, 438, 468, 1129, 1143, 1144, - 1145, 1146, 1147, 1115, 419, 904, 269, 239, 811, 475, - 1126, 1033, 401, 105, 384, 799, 263, 431, 68, 152, - 830, 1126, 799, 799, 1126, 347, 158, 1126, 1033, 215, - 745, 1126, 476, 591, 1126, 475, 718, 809, 66, 1033, - 254, 163, 475, 714, 1126, 487, 35, 898, 1126, 254, - 487, 442, 181, 1124, 487, 745, 745, 714, 415, 571, - 269, 158, 858, 859, 487, 254, 43, 502, 254, 406, - 663, 254, 916, 83, 285, 640, 81, 123, 287, 389, - 24, 45, 202, 687, 35, 714, 158, 181, 487, 431, - 181, 1124, 181, 616, 1124, 1124, 431, 745, 80, 783, - 1132, 1132, 1126, 158, 638, 49, 103, 200, 252, 346, - 146, 57, 330, 479, 533, 533, 146, 475, 146, 428, - 1050, 1050, 1050, 475, 1038, 1038, 298, 475, 1040, 146, - 63, 64, 1050, 1038, 1035, 440, 461, 475, 1053, 475, - 1053, 479, 533, 34, 1034, 475, 107, 179, 240, 243, - 348, 456, 475, 1054, 1055, 746, 1038, 442, 146, 479, - 533, 146, 479, 181, 744, 181, 745, 181, 745, 146, - 479, 533, 1139, 146, 533, 146, 146, 533, 146, 533, - 146, 81, 123, 287, 389, 158, 146, 533, 146, 158, - 181, 181, 515, 146, 479, 533, 146, 479, 533, 146, - 269, 1093, 384, 476, 479, 151, 269, 403, 512, 515, - 629, 925, 921, 762, 954, 762, 954, 762, 954, 762, - 954, 762, 954, 954, 954, 762, 954, 475, 592, 593, - 1140, 592, 26, 106, 129, 160, 165, 215, 216, 306, - 338, 344, 351, 384, 387, 406, 768, 1123, 1139, 767, - 1126, 187, 479, 944, 1135, 1033, 1096, 35, 1139, 783, - 476, 479, 223, 1140, 158, 158, 768, 1139, 343, 1140, - 515, 269, 475, 1118, 473, 958, 1097, 1056, 1113, 475, - 475, 158, 475, 475, 958, 475, 475, 475, 475, 475, - 475, 1056, 475, 475, 475, 475, 475, 475, 475, 475, - 958, 475, 475, 475, 475, 475, 475, 475, 475, 1056, - 1056, 1056, 958, 1056, 1093, 1117, 1135, 475, 1135, 3, - 8, 11, 15, 16, 17, 32, 35, 40, 47, 72, - 182, 187, 209, 210, 224, 257, 271, 274, 362, 459, - 462, 463, 464, 466, 467, 468, 469, 470, 471, 1088, - 1090, 1092, 439, 1071, 281, 1056, 207, 479, 966, 475, - 1135, 1117, 966, 115, 183, 524, 479, 65, 112, 515, - 35, 3, 112, 228, 513, 629, 1052, 1135, 1135, 86, - 128, 1068, 95, 112, 509, 510, 512, 629, 112, 509, - 223, 1124, 87, 329, 749, 476, 479, 913, 476, 479, - 964, 1125, 35, 476, 479, 479, 916, 960, 960, 974, - 975, 1056, 960, 155, 251, 985, 213, 252, 312, 360, - 417, 26, 980, 1056, 466, 467, 981, 982, 1056, 1058, - 994, 995, 979, 978, 976, 977, 158, 997, 264, 999, - 976, 994, 1013, 933, 1124, 35, 1140, 357, 1093, 396, - 396, 344, 187, 198, 275, 278, 359, 427, 468, 802, - 803, 804, 806, 808, 810, 1033, 1141, 396, 430, 396, - 344, 1129, 477, 396, 396, 344, 225, 396, 396, 387, - 505, 285, 886, 888, 464, 890, 158, 169, 187, 333, - 778, 779, 66, 84, 142, 160, 302, 412, 588, 589, - 84, 112, 254, 396, 84, 396, 112, 254, 344, 84, - 124, 134, 285, 324, 710, 344, 646, 20, 25, 60, - 73, 88, 129, 140, 160, 165, 237, 271, 306, 338, - 344, 351, 354, 384, 391, 399, 406, 431, 638, 1126, - 146, 324, 357, 528, 269, 629, 269, 349, 220, 396, - 1140, 396, 259, 629, 116, 208, 344, 355, 398, 507, - 330, 357, 814, 823, 476, 797, 802, 396, 418, 387, - 1124, 74, 142, 181, 578, 588, 1140, 74, 84, 848, - 289, 269, 269, 340, 342, 401, 84, 848, 29, 327, - 340, 342, 401, 340, 1124, 159, 193, 264, 745, 475, - 396, 396, 180, 475, 537, 234, 387, 415, 438, 440, - 537, 84, 479, 4, 4, 285, 187, 146, 120, 324, - 357, 528, 419, 419, 253, 1033, 396, 344, 475, 828, - 1126, 1124, 269, 396, 396, 344, 823, 384, 384, 396, - 396, 384, 714, 106, 357, 519, 396, 489, 519, 269, - 396, 396, 344, 823, 1124, 396, 396, 1124, 1035, 629, - 53, 628, 629, 629, 104, 238, 241, 53, 396, 487, - 245, 344, 487, 252, 627, 396, 396, 259, 1135, 656, - 396, 396, 344, 1135, 396, 309, 396, 309, 714, 387, - 1011, 289, 289, 84, 396, 848, 344, 396, 396, 537, - 537, 745, 745, 745, 745, 1124, 42, 424, 42, 42, - 396, 42, 396, 424, 344, 479, 519, 418, 673, 1138, - 396, 489, 519, 1124, 396, 344, 285, 324, 312, 325, - 353, 511, 879, 1094, 1094, 1095, 476, 13, 14, 479, - 972, 973, 474, 480, 1130, 1140, 1124, 209, 1033, 269, - 209, 442, 209, 629, 745, 745, 209, 269, 209, 209, - 269, 81, 123, 287, 389, 1033, 269, 209, 209, 209, - 396, 438, 562, 406, 3, 719, 720, 714, 475, 35, - 146, 745, 715, 716, 1143, 24, 886, 1033, 269, 146, - 643, 1126, 254, 289, 475, 488, 728, 419, 316, 431, - 1124, 26, 384, 438, 818, 488, 146, 1138, 91, 169, - 503, 570, 622, 686, 763, 781, 882, 146, 1135, 664, - 665, 146, 269, 1135, 1138, 231, 745, 745, 745, 745, - 264, 117, 201, 404, 417, 688, 689, 138, 311, 475, - 673, 254, 488, 1124, 254, 624, 626, 254, 35, 264, - 289, 475, 591, 591, 181, 619, 1124, 158, 181, 784, - 1130, 475, 800, 800, 35, 1033, 215, 438, 440, 956, - 346, 812, 811, 1033, 1127, 475, 1093, 1134, 747, 1050, - 1050, 34, 1034, 394, 394, 1134, 1134, 1033, 473, 473, - 1134, 396, 396, 396, 475, 396, 1134, 1038, 798, 799, - 1139, 1138, 146, 533, 146, 419, 146, 419, 829, 830, - 533, 798, 1139, 798, 1126, 1126, 1033, 747, 1139, 673, - 146, 146, 533, 744, 745, 1125, 1126, 1126, 745, 476, - 181, 1124, 921, 923, 954, 954, 954, 954, 954, 954, - 592, 476, 479, 476, 166, 307, 339, 352, 385, 1125, - 744, 105, 354, 798, 1125, 263, 798, 798, 1125, 1123, - 1123, 1125, 744, 396, 438, 774, 141, 225, 670, 671, - 20, 144, 340, 360, 945, 1011, 258, 946, 476, 479, - 928, 396, 1124, 842, 843, 845, 766, 765, 766, 163, - 170, 775, 1140, 25, 74, 106, 129, 140, 160, 165, - 216, 237, 306, 309, 335, 338, 344, 351, 379, 384, - 387, 406, 431, 638, 756, 757, 1093, 1115, 474, 1093, - 1097, 1098, 434, 1110, 1111, 1056, 1093, 475, 1134, 1134, - 3, 107, 179, 240, 243, 348, 456, 1099, 1100, 1135, - 1093, 1093, 1093, 1134, 1134, 1056, 828, 1056, 1101, 340, - 466, 467, 475, 1057, 1058, 1090, 1103, 476, 1093, 1056, - 1093, 1104, 1056, 52, 163, 219, 397, 1056, 1093, 1107, - 1093, 245, 1058, 1056, 1066, 1067, 1068, 245, 1056, 1068, - 476, 479, 1134, 1054, 1033, 1056, 1056, 1056, 1056, 1143, - 394, 39, 381, 1119, 745, 1056, 475, 958, 1108, 126, - 128, 151, 254, 259, 264, 403, 413, 1056, 475, 1056, - 396, 47, 182, 187, 224, 362, 1056, 1056, 1056, 1056, - 1056, 1056, 1056, 1056, 1056, 1056, 26, 33, 367, 1087, - 172, 154, 1072, 340, 475, 1084, 168, 228, 384, 388, - 390, 415, 967, 1124, 1122, 163, 1001, 1094, 1001, 1124, - 398, 475, 1135, 479, 476, 180, 180, 533, 919, 907, - 911, 912, 1056, 476, 475, 919, 910, 917, 479, 36, - 121, 419, 792, 340, 341, 466, 467, 982, 984, 1058, - 360, 213, 270, 479, 4, 983, 1134, 983, 340, 341, - 984, 1123, 258, 364, 947, 995, 977, 419, 942, 112, - 283, 475, 934, 957, 35, 1140, 475, 949, 950, 951, - 1140, 476, 1138, 1126, 1126, 278, 53, 1141, 476, 804, - 806, 803, 806, 1141, 275, 476, 479, 746, 1138, 1126, - 1126, 1129, 1138, 1126, 1126, 1138, 1127, 1126, 112, 512, - 1136, 335, 418, 765, 344, 169, 765, 475, 1126, 419, - 785, 213, 213, 419, 475, 613, 181, 1126, 259, 1138, - 1126, 1126, 1056, 259, 1126, 1126, 29, 327, 396, 396, - 1126, 396, 647, 239, 811, 475, 745, 745, 1033, 401, - 105, 384, 799, 431, 68, 152, 830, 799, 799, 1126, - 745, 1126, 745, 347, 158, 1033, 745, 215, 175, 252, - 285, 324, 423, 650, 651, 652, 1011, 396, 848, 344, - 259, 148, 116, 208, 1138, 1126, 269, 1126, 476, 479, - 1137, 1139, 1126, 324, 528, 181, 578, 254, 1033, 1126, - 1134, 1140, 1124, 1126, 148, 223, 1126, 26, 418, 1126, - 181, 1126, 181, 1140, 342, 401, 342, 401, 223, 1126, - 26, 418, 1126, 223, 340, 1124, 22, 131, 357, 657, - 658, 659, 660, 1143, 1138, 1126, 112, 164, 255, 419, - 536, 539, 540, 1143, 1126, 267, 70, 267, 1126, 531, - 396, 387, 1124, 269, 396, 848, 344, 1128, 1140, 1128, - 479, 476, 479, 1138, 1126, 853, 854, 1143, 269, 324, - 396, 681, 148, 1138, 1126, 1126, 1012, 1012, 1138, 1126, - 1012, 1127, 1137, 3, 83, 136, 193, 291, 410, 418, - 421, 490, 148, 1138, 1126, 1126, 324, 1138, 1126, 324, - 357, 528, 626, 629, 745, 1126, 629, 745, 1126, 629, - 1138, 1126, 1138, 1126, 1126, 1138, 818, 1126, 862, 863, - 1143, 1126, 324, 357, 528, 529, 1124, 1124, 1126, 1126, - 1126, 1126, 1138, 1126, 22, 28, 131, 285, 324, 357, - 285, 324, 357, 714, 324, 357, 324, 357, 120, 324, - 1025, 1140, 181, 724, 1140, 181, 1140, 1138, 1126, 1126, - 1135, 1126, 22, 552, 354, 1137, 324, 357, 528, 1126, - 1126, 396, 396, 79, 409, 312, 479, 972, 972, 972, - 1056, 1056, 427, 1095, 476, 1056, 1116, 259, 753, 1135, - 35, 129, 745, 753, 753, 209, 419, 419, 753, 745, - 753, 753, 745, 215, 745, 753, 753, 753, 308, 556, - 267, 163, 396, 555, 191, 464, 476, 479, 1056, 1033, - 745, 476, 479, 464, 688, 580, 1143, 1126, 57, 163, - 344, 430, 644, 651, 652, 146, 264, 224, 572, 574, - 576, 578, 585, 588, 23, 187, 335, 382, 490, 491, - 158, 1128, 431, 1124, 35, 682, 385, 1012, 714, 501, - 1140, 502, 274, 571, 1126, 160, 745, 1093, 309, 1135, - 714, 714, 714, 714, 264, 269, 274, 475, 714, 1023, - 1024, 1025, 354, 146, 475, 146, 146, 145, 957, 745, - 264, 572, 1140, 438, 440, 609, 438, 538, 254, 35, - 591, 1135, 254, 269, 476, 801, 802, 807, 35, 215, - 332, 399, 437, 813, 814, 815, 813, 269, 215, 515, - 178, 178, 158, 533, 35, 1093, 476, 476, 533, 473, - 458, 458, 476, 476, 1134, 474, 1134, 476, 179, 240, - 1055, 240, 1055, 1055, 1134, 243, 476, 533, 744, 745, - 1128, 745, 1128, 533, 533, 533, 533, 215, 533, 354, - 158, 515, 533, 533, 269, 533, 254, 476, 593, 187, - 187, 187, 187, 187, 442, 1125, 629, 630, 172, 769, - 770, 1138, 23, 775, 396, 475, 163, 144, 360, 144, - 360, 340, 417, 242, 1033, 1138, 438, 617, 1124, 1126, - 163, 269, 769, 53, 533, 811, 1033, 401, 384, 799, - 263, 431, 799, 799, 1033, 215, 745, 1126, 476, 474, - 474, 479, 1056, 133, 1111, 1112, 35, 476, 1056, 476, - 476, 476, 163, 476, 476, 476, 476, 476, 479, 476, - 293, 1102, 476, 475, 1057, 1057, 1093, 11, 15, 16, - 17, 187, 209, 271, 462, 463, 464, 466, 467, 468, - 469, 470, 471, 1090, 1057, 476, 476, 158, 163, 1105, - 1106, 476, 35, 1107, 1093, 1107, 1107, 163, 476, 476, - 1143, 290, 1070, 35, 476, 479, 1056, 1143, 479, 1056, - 1118, 1056, 476, 458, 1057, 1057, 139, 1093, 163, 126, - 128, 151, 259, 264, 403, 413, 475, 139, 828, 1056, - 381, 1119, 1056, 1108, 1056, 396, 475, 958, 475, 475, - 280, 1076, 475, 1093, 388, 390, 388, 390, 1124, 968, - 968, 968, 218, 341, 455, 475, 958, 1002, 1003, 1004, - 1011, 1016, 1026, 1059, 1061, 1062, 1140, 435, 1021, 972, - 1021, 880, 1134, 1054, 510, 919, 928, 975, 271, 1088, - 1091, 460, 793, 4, 1134, 984, 270, 417, 981, 233, - 1002, 435, 1022, 425, 383, 418, 935, 936, 937, 1140, - 269, 938, 1140, 951, 952, 479, 1001, 464, 1118, 810, - 746, 806, 806, 53, 808, 470, 1139, 1139, 269, 1125, - 272, 269, 1056, 589, 1128, 475, 475, 475, 613, 191, - 592, 703, 146, 533, 396, 1138, 1126, 515, 1126, 1033, - 1126, 442, 745, 745, 745, 745, 81, 123, 287, 389, - 1033, 1126, 633, 1126, 175, 423, 396, 396, 633, 650, - 656, 324, 357, 528, 1126, 1126, 1126, 199, 1126, 259, - 802, 284, 357, 396, 254, 146, 273, 654, 703, 357, - 22, 131, 328, 329, 357, 532, 541, 542, 656, 849, - 1126, 349, 146, 533, 146, 533, 1126, 1126, 1126, 1126, - 349, 349, 223, 659, 660, 659, 476, 479, 661, 1135, - 191, 476, 479, 464, 477, 1138, 1126, 324, 357, 528, - 148, 1126, 1126, 1126, 285, 324, 357, 22, 131, 285, - 324, 357, 1033, 253, 1033, 476, 479, 464, 1124, 396, - 1139, 419, 678, 1126, 225, 291, 259, 1135, 291, 1139, - 416, 1126, 396, 396, 344, 479, 818, 284, 357, 84, - 396, 848, 344, 112, 158, 543, 396, 396, 235, 235, - 235, 396, 396, 344, 396, 396, 344, 396, 344, 396, - 344, 269, 396, 533, 1033, 254, 1135, 357, 849, 146, - 533, 396, 396, 1126, 396, 344, 1138, 1126, 476, 476, - 476, 1095, 474, 1033, 745, 209, 753, 1128, 1128, 209, - 209, 1126, 209, 374, 375, 557, 1135, 556, 175, 253, - 271, 466, 467, 629, 717, 806, 1091, 1135, 1147, 3, - 720, 476, 476, 163, 714, 716, 717, 269, 66, 72, - 84, 112, 114, 167, 195, 254, 259, 302, 318, 412, - 581, 582, 584, 145, 434, 487, 515, 1126, 515, 654, - 1124, 1124, 1124, 476, 479, 1139, 172, 335, 1139, 1134, - 406, 1124, 591, 3, 158, 683, 43, 502, 326, 384, - 663, 105, 916, 163, 862, 538, 592, 1124, 689, 721, - 722, 1135, 476, 479, 1126, 158, 592, 1124, 616, 1124, - 1126, 617, 475, 573, 1124, 476, 267, 537, 267, 269, - 610, 537, 35, 146, 957, 538, 396, 146, 1011, 476, - 479, 112, 464, 816, 1135, 515, 384, 805, 806, 158, - 817, 815, 117, 201, 350, 417, 871, 1126, 175, 957, - 1033, 476, 1134, 1053, 1053, 474, 474, 476, 533, 419, - 533, 419, 533, 1126, 1126, 673, 533, 745, 146, 344, - 344, 344, 344, 344, 1125, 479, 1138, 438, 479, 771, - 272, 1012, 354, 144, 144, 105, 252, 1139, 768, 533, - 1138, 209, 209, 209, 629, 209, 209, 209, 209, 209, - 1097, 392, 1056, 137, 1033, 476, 1056, 1056, 1056, 1105, - 476, 1093, 479, 1033, 1057, 1057, 1057, 1057, 126, 128, - 254, 264, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, - 1057, 1057, 1056, 1056, 1106, 1105, 1033, 476, 476, 476, - 1093, 476, 479, 53, 1058, 476, 1143, 1067, 299, 378, - 1069, 476, 479, 430, 1063, 35, 476, 1135, 1056, 32, - 32, 1056, 476, 1056, 163, 475, 1096, 1056, 476, 139, - 1057, 1057, 139, 139, 1056, 1056, 973, 435, 475, 1077, - 1140, 476, 1093, 479, 968, 968, 968, 968, 1124, 1124, - 1124, 958, 1016, 1026, 163, 475, 958, 1003, 1004, 35, - 1005, 1006, 1140, 479, 92, 164, 197, 212, 222, 248, - 334, 1008, 1006, 35, 1005, 1007, 1140, 1006, 461, 1020, - 1117, 1056, 172, 986, 476, 986, 476, 476, 475, 793, - 155, 217, 270, 95, 1056, 331, 940, 424, 476, 479, - 1118, 82, 940, 476, 479, 950, 1022, 1056, 476, 470, - 810, 406, 166, 339, 345, 352, 385, 407, 780, 158, - 780, 476, 475, 596, 597, 787, 1061, 1140, 592, 592, - 703, 1130, 476, 114, 195, 252, 254, 704, 1126, 1126, - 35, 1126, 419, 419, 745, 745, 745, 745, 215, 746, - 1138, 1126, 396, 848, 344, 396, 199, 53, 387, 1126, - 146, 578, 475, 580, 373, 167, 180, 254, 537, 487, - 105, 167, 254, 373, 376, 537, 627, 357, 542, 406, - 1126, 1140, 349, 658, 1126, 540, 717, 1143, 284, 357, - 396, 848, 344, 1126, 396, 396, 396, 344, 165, 271, - 376, 726, 727, 165, 271, 734, 735, 396, 396, 344, - 476, 476, 476, 854, 253, 629, 806, 855, 1091, 1135, - 1147, 324, 1126, 475, 438, 679, 1136, 1135, 1135, 1135, - 1126, 1126, 1126, 863, 53, 387, 1126, 1126, 1126, 1126, - 425, 1126, 1126, 158, 158, 326, 158, 181, 1138, 1126, - 1126, 1138, 1126, 1126, 1126, 1126, 1126, 1126, 148, 1126, - 72, 534, 146, 24, 45, 406, 1140, 1126, 1135, 656, - 1126, 1126, 972, 476, 209, 753, 209, 209, 753, 753, - 209, 753, 487, 557, 633, 703, 438, 440, 745, 1124, - 475, 745, 1126, 1057, 29, 53, 583, 115, 183, 114, - 259, 213, 1124, 818, 306, 706, 707, 1140, 643, 289, - 475, 573, 586, 194, 603, 576, 1139, 1139, 1033, 475, - 538, 26, 117, 201, 350, 417, 684, 396, 680, 1138, - 181, 1124, 665, 442, 269, 1002, 818, 319, 690, 476, - 479, 1025, 654, 673, 476, 624, 35, 264, 289, 475, - 930, 575, 577, 579, 588, 1140, 289, 604, 605, 573, - 603, 78, 387, 611, 957, 619, 617, 611, 1135, 1130, - 785, 807, 1056, 1056, 479, 475, 813, 406, 479, 396, - 475, 633, 476, 474, 1128, 1128, 533, 354, 533, 1125, - 1125, 1125, 1125, 1125, 629, 169, 770, 476, 1126, 105, - 775, 163, 259, 758, 1135, 758, 758, 209, 758, 758, - 758, 758, 758, 1056, 476, 476, 1106, 476, 1056, 163, - 126, 128, 264, 475, 476, 445, 1065, 1093, 317, 53, - 436, 436, 476, 1056, 252, 1056, 479, 1064, 1035, 1056, - 1056, 1056, 1096, 476, 1056, 32, 32, 1056, 1056, 139, - 476, 476, 1056, 1078, 1140, 476, 1056, 1124, 1124, 1124, - 1124, 1006, 1007, 1006, 475, 450, 1058, 476, 1140, 475, - 1003, 212, 279, 1009, 1003, 1009, 212, 1008, 1009, 212, - 386, 1014, 475, 1140, 475, 276, 53, 176, 993, 1135, - 993, 1135, 828, 264, 1121, 957, 283, 957, 937, 269, - 475, 939, 464, 951, 940, 406, 476, 396, 765, 163, - 703, 1056, 476, 479, 438, 72, 790, 790, 476, 476, - 188, 594, 115, 183, 193, 114, 421, 533, 1033, 1128, - 1128, 1126, 1126, 1126, 1126, 1126, 1139, 1126, 578, 655, - 659, 1136, 583, 181, 259, 629, 583, 259, 1136, 1140, - 1033, 533, 533, 464, 53, 387, 1126, 1126, 1126, 1126, - 1138, 1126, 1126, 1134, 1134, 1033, 479, 1134, 1134, 479, - 1138, 1126, 1126, 396, 1056, 66, 1139, 1126, 396, 396, - 163, 187, 438, 1125, 1125, 745, 1125, 146, 1126, 745, - 1135, 1135, 1033, 533, 533, 476, 209, 753, 753, 753, - 753, 475, 558, 559, 419, 563, 564, 165, 198, 165, - 163, 702, 1056, 254, 582, 112, 35, 818, 591, 419, - 612, 1132, 32, 145, 187, 264, 572, 543, 143, 189, - 475, 354, 419, 592, 35, 1139, 678, 502, 254, 475, - 160, 1126, 1093, 250, 268, 691, 692, 693, 158, 696, - 1135, 354, 538, 957, 745, 264, 572, 617, 476, 479, - 438, 580, 53, 609, 543, 604, 117, 131, 299, 1126, - 438, 883, 35, 163, 269, 475, 1135, 804, 819, 820, - 1141, 1033, 158, 1124, 163, 396, 839, 196, 634, 533, - 533, 533, 1126, 272, 207, 533, 769, 758, 476, 1057, - 163, 475, 1096, 475, 476, 479, 476, 1058, 317, 476, - 424, 370, 476, 476, 476, 1056, 1056, 1056, 476, 289, - 1079, 476, 1017, 1018, 1061, 475, 1070, 1005, 475, 1125, - 1003, 269, 419, 1010, 1003, 212, 1003, 1132, 1024, 475, - 1024, 1140, 94, 173, 337, 475, 987, 988, 989, 990, - 991, 992, 1056, 1056, 437, 1073, 1073, 476, 954, 935, - 84, 786, 787, 127, 1056, 769, 269, 769, 476, 594, - 597, 271, 828, 745, 745, 791, 791, 318, 594, 475, - 818, 476, 396, 357, 946, 476, 479, 35, 146, 534, - 717, 1139, 1126, 396, 475, 799, 828, 830, 727, 475, - 475, 735, 1126, 476, 475, 357, 946, 1126, 1126, 475, - 475, 475, 438, 461, 901, 326, 901, 901, 158, 534, - 753, 565, 566, 1143, 49, 93, 118, 135, 139, 159, - 162, 177, 259, 267, 310, 560, 487, 119, 799, 35, - 835, 835, 1124, 703, 476, 180, 612, 236, 595, 191, - 475, 707, 306, 475, 1124, 476, 354, 26, 77, 85, - 113, 180, 192, 373, 376, 587, 587, 1123, 1126, 1128, - 476, 957, 679, 146, 105, 654, 163, 692, 340, 384, - 694, 132, 697, 434, 699, 1126, 35, 617, 573, 1124, - 476, 577, 273, 3, 606, 1144, 610, 604, 609, 341, - 341, 58, 66, 228, 957, 745, 1011, 786, 806, 476, - 479, 406, 1021, 368, 368, 476, 633, 252, 423, 635, - 636, 1126, 533, 1057, 1096, 476, 1066, 1093, 53, 252, - 457, 53, 972, 476, 479, 35, 1019, 112, 1031, 1032, - 1057, 75, 1125, 476, 1056, 475, 1003, 1010, 475, 476, - 1024, 476, 475, 358, 475, 476, 479, 1074, 1075, 1140, - 424, 1126, 476, 479, 255, 417, 771, 780, 533, 790, - 818, 475, 792, 792, 1124, 818, 592, 612, 1126, 387, - 659, 180, 419, 535, 357, 946, 1126, 1096, 158, 730, - 730, 1096, 1096, 1056, 387, 151, 238, 241, 259, 403, - 546, 548, 549, 629, 1135, 546, 547, 544, 545, 1142, - 744, 745, 744, 745, 1125, 533, 476, 479, 468, 475, - 512, 567, 629, 898, 1135, 898, 254, 259, 310, 898, - 898, 558, 1135, 835, 38, 185, 158, 252, 590, 475, - 625, 164, 288, 363, 269, 599, 600, 601, 387, 476, - 1132, 5, 708, 573, 603, 1126, 476, 654, 152, 729, - 538, 883, 1124, 442, 1002, 898, 340, 372, 698, 475, - 145, 654, 957, 604, 573, 603, 580, 475, 611, 609, - 610, 66, 272, 66, 617, 785, 476, 813, 819, 1033, - 127, 438, 438, 423, 633, 654, 476, 476, 476, 317, - 424, 1093, 174, 311, 341, 1080, 1020, 1017, 475, 1057, - 476, 479, 35, 1027, 1028, 1140, 476, 1125, 1093, 476, - 1093, 475, 1093, 988, 479, 35, 957, 1021, 787, 357, - 163, 791, 612, 828, 793, 793, 591, 612, 476, 703, - 1126, 625, 1056, 387, 476, 275, 347, 315, 731, 731, - 476, 476, 476, 1126, 476, 479, 476, 479, 476, 479, - 1134, 901, 566, 512, 568, 569, 1135, 1135, 259, 592, - 468, 592, 1135, 1135, 132, 193, 626, 117, 417, 269, - 601, 269, 600, 1126, 475, 476, 479, 543, 354, 654, - 745, 35, 35, 475, 1126, 695, 1140, 1056, 306, 883, - 609, 543, 604, 475, 607, 608, 1061, 1140, 610, 611, - 272, 272, 475, 188, 788, 27, 202, 872, 165, 165, - 47, 95, 408, 1056, 1081, 1082, 1081, 1081, 476, 1024, - 479, 1032, 1143, 476, 479, 158, 1033, 476, 476, 476, - 987, 476, 1075, 1077, 949, 769, 792, 435, 598, 476, - 595, 703, 946, 1126, 799, 53, 946, 396, 549, 546, - 544, 745, 476, 479, 592, 340, 476, 57, 252, 330, - 357, 602, 602, 476, 5, 354, 1126, 726, 957, 654, - 476, 1132, 610, 604, 609, 1056, 476, 479, 790, 790, - 611, 786, 475, 538, 255, 475, 867, 869, 873, 932, - 941, 948, 957, 799, 799, 1082, 340, 157, 297, 157, - 297, 142, 1083, 1083, 1083, 476, 1058, 1028, 276, 3, - 112, 254, 259, 1029, 1030, 325, 1015, 476, 1021, 533, - 793, 475, 703, 599, 946, 745, 475, 569, 699, 21, - 112, 259, 1126, 654, 883, 475, 611, 609, 610, 476, - 608, 791, 791, 476, 787, 789, 611, 868, 869, 870, - 958, 959, 479, 479, 32, 95, 172, 252, 393, 1070, - 1057, 1057, 259, 1030, 475, 1056, 703, 548, 145, 654, - 4, 700, 701, 1134, 1135, 1143, 610, 611, 790, 788, - 476, 479, 1021, 476, 478, 396, 163, 1082, 340, 277, - 75, 1056, 476, 476, 306, 476, 479, 611, 791, 538, - 787, 870, 368, 368, 1027, 476, 1132, 701, 611, 438, - 438, 476, 475, 1021, 165, 165, 700, 799, 799, 476 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 481, 482, 483, 483, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, - 485, 486, 487, 487, 487, 488, 488, 489, 489, 490, - 490, 490, 490, 490, 490, 490, 490, 490, 491, 491, - 491, 491, 491, 491, 492, 493, 493, 494, 494, 495, - 495, 495, 495, 496, 496, 496, 496, 496, 496, 497, - 498, 499, 499, 500, 500, 500, 500, 501, 501, 502, - 502, 503, 503, 503, 503, 503, 503, 504, 504, 504, - 504, 505, 505, 505, 506, 506, 506, 506, 507, 507, - 507, 507, 507, 507, 507, 507, 507, 507, 507, 508, - 508, 509, 509, 510, 510, 511, 511, 511, 511, 512, - 512, 512, 512, 513, 513, 513, 513, 513, 513, 513, - 514, 514, 514, 515, 515, 516, 516, 517, 517, 517, - 517, 518, 518, 519, 519, 520, 520, 521, 521, 521, - 521, 521, 521, 521, 522, 523, 523, 524, 524, 525, - 526, 526, 526, 526, 526, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 527, 527, 527, 528, 528, 529, 529, 530, 531, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 532, 532, 533, 533, - 533, 534, 534, 535, 535, 536, 536, 536, 536, 537, - 538, 538, 539, 539, 540, 540, 540, 540, 541, 541, - 542, 542, 542, 542, 543, 543, 543, 543, 544, 545, - 545, 546, 546, 546, 546, 546, 547, 547, 548, 548, - 549, 549, 549, 550, 551, 551, 552, 552, 552, 552, - 553, 553, 554, 554, 555, 555, 556, 556, 557, 557, - 557, 558, 558, 559, 559, 560, 560, 560, 560, 560, - 560, 560, 560, 560, 560, 560, 560, 560, 560, 561, - 561, 562, 562, 563, 563, 564, 564, 565, 565, 566, - 567, 567, 567, 567, 567, 568, 568, 569, 570, 570, - 570, 570, 570, 570, 571, 571, 571, 571, 571, 571, - 571, 571, 572, 572, 573, 573, 574, 574, 575, 575, - 576, 576, 576, 577, 577, 578, 579, 579, 580, 580, - 581, 581, 581, 581, 582, 582, 582, 582, 582, 582, - 582, 582, 583, 583, 584, 584, 584, 584, 585, 586, - 586, 586, 587, 587, 587, 587, 587, 587, 587, 587, - 588, 588, 589, 589, 589, 589, 589, 589, 589, 590, - 590, 591, 591, 592, 592, 593, 594, 594, 595, 595, - 595, 595, 596, 596, 597, 597, 598, 598, 599, 599, - 599, 599, 599, 600, 601, 602, 602, 602, 602, 602, - 603, 603, 604, 604, 605, 606, 606, 607, 607, 608, - 608, 608, 609, 609, 609, 609, 610, 610, 610, 610, - 611, 611, 612, 612, 613, 614, 614, 615, 615, 616, - 617, 617, 617, 618, 618, 619, 620, 620, 621, 622, - 622, 623, 623, 624, 624, 625, 625, 626, 626, 627, - 627, 627, 627, 627, 627, 627, 627, 627, 627, 627, - 627, 627, 627, 628, 628, 629, 629, 629, 629, 630, - 630, 631, 631, 632, 632, 633, 633, 634, 634, 635, - 635, 636, 636, 637, 637, 638, 638, 639, 640, 640, - 641, 641, 642, 642, 643, 643, 644, 644, 644, 644, - 645, 646, 646, 647, 648, 648, 648, 648, 648, 648, - 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, - 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, - 648, 648, 649, 650, 650, 650, 650, 651, 651, 652, - 652, 653, 653, 654, 654, 655, 655, 656, 657, 657, - 658, 658, 658, 658, 659, 660, 661, 662, 662, 663, - 663, 664, 664, 665, 665, 666, 666, 666, 667, 667, - 667, 667, 668, 668, 669, 670, 670, 671, 671, 672, - 672, 673, 673, 674, 674, 675, 676, 677, 678, 678, - 679, 679, 680, 680, 681, 681, 682, 682, 683, 683, - 684, 684, 684, 684, 684, 685, 686, 686, 687, 687, - 687, 688, 688, 689, 689, 689, 689, 689, 690, 690, - 691, 691, 692, 693, 693, 694, 694, 695, 696, 696, - 697, 697, 698, 698, 699, 699, 700, 700, 700, 701, - 701, 701, 701, 702, 702, 703, 703, 704, 704, 704, - 704, 704, 704, 705, 705, 706, 706, 707, 708, 708, - 709, 710, 710, 710, 710, 711, 712, 713, 713, 713, - 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, - 713, 713, 713, 714, 715, 715, 716, 716, 717, 717, - 717, 717, 717, 717, 718, 719, 719, 720, 721, 721, - 722, 722, 723, 723, 723, 723, 724, 724, 725, 726, - 726, 727, 727, 727, 727, 727, 728, 728, 729, 729, - 730, 730, 730, 731, 731, 732, 733, 733, 734, 734, - 735, 735, 736, 736, 737, 737, 738, 739, 740, 740, - 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, - 741, 741, 741, 741, 741, 741, 741, 741, 741, 741, - 741, 741, 741, 742, 742, 742, 742, 742, 742, 742, - 743, 743, 743, 744, 744, 745, 745, 746, 746, 747, - 747, 748, 749, 749, 749, 750, 750, 750, 750, 750, - 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, - 750, 750, 750, 750, 751, 751, 751, 751, 751, 751, - 751, 751, 751, 751, 751, 751, 751, 751, 752, 752, - 752, 752, 752, 752, 752, 752, 752, 752, 752, 752, - 753, 753, 754, 754, 754, 754, 754, 754, 754, 754, - 754, 755, 755, 756, 756, 756, 756, 756, 756, 757, - 757, 757, 757, 757, 757, 757, 757, 758, 758, 759, - 759, 760, 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 761, 761, 762, - 762, 763, 764, 764, 765, 765, 765, 765, 765, 766, - 766, 767, 767, 767, 767, 768, 768, 768, 768, 768, - 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, - 768, 768, 768, 768, 768, 769, 769, 770, 770, 771, - 771, 772, 773, 773, 774, 774, 775, 775, 776, 777, - 777, 778, 778, 778, 779, 779, 779, 780, 780, 780, - 780, 780, 780, 781, 781, 782, 782, 783, 783, 784, - 784, 785, 785, 786, 786, 787, 787, 787, 788, 788, - 789, 789, 790, 790, 791, 791, 792, 792, 792, 793, - 793, 793, 794, 794, 794, 794, 795, 795, 796, 796, - 797, 797, 798, 798, 799, 799, 799, 799, 800, 800, - 801, 801, 802, 802, 802, 802, 802, 803, 803, 803, - 803, 803, 804, 805, 806, 806, 806, 807, 807, 807, - 808, 809, 809, 809, 809, 810, 810, 811, 812, 812, - 813, 813, 814, 814, 814, 814, 814, 814, 814, 814, - 814, 814, 814, 814, 814, 814, 814, 814, 815, 815, - 815, 815, 815, 816, 816, 817, 817, 818, 818, 819, - 820, 820, 821, 821, 821, 822, 822, 823, 823, 824, - 824, 824, 824, 824, 824, 825, 825, 826, 826, 827, - 827, 827, 827, 828, 828, 829, 829, 830, 831, 832, - 832, 833, 833, 834, 834, 834, 835, 835, 835, 836, - 837, 837, 838, 839, 839, 839, 839, 840, 841, 841, - 841, 841, 842, 842, 843, 843, 843, 844, 844, 845, - 846, 846, 847, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 847, 848, 848, 849, 849, 850, - 850, 850, 850, 850, 850, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 852, 853, 853, 854, 854, 855, 855, 855, - 855, 855, 856, 856, 856, 856, 856, 856, 856, 856, - 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - 856, 856, 856, 856, 856, 856, 857, 858, 858, 859, - 859, 860, 860, 860, 860, 861, 862, 862, 863, 864, - 864, 864, 864, 864, 864, 865, 865, 866, 867, 867, - 867, 868, 868, 869, 869, 869, 869, 869, 870, 870, - 871, 871, 871, 871, 872, 872, 872, 873, 874, 874, - 875, 876, 876, 877, 877, 877, 877, 877, 877, 877, - 877, 877, 877, 877, 877, 877, 877, 878, 878, 878, - 879, 879, 879, 879, 879, 880, 880, 880, 881, 881, - 882, 882, 882, 882, 883, 883, 883, 883, 884, 885, - 886, 886, 887, 887, 888, 888, 888, 889, 889, 889, - 889, 889, 889, 889, 890, 890, 891, 891, 891, 892, - 893, 893, 894, 895, 895, 896, 897, 897, 897, 897, - 897, 897, 897, 898, 898, 899, 900, 900, 900, 900, - 900, 900, 901, 901, 902, 903, 903, 903, 904, 904, - 905, 905, 906, 906, 907, 907, 907, 907, 907, 908, - 908, 909, 909, 910, 911, 911, 912, 912, 913, 913, - 914, 914, 915, 915, 916, 916, 917, 918, 918, 919, - 919, 920, 920, 920, 920, 921, 921, 921, 921, 921, - 921, 921, 921, 921, 922, 922, 923, 924, 924, 925, - 925, 925, 926, 927, 927, 928, 928, 928, 928, 929, - 929, 930, 930, 931, 931, 931, 931, 932, 933, 933, - 934, 934, 934, 934, 934, 935, 935, 936, 936, 937, - 938, 938, 938, 939, 939, 939, 940, 940, 941, 942, - 942, 943, 944, 944, 945, 945, 945, 945, 945, 945, - 945, 945, 946, 946, 947, 947, 947, 948, 949, 949, - 950, 950, 951, 952, 952, 953, 954, 955, 955, 955, - 955, 955, 956, 956, 956, 957, 957, 958, 958, 959, - 959, 959, 959, 959, 959, 959, 959, 960, 960, 961, - 961, 961, 961, 961, 961, 961, 962, 962, 962, 963, - 963, 964, 965, 965, 966, 966, 967, 967, 967, 967, - 967, 967, 967, 967, 967, 968, 968, 969, 969, 969, - 970, 970, 971, 971, 972, 972, 973, 974, 974, 975, - 975, 976, 976, 976, 976, 977, 977, 978, 978, 978, - 978, 979, 979, 980, 980, 981, 982, 982, 982, 983, - 983, 984, 984, 985, 985, 986, 986, 987, 987, 988, - 988, 988, 988, 988, 989, 990, 991, 992, 993, 993, - 994, 994, 995, 995, 996, 996, 997, 998, 998, 998, - 998, 999, 999, 1000, 1000, 1001, 1001, 1002, 1002, 1003, - 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1004, - 1004, 1004, 1004, 1004, 1004, 1005, 1005, 1005, 1005, 1006, - 1006, 1007, 1007, 1007, 1007, 1007, 1008, 1008, 1008, 1008, - 1009, 1009, 1010, 1010, 1011, 1011, 1011, 1011, 1012, 1012, - 1013, 1013, 1013, 1014, 1015, 1015, 1016, 1016, 1017, 1018, - 1018, 1019, 1019, 1020, 1020, 1021, 1021, 1022, 1022, 1022, - 1023, 1023, 1024, 1024, 1025, 1026, 1026, 1027, 1027, 1028, - 1028, 1028, 1029, 1029, 1030, 1030, 1030, 1030, 1031, 1031, - 1032, 1032, 1033, 1033, 1033, 1033, 1033, 1033, 1034, 1034, - 1034, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1036, 1036, - 1036, 1036, 1037, 1037, 1038, 1038, 1039, 1039, 1039, 1039, - 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1040, 1040, 1041, - 1041, 1042, 1042, 1043, 1044, 1045, 1045, 1046, 1046, 1047, - 1048, 1049, 1049, 1049, 1049, 1049, 1049, 1050, 1050, 1051, - 1051, 1051, 1051, 1052, 1053, 1053, 1053, 1054, 1054, 1054, - 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, - 1054, 1055, 1055, 1056, 1056, 1056, 1056, 1056, 1056, 1056, - 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, - 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, - 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, - 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, - 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1056, - 1056, 1056, 1056, 1056, 1056, 1056, 1056, 1057, 1057, 1057, - 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, - 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, - 1057, 1057, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, - 1058, 1058, 1058, 1058, 1058, 1058, 1059, 1059, 1059, 1059, - 1059, 1059, 1059, 1060, 1060, 1061, 1061, 1062, 1062, 1062, - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1063, - 1063, 1064, 1064, 1064, 1064, 1065, 1066, 1066, 1067, 1067, - 1068, 1068, 1069, 1069, 1069, 1070, 1070, 1070, 1070, 1071, - 1071, 1072, 1072, 1073, 1073, 1074, 1074, 1075, 1076, 1076, - 1076, 1077, 1078, 1078, 1079, 1079, 1080, 1080, 1080, 1080, - 1081, 1081, 1082, 1082, 1082, 1082, 1082, 1083, 1083, 1083, - 1083, 1083, 1084, 1084, 1084, 1085, 1085, 1086, 1087, 1087, - 1087, 1088, 1088, 1089, 1089, 1089, 1089, 1089, 1089, 1089, - 1089, 1089, 1089, 1089, 1089, 1090, 1090, 1091, 1091, 1092, - 1092, 1092, 1092, 1092, 1092, 1093, 1093, 1094, 1094, 1095, - 1095, 1095, 1096, 1096, 1097, 1097, 1097, 1098, 1098, 1099, - 1099, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1101, - 1101, 1102, 1103, 1103, 1104, 1104, 1104, 1104, 1104, 1104, - 1105, 1106, 1107, 1107, 1107, 1108, 1108, 1109, 1110, 1110, - 1111, 1112, 1112, 1113, 1113, 1114, 1114, 1115, 1115, 1115, - 1115, 1116, 1116, 1117, 1117, 1118, 1118, 1119, 1119, 1120, - 1120, 1121, 1121, 1122, 1122, 1122, 1122, 1123, 1123, 1124, - 1124, 1125, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, - 1132, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, - 1133, 1133, 1133, 1133, 1134, 1135, 1136, 1136, 1136, 1137, - 1138, 1138, 1138, 1139, 1139, 1140, 1140, 1140, 1141, 1141, - 1141, 1142, 1142, 1142, 1142, 1143, 1143, 1143, 1143, 1143, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1144, - 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, - 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, - 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, - 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, - 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, - 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, - 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, 1146, - 1146, 1146, 1146, 1147, 1147, 1147, 1147, 1147, 1147, 1147, - 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, - 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, - 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, - 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, - 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, - 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, - 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 3, 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, 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, - 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, - 2, 5, 1, 1, 0, 2, 0, 2, 0, 2, - 2, 3, 3, 1, 3, 3, 2, 1, 1, 2, - 2, 2, 3, 3, 5, 5, 5, 0, 3, 5, - 5, 5, 5, 3, 5, 3, 5, 3, 5, 5, - 6, 1, 1, 6, 4, 9, 7, 1, 0, 2, - 0, 1, 1, 1, 1, 1, 1, 3, 2, 3, - 3, 2, 5, 1, 3, 3, 3, 3, 1, 3, - 3, 2, 2, 2, 2, 3, 3, 3, 3, 1, - 3, 1, 3, 1, 1, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 3, 5, 1, 1, 1, - 1, 1, 0, 1, 1, 2, 3, 1, 2, 3, - 2, 1, 1, 2, 1, 2, 1, 3, 3, 2, - 3, 4, 3, 2, 4, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 4, 6, 4, 6, 10, - 13, 4, 6, 4, 10, 13, 4, 6, 4, 6, - 5, 7, 11, 14, 1, 3, 4, 3, 3, 2, - 5, 3, 6, 4, 6, 6, 6, 6, 5, 5, - 6, 9, 4, 5, 7, 6, 4, 8, 4, 2, - 4, 3, 6, 4, 3, 3, 3, 3, 2, 2, - 3, 4, 4, 3, 3, 3, 3, 3, 3, 4, - 4, 3, 2, 3, 2, 2, 3, 3, 2, 2, - 3, 4, 4, 4, 5, 1, 3, 2, 1, 1, - 0, 2, 0, 2, 0, 1, 1, 1, 3, 3, - 2, 0, 1, 3, 3, 1, 5, 3, 1, 2, - 1, 3, 2, 3, 6, 6, 10, 1, 2, 1, - 3, 1, 1, 1, 1, 1, 1, 3, 1, 3, - 1, 1, 1, 4, 1, 3, 4, 6, 4, 8, - 2, 2, 11, 9, 1, 1, 1, 0, 1, 1, - 1, 1, 3, 2, 0, 1, 1, 1, 3, 3, - 1, 1, 3, 3, 3, 3, 4, 3, 2, 1, - 0, 2, 0, 3, 0, 1, 0, 1, 3, 2, - 1, 1, 1, 3, 0, 1, 3, 1, 12, 15, - 11, 14, 13, 16, 1, 1, 2, 2, 2, 2, - 1, 0, 1, 0, 3, 0, 1, 3, 1, 3, - 1, 1, 1, 1, 1, 4, 2, 4, 2, 0, - 3, 1, 1, 2, 2, 1, 3, 4, 5, 2, - 5, 5, 1, 2, 1, 2, 2, 2, 3, 3, - 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 1, 5, 8, 3, 9, 4, 10, 11, 2, - 0, 3, 0, 1, 3, 1, 4, 0, 2, 2, - 2, 0, 1, 3, 3, 6, 4, 0, 1, 1, - 2, 2, 0, 3, 3, 2, 1, 1, 2, 2, - 4, 0, 1, 0, 6, 1, 1, 1, 3, 3, - 3, 5, 2, 2, 2, 0, 3, 4, 4, 0, - 2, 0, 4, 0, 3, 8, 11, 7, 10, 5, - 2, 3, 0, 8, 11, 4, 1, 0, 6, 5, - 8, 4, 6, 1, 0, 3, 0, 1, 2, 2, - 2, 1, 2, 3, 2, 2, 2, 2, 3, 3, - 3, 1, 3, 1, 0, 1, 2, 2, 1, 1, - 3, 6, 10, 1, 0, 1, 2, 2, 0, 2, - 2, 1, 0, 5, 7, 1, 0, 7, 2, 0, - 3, 5, 5, 8, 2, 0, 2, 2, 2, 1, - 5, 2, 0, 2, 7, 6, 10, 6, 6, 6, - 6, 7, 6, 9, 9, 6, 6, 6, 7, 6, - 8, 8, 8, 8, 6, 6, 7, 7, 8, 6, - 9, 6, 7, 2, 2, 2, 2, 1, 2, 1, - 0, 7, 6, 4, 0, 1, 3, 4, 1, 3, - 1, 2, 2, 2, 2, 1, 1, 10, 13, 2, - 0, 2, 2, 1, 0, 5, 4, 4, 11, 14, - 12, 15, 5, 7, 11, 2, 1, 4, 0, 8, - 11, 1, 1, 7, 9, 8, 10, 8, 4, 0, - 5, 0, 2, 0, 2, 0, 2, 0, 2, 0, - 1, 1, 1, 1, 1, 8, 16, 20, 1, 1, - 2, 1, 3, 1, 1, 1, 3, 1, 2, 0, - 1, 2, 4, 1, 1, 1, 1, 1, 3, 0, - 1, 0, 1, 1, 4, 0, 1, 3, 0, 1, - 1, 1, 1, 2, 0, 0, 2, 2, 1, 2, - 2, 2, 2, 11, 13, 1, 3, 5, 1, 3, - 5, 1, 2, 2, 1, 8, 4, 5, 4, 4, - 4, 3, 7, 8, 6, 6, 6, 6, 6, 4, - 7, 5, 8, 3, 1, 3, 3, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 3, 3, 1, 0, - 1, 3, 7, 9, 9, 8, 3, 0, 13, 1, - 3, 5, 5, 3, 6, 2, 1, 0, 2, 0, - 2, 4, 0, 1, 0, 6, 8, 8, 1, 3, - 5, 5, 7, 9, 7, 9, 5, 6, 6, 4, - 6, 4, 6, 8, 4, 6, 4, 6, 5, 7, - 1, 1, 1, 2, 1, 2, 1, 1, 1, 3, - 3, 3, 3, 2, 2, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 2, 2, 3, 1, - 3, 5, 2, 2, 0, 6, 6, 6, 6, 6, - 6, 6, 8, 9, 8, 6, 6, 8, 9, 8, - 9, 9, 7, 10, 1, 1, 1, 1, 1, 1, - 2, 1, 1, 2, 3, 3, 3, 3, 2, 1, - 2, 1, 3, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 8, 8, 8, 8, 8, 8, 9, 8, - 8, 2, 0, 1, 2, 1, 1, 1, 2, 1, - 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 1, 2, 3, 3, 3, 3, 4, 4, 3, - 3, 3, 4, 4, 3, 4, 4, 1, 1, 1, - 0, 7, 7, 10, 1, 1, 2, 4, 5, 1, - 3, 2, 2, 2, 2, 1, 2, 2, 4, 3, - 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, - 5, 5, 5, 5, 5, 1, 3, 1, 2, 3, - 0, 6, 6, 9, 3, 0, 3, 0, 5, 2, - 0, 3, 3, 3, 7, 7, 10, 1, 1, 1, - 1, 1, 1, 15, 18, 1, 0, 1, 0, 1, - 0, 2, 0, 1, 3, 5, 5, 7, 4, 0, - 1, 3, 2, 0, 1, 0, 1, 1, 0, 2, - 2, 0, 8, 11, 6, 6, 2, 0, 3, 2, - 1, 3, 1, 3, 2, 1, 1, 2, 3, 2, - 1, 3, 3, 3, 2, 2, 1, 1, 1, 1, - 2, 1, 1, 1, 1, 4, 5, 1, 3, 3, - 1, 3, 3, 5, 6, 1, 3, 2, 1, 3, - 1, 2, 4, 5, 1, 1, 1, 1, 3, 3, - 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, - 2, 1, 1, 1, 3, 3, 5, 2, 0, 2, - 1, 3, 5, 5, 5, 1, 2, 1, 0, 4, - 6, 4, 6, 4, 6, 4, 6, 4, 6, 3, - 5, 5, 5, 1, 3, 1, 3, 2, 2, 1, - 2, 1, 2, 11, 10, 10, 2, 2, 0, 9, - 2, 0, 10, 11, 11, 5, 5, 8, 3, 3, - 6, 6, 1, 1, 1, 1, 1, 1, 3, 1, - 5, 5, 6, 6, 6, 6, 6, 8, 8, 6, - 6, 7, 9, 9, 8, 10, 6, 6, 6, 6, - 6, 6, 6, 8, 6, 8, 6, 8, 7, 9, - 6, 8, 7, 9, 8, 10, 9, 11, 8, 10, - 9, 11, 8, 8, 7, 6, 6, 6, 6, 8, - 8, 8, 8, 6, 9, 1, 0, 2, 0, 7, - 7, 7, 9, 8, 7, 6, 6, 6, 6, 6, - 6, 6, 9, 9, 6, 6, 6, 8, 6, 8, - 8, 8, 8, 6, 8, 6, 8, 7, 9, 7, - 9, 6, 7, 1, 3, 3, 3, 1, 1, 1, - 1, 1, 6, 6, 6, 6, 6, 6, 7, 7, - 6, 9, 9, 6, 6, 6, 6, 6, 6, 8, - 8, 8, 6, 7, 6, 6, 5, 1, 0, 3, - 3, 5, 6, 6, 6, 8, 1, 3, 1, 5, - 5, 6, 7, 4, 4, 4, 6, 13, 1, 1, - 3, 3, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 0, 3, 2, 0, - 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, - 3, 2, 5, 4, 3, 3, 3, 1, 1, 0, - 3, 2, 2, 1, 2, 1, 3, 2, 1, 0, - 9, 11, 12, 14, 3, 4, 4, 0, 2, 5, - 1, 0, 1, 2, 3, 3, 3, 1, 2, 1, - 1, 1, 1, 1, 1, 0, 5, 4, 6, 4, - 3, 5, 5, 4, 4, 6, 4, 6, 6, 5, - 7, 9, 6, 1, 0, 6, 11, 11, 11, 13, - 9, 11, 1, 1, 10, 4, 2, 5, 2, 0, - 6, 5, 1, 3, 1, 1, 1, 1, 1, 3, - 5, 1, 3, 1, 1, 1, 1, 0, 1, 0, - 1, 0, 1, 0, 3, 0, 2, 1, 3, 1, - 0, 2, 4, 3, 5, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, - 1, 0, 5, 3, 0, 1, 1, 1, 1, 3, - 9, 3, 0, 2, 3, 2, 3, 7, 1, 3, - 1, 4, 4, 7, 2, 1, 1, 1, 3, 2, - 8, 5, 0, 4, 3, 0, 2, 0, 7, 2, - 0, 5, 3, 0, 2, 2, 2, 3, 1, 3, - 1, 2, 1, 0, 1, 2, 0, 8, 1, 3, - 3, 5, 2, 1, 3, 7, 1, 0, 3, 2, - 2, 2, 0, 2, 2, 1, 1, 3, 3, 1, - 2, 4, 4, 2, 3, 5, 5, 1, 1, 9, - 9, 1, 2, 4, 4, 4, 2, 2, 3, 1, - 3, 6, 1, 0, 2, 0, 3, 3, 4, 4, - 4, 4, 3, 2, 1, 1, 0, 1, 1, 0, - 1, 5, 1, 0, 1, 0, 3, 1, 3, 4, - 3, 2, 2, 1, 1, 1, 0, 2, 4, 5, - 4, 2, 3, 1, 1, 1, 1, 2, 2, 1, - 1, 1, 1, 1, 1, 3, 0, 1, 3, 1, - 1, 1, 1, 1, 2, 4, 4, 5, 2, 0, - 1, 3, 1, 0, 1, 2, 3, 2, 4, 2, - 3, 2, 0, 4, 5, 2, 0, 1, 3, 2, - 3, 2, 3, 2, 3, 2, 3, 1, 4, 3, - 4, 5, 4, 5, 4, 5, 2, 4, 1, 1, - 0, 1, 4, 5, 4, 0, 2, 2, 2, 1, - 1, 0, 4, 2, 1, 2, 2, 4, 1, 3, - 1, 2, 3, 6, 4, 0, 2, 6, 2, 1, - 3, 4, 0, 2, 0, 2, 0, 2, 4, 0, - 1, 0, 1, 3, 3, 7, 12, 1, 3, 2, - 3, 3, 1, 2, 2, 2, 2, 1, 1, 3, - 3, 2, 2, 3, 5, 6, 2, 3, 3, 4, - 0, 1, 1, 1, 1, 1, 2, 4, 1, 1, - 1, 1, 2, 3, 3, 0, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 1, 3, 0, 1, - 1, 1, 1, 5, 2, 1, 1, 1, 1, 4, - 1, 2, 2, 1, 3, 3, 2, 1, 0, 5, - 2, 5, 2, 1, 3, 3, 0, 1, 1, 1, - 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, - 0, 1, 4, 1, 3, 3, 5, 2, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 3, 3, 2, 2, 3, 5, - 4, 6, 3, 5, 4, 6, 4, 6, 5, 7, - 3, 2, 4, 2, 3, 3, 4, 3, 4, 3, - 4, 5, 6, 6, 7, 6, 7, 6, 7, 3, - 4, 4, 6, 2, 3, 4, 1, 1, 3, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 2, 2, 5, 6, 6, 7, - 3, 4, 1, 1, 2, 4, 1, 1, 1, 2, - 2, 2, 2, 1, 1, 4, 3, 5, 6, 8, - 6, 6, 4, 4, 1, 1, 1, 5, 1, 1, - 4, 1, 4, 1, 4, 1, 4, 1, 1, 1, - 1, 1, 1, 6, 4, 4, 4, 4, 6, 5, - 5, 5, 4, 6, 4, 4, 4, 4, 5, 7, - 7, 9, 5, 4, 6, 5, 7, 7, 7, 2, - 3, 3, 3, 4, 0, 4, 1, 3, 3, 1, - 1, 1, 2, 2, 0, 2, 4, 4, 6, 5, - 0, 5, 0, 2, 0, 1, 3, 3, 2, 2, - 0, 6, 1, 0, 3, 0, 3, 3, 3, 0, - 1, 4, 2, 2, 2, 2, 2, 3, 2, 2, - 3, 0, 4, 3, 5, 4, 3, 5, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 4, 1, 4, 1, - 4, 1, 2, 1, 2, 1, 3, 1, 3, 1, - 3, 3, 1, 3, 3, 3, 2, 1, 3, 3, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 4, - 3, 2, 3, 0, 3, 3, 2, 2, 1, 0, - 2, 2, 3, 2, 1, 1, 3, 5, 1, 2, - 4, 2, 0, 1, 0, 1, 2, 2, 2, 3, - 5, 1, 0, 1, 2, 0, 2, 1, 0, 1, - 0, 1, 3, 3, 2, 1, 1, 1, 3, 1, - 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 2, 6, 2, 3, - 5, 1, 1, 1, 1, 1, 1, 2, 2, 1, - 1, 1, 1, 1, 3, 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, 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, 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, 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, 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, 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, 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, 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, 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, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 -}; - - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, yyscanner, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (0) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - -/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - -YY_ATTRIBUTE_UNUSED -static unsigned -yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -{ - unsigned res = 0; - int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; - if (0 <= yylocp->first_line) - { - res += YYFPRINTF (yyo, "%d", yylocp->first_line); - if (0 <= yylocp->first_column) - res += YYFPRINTF (yyo, ".%d", yylocp->first_column); - } - if (0 <= yylocp->last_line) - { - if (yylocp->first_line < yylocp->last_line) - { - res += YYFPRINTF (yyo, "-%d", yylocp->last_line); - if (0 <= end_col) - res += YYFPRINTF (yyo, ".%d", end_col); - } - else if (0 <= end_col && yylocp->first_column < end_col) - res += YYFPRINTF (yyo, "-%d", end_col); - } - return res; - } - -# define YY_LOCATION_PRINT(File, Loc) \ - yy_location_print_ (File, &(Loc)) - -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, yyscanner); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, core_yyscan_t yyscanner) -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - YYUSE (yylocationp); - YYUSE (yyscanner); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, core_yyscan_t yyscanner) -{ - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, yyscanner); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, core_yyscan_t yyscanner) -{ - unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , yyscanner); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, yylsp, Rule, yyscanner); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, core_yyscan_t yyscanner) -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (yyscanner); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (core_yyscan_t yyscanner) -{ -/* The lookahead symbol. */ -int yychar; - - -/* The semantic value of the lookahead symbol. */ -/* Default value used for initialization, for pacifying older GCCs - or non-GCC compilers. */ -YY_INITIAL_VALUE (static YYSTYPE yyval_default;) -YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); - -/* Location data for the lookahead symbol. */ -static YYLTYPE yyloc_default -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } -# endif -; -YYLTYPE yylloc = yyloc_default; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - 'yyls': related to locations. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - yylsp[0] = yylloc; - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (&yylval, &yylloc, yyscanner); - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 822 "gram.y" /* yacc.c:1646 */ - { - pg_yyget_extra(yyscanner)->parsetree = (yyvsp[0].list); - } -#line 25931 "gram.c" /* yacc.c:1646 */ - break; - - case 3: -#line 838 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[-2].list) != NIL) - { - /* update length of previous stmt */ - updateRawStmtEnd(llast_node(RawStmt, (yyvsp[-2].list)), (yylsp[-1])); - } - if ((yyvsp[0].node) != NULL) - (yyval.list) = lappend((yyvsp[-2].list), makeRawStmt((yyvsp[0].node), (yylsp[-1]) + 1)); - else - (yyval.list) = (yyvsp[-2].list); - } -#line 25947 "gram.c" /* yacc.c:1646 */ - break; - - case 4: -#line 850 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].node) != NULL) - (yyval.list) = list_make1(makeRawStmt((yyvsp[0].node), 0)); - else - (yyval.list) = NIL; - } -#line 25958 "gram.c" /* yacc.c:1646 */ - break; - - case 129: -#line 984 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 25964 "gram.c" /* yacc.c:1646 */ - break; - - case 130: -#line 994 "gram.y" /* yacc.c:1646 */ - { - CallStmt *n = makeNode(CallStmt); - n->funccall = castNode(FuncCall, (yyvsp[0].node)); - (yyval.node) = (Node *)n; - } -#line 25974 "gram.c" /* yacc.c:1646 */ - break; - - case 131: -#line 1009 "gram.y" /* yacc.c:1646 */ - { - CreateRoleStmt *n = makeNode(CreateRoleStmt); - n->stmt_type = ROLESTMT_ROLE; - n->role = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 25986 "gram.c" /* yacc.c:1646 */ - break; - - case 132: -#line 1019 "gram.y" /* yacc.c:1646 */ - {} -#line 25992 "gram.c" /* yacc.c:1646 */ - break; - - case 133: -#line 1020 "gram.y" /* yacc.c:1646 */ - {} -#line 25998 "gram.c" /* yacc.c:1646 */ - break; - - case 134: -#line 1021 "gram.y" /* yacc.c:1646 */ - {} -#line 26004 "gram.c" /* yacc.c:1646 */ - break; - - case 135: -#line 1030 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 26010 "gram.c" /* yacc.c:1646 */ - break; - - case 136: -#line 1031 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 26016 "gram.c" /* yacc.c:1646 */ - break; - - case 137: -#line 1035 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 26022 "gram.c" /* yacc.c:1646 */ - break; - - case 138: -#line 1036 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 26028 "gram.c" /* yacc.c:1646 */ - break; - - case 139: -#line 1041 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("password", - (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 26037 "gram.c" /* yacc.c:1646 */ - break; - - case 140: -#line 1046 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("password", NULL, (yylsp[-1])); - } -#line 26045 "gram.c" /* yacc.c:1646 */ - break; - - case 141: -#line 1050 "gram.y" /* yacc.c:1646 */ - { - /* - * These days, passwords are always stored in encrypted - * form, so there is no difference between PASSWORD and - * ENCRYPTED PASSWORD. - */ - (yyval.defelt) = makeDefElem("password", - (Node *)makeString((yyvsp[0].str)), (yylsp[-2])); - } -#line 26059 "gram.c" /* yacc.c:1646 */ - break; - - case 142: -#line 1060 "gram.y" /* yacc.c:1646 */ - { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("UNENCRYPTED PASSWORD is no longer supported"), - errhint("Remove UNENCRYPTED to store the password in encrypted form instead."), - parser_errposition((yylsp[-2])))); - } -#line 26071 "gram.c" /* yacc.c:1646 */ - break; - - case 143: -#line 1068 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("inherit", (Node *)makeInteger(true), (yylsp[0])); - } -#line 26079 "gram.c" /* yacc.c:1646 */ - break; - - case 144: -#line 1072 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("connectionlimit", (Node *)makeInteger((yyvsp[0].ival)), (yylsp[-2])); - } -#line 26087 "gram.c" /* yacc.c:1646 */ - break; - - case 145: -#line 1076 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("validUntil", (Node *)makeString((yyvsp[0].str)), (yylsp[-2])); - } -#line 26095 "gram.c" /* yacc.c:1646 */ - break; - - case 146: -#line 1081 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("rolemembers", (Node *)(yyvsp[0].list), (yylsp[-1])); - } -#line 26103 "gram.c" /* yacc.c:1646 */ - break; - - case 147: -#line 1085 "gram.y" /* yacc.c:1646 */ - { - /* - * We handle identifiers that aren't parser keywords with - * the following special-case codes, to avoid bloating the - * size of the main parser. - */ - if (strcmp((yyvsp[0].str), "superuser") == 0) - (yyval.defelt) = makeDefElem("superuser", (Node *)makeInteger(true), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "nosuperuser") == 0) - (yyval.defelt) = makeDefElem("superuser", (Node *)makeInteger(false), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "createrole") == 0) - (yyval.defelt) = makeDefElem("createrole", (Node *)makeInteger(true), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "nocreaterole") == 0) - (yyval.defelt) = makeDefElem("createrole", (Node *)makeInteger(false), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "replication") == 0) - (yyval.defelt) = makeDefElem("isreplication", (Node *)makeInteger(true), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "noreplication") == 0) - (yyval.defelt) = makeDefElem("isreplication", (Node *)makeInteger(false), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "createdb") == 0) - (yyval.defelt) = makeDefElem("createdb", (Node *)makeInteger(true), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "nocreatedb") == 0) - (yyval.defelt) = makeDefElem("createdb", (Node *)makeInteger(false), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "login") == 0) - (yyval.defelt) = makeDefElem("canlogin", (Node *)makeInteger(true), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "nologin") == 0) - (yyval.defelt) = makeDefElem("canlogin", (Node *)makeInteger(false), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "bypassrls") == 0) - (yyval.defelt) = makeDefElem("bypassrls", (Node *)makeInteger(true), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "nobypassrls") == 0) - (yyval.defelt) = makeDefElem("bypassrls", (Node *)makeInteger(false), (yylsp[0])); - else if (strcmp((yyvsp[0].str), "noinherit") == 0) - { - /* - * Note that INHERIT is a keyword, so it's handled by main parser, but - * NOINHERIT is handled here. - */ - (yyval.defelt) = makeDefElem("inherit", (Node *)makeInteger(false), (yylsp[0])); - } - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized role option \"%s\"", (yyvsp[0].str)), - parser_errposition((yylsp[0])))); - } -#line 26152 "gram.c" /* yacc.c:1646 */ - break; - - case 148: -#line 1132 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = (yyvsp[0].defelt); } -#line 26158 "gram.c" /* yacc.c:1646 */ - break; - - case 149: -#line 1135 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("sysid", (Node *)makeInteger((yyvsp[0].ival)), (yylsp[-1])); - } -#line 26166 "gram.c" /* yacc.c:1646 */ - break; - - case 150: -#line 1139 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("adminmembers", (Node *)(yyvsp[0].list), (yylsp[-1])); - } -#line 26174 "gram.c" /* yacc.c:1646 */ - break; - - case 151: -#line 1143 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("rolemembers", (Node *)(yyvsp[0].list), (yylsp[-1])); - } -#line 26182 "gram.c" /* yacc.c:1646 */ - break; - - case 152: -#line 1147 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("addroleto", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 26190 "gram.c" /* yacc.c:1646 */ - break; - - case 153: -#line 1151 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("addroleto", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 26198 "gram.c" /* yacc.c:1646 */ - break; - - case 154: -#line 1165 "gram.y" /* yacc.c:1646 */ - { - CreateRoleStmt *n = makeNode(CreateRoleStmt); - n->stmt_type = ROLESTMT_USER; - n->role = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26210 "gram.c" /* yacc.c:1646 */ - break; - - case 155: -#line 1183 "gram.y" /* yacc.c:1646 */ - { - AlterRoleStmt *n = makeNode(AlterRoleStmt); - n->role = (yyvsp[-2].rolespec); - n->action = +1; /* add, if there are members */ - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26222 "gram.c" /* yacc.c:1646 */ - break; - - case 156: -#line 1191 "gram.y" /* yacc.c:1646 */ - { - AlterRoleStmt *n = makeNode(AlterRoleStmt); - n->role = (yyvsp[-2].rolespec); - n->action = +1; /* add, if there are members */ - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26234 "gram.c" /* yacc.c:1646 */ - break; - - case 157: -#line 1201 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 26240 "gram.c" /* yacc.c:1646 */ - break; - - case 158: -#line 1202 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 26246 "gram.c" /* yacc.c:1646 */ - break; - - case 159: -#line 1207 "gram.y" /* yacc.c:1646 */ - { - AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); - n->role = (yyvsp[-2].rolespec); - n->database = (yyvsp[-1].str); - n->setstmt = (yyvsp[0].vsetstmt); - (yyval.node) = (Node *)n; - } -#line 26258 "gram.c" /* yacc.c:1646 */ - break; - - case 160: -#line 1215 "gram.y" /* yacc.c:1646 */ - { - AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); - n->role = NULL; - n->database = (yyvsp[-1].str); - n->setstmt = (yyvsp[0].vsetstmt); - (yyval.node) = (Node *)n; - } -#line 26270 "gram.c" /* yacc.c:1646 */ - break; - - case 161: -#line 1223 "gram.y" /* yacc.c:1646 */ - { - AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); - n->role = (yyvsp[-2].rolespec); - n->database = (yyvsp[-1].str); - n->setstmt = (yyvsp[0].vsetstmt); - (yyval.node) = (Node *)n; - } -#line 26282 "gram.c" /* yacc.c:1646 */ - break; - - case 162: -#line 1231 "gram.y" /* yacc.c:1646 */ - { - AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); - n->role = NULL; - n->database = (yyvsp[-1].str); - n->setstmt = (yyvsp[0].vsetstmt); - (yyval.node) = (Node *)n; - } -#line 26294 "gram.c" /* yacc.c:1646 */ - break; - - case 163: -#line 1252 "gram.y" /* yacc.c:1646 */ - { - DropRoleStmt *n = makeNode(DropRoleStmt); - n->missing_ok = false; - n->roles = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26305 "gram.c" /* yacc.c:1646 */ - break; - - case 164: -#line 1259 "gram.y" /* yacc.c:1646 */ - { - DropRoleStmt *n = makeNode(DropRoleStmt); - n->missing_ok = true; - n->roles = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26316 "gram.c" /* yacc.c:1646 */ - break; - - case 165: -#line 1266 "gram.y" /* yacc.c:1646 */ - { - DropRoleStmt *n = makeNode(DropRoleStmt); - n->missing_ok = false; - n->roles = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26327 "gram.c" /* yacc.c:1646 */ - break; - - case 166: -#line 1273 "gram.y" /* yacc.c:1646 */ - { - DropRoleStmt *n = makeNode(DropRoleStmt); - n->roles = (yyvsp[0].list); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 26338 "gram.c" /* yacc.c:1646 */ - break; - - case 167: -#line 1280 "gram.y" /* yacc.c:1646 */ - { - DropRoleStmt *n = makeNode(DropRoleStmt); - n->missing_ok = false; - n->roles = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26349 "gram.c" /* yacc.c:1646 */ - break; - - case 168: -#line 1287 "gram.y" /* yacc.c:1646 */ - { - DropRoleStmt *n = makeNode(DropRoleStmt); - n->missing_ok = true; - n->roles = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26360 "gram.c" /* yacc.c:1646 */ - break; - - case 169: -#line 1304 "gram.y" /* yacc.c:1646 */ - { - CreateRoleStmt *n = makeNode(CreateRoleStmt); - n->stmt_type = ROLESTMT_GROUP; - n->role = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 26372 "gram.c" /* yacc.c:1646 */ - break; - - case 170: -#line 1322 "gram.y" /* yacc.c:1646 */ - { - AlterRoleStmt *n = makeNode(AlterRoleStmt); - n->role = (yyvsp[-3].rolespec); - n->action = (yyvsp[-2].ival); - n->options = list_make1(makeDefElem("rolemembers", - (Node *)(yyvsp[0].list), (yylsp[0]))); - (yyval.node) = (Node *)n; - } -#line 26385 "gram.c" /* yacc.c:1646 */ - break; - - case 171: -#line 1332 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = +1; } -#line 26391 "gram.c" /* yacc.c:1646 */ - break; - - case 172: -#line 1333 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = -1; } -#line 26397 "gram.c" /* yacc.c:1646 */ - break; - - case 173: -#line 1345 "gram.y" /* yacc.c:1646 */ - { - CreateSchemaStmt *n = makeNode(CreateSchemaStmt); - /* One can omit the schema name or the authorization id. */ - n->schemaname = (yyvsp[-3].str); - n->authrole = (yyvsp[-1].rolespec); - n->schemaElts = (yyvsp[0].list); - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 26411 "gram.c" /* yacc.c:1646 */ - break; - - case 174: -#line 1355 "gram.y" /* yacc.c:1646 */ - { - CreateSchemaStmt *n = makeNode(CreateSchemaStmt); - /* ...but not both */ - n->schemaname = (yyvsp[-1].str); - n->authrole = NULL; - n->schemaElts = (yyvsp[0].list); - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 26425 "gram.c" /* yacc.c:1646 */ - break; - - case 175: -#line 1365 "gram.y" /* yacc.c:1646 */ - { - CreateSchemaStmt *n = makeNode(CreateSchemaStmt); - /* schema name can be omitted here, too */ - n->schemaname = (yyvsp[-3].str); - n->authrole = (yyvsp[-1].rolespec); - if ((yyvsp[0].list) != NIL) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"), - parser_errposition((yylsp[0])))); - n->schemaElts = (yyvsp[0].list); - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 26444 "gram.c" /* yacc.c:1646 */ - break; - - case 176: -#line 1380 "gram.y" /* yacc.c:1646 */ - { - CreateSchemaStmt *n = makeNode(CreateSchemaStmt); - /* ...but not here */ - n->schemaname = (yyvsp[-1].str); - n->authrole = NULL; - if ((yyvsp[0].list) != NIL) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"), - parser_errposition((yylsp[0])))); - n->schemaElts = (yyvsp[0].list); - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 26463 "gram.c" /* yacc.c:1646 */ - break; - - case 177: -#line 1397 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 26469 "gram.c" /* yacc.c:1646 */ - break; - - case 178: -#line 1398 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 26475 "gram.c" /* yacc.c:1646 */ - break; - - case 179: -#line 1403 "gram.y" /* yacc.c:1646 */ - { - if ((yyloc) < 0) /* see comments for YYLLOC_DEFAULT */ - (yyloc) = (yylsp[0]); - (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].node)); - } -#line 26485 "gram.c" /* yacc.c:1646 */ - break; - - case 180: -#line 1409 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 26491 "gram.c" /* yacc.c:1646 */ - break; - - case 187: -#line 1437 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = (yyvsp[0].vsetstmt); - n->type = T_PgpoolVariableSetStmt; /* Hack to keep changes minumum */ - n->is_local = false; - (yyval.node) = (Node *) n; - } -#line 26502 "gram.c" /* yacc.c:1646 */ - break; - - case 188: -#line 1444 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = (yyvsp[0].vsetstmt); - n->is_local = false; - (yyval.node) = (Node *) n; - } -#line 26512 "gram.c" /* yacc.c:1646 */ - break; - - case 189: -#line 1450 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = (yyvsp[0].vsetstmt); - n->is_local = true; - (yyval.node) = (Node *) n; - } -#line 26522 "gram.c" /* yacc.c:1646 */ - break; - - case 190: -#line 1456 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = (yyvsp[0].vsetstmt); - n->is_local = false; - (yyval.node) = (Node *) n; - } -#line 26532 "gram.c" /* yacc.c:1646 */ - break; - - case 191: -#line 1465 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_MULTI; - n->name = "TRANSACTION"; - n->args = (yyvsp[0].list); - (yyval.vsetstmt) = n; - } -#line 26544 "gram.c" /* yacc.c:1646 */ - break; - - case 192: -#line 1473 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_MULTI; - n->name = "SESSION CHARACTERISTICS"; - n->args = (yyvsp[0].list); - (yyval.vsetstmt) = n; - } -#line 26556 "gram.c" /* yacc.c:1646 */ - break; - - case 194: -#line 1485 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = (yyvsp[-2].str); - n->args = (yyvsp[0].list); - (yyval.vsetstmt) = n; - } -#line 26568 "gram.c" /* yacc.c:1646 */ - break; - - case 195: -#line 1493 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = (yyvsp[-2].str); - n->args = (yyvsp[0].list); - (yyval.vsetstmt) = n; - } -#line 26580 "gram.c" /* yacc.c:1646 */ - break; - - case 196: -#line 1501 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_DEFAULT; - n->name = (yyvsp[-2].str); - (yyval.vsetstmt) = n; - } -#line 26591 "gram.c" /* yacc.c:1646 */ - break; - - case 197: -#line 1508 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_DEFAULT; - n->name = (yyvsp[-2].str); - (yyval.vsetstmt) = n; - } -#line 26602 "gram.c" /* yacc.c:1646 */ - break; - - case 198: -#line 1516 "gram.y" /* yacc.c:1646 */ - {(yyval.vsetstmt) = (yyvsp[0].vsetstmt);} -#line 26608 "gram.c" /* yacc.c:1646 */ - break; - - case 199: -#line 1518 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_CURRENT; - n->name = (yyvsp[-2].str); - (yyval.vsetstmt) = n; - } -#line 26619 "gram.c" /* yacc.c:1646 */ - break; - - case 200: -#line 1526 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = "timezone"; - if ((yyvsp[0].node) != NULL) - n->args = list_make1((yyvsp[0].node)); - else - n->kind = VAR_SET_DEFAULT; - (yyval.vsetstmt) = n; - } -#line 26634 "gram.c" /* yacc.c:1646 */ - break; - - case 201: -#line 1537 "gram.y" /* yacc.c:1646 */ - { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("current database cannot be changed"), - parser_errposition((yylsp[0])))); - (yyval.vsetstmt) = NULL; /*not reached*/ - } -#line 26646 "gram.c" /* yacc.c:1646 */ - break; - - case 202: -#line 1545 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = "search_path"; - n->args = list_make1(makeStringConst((yyvsp[0].str), (yylsp[0]))); - (yyval.vsetstmt) = n; - } -#line 26658 "gram.c" /* yacc.c:1646 */ - break; - - case 203: -#line 1553 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = "client_encoding"; - if ((yyvsp[0].str) != NULL) - n->args = list_make1(makeStringConst((yyvsp[0].str), (yylsp[0]))); - else - n->kind = VAR_SET_DEFAULT; - (yyval.vsetstmt) = n; - } -#line 26673 "gram.c" /* yacc.c:1646 */ - break; - - case 204: -#line 1564 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = "role"; - n->args = list_make1(makeStringConst((yyvsp[0].str), (yylsp[0]))); - (yyval.vsetstmt) = n; - } -#line 26685 "gram.c" /* yacc.c:1646 */ - break; - - case 205: -#line 1572 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = "session_authorization"; - n->args = list_make1(makeStringConst((yyvsp[0].str), (yylsp[0]))); - (yyval.vsetstmt) = n; - } -#line 26697 "gram.c" /* yacc.c:1646 */ - break; - - case 206: -#line 1580 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_DEFAULT; - n->name = "session_authorization"; - (yyval.vsetstmt) = n; - } -#line 26708 "gram.c" /* yacc.c:1646 */ - break; - - case 207: -#line 1587 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_VALUE; - n->name = "xmloption"; - n->args = list_make1(makeStringConst((yyvsp[0].ival) == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", (yylsp[0]))); - (yyval.vsetstmt) = n; - } -#line 26720 "gram.c" /* yacc.c:1646 */ - break; - - case 208: -#line 1596 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_SET_MULTI; - n->name = "TRANSACTION SNAPSHOT"; - n->args = list_make1(makeStringConst((yyvsp[0].str), (yylsp[0]))); - (yyval.vsetstmt) = n; - } -#line 26732 "gram.c" /* yacc.c:1646 */ - break; - - case 209: -#line 1605 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 26738 "gram.c" /* yacc.c:1646 */ - break; - - case 210: -#line 1607 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = psprintf("%s.%s", (yyvsp[-2].str), (yyvsp[0].str)); } -#line 26744 "gram.c" /* yacc.c:1646 */ - break; - - case 211: -#line 1610 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 26750 "gram.c" /* yacc.c:1646 */ - break; - - case 212: -#line 1611 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 26756 "gram.c" /* yacc.c:1646 */ - break; - - case 213: -#line 1615 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeStringConst((yyvsp[0].str), (yylsp[0])); } -#line 26762 "gram.c" /* yacc.c:1646 */ - break; - - case 214: -#line 1617 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeAConst((yyvsp[0].value), (yylsp[0])); } -#line 26768 "gram.c" /* yacc.c:1646 */ - break; - - case 215: -#line 1620 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "read uncommitted"; } -#line 26774 "gram.c" /* yacc.c:1646 */ - break; - - case 216: -#line 1621 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "read committed"; } -#line 26780 "gram.c" /* yacc.c:1646 */ - break; - - case 217: -#line 1622 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "repeatable read"; } -#line 26786 "gram.c" /* yacc.c:1646 */ - break; - - case 218: -#line 1623 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "serializable"; } -#line 26792 "gram.c" /* yacc.c:1646 */ - break; - - case 219: -#line 1627 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "true"; } -#line 26798 "gram.c" /* yacc.c:1646 */ - break; - - case 220: -#line 1628 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "false"; } -#line 26804 "gram.c" /* yacc.c:1646 */ - break; - - case 221: -#line 1629 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "on"; } -#line 26810 "gram.c" /* yacc.c:1646 */ - break; - - case 222: -#line 1635 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 26816 "gram.c" /* yacc.c:1646 */ - break; - - case 223: -#line 1648 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeStringConst((yyvsp[0].str), (yylsp[0])); - } -#line 26824 "gram.c" /* yacc.c:1646 */ - break; - - case 224: -#line 1652 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeStringConst((yyvsp[0].str), (yylsp[0])); - } -#line 26832 "gram.c" /* yacc.c:1646 */ - break; - - case 225: -#line 1656 "gram.y" /* yacc.c:1646 */ - { - TypeName *t = (yyvsp[-2].typnam); - if ((yyvsp[0].list) != NIL) - { - A_Const *n = (A_Const *) linitial((yyvsp[0].list)); - if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("time zone interval must be HOUR or HOUR TO MINUTE"), - parser_errposition((yylsp[0])))); - } - t->typmods = (yyvsp[0].list); - (yyval.node) = makeStringConstCast((yyvsp[-1].str), (yylsp[-1]), t); - } -#line 26851 "gram.c" /* yacc.c:1646 */ - break; - - case 226: -#line 1671 "gram.y" /* yacc.c:1646 */ - { - TypeName *t = (yyvsp[-4].typnam); - t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), - makeIntConst((yyvsp[-2].ival), (yylsp[-2]))); - (yyval.node) = makeStringConstCast((yyvsp[0].str), (yylsp[0]), t); - } -#line 26862 "gram.c" /* yacc.c:1646 */ - break; - - case 227: -#line 1677 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeAConst((yyvsp[0].value), (yylsp[0])); } -#line 26868 "gram.c" /* yacc.c:1646 */ - break; - - case 228: -#line 1678 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 26874 "gram.c" /* yacc.c:1646 */ - break; - - case 229: -#line 1679 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 26880 "gram.c" /* yacc.c:1646 */ - break; - - case 230: -#line 1683 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 26886 "gram.c" /* yacc.c:1646 */ - break; - - case 231: -#line 1684 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 26892 "gram.c" /* yacc.c:1646 */ - break; - - case 232: -#line 1685 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 26898 "gram.c" /* yacc.c:1646 */ - break; - - case 233: -#line 1689 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 26904 "gram.c" /* yacc.c:1646 */ - break; - - case 234: -#line 1690 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 26910 "gram.c" /* yacc.c:1646 */ - break; - - case 235: -#line 1694 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) (yyvsp[0].vsetstmt); } -#line 26916 "gram.c" /* yacc.c:1646 */ - break; - - case 236: -#line 1696 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = (yyvsp[0].vsetstmt); - n->type = T_PgpoolVariableSetStmt; /* Hack to keep the changes minumum */ - (yyval.node) = (Node *) n; - } -#line 26926 "gram.c" /* yacc.c:1646 */ - break; - - case 237: -#line 1704 "gram.y" /* yacc.c:1646 */ - { (yyval.vsetstmt) = (yyvsp[0].vsetstmt); } -#line 26932 "gram.c" /* yacc.c:1646 */ - break; - - case 238: -#line 1706 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_RESET; - n->name = "timezone"; - (yyval.vsetstmt) = n; - } -#line 26943 "gram.c" /* yacc.c:1646 */ - break; - - case 239: -#line 1713 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_RESET; - n->name = "transaction_isolation"; - (yyval.vsetstmt) = n; - } -#line 26954 "gram.c" /* yacc.c:1646 */ - break; - - case 240: -#line 1720 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_RESET; - n->name = "session_authorization"; - (yyval.vsetstmt) = n; - } -#line 26965 "gram.c" /* yacc.c:1646 */ - break; - - case 241: -#line 1730 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_RESET; - n->name = (yyvsp[0].str); - (yyval.vsetstmt) = n; - } -#line 26976 "gram.c" /* yacc.c:1646 */ - break; - - case 242: -#line 1737 "gram.y" /* yacc.c:1646 */ - { - VariableSetStmt *n = makeNode(VariableSetStmt); - n->kind = VAR_RESET_ALL; - (yyval.vsetstmt) = n; - } -#line 26986 "gram.c" /* yacc.c:1646 */ - break; - - case 243: -#line 1746 "gram.y" /* yacc.c:1646 */ - { (yyval.vsetstmt) = (yyvsp[0].vsetstmt); } -#line 26992 "gram.c" /* yacc.c:1646 */ - break; - - case 244: -#line 1747 "gram.y" /* yacc.c:1646 */ - { (yyval.vsetstmt) = (VariableSetStmt *) (yyvsp[0].node); } -#line 26998 "gram.c" /* yacc.c:1646 */ - break; - - case 245: -#line 1752 "gram.y" /* yacc.c:1646 */ - { (yyval.vsetstmt) = (yyvsp[0].vsetstmt); } -#line 27004 "gram.c" /* yacc.c:1646 */ - break; - - case 246: -#line 1753 "gram.y" /* yacc.c:1646 */ - { (yyval.vsetstmt) = (VariableSetStmt *) (yyvsp[0].node); } -#line 27010 "gram.c" /* yacc.c:1646 */ - break; - - case 247: -#line 1760 "gram.y" /* yacc.c:1646 */ - { - VariableShowStmt *n = (VariableShowStmt *)newNode(sizeof(VariableShowStmt),T_PgpoolVariableShowStmt); - n->name = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 27020 "gram.c" /* yacc.c:1646 */ - break; - - case 248: -#line 1766 "gram.y" /* yacc.c:1646 */ - { - VariableShowStmt *n = (VariableShowStmt *)newNode(sizeof(VariableShowStmt),T_PgpoolVariableShowStmt); - n->name = "all"; - (yyval.node) = (Node *) n; - } -#line 27030 "gram.c" /* yacc.c:1646 */ - break; - - case 249: -#line 1772 "gram.y" /* yacc.c:1646 */ - { - VariableShowStmt *n = makeNode(VariableShowStmt); - n->name = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 27040 "gram.c" /* yacc.c:1646 */ - break; - - case 250: -#line 1778 "gram.y" /* yacc.c:1646 */ - { - VariableShowStmt *n = makeNode(VariableShowStmt); - n->name = "timezone"; - (yyval.node) = (Node *) n; - } -#line 27050 "gram.c" /* yacc.c:1646 */ - break; - - case 251: -#line 1784 "gram.y" /* yacc.c:1646 */ - { - VariableShowStmt *n = makeNode(VariableShowStmt); - n->name = "transaction_isolation"; - (yyval.node) = (Node *) n; - } -#line 27060 "gram.c" /* yacc.c:1646 */ - break; - - case 252: -#line 1790 "gram.y" /* yacc.c:1646 */ - { - VariableShowStmt *n = makeNode(VariableShowStmt); - n->name = "session_authorization"; - (yyval.node) = (Node *) n; - } -#line 27070 "gram.c" /* yacc.c:1646 */ - break; - - case 253: -#line 1796 "gram.y" /* yacc.c:1646 */ - { - VariableShowStmt *n = makeNode(VariableShowStmt); - n->name = "all"; - (yyval.node) = (Node *) n; - } -#line 27080 "gram.c" /* yacc.c:1646 */ - break; - - case 254: -#line 1806 "gram.y" /* yacc.c:1646 */ - { - ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt); - n->constraints = (yyvsp[-1].list); - n->deferred = (yyvsp[0].boolean); - (yyval.node) = (Node *) n; - } -#line 27091 "gram.c" /* yacc.c:1646 */ - break; - - case 255: -#line 1815 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 27097 "gram.c" /* yacc.c:1646 */ - break; - - case 256: -#line 1816 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 27103 "gram.c" /* yacc.c:1646 */ - break; - - case 257: -#line 1820 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 27109 "gram.c" /* yacc.c:1646 */ - break; - - case 258: -#line 1821 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 27115 "gram.c" /* yacc.c:1646 */ - break; - - case 259: -#line 1830 "gram.y" /* yacc.c:1646 */ - { - CheckPointStmt *n = makeNode(CheckPointStmt); - (yyval.node) = (Node *)n; - } -#line 27124 "gram.c" /* yacc.c:1646 */ - break; - - case 260: -#line 1845 "gram.y" /* yacc.c:1646 */ - { - DiscardStmt *n = makeNode(DiscardStmt); - n->target = DISCARD_ALL; - (yyval.node) = (Node *) n; - } -#line 27134 "gram.c" /* yacc.c:1646 */ - break; - - case 261: -#line 1851 "gram.y" /* yacc.c:1646 */ - { - DiscardStmt *n = makeNode(DiscardStmt); - n->target = DISCARD_TEMP; - (yyval.node) = (Node *) n; - } -#line 27144 "gram.c" /* yacc.c:1646 */ - break; - - case 262: -#line 1857 "gram.y" /* yacc.c:1646 */ - { - DiscardStmt *n = makeNode(DiscardStmt); - n->target = DISCARD_TEMP; - (yyval.node) = (Node *) n; - } -#line 27154 "gram.c" /* yacc.c:1646 */ - break; - - case 263: -#line 1863 "gram.y" /* yacc.c:1646 */ - { - DiscardStmt *n = makeNode(DiscardStmt); - n->target = DISCARD_PLANS; - (yyval.node) = (Node *) n; - } -#line 27164 "gram.c" /* yacc.c:1646 */ - break; - - case 264: -#line 1869 "gram.y" /* yacc.c:1646 */ - { - DiscardStmt *n = makeNode(DiscardStmt); - n->target = DISCARD_SEQUENCES; - (yyval.node) = (Node *) n; - } -#line 27174 "gram.c" /* yacc.c:1646 */ - break; - - case 265: -#line 1888 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_TABLE; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27187 "gram.c" /* yacc.c:1646 */ - break; - - case 266: -#line 1897 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_TABLE; - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27200 "gram.c" /* yacc.c:1646 */ - break; - - case 267: -#line 1906 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = list_make1((yyvsp[0].node)); - n->relkind = OBJECT_TABLE; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27213 "gram.c" /* yacc.c:1646 */ - break; - - case 268: -#line 1915 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = list_make1((yyvsp[0].node)); - n->relkind = OBJECT_TABLE; - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27226 "gram.c" /* yacc.c:1646 */ - break; - - case 269: -#line 1924 "gram.y" /* yacc.c:1646 */ - { - AlterTableMoveAllStmt *n = - makeNode(AlterTableMoveAllStmt); - n->orig_tablespacename = (yyvsp[-4].str); - n->objtype = OBJECT_TABLE; - n->roles = NIL; - n->new_tablespacename = (yyvsp[-1].str); - n->nowait = (yyvsp[0].boolean); - (yyval.node) = (Node *)n; - } -#line 27241 "gram.c" /* yacc.c:1646 */ - break; - - case 270: -#line 1935 "gram.y" /* yacc.c:1646 */ - { - AlterTableMoveAllStmt *n = - makeNode(AlterTableMoveAllStmt); - n->orig_tablespacename = (yyvsp[-7].str); - n->objtype = OBJECT_TABLE; - n->roles = (yyvsp[-4].list); - n->new_tablespacename = (yyvsp[-1].str); - n->nowait = (yyvsp[0].boolean); - (yyval.node) = (Node *)n; - } -#line 27256 "gram.c" /* yacc.c:1646 */ - break; - - case 271: -#line 1946 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_INDEX; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27269 "gram.c" /* yacc.c:1646 */ - break; - - case 272: -#line 1955 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_INDEX; - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27282 "gram.c" /* yacc.c:1646 */ - break; - - case 273: -#line 1964 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = list_make1((yyvsp[0].node)); - n->relkind = OBJECT_INDEX; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27295 "gram.c" /* yacc.c:1646 */ - break; - - case 274: -#line 1973 "gram.y" /* yacc.c:1646 */ - { - AlterTableMoveAllStmt *n = - makeNode(AlterTableMoveAllStmt); - n->orig_tablespacename = (yyvsp[-4].str); - n->objtype = OBJECT_INDEX; - n->roles = NIL; - n->new_tablespacename = (yyvsp[-1].str); - n->nowait = (yyvsp[0].boolean); - (yyval.node) = (Node *)n; - } -#line 27310 "gram.c" /* yacc.c:1646 */ - break; - - case 275: -#line 1984 "gram.y" /* yacc.c:1646 */ - { - AlterTableMoveAllStmt *n = - makeNode(AlterTableMoveAllStmt); - n->orig_tablespacename = (yyvsp[-7].str); - n->objtype = OBJECT_INDEX; - n->roles = (yyvsp[-4].list); - n->new_tablespacename = (yyvsp[-1].str); - n->nowait = (yyvsp[0].boolean); - (yyval.node) = (Node *)n; - } -#line 27325 "gram.c" /* yacc.c:1646 */ - break; - - case 276: -#line 1995 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_SEQUENCE; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27338 "gram.c" /* yacc.c:1646 */ - break; - - case 277: -#line 2004 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_SEQUENCE; - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27351 "gram.c" /* yacc.c:1646 */ - break; - - case 278: -#line 2013 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_VIEW; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27364 "gram.c" /* yacc.c:1646 */ - break; - - case 279: -#line 2022 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_VIEW; - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27377 "gram.c" /* yacc.c:1646 */ - break; - - case 280: -#line 2031 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_MATVIEW; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27390 "gram.c" /* yacc.c:1646 */ - break; - - case 281: -#line 2040 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_MATVIEW; - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27403 "gram.c" /* yacc.c:1646 */ - break; - - case 282: -#line 2049 "gram.y" /* yacc.c:1646 */ - { - AlterTableMoveAllStmt *n = - makeNode(AlterTableMoveAllStmt); - n->orig_tablespacename = (yyvsp[-4].str); - n->objtype = OBJECT_MATVIEW; - n->roles = NIL; - n->new_tablespacename = (yyvsp[-1].str); - n->nowait = (yyvsp[0].boolean); - (yyval.node) = (Node *)n; - } -#line 27418 "gram.c" /* yacc.c:1646 */ - break; - - case 283: -#line 2060 "gram.y" /* yacc.c:1646 */ - { - AlterTableMoveAllStmt *n = - makeNode(AlterTableMoveAllStmt); - n->orig_tablespacename = (yyvsp[-7].str); - n->objtype = OBJECT_MATVIEW; - n->roles = (yyvsp[-4].list); - n->new_tablespacename = (yyvsp[-1].str); - n->nowait = (yyvsp[0].boolean); - (yyval.node) = (Node *)n; - } -#line 27433 "gram.c" /* yacc.c:1646 */ - break; - - case 284: -#line 2073 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 27439 "gram.c" /* yacc.c:1646 */ - break; - - case 285: -#line 2074 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 27445 "gram.c" /* yacc.c:1646 */ - break; - - case 286: -#line 2080 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - PartitionCmd *cmd = makeNode(PartitionCmd); - - n->subtype = AT_AttachPartition; - cmd->name = (yyvsp[-1].range); - cmd->bound = (yyvsp[0].partboundspec); - n->def = (Node *) cmd; - - (yyval.node) = (Node *) n; - } -#line 27461 "gram.c" /* yacc.c:1646 */ - break; - - case 287: -#line 2093 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - PartitionCmd *cmd = makeNode(PartitionCmd); - - n->subtype = AT_DetachPartition; - cmd->name = (yyvsp[0].range); - cmd->bound = NULL; - n->def = (Node *) cmd; - - (yyval.node) = (Node *) n; - } -#line 27477 "gram.c" /* yacc.c:1646 */ - break; - - case 288: -#line 2109 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - PartitionCmd *cmd = makeNode(PartitionCmd); - - n->subtype = AT_AttachPartition; - cmd->name = (yyvsp[0].range); - cmd->bound = NULL; - n->def = (Node *) cmd; - - (yyval.node) = (Node *) n; - } -#line 27493 "gram.c" /* yacc.c:1646 */ - break; - - case 289: -#line 2125 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddColumn; - n->def = (yyvsp[0].node); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27505 "gram.c" /* yacc.c:1646 */ - break; - - case 290: -#line 2134 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddColumn; - n->def = (yyvsp[0].node); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27517 "gram.c" /* yacc.c:1646 */ - break; - - case 291: -#line 2143 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddColumn; - n->def = (yyvsp[0].node); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27529 "gram.c" /* yacc.c:1646 */ - break; - - case 292: -#line 2152 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddColumn; - n->def = (yyvsp[0].node); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27541 "gram.c" /* yacc.c:1646 */ - break; - - case 293: -#line 2161 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ColumnDefault; - n->name = (yyvsp[-1].str); - n->def = (yyvsp[0].node); - (yyval.node) = (Node *)n; - } -#line 27553 "gram.c" /* yacc.c:1646 */ - break; - - case 294: -#line 2170 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropNotNull; - n->name = (yyvsp[-3].str); - (yyval.node) = (Node *)n; - } -#line 27564 "gram.c" /* yacc.c:1646 */ - break; - - case 295: -#line 2178 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetNotNull; - n->name = (yyvsp[-3].str); - (yyval.node) = (Node *)n; - } -#line 27575 "gram.c" /* yacc.c:1646 */ - break; - - case 296: -#line 2186 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetStatistics; - n->name = (yyvsp[-3].str); - n->def = (Node *) makeInteger((yyvsp[0].ival)); - (yyval.node) = (Node *)n; - } -#line 27587 "gram.c" /* yacc.c:1646 */ - break; - - case 297: -#line 2195 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - - if ((yyvsp[-3].ival) <= 0 || (yyvsp[-3].ival) > PG_INT16_MAX) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("column number must be in range from 1 to %d", PG_INT16_MAX), - parser_errposition((yylsp[-3])))); - - n->subtype = AT_SetStatistics; - n->num = (int16) (yyvsp[-3].ival); - n->def = (Node *) makeInteger((yyvsp[0].ival)); - (yyval.node) = (Node *)n; - } -#line 27606 "gram.c" /* yacc.c:1646 */ - break; - - case 298: -#line 2211 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetOptions; - n->name = (yyvsp[-2].str); - n->def = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 27618 "gram.c" /* yacc.c:1646 */ - break; - - case 299: -#line 2220 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ResetOptions; - n->name = (yyvsp[-2].str); - n->def = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 27630 "gram.c" /* yacc.c:1646 */ - break; - - case 300: -#line 2229 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetStorage; - n->name = (yyvsp[-3].str); - n->def = (Node *) makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 27642 "gram.c" /* yacc.c:1646 */ - break; - - case 301: -#line 2238 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - Constraint *c = makeNode(Constraint); - - c->contype = CONSTR_IDENTITY; - c->generated_when = (yyvsp[-3].ival); - c->options = (yyvsp[0].list); - c->location = (yylsp[-4]); - - n->subtype = AT_AddIdentity; - n->name = (yyvsp[-6].str); - n->def = (Node *) c; - - (yyval.node) = (Node *)n; - } -#line 27662 "gram.c" /* yacc.c:1646 */ - break; - - case 302: -#line 2255 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetIdentity; - n->name = (yyvsp[-1].str); - n->def = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 27674 "gram.c" /* yacc.c:1646 */ - break; - - case 303: -#line 2264 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropIdentity; - n->name = (yyvsp[-2].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27686 "gram.c" /* yacc.c:1646 */ - break; - - case 304: -#line 2273 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropIdentity; - n->name = (yyvsp[-4].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27698 "gram.c" /* yacc.c:1646 */ - break; - - case 305: -#line 2282 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropColumn; - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27711 "gram.c" /* yacc.c:1646 */ - break; - - case 306: -#line 2292 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropColumn; - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27724 "gram.c" /* yacc.c:1646 */ - break; - - case 307: -#line 2305 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - ColumnDef *def = makeNode(ColumnDef); - n->subtype = AT_AlterColumnType; - n->name = (yyvsp[-5].str); - n->def = (Node *) def; - /* We only use these fields of the ColumnDef node */ - def->typeName = (yyvsp[-2].typnam); - def->collClause = (CollateClause *) (yyvsp[-1].node); - def->raw_default = (yyvsp[0].node); - def->location = (yylsp[-5]); - (yyval.node) = (Node *)n; - } -#line 27742 "gram.c" /* yacc.c:1646 */ - break; - - case 308: -#line 2320 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AlterColumnGenericOptions; - n->name = (yyvsp[-1].str); - n->def = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 27754 "gram.c" /* yacc.c:1646 */ - break; - - case 309: -#line 2329 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddConstraint; - n->def = (yyvsp[0].node); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27766 "gram.c" /* yacc.c:1646 */ - break; - - case 310: -#line 2338 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - Constraint *c = makeNode(Constraint); - n->subtype = AT_AlterConstraint; - n->def = (Node *) c; - c->contype = CONSTR_FOREIGN; /* others not supported, yet */ - c->conname = (yyvsp[-1].str); - processCASbits((yyvsp[0].ival), (yylsp[0]), "ALTER CONSTRAINT statement", - &c->deferrable, - &c->initdeferred, - NULL, NULL, yyscanner); - (yyval.node) = (Node *)n; - } -#line 27784 "gram.c" /* yacc.c:1646 */ - break; - - case 311: -#line 2353 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ValidateConstraint; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27795 "gram.c" /* yacc.c:1646 */ - break; - - case 312: -#line 2361 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropConstraint; - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 27808 "gram.c" /* yacc.c:1646 */ - break; - - case 313: -#line 2371 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropConstraint; - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 27821 "gram.c" /* yacc.c:1646 */ - break; - - case 314: -#line 2381 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddOids; - (yyval.node) = (Node *)n; - } -#line 27831 "gram.c" /* yacc.c:1646 */ - break; - - case 315: -#line 2388 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropOids; - (yyval.node) = (Node *)n; - } -#line 27841 "gram.c" /* yacc.c:1646 */ - break; - - case 316: -#line 2395 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ClusterOn; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27852 "gram.c" /* yacc.c:1646 */ - break; - - case 317: -#line 2403 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropCluster; - n->name = NULL; - (yyval.node) = (Node *)n; - } -#line 27863 "gram.c" /* yacc.c:1646 */ - break; - - case 318: -#line 2411 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetLogged; - (yyval.node) = (Node *)n; - } -#line 27873 "gram.c" /* yacc.c:1646 */ - break; - - case 319: -#line 2418 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetUnLogged; - (yyval.node) = (Node *)n; - } -#line 27883 "gram.c" /* yacc.c:1646 */ - break; - - case 320: -#line 2425 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableTrig; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27894 "gram.c" /* yacc.c:1646 */ - break; - - case 321: -#line 2433 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableAlwaysTrig; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27905 "gram.c" /* yacc.c:1646 */ - break; - - case 322: -#line 2441 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableReplicaTrig; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27916 "gram.c" /* yacc.c:1646 */ - break; - - case 323: -#line 2449 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableTrigAll; - (yyval.node) = (Node *)n; - } -#line 27926 "gram.c" /* yacc.c:1646 */ - break; - - case 324: -#line 2456 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableTrigUser; - (yyval.node) = (Node *)n; - } -#line 27936 "gram.c" /* yacc.c:1646 */ - break; - - case 325: -#line 2463 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DisableTrig; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27947 "gram.c" /* yacc.c:1646 */ - break; - - case 326: -#line 2471 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DisableTrigAll; - (yyval.node) = (Node *)n; - } -#line 27957 "gram.c" /* yacc.c:1646 */ - break; - - case 327: -#line 2478 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DisableTrigUser; - (yyval.node) = (Node *)n; - } -#line 27967 "gram.c" /* yacc.c:1646 */ - break; - - case 328: -#line 2485 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableRule; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27978 "gram.c" /* yacc.c:1646 */ - break; - - case 329: -#line 2493 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableAlwaysRule; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 27989 "gram.c" /* yacc.c:1646 */ - break; - - case 330: -#line 2501 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableReplicaRule; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 28000 "gram.c" /* yacc.c:1646 */ - break; - - case 331: -#line 2509 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DisableRule; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 28011 "gram.c" /* yacc.c:1646 */ - break; - - case 332: -#line 2517 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddInherit; - n->def = (Node *) (yyvsp[0].range); - (yyval.node) = (Node *)n; - } -#line 28022 "gram.c" /* yacc.c:1646 */ - break; - - case 333: -#line 2525 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropInherit; - n->def = (Node *) (yyvsp[0].range); - (yyval.node) = (Node *)n; - } -#line 28033 "gram.c" /* yacc.c:1646 */ - break; - - case 334: -#line 2533 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - TypeName *def = makeTypeNameFromNameList((yyvsp[0].list)); - def->location = (yylsp[0]); - n->subtype = AT_AddOf; - n->def = (Node *) def; - (yyval.node) = (Node *)n; - } -#line 28046 "gram.c" /* yacc.c:1646 */ - break; - - case 335: -#line 2543 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropOf; - (yyval.node) = (Node *)n; - } -#line 28056 "gram.c" /* yacc.c:1646 */ - break; - - case 336: -#line 2550 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ChangeOwner; - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 28067 "gram.c" /* yacc.c:1646 */ - break; - - case 337: -#line 2558 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetTableSpace; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 28078 "gram.c" /* yacc.c:1646 */ - break; - - case 338: -#line 2566 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_SetRelOptions; - n->def = (Node *)(yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 28089 "gram.c" /* yacc.c:1646 */ - break; - - case 339: -#line 2574 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ResetRelOptions; - n->def = (Node *)(yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 28100 "gram.c" /* yacc.c:1646 */ - break; - - case 340: -#line 2582 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ReplicaIdentity; - n->def = (yyvsp[0].node); - (yyval.node) = (Node *)n; - } -#line 28111 "gram.c" /* yacc.c:1646 */ - break; - - case 341: -#line 2590 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_EnableRowSecurity; - (yyval.node) = (Node *)n; - } -#line 28121 "gram.c" /* yacc.c:1646 */ - break; - - case 342: -#line 2597 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DisableRowSecurity; - (yyval.node) = (Node *)n; - } -#line 28131 "gram.c" /* yacc.c:1646 */ - break; - - case 343: -#line 2604 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_ForceRowSecurity; - (yyval.node) = (Node *)n; - } -#line 28141 "gram.c" /* yacc.c:1646 */ - break; - - case 344: -#line 2611 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_NoForceRowSecurity; - (yyval.node) = (Node *)n; - } -#line 28151 "gram.c" /* yacc.c:1646 */ - break; - - case 345: -#line 2617 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_GenericOptions; - n->def = (Node *)(yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 28162 "gram.c" /* yacc.c:1646 */ - break; - - case 346: -#line 2626 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 28168 "gram.c" /* yacc.c:1646 */ - break; - - case 347: -#line 2627 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 28174 "gram.c" /* yacc.c:1646 */ - break; - - case 348: -#line 2631 "gram.y" /* yacc.c:1646 */ - { (yyval.dbehavior) = DROP_CASCADE; } -#line 28180 "gram.c" /* yacc.c:1646 */ - break; - - case 349: -#line 2632 "gram.y" /* yacc.c:1646 */ - { (yyval.dbehavior) = DROP_RESTRICT; } -#line 28186 "gram.c" /* yacc.c:1646 */ - break; - - case 350: -#line 2633 "gram.y" /* yacc.c:1646 */ - { (yyval.dbehavior) = DROP_RESTRICT; /* default */ } -#line 28192 "gram.c" /* yacc.c:1646 */ - break; - - case 351: -#line 2638 "gram.y" /* yacc.c:1646 */ - { - CollateClause *n = makeNode(CollateClause); - n->arg = NULL; - n->collname = (yyvsp[0].list); - n->location = (yylsp[-1]); - (yyval.node) = (Node *) n; - } -#line 28204 "gram.c" /* yacc.c:1646 */ - break; - - case 352: -#line 2645 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 28210 "gram.c" /* yacc.c:1646 */ - break; - - case 353: -#line 2649 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 28216 "gram.c" /* yacc.c:1646 */ - break; - - case 354: -#line 2650 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 28222 "gram.c" /* yacc.c:1646 */ - break; - - case 355: -#line 2655 "gram.y" /* yacc.c:1646 */ - { - ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); - n->identity_type = REPLICA_IDENTITY_NOTHING; - n->name = NULL; - (yyval.node) = (Node *) n; - } -#line 28233 "gram.c" /* yacc.c:1646 */ - break; - - case 356: -#line 2662 "gram.y" /* yacc.c:1646 */ - { - ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); - n->identity_type = REPLICA_IDENTITY_FULL; - n->name = NULL; - (yyval.node) = (Node *) n; - } -#line 28244 "gram.c" /* yacc.c:1646 */ - break; - - case 357: -#line 2669 "gram.y" /* yacc.c:1646 */ - { - ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); - n->identity_type = REPLICA_IDENTITY_DEFAULT; - n->name = NULL; - (yyval.node) = (Node *) n; - } -#line 28255 "gram.c" /* yacc.c:1646 */ - break; - - case 358: -#line 2676 "gram.y" /* yacc.c:1646 */ - { - ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); - n->identity_type = REPLICA_IDENTITY_INDEX; - n->name = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 28266 "gram.c" /* yacc.c:1646 */ - break; - - case 359: -#line 2685 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 28272 "gram.c" /* yacc.c:1646 */ - break; - - case 360: -#line 2688 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 28278 "gram.c" /* yacc.c:1646 */ - break; - - case 361: -#line 2689 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 28284 "gram.c" /* yacc.c:1646 */ - break; - - case 362: -#line 2693 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 28290 "gram.c" /* yacc.c:1646 */ - break; - - case 363: -#line 2694 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); } -#line 28296 "gram.c" /* yacc.c:1646 */ - break; - - case 364: -#line 2700 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-2].str), (Node *) (yyvsp[0].node), (yylsp[-2])); - } -#line 28304 "gram.c" /* yacc.c:1646 */ - break; - - case 365: -#line 2704 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[0].str), NULL, (yylsp[0])); - } -#line 28312 "gram.c" /* yacc.c:1646 */ - break; - - case 366: -#line 2708 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElemExtended((yyvsp[-4].str), (yyvsp[-2].str), (Node *) (yyvsp[0].node), - DEFELEM_UNSPEC, (yylsp[-4])); - } -#line 28321 "gram.c" /* yacc.c:1646 */ - break; - - case 367: -#line 2713 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElemExtended((yyvsp[-2].str), (yyvsp[0].str), NULL, DEFELEM_UNSPEC, (yylsp[-2])); - } -#line 28329 "gram.c" /* yacc.c:1646 */ - break; - - case 368: -#line 2720 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 28335 "gram.c" /* yacc.c:1646 */ - break; - - case 369: -#line 2722 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 28341 "gram.c" /* yacc.c:1646 */ - break; - - case 370: -#line 2727 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("restart", NULL, (yylsp[0])); - } -#line 28349 "gram.c" /* yacc.c:1646 */ - break; - - case 371: -#line 2731 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("restart", (Node *)(yyvsp[0].value), (yylsp[-2])); - } -#line 28357 "gram.c" /* yacc.c:1646 */ - break; - - case 372: -#line 2735 "gram.y" /* yacc.c:1646 */ - { - if (strcmp((yyvsp[0].defelt)->defname, "as") == 0 || - strcmp((yyvsp[0].defelt)->defname, "restart") == 0 || - strcmp((yyvsp[0].defelt)->defname, "owned_by") == 0) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("sequence option \"%s\" not supported here", (yyvsp[0].defelt)->defname), - parser_errposition((yylsp[0])))); - (yyval.defelt) = (yyvsp[0].defelt); - } -#line 28372 "gram.c" /* yacc.c:1646 */ - break; - - case 373: -#line 2746 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("generated", (Node *) makeInteger((yyvsp[0].ival)), (yylsp[-2])); - } -#line 28380 "gram.c" /* yacc.c:1646 */ - break; - - case 374: -#line 2754 "gram.y" /* yacc.c:1646 */ - { - ListCell *lc; - PartitionBoundSpec *n = makeNode(PartitionBoundSpec); - - n->strategy = PARTITION_STRATEGY_HASH; - n->modulus = n->remainder = -1; - - foreach (lc, (yyvsp[-1].list)) - { - DefElem *opt = lfirst_node(DefElem, lc); - - if (strcmp(opt->defname, "modulus") == 0) - { - if (n->modulus != -1) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("modulus for hash partition provided more than once"), - parser_errposition(opt->location))); - n->modulus = defGetInt32(opt); - } - else if (strcmp(opt->defname, "remainder") == 0) - { - if (n->remainder != -1) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("remainder for hash partition provided more than once"), - parser_errposition(opt->location))); - n->remainder = defGetInt32(opt); - } - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized hash partition bound specification \"%s\"", - opt->defname), - parser_errposition(opt->location))); - } - - if (n->modulus == -1) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("modulus for hash partition must be specified"))); - if (n->remainder == -1) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("remainder for hash partition must be specified"))); - - n->location = (yylsp[-3]); - - (yyval.partboundspec) = n; - } -#line 28435 "gram.c" /* yacc.c:1646 */ - break; - - case 375: -#line 2807 "gram.y" /* yacc.c:1646 */ - { - PartitionBoundSpec *n = makeNode(PartitionBoundSpec); - - n->strategy = PARTITION_STRATEGY_LIST; - n->is_default = false; - n->listdatums = (yyvsp[-1].list); - n->location = (yylsp[-3]); - - (yyval.partboundspec) = n; - } -#line 28450 "gram.c" /* yacc.c:1646 */ - break; - - case 376: -#line 2820 "gram.y" /* yacc.c:1646 */ - { - PartitionBoundSpec *n = makeNode(PartitionBoundSpec); - - n->strategy = PARTITION_STRATEGY_RANGE; - n->is_default = false; - n->lowerdatums = (yyvsp[-5].list); - n->upperdatums = (yyvsp[-1].list); - n->location = (yylsp[-7]); - - (yyval.partboundspec) = n; - } -#line 28466 "gram.c" /* yacc.c:1646 */ - break; - - case 377: -#line 2834 "gram.y" /* yacc.c:1646 */ - { - PartitionBoundSpec *n = makeNode(PartitionBoundSpec); - - n->is_default = true; - n->location = (yylsp[0]); - - (yyval.partboundspec) = n; - } -#line 28479 "gram.c" /* yacc.c:1646 */ - break; - - case 378: -#line 2846 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-1].str), (Node *)makeInteger((yyvsp[0].ival)), (yylsp[-1])); - } -#line 28487 "gram.c" /* yacc.c:1646 */ - break; - - case 379: -#line 2853 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].defelt)); - } -#line 28495 "gram.c" /* yacc.c:1646 */ - break; - - case 380: -#line 2857 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); - } -#line 28503 "gram.c" /* yacc.c:1646 */ - break; - - case 381: -#line 2863 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeStringConst((yyvsp[0].str), (yylsp[0])); } -#line 28509 "gram.c" /* yacc.c:1646 */ - break; - - case 382: -#line 2864 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeAConst((yyvsp[0].value), (yylsp[0])); } -#line 28515 "gram.c" /* yacc.c:1646 */ - break; - - case 383: -#line 2865 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeStringConst(pstrdup("true"), (yylsp[0])); } -#line 28521 "gram.c" /* yacc.c:1646 */ - break; - - case 384: -#line 2866 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeStringConst(pstrdup("false"), (yylsp[0])); } -#line 28527 "gram.c" /* yacc.c:1646 */ - break; - - case 385: -#line 2867 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeNullAConst((yylsp[0])); } -#line 28533 "gram.c" /* yacc.c:1646 */ - break; - - case 386: -#line 2871 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 28539 "gram.c" /* yacc.c:1646 */ - break; - - case 387: -#line 2873 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 28545 "gram.c" /* yacc.c:1646 */ - break; - - case 388: -#line 2877 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 28551 "gram.c" /* yacc.c:1646 */ - break; - - case 389: -#line 2879 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 28557 "gram.c" /* yacc.c:1646 */ - break; - - case 390: -#line 2884 "gram.y" /* yacc.c:1646 */ - { - PartitionRangeDatum *n = makeNode(PartitionRangeDatum); - - n->kind = PARTITION_RANGE_DATUM_MINVALUE; - n->value = NULL; - n->location = (yylsp[0]); - - (yyval.node) = (Node *) n; - } -#line 28571 "gram.c" /* yacc.c:1646 */ - break; - - case 391: -#line 2894 "gram.y" /* yacc.c:1646 */ - { - PartitionRangeDatum *n = makeNode(PartitionRangeDatum); - - n->kind = PARTITION_RANGE_DATUM_MAXVALUE; - n->value = NULL; - n->location = (yylsp[0]); - - (yyval.node) = (Node *) n; - } -#line 28585 "gram.c" /* yacc.c:1646 */ - break; - - case 392: -#line 2904 "gram.y" /* yacc.c:1646 */ - { - PartitionRangeDatum *n = makeNode(PartitionRangeDatum); - - n->kind = PARTITION_RANGE_DATUM_VALUE; - n->value = (yyvsp[0].node); - n->location = (yylsp[0]); - - (yyval.node) = (Node *) n; - } -#line 28599 "gram.c" /* yacc.c:1646 */ - break; - - case 393: -#line 2924 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - - /* can't use qualified_name, sigh */ - n->relation = makeRangeVarFromAnyName((yyvsp[-1].list), (yylsp[-1]), yyscanner); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_TYPE; - (yyval.node) = (Node *)n; - } -#line 28613 "gram.c" /* yacc.c:1646 */ - break; - - case 394: -#line 2936 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 28619 "gram.c" /* yacc.c:1646 */ - break; - - case 395: -#line 2937 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 28625 "gram.c" /* yacc.c:1646 */ - break; - - case 396: -#line 2943 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddColumn; - n->def = (yyvsp[-1].node); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *)n; - } -#line 28637 "gram.c" /* yacc.c:1646 */ - break; - - case 397: -#line 2952 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropColumn; - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 28650 "gram.c" /* yacc.c:1646 */ - break; - - case 398: -#line 2962 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_DropColumn; - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 28663 "gram.c" /* yacc.c:1646 */ - break; - - case 399: -#line 2972 "gram.y" /* yacc.c:1646 */ - { - AlterTableCmd *n = makeNode(AlterTableCmd); - ColumnDef *def = makeNode(ColumnDef); - n->subtype = AT_AlterColumnType; - n->name = (yyvsp[-5].str); - n->def = (Node *) def; - n->behavior = (yyvsp[0].dbehavior); - /* We only use these fields of the ColumnDef node */ - def->typeName = (yyvsp[-2].typnam); - def->collClause = (CollateClause *) (yyvsp[-1].node); - def->raw_default = NULL; - def->location = (yylsp[-5]); - (yyval.node) = (Node *)n; - } -#line 28682 "gram.c" /* yacc.c:1646 */ - break; - - case 400: -#line 2998 "gram.y" /* yacc.c:1646 */ - { - ClosePortalStmt *n = makeNode(ClosePortalStmt); - n->portalname = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 28692 "gram.c" /* yacc.c:1646 */ - break; - - case 401: -#line 3004 "gram.y" /* yacc.c:1646 */ - { - ClosePortalStmt *n = makeNode(ClosePortalStmt); - n->portalname = NULL; - (yyval.node) = (Node *)n; - } -#line 28702 "gram.c" /* yacc.c:1646 */ - break; - - case 402: -#line 3038 "gram.y" /* yacc.c:1646 */ - { - CopyStmt *n = makeNode(CopyStmt); - n->relation = (yyvsp[-8].range); - n->query = NULL; - n->attlist = (yyvsp[-7].list); - n->is_from = (yyvsp[-5].boolean); - n->is_program = (yyvsp[-4].boolean); - n->filename = (yyvsp[-3].str); - - if (n->is_program && n->filename == NULL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("STDIN/STDOUT not allowed with PROGRAM"), - parser_errposition((yylsp[-3])))); - - n->options = NIL; - /* Concatenate user-supplied flags */ - if ((yyvsp[-9].defelt)) - n->options = lappend(n->options, (yyvsp[-9].defelt)); - if ((yyvsp[-6].defelt)) - n->options = lappend(n->options, (yyvsp[-6].defelt)); - if ((yyvsp[-2].defelt)) - n->options = lappend(n->options, (yyvsp[-2].defelt)); - if ((yyvsp[0].list)) - n->options = list_concat(n->options, (yyvsp[0].list)); - (yyval.node) = (Node *)n; - } -#line 28734 "gram.c" /* yacc.c:1646 */ - break; - - case 403: -#line 3066 "gram.y" /* yacc.c:1646 */ - { - CopyStmt *n = makeNode(CopyStmt); - n->relation = NULL; - n->query = (yyvsp[-6].node); - n->attlist = NIL; - n->is_from = false; - n->is_program = (yyvsp[-3].boolean); - n->filename = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - - if (n->is_program && n->filename == NULL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("STDIN/STDOUT not allowed with PROGRAM"), - parser_errposition((yylsp[-4])))); - - (yyval.node) = (Node *)n; - } -#line 28757 "gram.c" /* yacc.c:1646 */ - break; - - case 404: -#line 3087 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 28763 "gram.c" /* yacc.c:1646 */ - break; - - case 405: -#line 3088 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 28769 "gram.c" /* yacc.c:1646 */ - break; - - case 406: -#line 3092 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 28775 "gram.c" /* yacc.c:1646 */ - break; - - case 407: -#line 3093 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 28781 "gram.c" /* yacc.c:1646 */ - break; - - case 408: -#line 3102 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 28787 "gram.c" /* yacc.c:1646 */ - break; - - case 409: -#line 3103 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 28793 "gram.c" /* yacc.c:1646 */ - break; - - case 410: -#line 3104 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 28799 "gram.c" /* yacc.c:1646 */ - break; - - case 411: -#line 3107 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 28805 "gram.c" /* yacc.c:1646 */ - break; - - case 412: -#line 3108 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 28811 "gram.c" /* yacc.c:1646 */ - break; - - case 413: -#line 3113 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 28817 "gram.c" /* yacc.c:1646 */ - break; - - case 414: -#line 3114 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 28823 "gram.c" /* yacc.c:1646 */ - break; - - case 415: -#line 3119 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("format", (Node *)makeString("binary"), (yylsp[0])); - } -#line 28831 "gram.c" /* yacc.c:1646 */ - break; - - case 416: -#line 3123 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("oids", (Node *)makeInteger(true), (yylsp[0])); - } -#line 28839 "gram.c" /* yacc.c:1646 */ - break; - - case 417: -#line 3127 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("freeze", (Node *)makeInteger(true), (yylsp[0])); - } -#line 28847 "gram.c" /* yacc.c:1646 */ - break; - - case 418: -#line 3131 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("delimiter", (Node *)makeString((yyvsp[0].str)), (yylsp[-2])); - } -#line 28855 "gram.c" /* yacc.c:1646 */ - break; - - case 419: -#line 3135 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("null", (Node *)makeString((yyvsp[0].str)), (yylsp[-2])); - } -#line 28863 "gram.c" /* yacc.c:1646 */ - break; - - case 420: -#line 3139 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("format", (Node *)makeString("csv"), (yylsp[0])); - } -#line 28871 "gram.c" /* yacc.c:1646 */ - break; - - case 421: -#line 3143 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("header", (Node *)makeInteger(true), (yylsp[0])); - } -#line 28879 "gram.c" /* yacc.c:1646 */ - break; - - case 422: -#line 3147 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("quote", (Node *)makeString((yyvsp[0].str)), (yylsp[-2])); - } -#line 28887 "gram.c" /* yacc.c:1646 */ - break; - - case 423: -#line 3151 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("escape", (Node *)makeString((yyvsp[0].str)), (yylsp[-2])); - } -#line 28895 "gram.c" /* yacc.c:1646 */ - break; - - case 424: -#line 3155 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("force_quote", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 28903 "gram.c" /* yacc.c:1646 */ - break; - - case 425: -#line 3159 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("force_quote", (Node *)makeNode(A_Star), (yylsp[-2])); - } -#line 28911 "gram.c" /* yacc.c:1646 */ - break; - - case 426: -#line 3163 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("force_not_null", (Node *)(yyvsp[0].list), (yylsp[-3])); - } -#line 28919 "gram.c" /* yacc.c:1646 */ - break; - - case 427: -#line 3167 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("force_null", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 28927 "gram.c" /* yacc.c:1646 */ - break; - - case 428: -#line 3171 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("encoding", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 28935 "gram.c" /* yacc.c:1646 */ - break; - - case 429: -#line 3180 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("format", (Node *)makeString("binary"), (yylsp[0])); - } -#line 28943 "gram.c" /* yacc.c:1646 */ - break; - - case 430: -#line 3183 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = NULL; } -#line 28949 "gram.c" /* yacc.c:1646 */ - break; - - case 431: -#line 3188 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("oids", (Node *)makeInteger(true), (yylsp[-1])); - } -#line 28957 "gram.c" /* yacc.c:1646 */ - break; - - case 432: -#line 3191 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = NULL; } -#line 28963 "gram.c" /* yacc.c:1646 */ - break; - - case 433: -#line 3196 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("delimiter", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 28971 "gram.c" /* yacc.c:1646 */ - break; - - case 434: -#line 3199 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = NULL; } -#line 28977 "gram.c" /* yacc.c:1646 */ - break; - - case 435: -#line 3203 "gram.y" /* yacc.c:1646 */ - {} -#line 28983 "gram.c" /* yacc.c:1646 */ - break; - - case 436: -#line 3204 "gram.y" /* yacc.c:1646 */ - {} -#line 28989 "gram.c" /* yacc.c:1646 */ - break; - - case 437: -#line 3210 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].defelt)); - } -#line 28997 "gram.c" /* yacc.c:1646 */ - break; - - case 438: -#line 3214 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); - } -#line 29005 "gram.c" /* yacc.c:1646 */ - break; - - case 439: -#line 3221 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-1].str), (yyvsp[0].node), (yylsp[-1])); - } -#line 29013 "gram.c" /* yacc.c:1646 */ - break; - - case 440: -#line 3227 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeString((yyvsp[0].str)); } -#line 29019 "gram.c" /* yacc.c:1646 */ - break; - - case 441: -#line 3228 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) (yyvsp[0].value); } -#line 29025 "gram.c" /* yacc.c:1646 */ - break; - - case 442: -#line 3229 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeNode(A_Star); } -#line 29031 "gram.c" /* yacc.c:1646 */ - break; - - case 443: -#line 3230 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) (yyvsp[-1].list); } -#line 29037 "gram.c" /* yacc.c:1646 */ - break; - - case 444: -#line 3231 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 29043 "gram.c" /* yacc.c:1646 */ - break; - - case 445: -#line 3236 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].node)); - } -#line 29051 "gram.c" /* yacc.c:1646 */ - break; - - case 446: -#line 3240 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); - } -#line 29059 "gram.c" /* yacc.c:1646 */ - break; - - case 447: -#line 3247 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeString((yyvsp[0].str)); } -#line 29065 "gram.c" /* yacc.c:1646 */ - break; - - case 448: -#line 3260 "gram.y" /* yacc.c:1646 */ - { - CreateStmt *n = makeNode(CreateStmt); - (yyvsp[-8].range)->relpersistence = (yyvsp[-10].ival); - n->relation = (yyvsp[-8].range); - n->tableElts = (yyvsp[-6].list); - n->inhRelations = (yyvsp[-4].list); - n->partspec = (yyvsp[-3].partspec); - n->ofTypename = NULL; - n->constraints = NIL; - n->options = (yyvsp[-2].list); - n->oncommit = (yyvsp[-1].oncommit); - n->tablespacename = (yyvsp[0].str); - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 29085 "gram.c" /* yacc.c:1646 */ - break; - - case 449: -#line 3278 "gram.y" /* yacc.c:1646 */ - { - CreateStmt *n = makeNode(CreateStmt); - (yyvsp[-8].range)->relpersistence = (yyvsp[-13].ival); - n->relation = (yyvsp[-8].range); - n->tableElts = (yyvsp[-6].list); - n->inhRelations = (yyvsp[-4].list); - n->partspec = (yyvsp[-3].partspec); - n->ofTypename = NULL; - n->constraints = NIL; - n->options = (yyvsp[-2].list); - n->oncommit = (yyvsp[-1].oncommit); - n->tablespacename = (yyvsp[0].str); - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 29105 "gram.c" /* yacc.c:1646 */ - break; - - case 450: -#line 3296 "gram.y" /* yacc.c:1646 */ - { - CreateStmt *n = makeNode(CreateStmt); - (yyvsp[-7].range)->relpersistence = (yyvsp[-9].ival); - n->relation = (yyvsp[-7].range); - n->tableElts = (yyvsp[-4].list); - n->inhRelations = NIL; - n->partspec = (yyvsp[-3].partspec); - n->ofTypename = makeTypeNameFromNameList((yyvsp[-5].list)); - n->ofTypename->location = (yylsp[-5]); - n->constraints = NIL; - n->options = (yyvsp[-2].list); - n->oncommit = (yyvsp[-1].oncommit); - n->tablespacename = (yyvsp[0].str); - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 29126 "gram.c" /* yacc.c:1646 */ - break; - - case 451: -#line 3315 "gram.y" /* yacc.c:1646 */ - { - CreateStmt *n = makeNode(CreateStmt); - (yyvsp[-7].range)->relpersistence = (yyvsp[-12].ival); - n->relation = (yyvsp[-7].range); - n->tableElts = (yyvsp[-4].list); - n->inhRelations = NIL; - n->partspec = (yyvsp[-3].partspec); - n->ofTypename = makeTypeNameFromNameList((yyvsp[-5].list)); - n->ofTypename->location = (yylsp[-5]); - n->constraints = NIL; - n->options = (yyvsp[-2].list); - n->oncommit = (yyvsp[-1].oncommit); - n->tablespacename = (yyvsp[0].str); - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 29147 "gram.c" /* yacc.c:1646 */ - break; - - case 452: -#line 3334 "gram.y" /* yacc.c:1646 */ - { - CreateStmt *n = makeNode(CreateStmt); - (yyvsp[-9].range)->relpersistence = (yyvsp[-11].ival); - n->relation = (yyvsp[-9].range); - n->tableElts = (yyvsp[-5].list); - n->inhRelations = list_make1((yyvsp[-6].range)); - n->partbound = (yyvsp[-4].partboundspec); - n->partspec = (yyvsp[-3].partspec); - n->ofTypename = NULL; - n->constraints = NIL; - n->options = (yyvsp[-2].list); - n->oncommit = (yyvsp[-1].oncommit); - n->tablespacename = (yyvsp[0].str); - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 29168 "gram.c" /* yacc.c:1646 */ - break; - - case 453: -#line 3353 "gram.y" /* yacc.c:1646 */ - { - CreateStmt *n = makeNode(CreateStmt); - (yyvsp[-9].range)->relpersistence = (yyvsp[-14].ival); - n->relation = (yyvsp[-9].range); - n->tableElts = (yyvsp[-5].list); - n->inhRelations = list_make1((yyvsp[-6].range)); - n->partbound = (yyvsp[-4].partboundspec); - n->partspec = (yyvsp[-3].partspec); - n->ofTypename = NULL; - n->constraints = NIL; - n->options = (yyvsp[-2].list); - n->oncommit = (yyvsp[-1].oncommit); - n->tablespacename = (yyvsp[0].str); - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 29189 "gram.c" /* yacc.c:1646 */ - break; - - case 454: -#line 3382 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_TEMP; } -#line 29195 "gram.c" /* yacc.c:1646 */ - break; - - case 455: -#line 3383 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_TEMP; } -#line 29201 "gram.c" /* yacc.c:1646 */ - break; - - case 456: -#line 3384 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_TEMP; } -#line 29207 "gram.c" /* yacc.c:1646 */ - break; - - case 457: -#line 3385 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_TEMP; } -#line 29213 "gram.c" /* yacc.c:1646 */ - break; - - case 458: -#line 3387 "gram.y" /* yacc.c:1646 */ - { - ereport(WARNING, - (errmsg("GLOBAL is deprecated in temporary table creation"), - parser_errposition((yylsp[-1])))); - (yyval.ival) = RELPERSISTENCE_TEMP; - } -#line 29224 "gram.c" /* yacc.c:1646 */ - break; - - case 459: -#line 3394 "gram.y" /* yacc.c:1646 */ - { - ereport(WARNING, - (errmsg("GLOBAL is deprecated in temporary table creation"), - parser_errposition((yylsp[-1])))); - (yyval.ival) = RELPERSISTENCE_TEMP; - } -#line 29235 "gram.c" /* yacc.c:1646 */ - break; - - case 460: -#line 3400 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_UNLOGGED; } -#line 29241 "gram.c" /* yacc.c:1646 */ - break; - - case 461: -#line 3401 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_PERMANENT; } -#line 29247 "gram.c" /* yacc.c:1646 */ - break; - - case 462: -#line 3405 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 29253 "gram.c" /* yacc.c:1646 */ - break; - - case 463: -#line 3406 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 29259 "gram.c" /* yacc.c:1646 */ - break; - - case 464: -#line 3410 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 29265 "gram.c" /* yacc.c:1646 */ - break; - - case 465: -#line 3411 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 29271 "gram.c" /* yacc.c:1646 */ - break; - - case 466: -#line 3416 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].node)); - } -#line 29279 "gram.c" /* yacc.c:1646 */ - break; - - case 467: -#line 3420 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); - } -#line 29287 "gram.c" /* yacc.c:1646 */ - break; - - case 468: -#line 3427 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].node)); - } -#line 29295 "gram.c" /* yacc.c:1646 */ - break; - - case 469: -#line 3431 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); - } -#line 29303 "gram.c" /* yacc.c:1646 */ - break; - - case 470: -#line 3437 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29309 "gram.c" /* yacc.c:1646 */ - break; - - case 471: -#line 3438 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29315 "gram.c" /* yacc.c:1646 */ - break; - - case 472: -#line 3439 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29321 "gram.c" /* yacc.c:1646 */ - break; - - case 473: -#line 3443 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29327 "gram.c" /* yacc.c:1646 */ - break; - - case 474: -#line 3444 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29333 "gram.c" /* yacc.c:1646 */ - break; - - case 475: -#line 3448 "gram.y" /* yacc.c:1646 */ - { - ColumnDef *n = makeNode(ColumnDef); - n->colname = (yyvsp[-3].str); - n->typeName = (yyvsp[-2].typnam); - n->inhcount = 0; - 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; - n->collOid = InvalidOid; - n->fdwoptions = (yyvsp[-1].list); - SplitColQualList((yyvsp[0].list), &n->constraints, &n->collClause, - yyscanner); - n->location = (yylsp[-3]); - (yyval.node) = (Node *)n; - } -#line 29357 "gram.c" /* yacc.c:1646 */ - break; - - case 476: -#line 3470 "gram.y" /* yacc.c:1646 */ - { - ColumnDef *n = makeNode(ColumnDef); - n->colname = (yyvsp[-1].str); - n->typeName = NULL; - n->inhcount = 0; - 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; - n->collOid = InvalidOid; - SplitColQualList((yyvsp[0].list), &n->constraints, &n->collClause, - yyscanner); - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 29380 "gram.c" /* yacc.c:1646 */ - break; - - case 477: -#line 3489 "gram.y" /* yacc.c:1646 */ - { - ColumnDef *n = makeNode(ColumnDef); - n->colname = (yyvsp[-3].str); - n->typeName = NULL; - n->inhcount = 0; - 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; - n->collOid = InvalidOid; - SplitColQualList((yyvsp[0].list), &n->constraints, &n->collClause, - yyscanner); - n->location = (yylsp[-3]); - (yyval.node) = (Node *)n; - } -#line 29403 "gram.c" /* yacc.c:1646 */ - break; - - case 478: -#line 3510 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].node)); } -#line 29409 "gram.c" /* yacc.c:1646 */ - break; - - case 479: -#line 3511 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 29415 "gram.c" /* yacc.c:1646 */ - break; - - case 480: -#line 3516 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = castNode(Constraint, (yyvsp[0].node)); - n->conname = (yyvsp[-1].str); - n->location = (yylsp[-2]); - (yyval.node) = (Node *) n; - } -#line 29426 "gram.c" /* yacc.c:1646 */ - break; - - case 481: -#line 3522 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29432 "gram.c" /* yacc.c:1646 */ - break; - - case 482: -#line 3523 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29438 "gram.c" /* yacc.c:1646 */ - break; - - case 483: -#line 3525 "gram.y" /* yacc.c:1646 */ - { - /* - * Note: the CollateClause is momentarily included in - * the list built by ColQualList, but we split it out - * again in SplitColQualList. - */ - CollateClause *n = makeNode(CollateClause); - n->arg = NULL; - n->collname = (yyvsp[0].list); - n->location = (yylsp[-1]); - (yyval.node) = (Node *) n; - } -#line 29455 "gram.c" /* yacc.c:1646 */ - break; - - case 484: -#line 3556 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_NOTNULL; - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 29466 "gram.c" /* yacc.c:1646 */ - break; - - case 485: -#line 3563 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_NULL; - n->location = (yylsp[0]); - (yyval.node) = (Node *)n; - } -#line 29477 "gram.c" /* yacc.c:1646 */ - break; - - case 486: -#line 3570 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_UNIQUE; - n->location = (yylsp[-2]); - n->keys = NULL; - n->options = (yyvsp[-1].list); - n->indexname = NULL; - n->indexspace = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 29492 "gram.c" /* yacc.c:1646 */ - break; - - case 487: -#line 3581 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_PRIMARY; - n->location = (yylsp[-3]); - n->keys = NULL; - n->options = (yyvsp[-1].list); - n->indexname = NULL; - n->indexspace = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 29507 "gram.c" /* yacc.c:1646 */ - break; - - case 488: -#line 3592 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_CHECK; - n->location = (yylsp[-4]); - n->is_no_inherit = (yyvsp[0].boolean); - n->raw_expr = (yyvsp[-2].node); - n->cooked_expr = NULL; - n->skip_validation = false; - n->initially_valid = true; - (yyval.node) = (Node *)n; - } -#line 29523 "gram.c" /* yacc.c:1646 */ - break; - - case 489: -#line 3604 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_DEFAULT; - n->location = (yylsp[-1]); - n->raw_expr = (yyvsp[0].node); - n->cooked_expr = NULL; - n->skip_validation = false; - n->initially_valid = true; - (yyval.node) = (Node *)n; - } -#line 29538 "gram.c" /* yacc.c:1646 */ - break; - - case 490: -#line 3615 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_IDENTITY; - n->generated_when = (yyvsp[-3].ival); - n->options = (yyvsp[0].list); - n->location = (yylsp[-4]); - (yyval.node) = (Node *)n; - } -#line 29551 "gram.c" /* yacc.c:1646 */ - break; - - case 491: -#line 3624 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_FOREIGN; - n->location = (yylsp[-4]); - n->pktable = (yyvsp[-3].range); - n->fk_attrs = NIL; - n->pk_attrs = (yyvsp[-2].list); - n->fk_matchtype = (yyvsp[-1].ival); - n->fk_upd_action = (char) ((yyvsp[0].ival) >> 8); - n->fk_del_action = (char) ((yyvsp[0].ival) & 0xFF); - n->skip_validation = false; - n->initially_valid = true; - (yyval.node) = (Node *)n; - } -#line 29570 "gram.c" /* yacc.c:1646 */ - break; - - case 492: -#line 3641 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ATTRIBUTE_IDENTITY_ALWAYS; } -#line 29576 "gram.c" /* yacc.c:1646 */ - break; - - case 493: -#line 3642 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ATTRIBUTE_IDENTITY_BY_DEFAULT; } -#line 29582 "gram.c" /* yacc.c:1646 */ - break; - - case 494: -#line 3662 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_ATTR_DEFERRABLE; - n->location = (yylsp[0]); - (yyval.node) = (Node *)n; - } -#line 29593 "gram.c" /* yacc.c:1646 */ - break; - - case 495: -#line 3669 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_ATTR_NOT_DEFERRABLE; - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 29604 "gram.c" /* yacc.c:1646 */ - break; - - case 496: -#line 3676 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_ATTR_DEFERRED; - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 29615 "gram.c" /* yacc.c:1646 */ - break; - - case 497: -#line 3683 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_ATTR_IMMEDIATE; - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 29626 "gram.c" /* yacc.c:1646 */ - break; - - case 498: -#line 3694 "gram.y" /* yacc.c:1646 */ - { - TableLikeClause *n = makeNode(TableLikeClause); - n->relation = (yyvsp[-1].range); - n->options = (yyvsp[0].ival); - (yyval.node) = (Node *)n; - } -#line 29637 "gram.c" /* yacc.c:1646 */ - break; - - case 499: -#line 3703 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-2].ival) | (yyvsp[0].ival); } -#line 29643 "gram.c" /* yacc.c:1646 */ - break; - - case 500: -#line 3704 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-2].ival) & ~(yyvsp[0].ival); } -#line 29649 "gram.c" /* yacc.c:1646 */ - break; - - case 501: -#line 3705 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 29655 "gram.c" /* yacc.c:1646 */ - break; - - case 502: -#line 3709 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_COMMENTS; } -#line 29661 "gram.c" /* yacc.c:1646 */ - break; - - case 503: -#line 3710 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_CONSTRAINTS; } -#line 29667 "gram.c" /* yacc.c:1646 */ - break; - - case 504: -#line 3711 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_DEFAULTS; } -#line 29673 "gram.c" /* yacc.c:1646 */ - break; - - case 505: -#line 3712 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_IDENTITY; } -#line 29679 "gram.c" /* yacc.c:1646 */ - break; - - case 506: -#line 3713 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_INDEXES; } -#line 29685 "gram.c" /* yacc.c:1646 */ - break; - - case 507: -#line 3714 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_STATISTICS; } -#line 29691 "gram.c" /* yacc.c:1646 */ - break; - - case 508: -#line 3715 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_STORAGE; } -#line 29697 "gram.c" /* yacc.c:1646 */ - break; - - case 509: -#line 3716 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CREATE_TABLE_LIKE_ALL; } -#line 29703 "gram.c" /* yacc.c:1646 */ - break; - - case 510: -#line 3726 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = castNode(Constraint, (yyvsp[0].node)); - n->conname = (yyvsp[-1].str); - n->location = (yylsp[-2]); - (yyval.node) = (Node *) n; - } -#line 29714 "gram.c" /* yacc.c:1646 */ - break; - - case 511: -#line 3732 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 29720 "gram.c" /* yacc.c:1646 */ - break; - - case 512: -#line 3737 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_CHECK; - n->location = (yylsp[-4]); - n->raw_expr = (yyvsp[-2].node); - n->cooked_expr = NULL; - processCASbits((yyvsp[0].ival), (yylsp[0]), "CHECK", - NULL, NULL, &n->skip_validation, - &n->is_no_inherit, yyscanner); - n->initially_valid = !n->skip_validation; - (yyval.node) = (Node *)n; - } -#line 29737 "gram.c" /* yacc.c:1646 */ - break; - - case 513: -#line 3751 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_UNIQUE; - n->location = (yylsp[-7]); - n->keys = (yyvsp[-5].list); - n->including = (yyvsp[-3].list); - n->options = (yyvsp[-2].list); - n->indexname = NULL; - n->indexspace = (yyvsp[-1].str); - processCASbits((yyvsp[0].ival), (yylsp[0]), "UNIQUE", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - (yyval.node) = (Node *)n; - } -#line 29756 "gram.c" /* yacc.c:1646 */ - break; - - case 514: -#line 3766 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_UNIQUE; - n->location = (yylsp[-2]); - n->keys = NIL; - n->including = NIL; - n->options = NIL; - n->indexname = (yyvsp[-1].str); - n->indexspace = NULL; - processCASbits((yyvsp[0].ival), (yylsp[0]), "UNIQUE", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - (yyval.node) = (Node *)n; - } -#line 29775 "gram.c" /* yacc.c:1646 */ - break; - - case 515: -#line 3782 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_PRIMARY; - n->location = (yylsp[-8]); - n->keys = (yyvsp[-5].list); - n->including = (yyvsp[-3].list); - n->options = (yyvsp[-2].list); - n->indexname = NULL; - n->indexspace = (yyvsp[-1].str); - processCASbits((yyvsp[0].ival), (yylsp[0]), "PRIMARY KEY", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - (yyval.node) = (Node *)n; - } -#line 29794 "gram.c" /* yacc.c:1646 */ - break; - - case 516: -#line 3797 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_PRIMARY; - n->location = (yylsp[-3]); - n->keys = NIL; - n->including = NIL; - n->options = NIL; - n->indexname = (yyvsp[-1].str); - n->indexspace = NULL; - processCASbits((yyvsp[0].ival), (yylsp[0]), "PRIMARY KEY", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - (yyval.node) = (Node *)n; - } -#line 29813 "gram.c" /* yacc.c:1646 */ - break; - - case 517: -#line 3814 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_EXCLUSION; - n->location = (yylsp[-9]); - n->access_method = (yyvsp[-8].str); - n->exclusions = (yyvsp[-6].list); - n->including = (yyvsp[-4].list); - n->options = (yyvsp[-3].list); - n->indexname = NULL; - n->indexspace = (yyvsp[-2].str); - n->where_clause = (yyvsp[-1].node); - processCASbits((yyvsp[0].ival), (yylsp[0]), "EXCLUDE", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - (yyval.node) = (Node *)n; - } -#line 29834 "gram.c" /* yacc.c:1646 */ - break; - - case 518: -#line 3832 "gram.y" /* yacc.c:1646 */ - { - Constraint *n = makeNode(Constraint); - n->contype = CONSTR_FOREIGN; - n->location = (yylsp[-10]); - n->pktable = (yyvsp[-4].range); - n->fk_attrs = (yyvsp[-7].list); - n->pk_attrs = (yyvsp[-3].list); - n->fk_matchtype = (yyvsp[-2].ival); - n->fk_upd_action = (char) ((yyvsp[-1].ival) >> 8); - n->fk_del_action = (char) ((yyvsp[-1].ival) & 0xFF); - processCASbits((yyvsp[0].ival), (yylsp[0]), "FOREIGN KEY", - &n->deferrable, &n->initdeferred, - &n->skip_validation, NULL, - yyscanner); - n->initially_valid = !n->skip_validation; - (yyval.node) = (Node *)n; - } -#line 29856 "gram.c" /* yacc.c:1646 */ - break; - - case 519: -#line 3851 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 29862 "gram.c" /* yacc.c:1646 */ - break; - - case 520: -#line 3852 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 29868 "gram.c" /* yacc.c:1646 */ - break; - - case 521: -#line 3856 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 29874 "gram.c" /* yacc.c:1646 */ - break; - - case 522: -#line 3857 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 29880 "gram.c" /* yacc.c:1646 */ - break; - - case 523: -#line 3861 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 29886 "gram.c" /* yacc.c:1646 */ - break; - - case 524: -#line 3862 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 29892 "gram.c" /* yacc.c:1646 */ - break; - - case 525: -#line 3866 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeString((yyvsp[0].str)); - } -#line 29900 "gram.c" /* yacc.c:1646 */ - break; - - case 526: -#line 3871 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 29906 "gram.c" /* yacc.c:1646 */ - break; - - case 527: -#line 3872 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 29912 "gram.c" /* yacc.c:1646 */ - break; - - case 528: -#line 3876 "gram.y" /* yacc.c:1646 */ - { - (yyval.ival) = FKCONSTR_MATCH_FULL; - } -#line 29920 "gram.c" /* yacc.c:1646 */ - break; - - case 529: -#line 3880 "gram.y" /* yacc.c:1646 */ - { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"), - parser_errposition((yylsp[-1])))); - (yyval.ival) = FKCONSTR_MATCH_PARTIAL; - } -#line 29932 "gram.c" /* yacc.c:1646 */ - break; - - case 530: -#line 3888 "gram.y" /* yacc.c:1646 */ - { - (yyval.ival) = FKCONSTR_MATCH_SIMPLE; - } -#line 29940 "gram.c" /* yacc.c:1646 */ - break; - - case 531: -#line 3892 "gram.y" /* yacc.c:1646 */ - { - (yyval.ival) = FKCONSTR_MATCH_SIMPLE; - } -#line 29948 "gram.c" /* yacc.c:1646 */ - break; - - case 532: -#line 3898 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].list)); } -#line 29954 "gram.c" /* yacc.c:1646 */ - break; - - case 533: -#line 3900 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].list)); } -#line 29960 "gram.c" /* yacc.c:1646 */ - break; - - case 534: -#line 3904 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[-2].ielem), (yyvsp[0].list)); - } -#line 29968 "gram.c" /* yacc.c:1646 */ - break; - - case 535: -#line 3909 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[-5].ielem), (yyvsp[-1].list)); - } -#line 29976 "gram.c" /* yacc.c:1646 */ - break; - - case 536: -#line 3915 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 29982 "gram.c" /* yacc.c:1646 */ - break; - - case 537: -#line 3916 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 29988 "gram.c" /* yacc.c:1646 */ - break; - - case 538: -#line 3927 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ((yyvsp[0].ival) << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); } -#line 29994 "gram.c" /* yacc.c:1646 */ - break; - - case 539: -#line 3929 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (FKCONSTR_ACTION_NOACTION << 8) | ((yyvsp[0].ival) & 0xFF); } -#line 30000 "gram.c" /* yacc.c:1646 */ - break; - - case 540: -#line 3931 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ((yyvsp[-1].ival) << 8) | ((yyvsp[0].ival) & 0xFF); } -#line 30006 "gram.c" /* yacc.c:1646 */ - break; - - case 541: -#line 3933 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ((yyvsp[0].ival) << 8) | ((yyvsp[-1].ival) & 0xFF); } -#line 30012 "gram.c" /* yacc.c:1646 */ - break; - - case 542: -#line 3935 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (FKCONSTR_ACTION_NOACTION << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); } -#line 30018 "gram.c" /* yacc.c:1646 */ - break; - - case 543: -#line 3938 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 30024 "gram.c" /* yacc.c:1646 */ - break; - - case 544: -#line 3941 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 30030 "gram.c" /* yacc.c:1646 */ - break; - - case 545: -#line 3945 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FKCONSTR_ACTION_NOACTION; } -#line 30036 "gram.c" /* yacc.c:1646 */ - break; - - case 546: -#line 3946 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FKCONSTR_ACTION_RESTRICT; } -#line 30042 "gram.c" /* yacc.c:1646 */ - break; - - case 547: -#line 3947 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FKCONSTR_ACTION_CASCADE; } -#line 30048 "gram.c" /* yacc.c:1646 */ - break; - - case 548: -#line 3948 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FKCONSTR_ACTION_SETNULL; } -#line 30054 "gram.c" /* yacc.c:1646 */ - break; - - case 549: -#line 3949 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FKCONSTR_ACTION_SETDEFAULT; } -#line 30060 "gram.c" /* yacc.c:1646 */ - break; - - case 550: -#line 3952 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 30066 "gram.c" /* yacc.c:1646 */ - break; - - case 551: -#line 3953 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30072 "gram.c" /* yacc.c:1646 */ - break; - - case 552: -#line 3957 "gram.y" /* yacc.c:1646 */ - { (yyval.partspec) = (yyvsp[0].partspec); } -#line 30078 "gram.c" /* yacc.c:1646 */ - break; - - case 553: -#line 3958 "gram.y" /* yacc.c:1646 */ - { (yyval.partspec) = NULL; } -#line 30084 "gram.c" /* yacc.c:1646 */ - break; - - case 554: -#line 3962 "gram.y" /* yacc.c:1646 */ - { - PartitionSpec *n = makeNode(PartitionSpec); - - n->strategy = (yyvsp[-3].str); - n->partParams = (yyvsp[-1].list); - n->location = (yylsp[-5]); - - (yyval.partspec) = n; - } -#line 30098 "gram.c" /* yacc.c:1646 */ - break; - - case 555: -#line 3973 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 30104 "gram.c" /* yacc.c:1646 */ - break; - - case 556: -#line 3974 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 30110 "gram.c" /* yacc.c:1646 */ - break; - - case 557: -#line 3977 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].partelem)); } -#line 30116 "gram.c" /* yacc.c:1646 */ - break; - - case 558: -#line 3978 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].partelem)); } -#line 30122 "gram.c" /* yacc.c:1646 */ - break; - - case 559: -#line 3982 "gram.y" /* yacc.c:1646 */ - { - PartitionElem *n = makeNode(PartitionElem); - - n->name = (yyvsp[-2].str); - n->expr = NULL; - n->collation = (yyvsp[-1].list); - n->opclass = (yyvsp[0].list); - n->location = (yylsp[-2]); - (yyval.partelem) = n; - } -#line 30137 "gram.c" /* yacc.c:1646 */ - break; - - case 560: -#line 3993 "gram.y" /* yacc.c:1646 */ - { - PartitionElem *n = makeNode(PartitionElem); - - n->name = NULL; - n->expr = (yyvsp[-2].node); - n->collation = (yyvsp[-1].list); - n->opclass = (yyvsp[0].list); - n->location = (yylsp[-2]); - (yyval.partelem) = n; - } -#line 30152 "gram.c" /* yacc.c:1646 */ - break; - - case 561: -#line 4004 "gram.y" /* yacc.c:1646 */ - { - PartitionElem *n = makeNode(PartitionElem); - - n->name = NULL; - n->expr = (yyvsp[-3].node); - n->collation = (yyvsp[-1].list); - n->opclass = (yyvsp[0].list); - n->location = (yylsp[-4]); - (yyval.partelem) = n; - } -#line 30167 "gram.c" /* yacc.c:1646 */ - break; - - case 562: -#line 4017 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 30173 "gram.c" /* yacc.c:1646 */ - break; - - case 563: -#line 4018 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeDefElem("oids", (Node *) makeInteger(true), (yylsp[-1]))); } -#line 30179 "gram.c" /* yacc.c:1646 */ - break; - - case 564: -#line 4019 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeDefElem("oids", (Node *) makeInteger(false), (yylsp[-1]))); } -#line 30185 "gram.c" /* yacc.c:1646 */ - break; - - case 565: -#line 4020 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30191 "gram.c" /* yacc.c:1646 */ - break; - - case 566: -#line 4023 "gram.y" /* yacc.c:1646 */ - { (yyval.oncommit) = ONCOMMIT_DROP; } -#line 30197 "gram.c" /* yacc.c:1646 */ - break; - - case 567: -#line 4024 "gram.y" /* yacc.c:1646 */ - { (yyval.oncommit) = ONCOMMIT_DELETE_ROWS; } -#line 30203 "gram.c" /* yacc.c:1646 */ - break; - - case 568: -#line 4025 "gram.y" /* yacc.c:1646 */ - { (yyval.oncommit) = ONCOMMIT_PRESERVE_ROWS; } -#line 30209 "gram.c" /* yacc.c:1646 */ - break; - - case 569: -#line 4026 "gram.y" /* yacc.c:1646 */ - { (yyval.oncommit) = ONCOMMIT_NOOP; } -#line 30215 "gram.c" /* yacc.c:1646 */ - break; - - case 570: -#line 4029 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 30221 "gram.c" /* yacc.c:1646 */ - break; - - case 571: -#line 4030 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 30227 "gram.c" /* yacc.c:1646 */ - break; - - case 572: -#line 4033 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 30233 "gram.c" /* yacc.c:1646 */ - break; - - case 573: -#line 4034 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 30239 "gram.c" /* yacc.c:1646 */ - break; - - case 574: -#line 4037 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 30245 "gram.c" /* yacc.c:1646 */ - break; - - case 575: -#line 4057 "gram.y" /* yacc.c:1646 */ - { - CreateStatsStmt *n = makeNode(CreateStatsStmt); - n->defnames = (yyvsp[-5].list); - n->stat_types = (yyvsp[-4].list); - n->exprs = (yyvsp[-2].list); - n->relations = (yyvsp[0].list); - n->stxcomment = NULL; - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 30260 "gram.c" /* yacc.c:1646 */ - break; - - case 576: -#line 4069 "gram.y" /* yacc.c:1646 */ - { - CreateStatsStmt *n = makeNode(CreateStatsStmt); - n->defnames = (yyvsp[-5].list); - n->stat_types = (yyvsp[-4].list); - n->exprs = (yyvsp[-2].list); - n->relations = (yyvsp[0].list); - n->stxcomment = NULL; - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 30275 "gram.c" /* yacc.c:1646 */ - break; - - case 577: -#line 4093 "gram.y" /* yacc.c:1646 */ - { - CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); - ctas->query = (yyvsp[-1].node); - ctas->into = (yyvsp[-3].into); - ctas->relkind = OBJECT_TABLE; - ctas->is_select_into = false; - ctas->if_not_exists = false; - /* cram additional flags into the IntoClause */ - (yyvsp[-3].into)->rel->relpersistence = (yyvsp[-5].ival); - (yyvsp[-3].into)->skipData = !((yyvsp[0].boolean)); - (yyval.node) = (Node *) ctas; - } -#line 30292 "gram.c" /* yacc.c:1646 */ - break; - - case 578: -#line 4106 "gram.y" /* yacc.c:1646 */ - { - CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); - ctas->query = (yyvsp[-1].node); - ctas->into = (yyvsp[-3].into); - ctas->relkind = OBJECT_TABLE; - ctas->is_select_into = false; - ctas->if_not_exists = true; - /* cram additional flags into the IntoClause */ - (yyvsp[-3].into)->rel->relpersistence = (yyvsp[-8].ival); - (yyvsp[-3].into)->skipData = !((yyvsp[0].boolean)); - (yyval.node) = (Node *) ctas; - } -#line 30309 "gram.c" /* yacc.c:1646 */ - break; - - case 579: -#line 4122 "gram.y" /* yacc.c:1646 */ - { - (yyval.into) = makeNode(IntoClause); - (yyval.into)->rel = (yyvsp[-4].range); - (yyval.into)->colNames = (yyvsp[-3].list); - (yyval.into)->options = (yyvsp[-2].list); - (yyval.into)->onCommit = (yyvsp[-1].oncommit); - (yyval.into)->tableSpaceName = (yyvsp[0].str); - (yyval.into)->viewQuery = NULL; - (yyval.into)->skipData = false; /* might get changed later */ - } -#line 30324 "gram.c" /* yacc.c:1646 */ - break; - - case 580: -#line 4135 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 30330 "gram.c" /* yacc.c:1646 */ - break; - - case 581: -#line 4136 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 30336 "gram.c" /* yacc.c:1646 */ - break; - - case 582: -#line 4137 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 30342 "gram.c" /* yacc.c:1646 */ - break; - - case 583: -#line 4150 "gram.y" /* yacc.c:1646 */ - { - CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); - ctas->query = (yyvsp[-1].node); - ctas->into = (yyvsp[-3].into); - ctas->relkind = OBJECT_MATVIEW; - ctas->is_select_into = false; - ctas->if_not_exists = false; - /* cram additional flags into the IntoClause */ - (yyvsp[-3].into)->rel->relpersistence = (yyvsp[-6].ival); - (yyvsp[-3].into)->skipData = !((yyvsp[0].boolean)); - (yyval.node) = (Node *) ctas; - } -#line 30359 "gram.c" /* yacc.c:1646 */ - break; - - case 584: -#line 4163 "gram.y" /* yacc.c:1646 */ - { - CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); - ctas->query = (yyvsp[-1].node); - ctas->into = (yyvsp[-3].into); - ctas->relkind = OBJECT_MATVIEW; - ctas->is_select_into = false; - ctas->if_not_exists = true; - /* cram additional flags into the IntoClause */ - (yyvsp[-3].into)->rel->relpersistence = (yyvsp[-9].ival); - (yyvsp[-3].into)->skipData = !((yyvsp[0].boolean)); - (yyval.node) = (Node *) ctas; - } -#line 30376 "gram.c" /* yacc.c:1646 */ - break; - - case 585: -#line 4179 "gram.y" /* yacc.c:1646 */ - { - (yyval.into) = makeNode(IntoClause); - (yyval.into)->rel = (yyvsp[-3].range); - (yyval.into)->colNames = (yyvsp[-2].list); - (yyval.into)->options = (yyvsp[-1].list); - (yyval.into)->onCommit = ONCOMMIT_NOOP; - (yyval.into)->tableSpaceName = (yyvsp[0].str); - (yyval.into)->viewQuery = NULL; /* filled at analysis time */ - (yyval.into)->skipData = false; /* might get changed later */ - } -#line 30391 "gram.c" /* yacc.c:1646 */ - break; - - case 586: -#line 4191 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_UNLOGGED; } -#line 30397 "gram.c" /* yacc.c:1646 */ - break; - - case 587: -#line 4192 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RELPERSISTENCE_PERMANENT; } -#line 30403 "gram.c" /* yacc.c:1646 */ - break; - - case 588: -#line 4205 "gram.y" /* yacc.c:1646 */ - { - RefreshMatViewStmt *n = makeNode(RefreshMatViewStmt); - n->concurrent = (yyvsp[-2].boolean); - n->relation = (yyvsp[-1].range); - n->skipData = !((yyvsp[0].boolean)); - (yyval.node) = (Node *) n; - } -#line 30415 "gram.c" /* yacc.c:1646 */ - break; - - case 589: -#line 4225 "gram.y" /* yacc.c:1646 */ - { - CreateSeqStmt *n = makeNode(CreateSeqStmt); - (yyvsp[-1].range)->relpersistence = (yyvsp[-3].ival); - n->sequence = (yyvsp[-1].range); - n->options = (yyvsp[0].list); - n->ownerId = InvalidOid; - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 30429 "gram.c" /* yacc.c:1646 */ - break; - - case 590: -#line 4235 "gram.y" /* yacc.c:1646 */ - { - CreateSeqStmt *n = makeNode(CreateSeqStmt); - (yyvsp[-1].range)->relpersistence = (yyvsp[-6].ival); - n->sequence = (yyvsp[-1].range); - n->options = (yyvsp[0].list); - n->ownerId = InvalidOid; - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 30443 "gram.c" /* yacc.c:1646 */ - break; - - case 591: -#line 4248 "gram.y" /* yacc.c:1646 */ - { - AlterSeqStmt *n = makeNode(AlterSeqStmt); - n->sequence = (yyvsp[-1].range); - n->options = (yyvsp[0].list); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 30455 "gram.c" /* yacc.c:1646 */ - break; - - case 592: -#line 4256 "gram.y" /* yacc.c:1646 */ - { - AlterSeqStmt *n = makeNode(AlterSeqStmt); - n->sequence = (yyvsp[-1].range); - n->options = (yyvsp[0].list); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 30467 "gram.c" /* yacc.c:1646 */ - break; - - case 593: -#line 4266 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 30473 "gram.c" /* yacc.c:1646 */ - break; - - case 594: -#line 4267 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30479 "gram.c" /* yacc.c:1646 */ - break; - - case 595: -#line 4270 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 30485 "gram.c" /* yacc.c:1646 */ - break; - - case 596: -#line 4271 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30491 "gram.c" /* yacc.c:1646 */ - break; - - case 597: -#line 4274 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 30497 "gram.c" /* yacc.c:1646 */ - break; - - case 598: -#line 4275 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 30503 "gram.c" /* yacc.c:1646 */ - break; - - case 599: -#line 4279 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("as", (Node *)(yyvsp[0].typnam), (yylsp[-1])); - } -#line 30511 "gram.c" /* yacc.c:1646 */ - break; - - case 600: -#line 4283 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("cache", (Node *)(yyvsp[0].value), (yylsp[-1])); - } -#line 30519 "gram.c" /* yacc.c:1646 */ - break; - - case 601: -#line 4287 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("cycle", (Node *)makeInteger(true), (yylsp[0])); - } -#line 30527 "gram.c" /* yacc.c:1646 */ - break; - - case 602: -#line 4291 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("cycle", (Node *)makeInteger(false), (yylsp[-1])); - } -#line 30535 "gram.c" /* yacc.c:1646 */ - break; - - case 603: -#line 4295 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("increment", (Node *)(yyvsp[0].value), (yylsp[-2])); - } -#line 30543 "gram.c" /* yacc.c:1646 */ - break; - - case 604: -#line 4299 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("maxvalue", (Node *)(yyvsp[0].value), (yylsp[-1])); - } -#line 30551 "gram.c" /* yacc.c:1646 */ - break; - - case 605: -#line 4303 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("minvalue", (Node *)(yyvsp[0].value), (yylsp[-1])); - } -#line 30559 "gram.c" /* yacc.c:1646 */ - break; - - case 606: -#line 4307 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("maxvalue", NULL, (yylsp[-1])); - } -#line 30567 "gram.c" /* yacc.c:1646 */ - break; - - case 607: -#line 4311 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("minvalue", NULL, (yylsp[-1])); - } -#line 30575 "gram.c" /* yacc.c:1646 */ - break; - - case 608: -#line 4315 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("owned_by", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 30583 "gram.c" /* yacc.c:1646 */ - break; - - case 609: -#line 4319 "gram.y" /* yacc.c:1646 */ - { - /* not documented, only used by pg_dump */ - (yyval.defelt) = makeDefElem("sequence_name", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 30592 "gram.c" /* yacc.c:1646 */ - break; - - case 610: -#line 4324 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("start", (Node *)(yyvsp[0].value), (yylsp[-2])); - } -#line 30600 "gram.c" /* yacc.c:1646 */ - break; - - case 611: -#line 4328 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("restart", NULL, (yylsp[0])); - } -#line 30608 "gram.c" /* yacc.c:1646 */ - break; - - case 612: -#line 4332 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("restart", (Node *)(yyvsp[0].value), (yylsp[-2])); - } -#line 30616 "gram.c" /* yacc.c:1646 */ - break; - - case 613: -#line 4337 "gram.y" /* yacc.c:1646 */ - {} -#line 30622 "gram.c" /* yacc.c:1646 */ - break; - - case 614: -#line 4338 "gram.y" /* yacc.c:1646 */ - {} -#line 30628 "gram.c" /* yacc.c:1646 */ - break; - - case 615: -#line 4342 "gram.y" /* yacc.c:1646 */ - { (yyval.value) = makeFloat((yyvsp[0].str)); } -#line 30634 "gram.c" /* yacc.c:1646 */ - break; - - case 616: -#line 4343 "gram.y" /* yacc.c:1646 */ - { (yyval.value) = makeFloat((yyvsp[0].str)); } -#line 30640 "gram.c" /* yacc.c:1646 */ - break; - - case 617: -#line 4345 "gram.y" /* yacc.c:1646 */ - { - (yyval.value) = makeFloat((yyvsp[0].str)); - doNegateFloat((yyval.value)); - } -#line 30649 "gram.c" /* yacc.c:1646 */ - break; - - case 618: -#line 4349 "gram.y" /* yacc.c:1646 */ - { (yyval.value) = makeInteger((yyvsp[0].ival)); } -#line 30655 "gram.c" /* yacc.c:1646 */ - break; - - case 619: -#line 4352 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].value)); } -#line 30661 "gram.c" /* yacc.c:1646 */ - break; - - case 620: -#line 4353 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].value)); } -#line 30667 "gram.c" /* yacc.c:1646 */ - break; - - case 621: -#line 4366 "gram.y" /* yacc.c:1646 */ - { - CreatePLangStmt *n = makeNode(CreatePLangStmt); - n->replace = (yyvsp[-4].boolean); - n->plname = (yyvsp[0].str); - /* parameters are all to be supplied by system */ - n->plhandler = NIL; - n->plinline = NIL; - n->plvalidator = NIL; - n->pltrusted = false; - (yyval.node) = (Node *)n; - } -#line 30683 "gram.c" /* yacc.c:1646 */ - break; - - case 622: -#line 4379 "gram.y" /* yacc.c:1646 */ - { - CreatePLangStmt *n = makeNode(CreatePLangStmt); - n->replace = (yyvsp[-8].boolean); - n->plname = (yyvsp[-4].str); - n->plhandler = (yyvsp[-2].list); - n->plinline = (yyvsp[-1].list); - n->plvalidator = (yyvsp[0].list); - n->pltrusted = (yyvsp[-7].boolean); - (yyval.node) = (Node *)n; - } -#line 30698 "gram.c" /* yacc.c:1646 */ - break; - - case 623: -#line 4392 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 30704 "gram.c" /* yacc.c:1646 */ - break; - - case 624: -#line 4393 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 30710 "gram.c" /* yacc.c:1646 */ - break; - - case 625: -#line 4401 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 30716 "gram.c" /* yacc.c:1646 */ - break; - - case 626: -#line 4402 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lcons(makeString((yyvsp[-1].str)), (yyvsp[0].list)); } -#line 30722 "gram.c" /* yacc.c:1646 */ - break; - - case 627: -#line 4406 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 30728 "gram.c" /* yacc.c:1646 */ - break; - - case 628: -#line 4407 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30734 "gram.c" /* yacc.c:1646 */ - break; - - case 629: -#line 4411 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 30740 "gram.c" /* yacc.c:1646 */ - break; - - case 630: -#line 4412 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30746 "gram.c" /* yacc.c:1646 */ - break; - - case 631: -#line 4416 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 30752 "gram.c" /* yacc.c:1646 */ - break; - - case 632: -#line 4417 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30758 "gram.c" /* yacc.c:1646 */ - break; - - case 633: -#line 4422 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_LANGUAGE; - n->objects = list_make1(makeString((yyvsp[-1].str))); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 30772 "gram.c" /* yacc.c:1646 */ - break; - - case 634: -#line 4432 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_LANGUAGE; - n->objects = list_make1(makeString((yyvsp[-1].str))); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 30786 "gram.c" /* yacc.c:1646 */ - break; - - case 635: -#line 4444 "gram.y" /* yacc.c:1646 */ - {} -#line 30792 "gram.c" /* yacc.c:1646 */ - break; - - case 636: -#line 4445 "gram.y" /* yacc.c:1646 */ - {} -#line 30798 "gram.c" /* yacc.c:1646 */ - break; - - case 637: -#line 4456 "gram.y" /* yacc.c:1646 */ - { - CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt); - n->tablespacename = (yyvsp[-4].str); - n->owner = (yyvsp[-3].rolespec); - n->location = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 30811 "gram.c" /* yacc.c:1646 */ - break; - - case 638: -#line 4466 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = (yyvsp[0].rolespec); } -#line 30817 "gram.c" /* yacc.c:1646 */ - break; - - case 639: -#line 4467 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = NULL; } -#line 30823 "gram.c" /* yacc.c:1646 */ - break; - - case 640: -#line 4481 "gram.y" /* yacc.c:1646 */ - { - DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); - n->tablespacename = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *) n; - } -#line 30834 "gram.c" /* yacc.c:1646 */ - break; - - case 641: -#line 4488 "gram.y" /* yacc.c:1646 */ - { - DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); - n->tablespacename = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *) n; - } -#line 30845 "gram.c" /* yacc.c:1646 */ - break; - - case 642: -#line 4505 "gram.y" /* yacc.c:1646 */ - { - CreateExtensionStmt *n = makeNode(CreateExtensionStmt); - n->extname = (yyvsp[-2].str); - n->if_not_exists = false; - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 30857 "gram.c" /* yacc.c:1646 */ - break; - - case 643: -#line 4513 "gram.y" /* yacc.c:1646 */ - { - CreateExtensionStmt *n = makeNode(CreateExtensionStmt); - n->extname = (yyvsp[-2].str); - n->if_not_exists = true; - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 30869 "gram.c" /* yacc.c:1646 */ - break; - - case 644: -#line 4524 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 30875 "gram.c" /* yacc.c:1646 */ - break; - - case 645: -#line 4526 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30881 "gram.c" /* yacc.c:1646 */ - break; - - case 646: -#line 4531 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("schema", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 30889 "gram.c" /* yacc.c:1646 */ - break; - - case 647: -#line 4535 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("new_version", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 30897 "gram.c" /* yacc.c:1646 */ - break; - - case 648: -#line 4539 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("old_version", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 30905 "gram.c" /* yacc.c:1646 */ - break; - - case 649: -#line 4543 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("cascade", (Node *)makeInteger(true), (yylsp[0])); - } -#line 30913 "gram.c" /* yacc.c:1646 */ - break; - - case 650: -#line 4555 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionStmt *n = makeNode(AlterExtensionStmt); - n->extname = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 30924 "gram.c" /* yacc.c:1646 */ - break; - - case 651: -#line 4565 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 30930 "gram.c" /* yacc.c:1646 */ - break; - - case 652: -#line 4567 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 30936 "gram.c" /* yacc.c:1646 */ - break; - - case 653: -#line 4572 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("new_version", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 30944 "gram.c" /* yacc.c:1646 */ - break; - - case 654: -#line 4585 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-4].str); - n->action = (yyvsp[-3].ival); - n->objtype = OBJECT_ACCESS_METHOD; - n->object = (Node *) makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 30957 "gram.c" /* yacc.c:1646 */ - break; - - case 655: -#line 4594 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_AGGREGATE; - n->object = (Node *) (yyvsp[0].objwithargs); - (yyval.node) = (Node *)n; - } -#line 30970 "gram.c" /* yacc.c:1646 */ - break; - - case 656: -#line 4603 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-7].str); - n->action = (yyvsp[-6].ival); - n->objtype = OBJECT_CAST; - n->object = (Node *) list_make2((yyvsp[-3].typnam), (yyvsp[-1].typnam)); - (yyval.node) = (Node *) n; - } -#line 30983 "gram.c" /* yacc.c:1646 */ - break; - - case 657: -#line 4612 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_COLLATION; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 30996 "gram.c" /* yacc.c:1646 */ - break; - - case 658: -#line 4621 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_CONVERSION; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31009 "gram.c" /* yacc.c:1646 */ - break; - - case 659: -#line 4630 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_DOMAIN; - n->object = (Node *) (yyvsp[0].typnam); - (yyval.node) = (Node *)n; - } -#line 31022 "gram.c" /* yacc.c:1646 */ - break; - - case 660: -#line 4639 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_FUNCTION; - n->object = (Node *) (yyvsp[0].objwithargs); - (yyval.node) = (Node *)n; - } -#line 31035 "gram.c" /* yacc.c:1646 */ - break; - - case 661: -#line 4648 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-4].str); - n->action = (yyvsp[-3].ival); - n->objtype = OBJECT_LANGUAGE; - n->object = (Node *) makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 31048 "gram.c" /* yacc.c:1646 */ - break; - - case 662: -#line 4657 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_OPERATOR; - n->object = (Node *) (yyvsp[0].objwithargs); - (yyval.node) = (Node *)n; - } -#line 31061 "gram.c" /* yacc.c:1646 */ - break; - - case 663: -#line 4666 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-6].str); - n->action = (yyvsp[-5].ival); - n->objtype = OBJECT_OPCLASS; - n->object = (Node *) lcons(makeString((yyvsp[0].str)), (yyvsp[-2].list)); - (yyval.node) = (Node *)n; - } -#line 31074 "gram.c" /* yacc.c:1646 */ - break; - - case 664: -#line 4675 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-6].str); - n->action = (yyvsp[-5].ival); - n->objtype = OBJECT_OPFAMILY; - n->object = (Node *) lcons(makeString((yyvsp[0].str)), (yyvsp[-2].list)); - (yyval.node) = (Node *)n; - } -#line 31087 "gram.c" /* yacc.c:1646 */ - break; - - case 665: -#line 4684 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_PROCEDURE; - n->object = (Node *) (yyvsp[0].objwithargs); - (yyval.node) = (Node *)n; - } -#line 31100 "gram.c" /* yacc.c:1646 */ - break; - - case 666: -#line 4693 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_ROUTINE; - n->object = (Node *) (yyvsp[0].objwithargs); - (yyval.node) = (Node *)n; - } -#line 31113 "gram.c" /* yacc.c:1646 */ - break; - - case 667: -#line 4702 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_SCHEMA; - n->object = (Node *) makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 31126 "gram.c" /* yacc.c:1646 */ - break; - - case 668: -#line 4711 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-4].str); - n->action = (yyvsp[-3].ival); - n->objtype = OBJECT_EVENT_TRIGGER; - n->object = (Node *) makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 31139 "gram.c" /* yacc.c:1646 */ - break; - - case 669: -#line 4720 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_TABLE; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31152 "gram.c" /* yacc.c:1646 */ - break; - - case 670: -#line 4729 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-5].str); - n->action = (yyvsp[-4].ival); - n->objtype = OBJECT_TSPARSER; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31165 "gram.c" /* yacc.c:1646 */ - break; - - case 671: -#line 4738 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-5].str); - n->action = (yyvsp[-4].ival); - n->objtype = OBJECT_TSDICTIONARY; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31178 "gram.c" /* yacc.c:1646 */ - break; - - case 672: -#line 4747 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-5].str); - n->action = (yyvsp[-4].ival); - n->objtype = OBJECT_TSTEMPLATE; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31191 "gram.c" /* yacc.c:1646 */ - break; - - case 673: -#line 4756 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-5].str); - n->action = (yyvsp[-4].ival); - n->objtype = OBJECT_TSCONFIGURATION; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31204 "gram.c" /* yacc.c:1646 */ - break; - - case 674: -#line 4765 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_SEQUENCE; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31217 "gram.c" /* yacc.c:1646 */ - break; - - case 675: -#line 4774 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_VIEW; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31230 "gram.c" /* yacc.c:1646 */ - break; - - case 676: -#line 4783 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-4].str); - n->action = (yyvsp[-3].ival); - n->objtype = OBJECT_MATVIEW; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31243 "gram.c" /* yacc.c:1646 */ - break; - - case 677: -#line 4792 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-4].str); - n->action = (yyvsp[-3].ival); - n->objtype = OBJECT_FOREIGN_TABLE; - n->object = (Node *) (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 31256 "gram.c" /* yacc.c:1646 */ - break; - - case 678: -#line 4801 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-5].str); - n->action = (yyvsp[-4].ival); - n->objtype = OBJECT_FDW; - n->object = (Node *) makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 31269 "gram.c" /* yacc.c:1646 */ - break; - - case 679: -#line 4810 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_FOREIGN_SERVER; - n->object = (Node *) makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 31282 "gram.c" /* yacc.c:1646 */ - break; - - case 680: -#line 4819 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-6].str); - n->action = (yyvsp[-5].ival); - n->objtype = OBJECT_TRANSFORM; - n->object = (Node *) list_make2((yyvsp[-2].typnam), makeString((yyvsp[0].str))); - (yyval.node) = (Node *)n; - } -#line 31295 "gram.c" /* yacc.c:1646 */ - break; - - case 681: -#line 4828 "gram.y" /* yacc.c:1646 */ - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = (yyvsp[-3].str); - n->action = (yyvsp[-2].ival); - n->objtype = OBJECT_TYPE; - n->object = (Node *) (yyvsp[0].typnam); - (yyval.node) = (Node *)n; - } -#line 31308 "gram.c" /* yacc.c:1646 */ - break; - - case 682: -#line 4846 "gram.y" /* yacc.c:1646 */ - { - CreateFdwStmt *n = makeNode(CreateFdwStmt); - n->fdwname = (yyvsp[-2].str); - n->func_options = (yyvsp[-1].list); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31320 "gram.c" /* yacc.c:1646 */ - break; - - case 683: -#line 4856 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("handler", (Node *)(yyvsp[0].list), (yylsp[-1])); } -#line 31326 "gram.c" /* yacc.c:1646 */ - break; - - case 684: -#line 4857 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("handler", NULL, (yylsp[-1])); } -#line 31332 "gram.c" /* yacc.c:1646 */ - break; - - case 685: -#line 4858 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("validator", (Node *)(yyvsp[0].list), (yylsp[-1])); } -#line 31338 "gram.c" /* yacc.c:1646 */ - break; - - case 686: -#line 4859 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("validator", NULL, (yylsp[-1])); } -#line 31344 "gram.c" /* yacc.c:1646 */ - break; - - case 687: -#line 4863 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 31350 "gram.c" /* yacc.c:1646 */ - break; - - case 688: -#line 4864 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 31356 "gram.c" /* yacc.c:1646 */ - break; - - case 689: -#line 4868 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 31362 "gram.c" /* yacc.c:1646 */ - break; - - case 690: -#line 4869 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 31368 "gram.c" /* yacc.c:1646 */ - break; - - case 691: -#line 4880 "gram.y" /* yacc.c:1646 */ - { - AlterFdwStmt *n = makeNode(AlterFdwStmt); - n->fdwname = (yyvsp[-2].str); - n->func_options = (yyvsp[-1].list); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31380 "gram.c" /* yacc.c:1646 */ - break; - - case 692: -#line 4888 "gram.y" /* yacc.c:1646 */ - { - AlterFdwStmt *n = makeNode(AlterFdwStmt); - n->fdwname = (yyvsp[-1].str); - n->func_options = (yyvsp[0].list); - n->options = NIL; - (yyval.node) = (Node *) n; - } -#line 31392 "gram.c" /* yacc.c:1646 */ - break; - - case 693: -#line 4899 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 31398 "gram.c" /* yacc.c:1646 */ - break; - - case 694: -#line 4900 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 31404 "gram.c" /* yacc.c:1646 */ - break; - - case 695: -#line 4905 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].defelt)); - } -#line 31412 "gram.c" /* yacc.c:1646 */ - break; - - case 696: -#line 4909 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); - } -#line 31420 "gram.c" /* yacc.c:1646 */ - break; - - case 697: -#line 4916 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 31426 "gram.c" /* yacc.c:1646 */ - break; - - case 698: -#line 4921 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].defelt)); - } -#line 31434 "gram.c" /* yacc.c:1646 */ - break; - - case 699: -#line 4925 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); - } -#line 31442 "gram.c" /* yacc.c:1646 */ - break; - - case 700: -#line 4932 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = (yyvsp[0].defelt); - } -#line 31450 "gram.c" /* yacc.c:1646 */ - break; - - case 701: -#line 4936 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = (yyvsp[0].defelt); - (yyval.defelt)->defaction = DEFELEM_SET; - } -#line 31459 "gram.c" /* yacc.c:1646 */ - break; - - case 702: -#line 4941 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = (yyvsp[0].defelt); - (yyval.defelt)->defaction = DEFELEM_ADD; - } -#line 31468 "gram.c" /* yacc.c:1646 */ - break; - - case 703: -#line 4946 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElemExtended(NULL, (yyvsp[0].str), NULL, DEFELEM_DROP, (yylsp[0])); - } -#line 31476 "gram.c" /* yacc.c:1646 */ - break; - - case 704: -#line 4953 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-1].str), (yyvsp[0].node), (yylsp[-1])); - } -#line 31484 "gram.c" /* yacc.c:1646 */ - break; - - case 705: -#line 4959 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 31490 "gram.c" /* yacc.c:1646 */ - break; - - case 706: -#line 4964 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeString((yyvsp[0].str)); } -#line 31496 "gram.c" /* yacc.c:1646 */ - break; - - case 707: -#line 4976 "gram.y" /* yacc.c:1646 */ - { - CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt); - n->servername = (yyvsp[-7].str); - n->servertype = (yyvsp[-6].str); - n->version = (yyvsp[-5].str); - n->fdwname = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - n->if_not_exists = false; - (yyval.node) = (Node *) n; - } -#line 31511 "gram.c" /* yacc.c:1646 */ - break; - - case 708: -#line 4988 "gram.y" /* yacc.c:1646 */ - { - CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt); - n->servername = (yyvsp[-7].str); - n->servertype = (yyvsp[-6].str); - n->version = (yyvsp[-5].str); - n->fdwname = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - n->if_not_exists = true; - (yyval.node) = (Node *) n; - } -#line 31526 "gram.c" /* yacc.c:1646 */ - break; - - case 709: -#line 5001 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 31532 "gram.c" /* yacc.c:1646 */ - break; - - case 710: -#line 5002 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 31538 "gram.c" /* yacc.c:1646 */ - break; - - case 711: -#line 5007 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 31544 "gram.c" /* yacc.c:1646 */ - break; - - case 712: -#line 5008 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 31550 "gram.c" /* yacc.c:1646 */ - break; - - case 713: -#line 5012 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 31556 "gram.c" /* yacc.c:1646 */ - break; - - case 714: -#line 5013 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 31562 "gram.c" /* yacc.c:1646 */ - break; - - case 715: -#line 5024 "gram.y" /* yacc.c:1646 */ - { - AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); - n->servername = (yyvsp[-2].str); - n->version = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - n->has_version = true; - (yyval.node) = (Node *) n; - } -#line 31575 "gram.c" /* yacc.c:1646 */ - break; - - case 716: -#line 5033 "gram.y" /* yacc.c:1646 */ - { - AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); - n->servername = (yyvsp[-1].str); - n->version = (yyvsp[0].str); - n->has_version = true; - (yyval.node) = (Node *) n; - } -#line 31587 "gram.c" /* yacc.c:1646 */ - break; - - case 717: -#line 5041 "gram.y" /* yacc.c:1646 */ - { - AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31598 "gram.c" /* yacc.c:1646 */ - break; - - case 718: -#line 5060 "gram.y" /* yacc.c:1646 */ - { - CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); - (yyvsp[-7].range)->relpersistence = RELPERSISTENCE_PERMANENT; - n->base.relation = (yyvsp[-7].range); - n->base.tableElts = (yyvsp[-5].list); - n->base.inhRelations = (yyvsp[-3].list); - n->base.ofTypename = NULL; - n->base.constraints = NIL; - n->base.options = NIL; - n->base.oncommit = ONCOMMIT_NOOP; - n->base.tablespacename = NULL; - n->base.if_not_exists = false; - /* FDW-specific data */ - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31620 "gram.c" /* yacc.c:1646 */ - break; - - case 719: -#line 5080 "gram.y" /* yacc.c:1646 */ - { - CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); - (yyvsp[-7].range)->relpersistence = RELPERSISTENCE_PERMANENT; - n->base.relation = (yyvsp[-7].range); - n->base.tableElts = (yyvsp[-5].list); - n->base.inhRelations = (yyvsp[-3].list); - n->base.ofTypename = NULL; - n->base.constraints = NIL; - n->base.options = NIL; - n->base.oncommit = ONCOMMIT_NOOP; - n->base.tablespacename = NULL; - n->base.if_not_exists = true; - /* FDW-specific data */ - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31642 "gram.c" /* yacc.c:1646 */ - break; - - case 720: -#line 5100 "gram.y" /* yacc.c:1646 */ - { - CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); - (yyvsp[-8].range)->relpersistence = RELPERSISTENCE_PERMANENT; - n->base.relation = (yyvsp[-8].range); - n->base.inhRelations = list_make1((yyvsp[-5].range)); - n->base.tableElts = (yyvsp[-4].list); - n->base.partbound = (yyvsp[-3].partboundspec); - n->base.ofTypename = NULL; - n->base.constraints = NIL; - n->base.options = NIL; - n->base.oncommit = ONCOMMIT_NOOP; - n->base.tablespacename = NULL; - n->base.if_not_exists = false; - /* FDW-specific data */ - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31665 "gram.c" /* yacc.c:1646 */ - break; - - case 721: -#line 5121 "gram.y" /* yacc.c:1646 */ - { - CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); - (yyvsp[-8].range)->relpersistence = RELPERSISTENCE_PERMANENT; - n->base.relation = (yyvsp[-8].range); - n->base.inhRelations = list_make1((yyvsp[-5].range)); - n->base.tableElts = (yyvsp[-4].list); - n->base.partbound = (yyvsp[-3].partboundspec); - n->base.ofTypename = NULL; - n->base.constraints = NIL; - n->base.options = NIL; - n->base.oncommit = ONCOMMIT_NOOP; - n->base.tablespacename = NULL; - n->base.if_not_exists = true; - /* FDW-specific data */ - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31688 "gram.c" /* yacc.c:1646 */ - break; - - case 722: -#line 5150 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_FOREIGN_TABLE; - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 31701 "gram.c" /* yacc.c:1646 */ - break; - - case 723: -#line 5159 "gram.y" /* yacc.c:1646 */ - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = (yyvsp[-1].range); - n->cmds = (yyvsp[0].list); - n->relkind = OBJECT_FOREIGN_TABLE; - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 31714 "gram.c" /* yacc.c:1646 */ - break; - - case 724: -#line 5181 "gram.y" /* yacc.c:1646 */ - { - ImportForeignSchemaStmt *n = makeNode(ImportForeignSchemaStmt); - n->server_name = (yyvsp[-3].str); - n->remote_schema = (yyvsp[-7].str); - n->local_schema = (yyvsp[-1].str); - n->list_type = (yyvsp[-6].importqual)->type; - n->table_list = (yyvsp[-6].importqual)->table_names; - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31729 "gram.c" /* yacc.c:1646 */ - break; - - case 725: -#line 5194 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FDW_IMPORT_SCHEMA_LIMIT_TO; } -#line 31735 "gram.c" /* yacc.c:1646 */ - break; - - case 726: -#line 5195 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FDW_IMPORT_SCHEMA_EXCEPT; } -#line 31741 "gram.c" /* yacc.c:1646 */ - break; - - case 727: -#line 5200 "gram.y" /* yacc.c:1646 */ - { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); - n->type = (yyvsp[-3].ival); - n->table_names = (yyvsp[-1].list); - (yyval.importqual) = n; - } -#line 31752 "gram.c" /* yacc.c:1646 */ - break; - - case 728: -#line 5207 "gram.y" /* yacc.c:1646 */ - { - ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); - n->type = FDW_IMPORT_SCHEMA_ALL; - n->table_names = NIL; - (yyval.importqual) = n; - } -#line 31763 "gram.c" /* yacc.c:1646 */ - break; - - case 729: -#line 5223 "gram.y" /* yacc.c:1646 */ - { - CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); - n->user = (yyvsp[-3].rolespec); - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - n->if_not_exists = false; - (yyval.node) = (Node *) n; - } -#line 31776 "gram.c" /* yacc.c:1646 */ - break; - - case 730: -#line 5232 "gram.y" /* yacc.c:1646 */ - { - CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); - n->user = (yyvsp[-3].rolespec); - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - n->if_not_exists = true; - (yyval.node) = (Node *) n; - } -#line 31789 "gram.c" /* yacc.c:1646 */ - break; - - case 731: -#line 5243 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = (yyvsp[0].rolespec); } -#line 31795 "gram.c" /* yacc.c:1646 */ - break; - - case 732: -#line 5244 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = makeRoleSpec(ROLESPEC_CURRENT_USER, (yylsp[0])); } -#line 31801 "gram.c" /* yacc.c:1646 */ - break; - - case 733: -#line 5257 "gram.y" /* yacc.c:1646 */ - { - DropUserMappingStmt *n = makeNode(DropUserMappingStmt); - n->user = (yyvsp[-2].rolespec); - n->servername = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *) n; - } -#line 31813 "gram.c" /* yacc.c:1646 */ - break; - - case 734: -#line 5265 "gram.y" /* yacc.c:1646 */ - { - DropUserMappingStmt *n = makeNode(DropUserMappingStmt); - n->user = (yyvsp[-2].rolespec); - n->servername = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *) n; - } -#line 31825 "gram.c" /* yacc.c:1646 */ - break; - - case 735: -#line 5282 "gram.y" /* yacc.c:1646 */ - { - AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt); - n->user = (yyvsp[-3].rolespec); - n->servername = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 31837 "gram.c" /* yacc.c:1646 */ - break; - - case 736: -#line 5308 "gram.y" /* yacc.c:1646 */ - { - CreatePolicyStmt *n = makeNode(CreatePolicyStmt); - n->policy_name = (yyvsp[-7].str); - n->table = (yyvsp[-5].range); - n->permissive = (yyvsp[-4].boolean); - n->cmd_name = (yyvsp[-3].str); - n->roles = (yyvsp[-2].list); - n->qual = (yyvsp[-1].node); - n->with_check = (yyvsp[0].node); - (yyval.node) = (Node *) n; - } -#line 31853 "gram.c" /* yacc.c:1646 */ - break; - - case 737: -#line 5324 "gram.y" /* yacc.c:1646 */ - { - AlterPolicyStmt *n = makeNode(AlterPolicyStmt); - n->policy_name = (yyvsp[-5].str); - n->table = (yyvsp[-3].range); - n->roles = (yyvsp[-2].list); - n->qual = (yyvsp[-1].node); - n->with_check = (yyvsp[0].node); - (yyval.node) = (Node *) n; - } -#line 31867 "gram.c" /* yacc.c:1646 */ - break; - - case 738: -#line 5336 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 31873 "gram.c" /* yacc.c:1646 */ - break; - - case 739: -#line 5337 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 31879 "gram.c" /* yacc.c:1646 */ - break; - - case 740: -#line 5341 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 31885 "gram.c" /* yacc.c:1646 */ - break; - - case 741: -#line 5342 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 31891 "gram.c" /* yacc.c:1646 */ - break; - - case 742: -#line 5346 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 31897 "gram.c" /* yacc.c:1646 */ - break; - - case 743: -#line 5347 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeRoleSpec(ROLESPEC_PUBLIC, -1)); } -#line 31903 "gram.c" /* yacc.c:1646 */ - break; - - case 744: -#line 5351 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 31909 "gram.c" /* yacc.c:1646 */ - break; - - case 745: -#line 5352 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NULL; } -#line 31915 "gram.c" /* yacc.c:1646 */ - break; - - case 746: -#line 5357 "gram.y" /* yacc.c:1646 */ - { - if (strcmp((yyvsp[0].str), "permissive") == 0) - (yyval.boolean) = true; - else if (strcmp((yyvsp[0].str), "restrictive") == 0) - (yyval.boolean) = false; - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized row security option \"%s\"", (yyvsp[0].str)), - errhint("Only PERMISSIVE or RESTRICTIVE policies are supported currently."), - parser_errposition((yylsp[0])))); - - } -#line 31933 "gram.c" /* yacc.c:1646 */ - break; - - case 747: -#line 5370 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 31939 "gram.c" /* yacc.c:1646 */ - break; - - case 748: -#line 5374 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 31945 "gram.c" /* yacc.c:1646 */ - break; - - case 749: -#line 5375 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "all"; } -#line 31951 "gram.c" /* yacc.c:1646 */ - break; - - case 750: -#line 5379 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "all"; } -#line 31957 "gram.c" /* yacc.c:1646 */ - break; - - case 751: -#line 5380 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "select"; } -#line 31963 "gram.c" /* yacc.c:1646 */ - break; - - case 752: -#line 5381 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "insert"; } -#line 31969 "gram.c" /* yacc.c:1646 */ - break; - - case 753: -#line 5382 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "update"; } -#line 31975 "gram.c" /* yacc.c:1646 */ - break; - - case 754: -#line 5383 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "delete"; } -#line 31981 "gram.c" /* yacc.c:1646 */ - break; - - case 755: -#line 5394 "gram.y" /* yacc.c:1646 */ - { - CreateAmStmt *n = makeNode(CreateAmStmt); - n->amname = (yyvsp[-4].str); - n->handler_name = (yyvsp[0].list); - n->amtype = AMTYPE_INDEX; - (yyval.node) = (Node *) n; - } -#line 31993 "gram.c" /* yacc.c:1646 */ - break; - - case 756: -#line 5414 "gram.y" /* yacc.c:1646 */ - { - CreateTrigStmt *n = makeNode(CreateTrigStmt); - n->trigname = (yyvsp[-13].str); - n->relation = (yyvsp[-9].range); - n->funcname = (yyvsp[-3].list); - n->args = (yyvsp[-1].list); - n->row = (yyvsp[-7].boolean); - n->timing = (yyvsp[-12].ival); - n->events = intVal(linitial((yyvsp[-11].list))); - n->columns = (List *) lsecond((yyvsp[-11].list)); - n->whenClause = (yyvsp[-6].node); - n->transitionRels = (yyvsp[-8].list); - n->isconstraint = false; - n->deferrable = false; - n->initdeferred = false; - n->constrrel = NULL; - (yyval.node) = (Node *)n; - } -#line 32016 "gram.c" /* yacc.c:1646 */ - break; - - case 757: -#line 5436 "gram.y" /* yacc.c:1646 */ - { - CreateTrigStmt *n = makeNode(CreateTrigStmt); - n->trigname = (yyvsp[-16].str); - n->relation = (yyvsp[-12].range); - n->funcname = (yyvsp[-3].list); - n->args = (yyvsp[-1].list); - n->row = true; - n->timing = TRIGGER_TYPE_AFTER; - n->events = intVal(linitial((yyvsp[-14].list))); - n->columns = (List *) lsecond((yyvsp[-14].list)); - n->whenClause = (yyvsp[-6].node); - n->transitionRels = NIL; - n->isconstraint = true; - processCASbits((yyvsp[-10].ival), (yylsp[-10]), "TRIGGER", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - n->constrrel = (yyvsp[-11].range); - (yyval.node) = (Node *)n; - } -#line 32040 "gram.c" /* yacc.c:1646 */ - break; - - case 758: -#line 5458 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = TRIGGER_TYPE_BEFORE; } -#line 32046 "gram.c" /* yacc.c:1646 */ - break; - - case 759: -#line 5459 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = TRIGGER_TYPE_AFTER; } -#line 32052 "gram.c" /* yacc.c:1646 */ - break; - - case 760: -#line 5460 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = TRIGGER_TYPE_INSTEAD; } -#line 32058 "gram.c" /* yacc.c:1646 */ - break; - - case 761: -#line 5465 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 32064 "gram.c" /* yacc.c:1646 */ - break; - - case 762: -#line 5467 "gram.y" /* yacc.c:1646 */ - { - int events1 = intVal(linitial((yyvsp[-2].list))); - int events2 = intVal(linitial((yyvsp[0].list))); - List *columns1 = (List *) lsecond((yyvsp[-2].list)); - List *columns2 = (List *) lsecond((yyvsp[0].list)); - - if (events1 & events2) - parser_yyerror("duplicate trigger events specified"); - /* - * concat'ing the columns lists loses information about - * which columns went with which event, but so long as - * only UPDATE carries columns and we disallow multiple - * UPDATE items, it doesn't matter. Command execution - * should just ignore the columns for non-UPDATE events. - */ - (yyval.list) = list_make2(makeInteger(events1 | events2), - list_concat(columns1, columns2)); - } -#line 32087 "gram.c" /* yacc.c:1646 */ - break; - - case 763: -#line 5489 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_INSERT), NIL); } -#line 32093 "gram.c" /* yacc.c:1646 */ - break; - - case 764: -#line 5491 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_DELETE), NIL); } -#line 32099 "gram.c" /* yacc.c:1646 */ - break; - - case 765: -#line 5493 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), NIL); } -#line 32105 "gram.c" /* yacc.c:1646 */ - break; - - case 766: -#line 5495 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), (yyvsp[0].list)); } -#line 32111 "gram.c" /* yacc.c:1646 */ - break; - - case 767: -#line 5497 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(makeInteger(TRIGGER_TYPE_TRUNCATE), NIL); } -#line 32117 "gram.c" /* yacc.c:1646 */ - break; - - case 768: -#line 5501 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 32123 "gram.c" /* yacc.c:1646 */ - break; - - case 769: -#line 5502 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 32129 "gram.c" /* yacc.c:1646 */ - break; - - case 770: -#line 5506 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 32135 "gram.c" /* yacc.c:1646 */ - break; - - case 771: -#line 5507 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].node)); } -#line 32141 "gram.c" /* yacc.c:1646 */ - break; - - case 772: -#line 5512 "gram.y" /* yacc.c:1646 */ - { - TriggerTransition *n = makeNode(TriggerTransition); - n->name = (yyvsp[0].str); - n->isNew = (yyvsp[-3].boolean); - n->isTable = (yyvsp[-2].boolean); - (yyval.node) = (Node *)n; - } -#line 32153 "gram.c" /* yacc.c:1646 */ - break; - - case 773: -#line 5522 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 32159 "gram.c" /* yacc.c:1646 */ - break; - - case 774: -#line 5523 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 32165 "gram.c" /* yacc.c:1646 */ - break; - - case 775: -#line 5527 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 32171 "gram.c" /* yacc.c:1646 */ - break; - - case 776: -#line 5536 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 32177 "gram.c" /* yacc.c:1646 */ - break; - - case 777: -#line 5540 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 32183 "gram.c" /* yacc.c:1646 */ - break; - - case 778: -#line 5545 "gram.y" /* yacc.c:1646 */ - { - (yyval.boolean) = (yyvsp[0].boolean); - } -#line 32191 "gram.c" /* yacc.c:1646 */ - break; - - case 779: -#line 5549 "gram.y" /* yacc.c:1646 */ - { - /* - * If ROW/STATEMENT not specified, default to - * STATEMENT, per SQL - */ - (yyval.boolean) = false; - } -#line 32203 "gram.c" /* yacc.c:1646 */ - break; - - case 780: -#line 5559 "gram.y" /* yacc.c:1646 */ - {} -#line 32209 "gram.c" /* yacc.c:1646 */ - break; - - case 781: -#line 5560 "gram.y" /* yacc.c:1646 */ - {} -#line 32215 "gram.c" /* yacc.c:1646 */ - break; - - case 782: -#line 5564 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 32221 "gram.c" /* yacc.c:1646 */ - break; - - case 783: -#line 5565 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 32227 "gram.c" /* yacc.c:1646 */ - break; - - case 784: -#line 5569 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 32233 "gram.c" /* yacc.c:1646 */ - break; - - case 785: -#line 5570 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 32239 "gram.c" /* yacc.c:1646 */ - break; - - case 786: -#line 5574 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].value)); } -#line 32245 "gram.c" /* yacc.c:1646 */ - break; - - case 787: -#line 5575 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].value)); } -#line 32251 "gram.c" /* yacc.c:1646 */ - break; - - case 788: -#line 5576 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 32257 "gram.c" /* yacc.c:1646 */ - break; - - case 789: -#line 5581 "gram.y" /* yacc.c:1646 */ - { - (yyval.value) = makeString(psprintf("%d", (yyvsp[0].ival))); - } -#line 32265 "gram.c" /* yacc.c:1646 */ - break; - - case 790: -#line 5584 "gram.y" /* yacc.c:1646 */ - { (yyval.value) = makeString((yyvsp[0].str)); } -#line 32271 "gram.c" /* yacc.c:1646 */ - break; - - case 791: -#line 5585 "gram.y" /* yacc.c:1646 */ - { (yyval.value) = makeString((yyvsp[0].str)); } -#line 32277 "gram.c" /* yacc.c:1646 */ - break; - - case 792: -#line 5586 "gram.y" /* yacc.c:1646 */ - { (yyval.value) = makeString((yyvsp[0].str)); } -#line 32283 "gram.c" /* yacc.c:1646 */ - break; - - case 793: -#line 5590 "gram.y" /* yacc.c:1646 */ - { (yyval.range) = (yyvsp[0].range); } -#line 32289 "gram.c" /* yacc.c:1646 */ - break; - - case 794: -#line 5591 "gram.y" /* yacc.c:1646 */ - { (yyval.range) = NULL; } -#line 32295 "gram.c" /* yacc.c:1646 */ - break; - - case 795: -#line 5596 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 32301 "gram.c" /* yacc.c:1646 */ - break; - - case 796: -#line 5598 "gram.y" /* yacc.c:1646 */ - { - /* - * We must complain about conflicting options. - * We could, but choose not to, complain about redundant - * options (ie, where $2's bit is already set in $1). - */ - int newspec = (yyvsp[-1].ival) | (yyvsp[0].ival); - - /* special message for this case */ - if ((newspec & (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) == (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"), - parser_errposition((yylsp[0])))); - /* generic message for other conflicts */ - if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) || - (newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting constraint properties"), - parser_errposition((yylsp[0])))); - (yyval.ival) = newspec; - } -#line 32329 "gram.c" /* yacc.c:1646 */ - break; - - case 797: -#line 5624 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CAS_NOT_DEFERRABLE; } -#line 32335 "gram.c" /* yacc.c:1646 */ - break; - - case 798: -#line 5625 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CAS_DEFERRABLE; } -#line 32341 "gram.c" /* yacc.c:1646 */ - break; - - case 799: -#line 5626 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CAS_INITIALLY_IMMEDIATE; } -#line 32347 "gram.c" /* yacc.c:1646 */ - break; - - case 800: -#line 5627 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CAS_INITIALLY_DEFERRED; } -#line 32353 "gram.c" /* yacc.c:1646 */ - break; - - case 801: -#line 5628 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CAS_NOT_VALID; } -#line 32359 "gram.c" /* yacc.c:1646 */ - break; - - case 802: -#line 5629 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CAS_NO_INHERIT; } -#line 32365 "gram.c" /* yacc.c:1646 */ - break; - - case 803: -#line 5644 "gram.y" /* yacc.c:1646 */ - { - CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt); - n->trigname = (yyvsp[-7].str); - n->eventname = (yyvsp[-5].str); - n->whenclause = NULL; - n->funcname = (yyvsp[-2].list); - (yyval.node) = (Node *)n; - } -#line 32378 "gram.c" /* yacc.c:1646 */ - break; - - case 804: -#line 5655 "gram.y" /* yacc.c:1646 */ - { - CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt); - n->trigname = (yyvsp[-9].str); - n->eventname = (yyvsp[-7].str); - n->whenclause = (yyvsp[-5].list); - n->funcname = (yyvsp[-2].list); - (yyval.node) = (Node *)n; - } -#line 32391 "gram.c" /* yacc.c:1646 */ - break; - - case 805: -#line 5667 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 32397 "gram.c" /* yacc.c:1646 */ - break; - - case 806: -#line 5669 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); } -#line 32403 "gram.c" /* yacc.c:1646 */ - break; - - case 807: -#line 5674 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem((yyvsp[-4].str), (Node *) (yyvsp[-1].list), (yylsp[-4])); } -#line 32409 "gram.c" /* yacc.c:1646 */ - break; - - case 808: -#line 5679 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 32415 "gram.c" /* yacc.c:1646 */ - break; - - case 809: -#line 5681 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), makeString((yyvsp[0].str))); } -#line 32421 "gram.c" /* yacc.c:1646 */ - break; - - case 810: -#line 5686 "gram.y" /* yacc.c:1646 */ - { - AlterEventTrigStmt *n = makeNode(AlterEventTrigStmt); - n->trigname = (yyvsp[-1].str); - n->tgenabled = (yyvsp[0].chr); - (yyval.node) = (Node *) n; - } -#line 32432 "gram.c" /* yacc.c:1646 */ - break; - - case 811: -#line 5695 "gram.y" /* yacc.c:1646 */ - { (yyval.chr) = TRIGGER_FIRES_ON_ORIGIN; } -#line 32438 "gram.c" /* yacc.c:1646 */ - break; - - case 812: -#line 5696 "gram.y" /* yacc.c:1646 */ - { (yyval.chr) = TRIGGER_FIRES_ON_REPLICA; } -#line 32444 "gram.c" /* yacc.c:1646 */ - break; - - case 813: -#line 5697 "gram.y" /* yacc.c:1646 */ - { (yyval.chr) = TRIGGER_FIRES_ALWAYS; } -#line 32450 "gram.c" /* yacc.c:1646 */ - break; - - case 814: -#line 5698 "gram.y" /* yacc.c:1646 */ - { (yyval.chr) = TRIGGER_DISABLED; } -#line 32456 "gram.c" /* yacc.c:1646 */ - break; - - case 815: -#line 5712 "gram.y" /* yacc.c:1646 */ - { - CreateTrigStmt *n = makeNode(CreateTrigStmt); - n->trigname = (yyvsp[-5].str); - n->args = list_make1((yyvsp[-2].node)); - n->isconstraint = true; - processCASbits((yyvsp[0].ival), (yylsp[0]), "ASSERTION", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("CREATE ASSERTION is not yet implemented"))); - - (yyval.node) = (Node *)n; - } -#line 32476 "gram.c" /* yacc.c:1646 */ - break; - - case 816: -#line 5731 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->objects = NIL; - n->behavior = (yyvsp[0].dbehavior); - n->removeType = OBJECT_TRIGGER; /* XXX */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("DROP ASSERTION is not yet implemented"))); - (yyval.node) = (Node *) n; - } -#line 32491 "gram.c" /* yacc.c:1646 */ - break; - - case 817: -#line 5753 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_AGGREGATE; - n->oldstyle = false; - n->defnames = (yyvsp[-2].list); - n->args = (yyvsp[-1].list); - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32505 "gram.c" /* yacc.c:1646 */ - break; - - case 818: -#line 5763 "gram.y" /* yacc.c:1646 */ - { - /* old-style (pre-8.2) syntax for CREATE AGGREGATE */ - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_AGGREGATE; - n->oldstyle = true; - n->defnames = (yyvsp[-1].list); - n->args = NIL; - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32520 "gram.c" /* yacc.c:1646 */ - break; - - case 819: -#line 5774 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_OPERATOR; - n->oldstyle = false; - n->defnames = (yyvsp[-1].list); - n->args = NIL; - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32534 "gram.c" /* yacc.c:1646 */ - break; - - case 820: -#line 5784 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_TYPE; - n->oldstyle = false; - n->defnames = (yyvsp[-1].list); - n->args = NIL; - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32548 "gram.c" /* yacc.c:1646 */ - break; - - case 821: -#line 5794 "gram.y" /* yacc.c:1646 */ - { - /* Shell type (identified by lack of definition) */ - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_TYPE; - n->oldstyle = false; - n->defnames = (yyvsp[0].list); - n->args = NIL; - n->definition = NIL; - (yyval.node) = (Node *)n; - } -#line 32563 "gram.c" /* yacc.c:1646 */ - break; - - case 822: -#line 5805 "gram.y" /* yacc.c:1646 */ - { - CompositeTypeStmt *n = makeNode(CompositeTypeStmt); - - /* can't use qualified_name, sigh */ - n->typevar = makeRangeVarFromAnyName((yyvsp[-4].list), (yylsp[-4]), yyscanner); - n->coldeflist = (yyvsp[-1].list); - (yyval.node) = (Node *)n; - } -#line 32576 "gram.c" /* yacc.c:1646 */ - break; - - case 823: -#line 5814 "gram.y" /* yacc.c:1646 */ - { - CreateEnumStmt *n = makeNode(CreateEnumStmt); - n->typeName = (yyvsp[-5].list); - n->vals = (yyvsp[-1].list); - (yyval.node) = (Node *)n; - } -#line 32587 "gram.c" /* yacc.c:1646 */ - break; - - case 824: -#line 5821 "gram.y" /* yacc.c:1646 */ - { - CreateRangeStmt *n = makeNode(CreateRangeStmt); - n->typeName = (yyvsp[-3].list); - n->params = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32598 "gram.c" /* yacc.c:1646 */ - break; - - case 825: -#line 5828 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_TSPARSER; - n->args = NIL; - n->defnames = (yyvsp[-1].list); - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32611 "gram.c" /* yacc.c:1646 */ - break; - - case 826: -#line 5837 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_TSDICTIONARY; - n->args = NIL; - n->defnames = (yyvsp[-1].list); - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32624 "gram.c" /* yacc.c:1646 */ - break; - - case 827: -#line 5846 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_TSTEMPLATE; - n->args = NIL; - n->defnames = (yyvsp[-1].list); - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32637 "gram.c" /* yacc.c:1646 */ - break; - - case 828: -#line 5855 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_TSCONFIGURATION; - n->args = NIL; - n->defnames = (yyvsp[-1].list); - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32650 "gram.c" /* yacc.c:1646 */ - break; - - case 829: -#line 5864 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_COLLATION; - n->args = NIL; - n->defnames = (yyvsp[-1].list); - n->definition = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 32663 "gram.c" /* yacc.c:1646 */ - break; - - case 830: -#line 5873 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_COLLATION; - n->args = NIL; - n->defnames = (yyvsp[-1].list); - n->definition = (yyvsp[0].list); - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 32677 "gram.c" /* yacc.c:1646 */ - break; - - case 831: -#line 5883 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_COLLATION; - n->args = NIL; - n->defnames = (yyvsp[-2].list); - n->definition = list_make1(makeDefElem("from", (Node *) (yyvsp[0].list), (yylsp[0]))); - (yyval.node) = (Node *)n; - } -#line 32690 "gram.c" /* yacc.c:1646 */ - break; - - case 832: -#line 5892 "gram.y" /* yacc.c:1646 */ - { - DefineStmt *n = makeNode(DefineStmt); - n->kind = OBJECT_COLLATION; - n->args = NIL; - n->defnames = (yyvsp[-2].list); - n->definition = list_make1(makeDefElem("from", (Node *) (yyvsp[0].list), (yylsp[0]))); - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 32704 "gram.c" /* yacc.c:1646 */ - break; - - case 833: -#line 5903 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 32710 "gram.c" /* yacc.c:1646 */ - break; - - case 834: -#line 5906 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 32716 "gram.c" /* yacc.c:1646 */ - break; - - case 835: -#line 5907 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); } -#line 32722 "gram.c" /* yacc.c:1646 */ - break; - - case 836: -#line 5911 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-2].str), (Node *) (yyvsp[0].node), (yylsp[-2])); - } -#line 32730 "gram.c" /* yacc.c:1646 */ - break; - - case 837: -#line 5915 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[0].str), NULL, (yylsp[0])); - } -#line 32738 "gram.c" /* yacc.c:1646 */ - break; - - case 838: -#line 5921 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)(yyvsp[0].typnam); } -#line 32744 "gram.c" /* yacc.c:1646 */ - break; - - case 839: -#line 5922 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)makeString(pstrdup((yyvsp[0].keyword))); } -#line 32750 "gram.c" /* yacc.c:1646 */ - break; - - case 840: -#line 5923 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)(yyvsp[0].list); } -#line 32756 "gram.c" /* yacc.c:1646 */ - break; - - case 841: -#line 5924 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)(yyvsp[0].value); } -#line 32762 "gram.c" /* yacc.c:1646 */ - break; - - case 842: -#line 5925 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)makeString((yyvsp[0].str)); } -#line 32768 "gram.c" /* yacc.c:1646 */ - break; - - case 843: -#line 5926 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)makeString(pstrdup((yyvsp[0].keyword))); } -#line 32774 "gram.c" /* yacc.c:1646 */ - break; - - case 844: -#line 5929 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 32780 "gram.c" /* yacc.c:1646 */ - break; - - case 845: -#line 5932 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 32786 "gram.c" /* yacc.c:1646 */ - break; - - case 846: -#line 5933 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); } -#line 32792 "gram.c" /* yacc.c:1646 */ - break; - - case 847: -#line 5942 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-2].str), (Node *)(yyvsp[0].node), (yylsp[-2])); - } -#line 32800 "gram.c" /* yacc.c:1646 */ - break; - - case 848: -#line 5948 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 32806 "gram.c" /* yacc.c:1646 */ - break; - - case 849: -#line 5949 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 32812 "gram.c" /* yacc.c:1646 */ - break; - - case 850: -#line 5953 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 32818 "gram.c" /* yacc.c:1646 */ - break; - - case 851: -#line 5955 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), makeString((yyvsp[0].str))); } -#line 32824 "gram.c" /* yacc.c:1646 */ - break; - - case 852: -#line 5966 "gram.y" /* yacc.c:1646 */ - { - AlterEnumStmt *n = makeNode(AlterEnumStmt); - n->typeName = (yyvsp[-4].list); - n->oldVal = NULL; - n->newVal = (yyvsp[0].str); - n->newValNeighbor = NULL; - n->newValIsAfter = true; - n->skipIfNewValExists = (yyvsp[-1].boolean); - (yyval.node) = (Node *) n; - } -#line 32839 "gram.c" /* yacc.c:1646 */ - break; - - case 853: -#line 5977 "gram.y" /* yacc.c:1646 */ - { - AlterEnumStmt *n = makeNode(AlterEnumStmt); - n->typeName = (yyvsp[-6].list); - n->oldVal = NULL; - n->newVal = (yyvsp[-2].str); - n->newValNeighbor = (yyvsp[0].str); - n->newValIsAfter = false; - n->skipIfNewValExists = (yyvsp[-3].boolean); - (yyval.node) = (Node *) n; - } -#line 32854 "gram.c" /* yacc.c:1646 */ - break; - - case 854: -#line 5988 "gram.y" /* yacc.c:1646 */ - { - AlterEnumStmt *n = makeNode(AlterEnumStmt); - n->typeName = (yyvsp[-6].list); - n->oldVal = NULL; - n->newVal = (yyvsp[-2].str); - n->newValNeighbor = (yyvsp[0].str); - n->newValIsAfter = true; - n->skipIfNewValExists = (yyvsp[-3].boolean); - (yyval.node) = (Node *) n; - } -#line 32869 "gram.c" /* yacc.c:1646 */ - break; - - case 855: -#line 5999 "gram.y" /* yacc.c:1646 */ - { - AlterEnumStmt *n = makeNode(AlterEnumStmt); - n->typeName = (yyvsp[-5].list); - n->oldVal = (yyvsp[-2].str); - n->newVal = (yyvsp[0].str); - n->newValNeighbor = NULL; - n->newValIsAfter = false; - n->skipIfNewValExists = false; - (yyval.node) = (Node *) n; - } -#line 32884 "gram.c" /* yacc.c:1646 */ - break; - - case 856: -#line 6011 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 32890 "gram.c" /* yacc.c:1646 */ - break; - - case 857: -#line 6012 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 32896 "gram.c" /* yacc.c:1646 */ - break; - - case 858: -#line 6030 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassStmt *n = makeNode(CreateOpClassStmt); - n->opclassname = (yyvsp[-9].list); - n->isDefault = (yyvsp[-8].boolean); - n->datatype = (yyvsp[-5].typnam); - n->amname = (yyvsp[-3].str); - n->opfamilyname = (yyvsp[-2].list); - n->items = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 32911 "gram.c" /* yacc.c:1646 */ - break; - - case 859: -#line 6043 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 32917 "gram.c" /* yacc.c:1646 */ - break; - - case 860: -#line 6044 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 32923 "gram.c" /* yacc.c:1646 */ - break; - - case 861: -#line 6049 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassItem *n = makeNode(CreateOpClassItem); - ObjectWithArgs *owa = makeNode(ObjectWithArgs); - owa->objname = (yyvsp[-2].list); - owa->objargs = NIL; - n->itemtype = OPCLASS_ITEM_OPERATOR; - n->name = owa; - n->number = (yyvsp[-3].ival); - n->order_family = (yyvsp[-1].list); - (yyval.node) = (Node *) n; - } -#line 32939 "gram.c" /* yacc.c:1646 */ - break; - - case 862: -#line 6062 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassItem *n = makeNode(CreateOpClassItem); - n->itemtype = OPCLASS_ITEM_OPERATOR; - n->name = (yyvsp[-2].objwithargs); - n->number = (yyvsp[-3].ival); - n->order_family = (yyvsp[-1].list); - (yyval.node) = (Node *) n; - } -#line 32952 "gram.c" /* yacc.c:1646 */ - break; - - case 863: -#line 6071 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassItem *n = makeNode(CreateOpClassItem); - n->itemtype = OPCLASS_ITEM_FUNCTION; - n->name = (yyvsp[0].objwithargs); - n->number = (yyvsp[-1].ival); - (yyval.node) = (Node *) n; - } -#line 32964 "gram.c" /* yacc.c:1646 */ - break; - - case 864: -#line 6079 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassItem *n = makeNode(CreateOpClassItem); - n->itemtype = OPCLASS_ITEM_FUNCTION; - n->name = (yyvsp[0].objwithargs); - n->number = (yyvsp[-4].ival); - n->class_args = (yyvsp[-2].list); - (yyval.node) = (Node *) n; - } -#line 32977 "gram.c" /* yacc.c:1646 */ - break; - - case 865: -#line 6088 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassItem *n = makeNode(CreateOpClassItem); - n->itemtype = OPCLASS_ITEM_STORAGETYPE; - n->storedtype = (yyvsp[0].typnam); - (yyval.node) = (Node *) n; - } -#line 32988 "gram.c" /* yacc.c:1646 */ - break; - - case 866: -#line 6096 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 32994 "gram.c" /* yacc.c:1646 */ - break; - - case 867: -#line 6097 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 33000 "gram.c" /* yacc.c:1646 */ - break; - - case 868: -#line 6100 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 33006 "gram.c" /* yacc.c:1646 */ - break; - - case 869: -#line 6101 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 33012 "gram.c" /* yacc.c:1646 */ - break; - - case 870: -#line 6104 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 33018 "gram.c" /* yacc.c:1646 */ - break; - - case 871: -#line 6105 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 33024 "gram.c" /* yacc.c:1646 */ - break; - - case 872: -#line 6106 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 33030 "gram.c" /* yacc.c:1646 */ - break; - - case 873: -#line 6110 "gram.y" /* yacc.c:1646 */ - { - /* - * RECHECK no longer does anything in opclass definitions, - * but we still accept it to ease porting of old database - * dumps. - */ - ereport(NOTICE, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("RECHECK is no longer required"), - errhint("Update your data type."), - parser_errposition((yylsp[0])))); - (yyval.boolean) = true; - } -#line 33048 "gram.c" /* yacc.c:1646 */ - break; - - case 874: -#line 6123 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 33054 "gram.c" /* yacc.c:1646 */ - break; - - case 875: -#line 6129 "gram.y" /* yacc.c:1646 */ - { - CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt); - n->opfamilyname = (yyvsp[-2].list); - n->amname = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33065 "gram.c" /* yacc.c:1646 */ - break; - - case 876: -#line 6139 "gram.y" /* yacc.c:1646 */ - { - AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); - n->opfamilyname = (yyvsp[-4].list); - n->amname = (yyvsp[-2].str); - n->isDrop = false; - n->items = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 33078 "gram.c" /* yacc.c:1646 */ - break; - - case 877: -#line 6148 "gram.y" /* yacc.c:1646 */ - { - AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); - n->opfamilyname = (yyvsp[-4].list); - n->amname = (yyvsp[-2].str); - n->isDrop = true; - n->items = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 33091 "gram.c" /* yacc.c:1646 */ - break; - - case 878: -#line 6159 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 33097 "gram.c" /* yacc.c:1646 */ - break; - - case 879: -#line 6160 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 33103 "gram.c" /* yacc.c:1646 */ - break; - - case 880: -#line 6165 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassItem *n = makeNode(CreateOpClassItem); - n->itemtype = OPCLASS_ITEM_OPERATOR; - n->number = (yyvsp[-3].ival); - n->class_args = (yyvsp[-1].list); - (yyval.node) = (Node *) n; - } -#line 33115 "gram.c" /* yacc.c:1646 */ - break; - - case 881: -#line 6173 "gram.y" /* yacc.c:1646 */ - { - CreateOpClassItem *n = makeNode(CreateOpClassItem); - n->itemtype = OPCLASS_ITEM_FUNCTION; - n->number = (yyvsp[-3].ival); - n->class_args = (yyvsp[-1].list); - (yyval.node) = (Node *) n; - } -#line 33127 "gram.c" /* yacc.c:1646 */ - break; - - case 882: -#line 6185 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->objects = list_make1(lcons(makeString((yyvsp[-1].str)), (yyvsp[-3].list))); - n->removeType = OBJECT_OPCLASS; - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33141 "gram.c" /* yacc.c:1646 */ - break; - - case 883: -#line 6195 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->objects = list_make1(lcons(makeString((yyvsp[-1].str)), (yyvsp[-3].list))); - n->removeType = OBJECT_OPCLASS; - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33155 "gram.c" /* yacc.c:1646 */ - break; - - case 884: -#line 6208 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->objects = list_make1(lcons(makeString((yyvsp[-1].str)), (yyvsp[-3].list))); - n->removeType = OBJECT_OPFAMILY; - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33169 "gram.c" /* yacc.c:1646 */ - break; - - case 885: -#line 6218 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->objects = list_make1(lcons(makeString((yyvsp[-1].str)), (yyvsp[-3].list))); - n->removeType = OBJECT_OPFAMILY; - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33183 "gram.c" /* yacc.c:1646 */ - break; - - case 886: -#line 6240 "gram.y" /* yacc.c:1646 */ - { - DropOwnedStmt *n = makeNode(DropOwnedStmt); - n->roles = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *)n; - } -#line 33194 "gram.c" /* yacc.c:1646 */ - break; - - case 887: -#line 6250 "gram.y" /* yacc.c:1646 */ - { - ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt); - n->roles = (yyvsp[-2].list); - n->newrole = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 33205 "gram.c" /* yacc.c:1646 */ - break; - - case 888: -#line 6268 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = (yyvsp[-4].objtype); - n->missing_ok = true; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 33219 "gram.c" /* yacc.c:1646 */ - break; - - case 889: -#line 6278 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = (yyvsp[-2].objtype); - n->missing_ok = false; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 33233 "gram.c" /* yacc.c:1646 */ - break; - - case 890: -#line 6288 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = (yyvsp[-4].objtype); - n->missing_ok = true; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 33247 "gram.c" /* yacc.c:1646 */ - break; - - case 891: -#line 6298 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = (yyvsp[-2].objtype); - n->missing_ok = false; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 33261 "gram.c" /* yacc.c:1646 */ - break; - - case 892: -#line 6308 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = (yyvsp[-4].objtype); - n->objects = list_make1(lappend((yyvsp[-1].list), makeString((yyvsp[-3].str)))); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33275 "gram.c" /* yacc.c:1646 */ - break; - - case 893: -#line 6318 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = (yyvsp[-6].objtype); - n->objects = list_make1(lappend((yyvsp[-1].list), makeString((yyvsp[-3].str)))); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33289 "gram.c" /* yacc.c:1646 */ - break; - - case 894: -#line 6328 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_TYPE; - n->missing_ok = false; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33303 "gram.c" /* yacc.c:1646 */ - break; - - case 895: -#line 6338 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_TYPE; - n->missing_ok = true; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33317 "gram.c" /* yacc.c:1646 */ - break; - - case 896: -#line 6348 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_DOMAIN; - n->missing_ok = false; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33331 "gram.c" /* yacc.c:1646 */ - break; - - case 897: -#line 6358 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_DOMAIN; - n->missing_ok = true; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = false; - (yyval.node) = (Node *) n; - } -#line 33345 "gram.c" /* yacc.c:1646 */ - break; - - case 898: -#line 6368 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_INDEX; - n->missing_ok = false; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = true; - (yyval.node) = (Node *)n; - } -#line 33359 "gram.c" /* yacc.c:1646 */ - break; - - case 899: -#line 6378 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_INDEX; - n->missing_ok = true; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->concurrent = true; - (yyval.node) = (Node *)n; - } -#line 33373 "gram.c" /* yacc.c:1646 */ - break; - - case 900: -#line 6391 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TABLE; } -#line 33379 "gram.c" /* yacc.c:1646 */ - break; - - case 901: -#line 6392 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SEQUENCE; } -#line 33385 "gram.c" /* yacc.c:1646 */ - break; - - case 902: -#line 6393 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_VIEW; } -#line 33391 "gram.c" /* yacc.c:1646 */ - break; - - case 903: -#line 6394 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_MATVIEW; } -#line 33397 "gram.c" /* yacc.c:1646 */ - break; - - case 904: -#line 6395 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_INDEX; } -#line 33403 "gram.c" /* yacc.c:1646 */ - break; - - case 905: -#line 6396 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_FOREIGN_TABLE; } -#line 33409 "gram.c" /* yacc.c:1646 */ - break; - - case 906: -#line 6397 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_COLLATION; } -#line 33415 "gram.c" /* yacc.c:1646 */ - break; - - case 907: -#line 6398 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_CONVERSION; } -#line 33421 "gram.c" /* yacc.c:1646 */ - break; - - case 908: -#line 6399 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_STATISTIC_EXT; } -#line 33427 "gram.c" /* yacc.c:1646 */ - break; - - case 909: -#line 6400 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSPARSER; } -#line 33433 "gram.c" /* yacc.c:1646 */ - break; - - case 910: -#line 6401 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSDICTIONARY; } -#line 33439 "gram.c" /* yacc.c:1646 */ - break; - - case 911: -#line 6402 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSTEMPLATE; } -#line 33445 "gram.c" /* yacc.c:1646 */ - break; - - case 912: -#line 6403 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSCONFIGURATION; } -#line 33451 "gram.c" /* yacc.c:1646 */ - break; - - case 913: -#line 6408 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_ACCESS_METHOD; } -#line 33457 "gram.c" /* yacc.c:1646 */ - break; - - case 914: -#line 6409 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_EVENT_TRIGGER; } -#line 33463 "gram.c" /* yacc.c:1646 */ - break; - - case 915: -#line 6410 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_EXTENSION; } -#line 33469 "gram.c" /* yacc.c:1646 */ - break; - - case 916: -#line 6411 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_FDW; } -#line 33475 "gram.c" /* yacc.c:1646 */ - break; - - case 917: -#line 6412 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_PUBLICATION; } -#line 33481 "gram.c" /* yacc.c:1646 */ - break; - - case 918: -#line 6413 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SCHEMA; } -#line 33487 "gram.c" /* yacc.c:1646 */ - break; - - case 919: -#line 6414 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_FOREIGN_SERVER; } -#line 33493 "gram.c" /* yacc.c:1646 */ - break; - - case 920: -#line 6419 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_POLICY; } -#line 33499 "gram.c" /* yacc.c:1646 */ - break; - - case 921: -#line 6420 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_RULE; } -#line 33505 "gram.c" /* yacc.c:1646 */ - break; - - case 922: -#line 6421 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TRIGGER; } -#line 33511 "gram.c" /* yacc.c:1646 */ - break; - - case 923: -#line 6425 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].list)); } -#line 33517 "gram.c" /* yacc.c:1646 */ - break; - - case 924: -#line 6426 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].list)); } -#line 33523 "gram.c" /* yacc.c:1646 */ - break; - - case 925: -#line 6429 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 33529 "gram.c" /* yacc.c:1646 */ - break; - - case 926: -#line 6430 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lcons(makeString((yyvsp[-1].str)), (yyvsp[0].list)); } -#line 33535 "gram.c" /* yacc.c:1646 */ - break; - - case 927: -#line 6434 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 33541 "gram.c" /* yacc.c:1646 */ - break; - - case 928: -#line 6436 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), makeString((yyvsp[0].str))); } -#line 33547 "gram.c" /* yacc.c:1646 */ - break; - - case 929: -#line 6440 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].typnam)); } -#line 33553 "gram.c" /* yacc.c:1646 */ - break; - - case 930: -#line 6441 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].typnam)); } -#line 33559 "gram.c" /* yacc.c:1646 */ - break; - - case 931: -#line 6452 "gram.y" /* yacc.c:1646 */ - { - TruncateStmt *n = makeNode(TruncateStmt); - n->relations = (yyvsp[-2].list); - n->restart_seqs = (yyvsp[-1].boolean); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *)n; - } -#line 33571 "gram.c" /* yacc.c:1646 */ - break; - - case 932: -#line 6462 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 33577 "gram.c" /* yacc.c:1646 */ - break; - - case 933: -#line 6463 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 33583 "gram.c" /* yacc.c:1646 */ - break; - - case 934: -#line 6464 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 33589 "gram.c" /* yacc.c:1646 */ - break; - - case 935: -#line 6499 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = (yyvsp[-3].objtype); - n->object = (Node *) (yyvsp[-2].list); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33601 "gram.c" /* yacc.c:1646 */ - break; - - case 936: -#line 6507 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = (yyvsp[-3].objtype); - n->object = (Node *) makeString((yyvsp[-2].str)); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33613 "gram.c" /* yacc.c:1646 */ - break; - - case 937: -#line 6515 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_TYPE; - n->object = (Node *) (yyvsp[-2].typnam); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33625 "gram.c" /* yacc.c:1646 */ - break; - - case 938: -#line 6523 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_DOMAIN; - n->object = (Node *) (yyvsp[-2].typnam); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33637 "gram.c" /* yacc.c:1646 */ - break; - - case 939: -#line 6531 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_AGGREGATE; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33649 "gram.c" /* yacc.c:1646 */ - break; - - case 940: -#line 6539 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_FUNCTION; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33661 "gram.c" /* yacc.c:1646 */ - break; - - case 941: -#line 6547 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_OPERATOR; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33673 "gram.c" /* yacc.c:1646 */ - break; - - case 942: -#line 6555 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_TABCONSTRAINT; - n->object = (Node *) lappend((yyvsp[-2].list), makeString((yyvsp[-4].str))); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33685 "gram.c" /* yacc.c:1646 */ - break; - - case 943: -#line 6563 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_DOMCONSTRAINT; - /* - * should use Typename not any_name in the production, but - * there's a shift/reduce conflict if we do that, so fix it - * up here. - */ - n->object = (Node *) list_make2(makeTypeNameFromNameList((yyvsp[-2].list)), makeString((yyvsp[-5].str))); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33702 "gram.c" /* yacc.c:1646 */ - break; - - case 944: -#line 6576 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_POLICY; - n->object = (Node *) lappend((yyvsp[-2].list), makeString((yyvsp[-4].str))); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33714 "gram.c" /* yacc.c:1646 */ - break; - - case 945: -#line 6584 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_PROCEDURE; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33726 "gram.c" /* yacc.c:1646 */ - break; - - case 946: -#line 6592 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_ROUTINE; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33738 "gram.c" /* yacc.c:1646 */ - break; - - case 947: -#line 6600 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_RULE; - n->object = (Node *) lappend((yyvsp[-2].list), makeString((yyvsp[-4].str))); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33750 "gram.c" /* yacc.c:1646 */ - break; - - case 948: -#line 6608 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_TRANSFORM; - n->object = (Node *) list_make2((yyvsp[-4].typnam), makeString((yyvsp[-2].str))); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33762 "gram.c" /* yacc.c:1646 */ - break; - - case 949: -#line 6616 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_TRIGGER; - n->object = (Node *) lappend((yyvsp[-2].list), makeString((yyvsp[-4].str))); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33774 "gram.c" /* yacc.c:1646 */ - break; - - case 950: -#line 6624 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_OPCLASS; - n->object = (Node *) lcons(makeString((yyvsp[-2].str)), (yyvsp[-4].list)); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33786 "gram.c" /* yacc.c:1646 */ - break; - - case 951: -#line 6632 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_OPFAMILY; - n->object = (Node *) lcons(makeString((yyvsp[-2].str)), (yyvsp[-4].list)); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33798 "gram.c" /* yacc.c:1646 */ - break; - - case 952: -#line 6640 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_LARGEOBJECT; - n->object = (Node *) (yyvsp[-2].value); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33810 "gram.c" /* yacc.c:1646 */ - break; - - case 953: -#line 6648 "gram.y" /* yacc.c:1646 */ - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_CAST; - n->object = (Node *) list_make2((yyvsp[-5].typnam), (yyvsp[-3].typnam)); - n->comment = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 33822 "gram.c" /* yacc.c:1646 */ - break; - - case 954: -#line 6659 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_COLUMN; } -#line 33828 "gram.c" /* yacc.c:1646 */ - break; - - case 955: -#line 6660 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_INDEX; } -#line 33834 "gram.c" /* yacc.c:1646 */ - break; - - case 956: -#line 6661 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SEQUENCE; } -#line 33840 "gram.c" /* yacc.c:1646 */ - break; - - case 957: -#line 6662 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_STATISTIC_EXT; } -#line 33846 "gram.c" /* yacc.c:1646 */ - break; - - case 958: -#line 6663 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TABLE; } -#line 33852 "gram.c" /* yacc.c:1646 */ - break; - - case 959: -#line 6664 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_VIEW; } -#line 33858 "gram.c" /* yacc.c:1646 */ - break; - - case 960: -#line 6665 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_MATVIEW; } -#line 33864 "gram.c" /* yacc.c:1646 */ - break; - - case 961: -#line 6666 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_COLLATION; } -#line 33870 "gram.c" /* yacc.c:1646 */ - break; - - case 962: -#line 6667 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_CONVERSION; } -#line 33876 "gram.c" /* yacc.c:1646 */ - break; - - case 963: -#line 6668 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_FOREIGN_TABLE; } -#line 33882 "gram.c" /* yacc.c:1646 */ - break; - - case 964: -#line 6669 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSCONFIGURATION; } -#line 33888 "gram.c" /* yacc.c:1646 */ - break; - - case 965: -#line 6670 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSDICTIONARY; } -#line 33894 "gram.c" /* yacc.c:1646 */ - break; - - case 966: -#line 6671 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSPARSER; } -#line 33900 "gram.c" /* yacc.c:1646 */ - break; - - case 967: -#line 6672 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TSTEMPLATE; } -#line 33906 "gram.c" /* yacc.c:1646 */ - break; - - case 968: -#line 6677 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_ACCESS_METHOD; } -#line 33912 "gram.c" /* yacc.c:1646 */ - break; - - case 969: -#line 6678 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_DATABASE; } -#line 33918 "gram.c" /* yacc.c:1646 */ - break; - - case 970: -#line 6679 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_EVENT_TRIGGER; } -#line 33924 "gram.c" /* yacc.c:1646 */ - break; - - case 971: -#line 6680 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_EXTENSION; } -#line 33930 "gram.c" /* yacc.c:1646 */ - break; - - case 972: -#line 6681 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_FDW; } -#line 33936 "gram.c" /* yacc.c:1646 */ - break; - - case 973: -#line 6682 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_LANGUAGE; } -#line 33942 "gram.c" /* yacc.c:1646 */ - break; - - case 974: -#line 6683 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_PUBLICATION; } -#line 33948 "gram.c" /* yacc.c:1646 */ - break; - - case 975: -#line 6684 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_ROLE; } -#line 33954 "gram.c" /* yacc.c:1646 */ - break; - - case 976: -#line 6685 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SCHEMA; } -#line 33960 "gram.c" /* yacc.c:1646 */ - break; - - case 977: -#line 6686 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_FOREIGN_SERVER; } -#line 33966 "gram.c" /* yacc.c:1646 */ - break; - - case 978: -#line 6687 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SUBSCRIPTION; } -#line 33972 "gram.c" /* yacc.c:1646 */ - break; - - case 979: -#line 6688 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TABLESPACE; } -#line 33978 "gram.c" /* yacc.c:1646 */ - break; - - case 980: -#line 6692 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 33984 "gram.c" /* yacc.c:1646 */ - break; - - case 981: -#line 6693 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 33990 "gram.c" /* yacc.c:1646 */ - break; - - case 982: -#line 6709 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = (yyvsp[-3].objtype); - n->object = (Node *) (yyvsp[-2].list); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34003 "gram.c" /* yacc.c:1646 */ - break; - - case 983: -#line 6719 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = (yyvsp[-3].objtype); - n->object = (Node *) makeString((yyvsp[-2].str)); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34016 "gram.c" /* yacc.c:1646 */ - break; - - case 984: -#line 6729 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = OBJECT_TYPE; - n->object = (Node *) (yyvsp[-2].typnam); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34029 "gram.c" /* yacc.c:1646 */ - break; - - case 985: -#line 6739 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = OBJECT_DOMAIN; - n->object = (Node *) (yyvsp[-2].typnam); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34042 "gram.c" /* yacc.c:1646 */ - break; - - case 986: -#line 6749 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = OBJECT_AGGREGATE; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34055 "gram.c" /* yacc.c:1646 */ - break; - - case 987: -#line 6759 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = OBJECT_FUNCTION; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34068 "gram.c" /* yacc.c:1646 */ - break; - - case 988: -#line 6769 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-6].str); - n->objtype = OBJECT_LARGEOBJECT; - n->object = (Node *) (yyvsp[-2].value); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34081 "gram.c" /* yacc.c:1646 */ - break; - - case 989: -#line 6779 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = OBJECT_PROCEDURE; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34094 "gram.c" /* yacc.c:1646 */ - break; - - case 990: -#line 6789 "gram.y" /* yacc.c:1646 */ - { - SecLabelStmt *n = makeNode(SecLabelStmt); - n->provider = (yyvsp[-5].str); - n->objtype = OBJECT_ROUTINE; - n->object = (Node *) (yyvsp[-2].objwithargs); - n->label = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 34107 "gram.c" /* yacc.c:1646 */ - break; - - case 991: -#line 6799 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 34113 "gram.c" /* yacc.c:1646 */ - break; - - case 992: -#line 6800 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 34119 "gram.c" /* yacc.c:1646 */ - break; - - case 993: -#line 6805 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_COLUMN; } -#line 34125 "gram.c" /* yacc.c:1646 */ - break; - - case 994: -#line 6806 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_FOREIGN_TABLE; } -#line 34131 "gram.c" /* yacc.c:1646 */ - break; - - case 995: -#line 6807 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SEQUENCE; } -#line 34137 "gram.c" /* yacc.c:1646 */ - break; - - case 996: -#line 6808 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TABLE; } -#line 34143 "gram.c" /* yacc.c:1646 */ - break; - - case 997: -#line 6809 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_VIEW; } -#line 34149 "gram.c" /* yacc.c:1646 */ - break; - - case 998: -#line 6810 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_MATVIEW; } -#line 34155 "gram.c" /* yacc.c:1646 */ - break; - - case 999: -#line 6815 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_DATABASE; } -#line 34161 "gram.c" /* yacc.c:1646 */ - break; - - case 1000: -#line 6816 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_EVENT_TRIGGER; } -#line 34167 "gram.c" /* yacc.c:1646 */ - break; - - case 1001: -#line 6817 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_LANGUAGE; } -#line 34173 "gram.c" /* yacc.c:1646 */ - break; - - case 1002: -#line 6818 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_PUBLICATION; } -#line 34179 "gram.c" /* yacc.c:1646 */ - break; - - case 1003: -#line 6819 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_ROLE; } -#line 34185 "gram.c" /* yacc.c:1646 */ - break; - - case 1004: -#line 6820 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SCHEMA; } -#line 34191 "gram.c" /* yacc.c:1646 */ - break; - - case 1005: -#line 6821 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_SUBSCRIPTION; } -#line 34197 "gram.c" /* yacc.c:1646 */ - break; - - case 1006: -#line 6822 "gram.y" /* yacc.c:1646 */ - { (yyval.objtype) = OBJECT_TABLESPACE; } -#line 34203 "gram.c" /* yacc.c:1646 */ - break; - - case 1007: -#line 6825 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 34209 "gram.c" /* yacc.c:1646 */ - break; - - case 1008: -#line 6826 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 34215 "gram.c" /* yacc.c:1646 */ - break; - - case 1009: -#line 6837 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = (FetchStmt *) (yyvsp[0].node); - n->ismove = false; - (yyval.node) = (Node *)n; - } -#line 34225 "gram.c" /* yacc.c:1646 */ - break; - - case 1010: -#line 6843 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = (FetchStmt *) (yyvsp[0].node); - n->ismove = true; - (yyval.node) = (Node *)n; - } -#line 34235 "gram.c" /* yacc.c:1646 */ - break; - - case 1011: -#line 6851 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = 1; - (yyval.node) = (Node *)n; - } -#line 34247 "gram.c" /* yacc.c:1646 */ - break; - - case 1012: -#line 6859 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = 1; - (yyval.node) = (Node *)n; - } -#line 34259 "gram.c" /* yacc.c:1646 */ - break; - - case 1013: -#line 6867 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = 1; - (yyval.node) = (Node *)n; - } -#line 34271 "gram.c" /* yacc.c:1646 */ - break; - - case 1014: -#line 6875 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_BACKWARD; - n->howMany = 1; - (yyval.node) = (Node *)n; - } -#line 34283 "gram.c" /* yacc.c:1646 */ - break; - - case 1015: -#line 6883 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_ABSOLUTE; - n->howMany = 1; - (yyval.node) = (Node *)n; - } -#line 34295 "gram.c" /* yacc.c:1646 */ - break; - - case 1016: -#line 6891 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_ABSOLUTE; - n->howMany = -1; - (yyval.node) = (Node *)n; - } -#line 34307 "gram.c" /* yacc.c:1646 */ - break; - - case 1017: -#line 6899 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_ABSOLUTE; - n->howMany = (yyvsp[-2].ival); - (yyval.node) = (Node *)n; - } -#line 34319 "gram.c" /* yacc.c:1646 */ - break; - - case 1018: -#line 6907 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_RELATIVE; - n->howMany = (yyvsp[-2].ival); - (yyval.node) = (Node *)n; - } -#line 34331 "gram.c" /* yacc.c:1646 */ - break; - - case 1019: -#line 6915 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = (yyvsp[-2].ival); - (yyval.node) = (Node *)n; - } -#line 34343 "gram.c" /* yacc.c:1646 */ - break; - - case 1020: -#line 6923 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = FETCH_ALL; - (yyval.node) = (Node *)n; - } -#line 34355 "gram.c" /* yacc.c:1646 */ - break; - - case 1021: -#line 6931 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = 1; - (yyval.node) = (Node *)n; - } -#line 34367 "gram.c" /* yacc.c:1646 */ - break; - - case 1022: -#line 6939 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = (yyvsp[-2].ival); - (yyval.node) = (Node *)n; - } -#line 34379 "gram.c" /* yacc.c:1646 */ - break; - - case 1023: -#line 6947 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_FORWARD; - n->howMany = FETCH_ALL; - (yyval.node) = (Node *)n; - } -#line 34391 "gram.c" /* yacc.c:1646 */ - break; - - case 1024: -#line 6955 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_BACKWARD; - n->howMany = 1; - (yyval.node) = (Node *)n; - } -#line 34403 "gram.c" /* yacc.c:1646 */ - break; - - case 1025: -#line 6963 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_BACKWARD; - n->howMany = (yyvsp[-2].ival); - (yyval.node) = (Node *)n; - } -#line 34415 "gram.c" /* yacc.c:1646 */ - break; - - case 1026: -#line 6971 "gram.y" /* yacc.c:1646 */ - { - FetchStmt *n = makeNode(FetchStmt); - n->portalname = (yyvsp[0].str); - n->direction = FETCH_BACKWARD; - n->howMany = FETCH_ALL; - (yyval.node) = (Node *)n; - } -#line 34427 "gram.c" /* yacc.c:1646 */ - break; - - case 1027: -#line 6980 "gram.y" /* yacc.c:1646 */ - {} -#line 34433 "gram.c" /* yacc.c:1646 */ - break; - - case 1028: -#line 6981 "gram.y" /* yacc.c:1646 */ - {} -#line 34439 "gram.c" /* yacc.c:1646 */ - break; - - case 1029: -#line 6984 "gram.y" /* yacc.c:1646 */ - {} -#line 34445 "gram.c" /* yacc.c:1646 */ - break; - - case 1030: -#line 6985 "gram.y" /* yacc.c:1646 */ - {} -#line 34451 "gram.c" /* yacc.c:1646 */ - break; - - case 1031: -#line 6997 "gram.y" /* yacc.c:1646 */ - { - GrantStmt *n = makeNode(GrantStmt); - n->is_grant = true; - n->privileges = (yyvsp[-5].list); - n->targtype = ((yyvsp[-3].privtarget))->targtype; - n->objtype = ((yyvsp[-3].privtarget))->objtype; - n->objects = ((yyvsp[-3].privtarget))->objs; - n->grantees = (yyvsp[-1].list); - n->grant_option = (yyvsp[0].boolean); - (yyval.node) = (Node*)n; - } -#line 34467 "gram.c" /* yacc.c:1646 */ - break; - - case 1032: -#line 7013 "gram.y" /* yacc.c:1646 */ - { - GrantStmt *n = makeNode(GrantStmt); - n->is_grant = false; - n->grant_option = false; - n->privileges = (yyvsp[-5].list); - n->targtype = ((yyvsp[-3].privtarget))->targtype; - n->objtype = ((yyvsp[-3].privtarget))->objtype; - n->objects = ((yyvsp[-3].privtarget))->objs; - n->grantees = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *)n; - } -#line 34484 "gram.c" /* yacc.c:1646 */ - break; - - case 1033: -#line 7027 "gram.y" /* yacc.c:1646 */ - { - GrantStmt *n = makeNode(GrantStmt); - n->is_grant = false; - n->grant_option = true; - n->privileges = (yyvsp[-5].list); - n->targtype = ((yyvsp[-3].privtarget))->targtype; - n->objtype = ((yyvsp[-3].privtarget))->objtype; - n->objects = ((yyvsp[-3].privtarget))->objs; - n->grantees = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *)n; - } -#line 34501 "gram.c" /* yacc.c:1646 */ - break; - - case 1034: -#line 7052 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 34507 "gram.c" /* yacc.c:1646 */ - break; - - case 1035: -#line 7054 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 34513 "gram.c" /* yacc.c:1646 */ - break; - - case 1036: -#line 7056 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 34519 "gram.c" /* yacc.c:1646 */ - break; - - case 1037: -#line 7058 "gram.y" /* yacc.c:1646 */ - { - AccessPriv *n = makeNode(AccessPriv); - n->priv_name = NULL; - n->cols = (yyvsp[-1].list); - (yyval.list) = list_make1(n); - } -#line 34530 "gram.c" /* yacc.c:1646 */ - break; - - case 1038: -#line 7065 "gram.y" /* yacc.c:1646 */ - { - AccessPriv *n = makeNode(AccessPriv); - n->priv_name = NULL; - n->cols = (yyvsp[-1].list); - (yyval.list) = list_make1(n); - } -#line 34541 "gram.c" /* yacc.c:1646 */ - break; - - case 1039: -#line 7073 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].accesspriv)); } -#line 34547 "gram.c" /* yacc.c:1646 */ - break; - - case 1040: -#line 7074 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].accesspriv)); } -#line 34553 "gram.c" /* yacc.c:1646 */ - break; - - case 1041: -#line 7078 "gram.y" /* yacc.c:1646 */ - { - AccessPriv *n = makeNode(AccessPriv); - n->priv_name = pstrdup((yyvsp[-1].keyword)); - n->cols = (yyvsp[0].list); - (yyval.accesspriv) = n; - } -#line 34564 "gram.c" /* yacc.c:1646 */ - break; - - case 1042: -#line 7085 "gram.y" /* yacc.c:1646 */ - { - AccessPriv *n = makeNode(AccessPriv); - n->priv_name = pstrdup((yyvsp[-1].keyword)); - n->cols = (yyvsp[0].list); - (yyval.accesspriv) = n; - } -#line 34575 "gram.c" /* yacc.c:1646 */ - break; - - case 1043: -#line 7092 "gram.y" /* yacc.c:1646 */ - { - AccessPriv *n = makeNode(AccessPriv); - n->priv_name = pstrdup((yyvsp[-1].keyword)); - n->cols = (yyvsp[0].list); - (yyval.accesspriv) = n; - } -#line 34586 "gram.c" /* yacc.c:1646 */ - break; - - case 1044: -#line 7099 "gram.y" /* yacc.c:1646 */ - { - AccessPriv *n = makeNode(AccessPriv); - n->priv_name = (yyvsp[-1].str); - n->cols = (yyvsp[0].list); - (yyval.accesspriv) = n; - } -#line 34597 "gram.c" /* yacc.c:1646 */ - break; - - case 1045: -#line 7113 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_TABLE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34609 "gram.c" /* yacc.c:1646 */ - break; - - case 1046: -#line 7121 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_TABLE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34621 "gram.c" /* yacc.c:1646 */ - break; - - case 1047: -#line 7129 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_SEQUENCE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34633 "gram.c" /* yacc.c:1646 */ - break; - - case 1048: -#line 7137 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_FDW; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34645 "gram.c" /* yacc.c:1646 */ - break; - - case 1049: -#line 7145 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_FOREIGN_SERVER; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34657 "gram.c" /* yacc.c:1646 */ - break; - - case 1050: -#line 7153 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_FUNCTION; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34669 "gram.c" /* yacc.c:1646 */ - break; - - case 1051: -#line 7161 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_PROCEDURE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34681 "gram.c" /* yacc.c:1646 */ - break; - - case 1052: -#line 7169 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_ROUTINE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34693 "gram.c" /* yacc.c:1646 */ - break; - - case 1053: -#line 7177 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_DATABASE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34705 "gram.c" /* yacc.c:1646 */ - break; - - case 1054: -#line 7185 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_DOMAIN; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34717 "gram.c" /* yacc.c:1646 */ - break; - - case 1055: -#line 7193 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_LANGUAGE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34729 "gram.c" /* yacc.c:1646 */ - break; - - case 1056: -#line 7201 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_LARGEOBJECT; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34741 "gram.c" /* yacc.c:1646 */ - break; - - case 1057: -#line 7209 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_SCHEMA; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34753 "gram.c" /* yacc.c:1646 */ - break; - - case 1058: -#line 7217 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_TABLESPACE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34765 "gram.c" /* yacc.c:1646 */ - break; - - case 1059: -#line 7225 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_OBJECT; - n->objtype = OBJECT_TYPE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34777 "gram.c" /* yacc.c:1646 */ - break; - - case 1060: -#line 7233 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_ALL_IN_SCHEMA; - n->objtype = OBJECT_TABLE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34789 "gram.c" /* yacc.c:1646 */ - break; - - case 1061: -#line 7241 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_ALL_IN_SCHEMA; - n->objtype = OBJECT_SEQUENCE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34801 "gram.c" /* yacc.c:1646 */ - break; - - case 1062: -#line 7249 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_ALL_IN_SCHEMA; - n->objtype = OBJECT_FUNCTION; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34813 "gram.c" /* yacc.c:1646 */ - break; - - case 1063: -#line 7257 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_ALL_IN_SCHEMA; - n->objtype = OBJECT_PROCEDURE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34825 "gram.c" /* yacc.c:1646 */ - break; - - case 1064: -#line 7265 "gram.y" /* yacc.c:1646 */ - { - PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); - n->targtype = ACL_TARGET_ALL_IN_SCHEMA; - n->objtype = OBJECT_ROUTINE; - n->objs = (yyvsp[0].list); - (yyval.privtarget) = n; - } -#line 34837 "gram.c" /* yacc.c:1646 */ - break; - - case 1065: -#line 7276 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].rolespec)); } -#line 34843 "gram.c" /* yacc.c:1646 */ - break; - - case 1066: -#line 7277 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].rolespec)); } -#line 34849 "gram.c" /* yacc.c:1646 */ - break; - - case 1067: -#line 7281 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = (yyvsp[0].rolespec); } -#line 34855 "gram.c" /* yacc.c:1646 */ - break; - - case 1068: -#line 7282 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = (yyvsp[0].rolespec); } -#line 34861 "gram.c" /* yacc.c:1646 */ - break; - - case 1069: -#line 7287 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 34867 "gram.c" /* yacc.c:1646 */ - break; - - case 1070: -#line 7288 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 34873 "gram.c" /* yacc.c:1646 */ - break; - - case 1071: -#line 7299 "gram.y" /* yacc.c:1646 */ - { - GrantRoleStmt *n = makeNode(GrantRoleStmt); - n->is_grant = true; - n->granted_roles = (yyvsp[-4].list); - n->grantee_roles = (yyvsp[-2].list); - n->admin_opt = (yyvsp[-1].boolean); - n->grantor = (yyvsp[0].rolespec); - (yyval.node) = (Node*)n; - } -#line 34887 "gram.c" /* yacc.c:1646 */ - break; - - case 1072: -#line 7312 "gram.y" /* yacc.c:1646 */ - { - GrantRoleStmt *n = makeNode(GrantRoleStmt); - n->is_grant = false; - n->admin_opt = false; - n->granted_roles = (yyvsp[-4].list); - n->grantee_roles = (yyvsp[-2].list); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node*)n; - } -#line 34901 "gram.c" /* yacc.c:1646 */ - break; - - case 1073: -#line 7322 "gram.y" /* yacc.c:1646 */ - { - GrantRoleStmt *n = makeNode(GrantRoleStmt); - n->is_grant = false; - n->admin_opt = true; - n->granted_roles = (yyvsp[-4].list); - n->grantee_roles = (yyvsp[-2].list); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node*)n; - } -#line 34915 "gram.c" /* yacc.c:1646 */ - break; - - case 1074: -#line 7333 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 34921 "gram.c" /* yacc.c:1646 */ - break; - - case 1075: -#line 7334 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 34927 "gram.c" /* yacc.c:1646 */ - break; - - case 1076: -#line 7337 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = (yyvsp[0].rolespec); } -#line 34933 "gram.c" /* yacc.c:1646 */ - break; - - case 1077: -#line 7338 "gram.y" /* yacc.c:1646 */ - { (yyval.rolespec) = NULL; } -#line 34939 "gram.c" /* yacc.c:1646 */ - break; - - case 1078: -#line 7349 "gram.y" /* yacc.c:1646 */ - { - AlterDefaultPrivilegesStmt *n = makeNode(AlterDefaultPrivilegesStmt); - n->options = (yyvsp[-1].list); - n->action = (GrantStmt *) (yyvsp[0].node); - (yyval.node) = (Node*)n; - } -#line 34950 "gram.c" /* yacc.c:1646 */ - break; - - case 1079: -#line 7358 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 34956 "gram.c" /* yacc.c:1646 */ - break; - - case 1080: -#line 7359 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 34962 "gram.c" /* yacc.c:1646 */ - break; - - case 1081: -#line 7364 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("schemas", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 34970 "gram.c" /* yacc.c:1646 */ - break; - - case 1082: -#line 7368 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("roles", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 34978 "gram.c" /* yacc.c:1646 */ - break; - - case 1083: -#line 7372 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("roles", (Node *)(yyvsp[0].list), (yylsp[-2])); - } -#line 34986 "gram.c" /* yacc.c:1646 */ - break; - - case 1084: -#line 7384 "gram.y" /* yacc.c:1646 */ - { - GrantStmt *n = makeNode(GrantStmt); - n->is_grant = true; - n->privileges = (yyvsp[-5].list); - n->targtype = ACL_TARGET_DEFAULTS; - n->objtype = (yyvsp[-3].ival); - n->objects = NIL; - n->grantees = (yyvsp[-1].list); - n->grant_option = (yyvsp[0].boolean); - (yyval.node) = (Node*)n; - } -#line 35002 "gram.c" /* yacc.c:1646 */ - break; - - case 1085: -#line 7397 "gram.y" /* yacc.c:1646 */ - { - GrantStmt *n = makeNode(GrantStmt); - n->is_grant = false; - n->grant_option = false; - n->privileges = (yyvsp[-5].list); - n->targtype = ACL_TARGET_DEFAULTS; - n->objtype = (yyvsp[-3].ival); - n->objects = NIL; - n->grantees = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *)n; - } -#line 35019 "gram.c" /* yacc.c:1646 */ - break; - - case 1086: -#line 7411 "gram.y" /* yacc.c:1646 */ - { - GrantStmt *n = makeNode(GrantStmt); - n->is_grant = false; - n->grant_option = true; - n->privileges = (yyvsp[-5].list); - n->targtype = ACL_TARGET_DEFAULTS; - n->objtype = (yyvsp[-3].ival); - n->objects = NIL; - n->grantees = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *)n; - } -#line 35036 "gram.c" /* yacc.c:1646 */ - break; - - case 1087: -#line 7426 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OBJECT_TABLE; } -#line 35042 "gram.c" /* yacc.c:1646 */ - break; - - case 1088: -#line 7427 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OBJECT_FUNCTION; } -#line 35048 "gram.c" /* yacc.c:1646 */ - break; - - case 1089: -#line 7428 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OBJECT_FUNCTION; } -#line 35054 "gram.c" /* yacc.c:1646 */ - break; - - case 1090: -#line 7429 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OBJECT_SEQUENCE; } -#line 35060 "gram.c" /* yacc.c:1646 */ - break; - - case 1091: -#line 7430 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OBJECT_TYPE; } -#line 35066 "gram.c" /* yacc.c:1646 */ - break; - - case 1092: -#line 7431 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OBJECT_SCHEMA; } -#line 35072 "gram.c" /* yacc.c:1646 */ - break; - - case 1093: -#line 7446 "gram.y" /* yacc.c:1646 */ - { - IndexStmt *n = makeNode(IndexStmt); - n->unique = (yyvsp[-13].boolean); - n->concurrent = (yyvsp[-11].boolean); - n->idxname = (yyvsp[-10].str); - n->relation = (yyvsp[-8].range); - n->relationId = InvalidOid; - n->accessMethod = (yyvsp[-7].str); - n->indexParams = (yyvsp[-5].list); - n->indexIncludingParams = (yyvsp[-3].list); - n->options = (yyvsp[-2].list); - n->tableSpace = (yyvsp[-1].str); - n->whereClause = (yyvsp[0].node); - n->excludeOpNames = NIL; - n->idxcomment = NULL; - n->indexOid = InvalidOid; - n->oldNode = InvalidOid; - n->primary = false; - n->isconstraint = false; - n->deferrable = false; - n->initdeferred = false; - n->transformed = false; - n->if_not_exists = false; - (yyval.node) = (Node *)n; - } -#line 35102 "gram.c" /* yacc.c:1646 */ - break; - - case 1094: -#line 7474 "gram.y" /* yacc.c:1646 */ - { - IndexStmt *n = makeNode(IndexStmt); - n->unique = (yyvsp[-16].boolean); - n->concurrent = (yyvsp[-14].boolean); - n->idxname = (yyvsp[-10].str); - n->relation = (yyvsp[-8].range); - n->relationId = InvalidOid; - n->accessMethod = (yyvsp[-7].str); - n->indexParams = (yyvsp[-5].list); - n->indexIncludingParams = (yyvsp[-3].list); - n->options = (yyvsp[-2].list); - n->tableSpace = (yyvsp[-1].str); - n->whereClause = (yyvsp[0].node); - n->excludeOpNames = NIL; - n->idxcomment = NULL; - n->indexOid = InvalidOid; - n->oldNode = InvalidOid; - n->primary = false; - n->isconstraint = false; - n->deferrable = false; - n->initdeferred = false; - n->transformed = false; - n->if_not_exists = true; - (yyval.node) = (Node *)n; - } -#line 35132 "gram.c" /* yacc.c:1646 */ - break; - - case 1095: -#line 7502 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 35138 "gram.c" /* yacc.c:1646 */ - break; - - case 1096: -#line 7503 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 35144 "gram.c" /* yacc.c:1646 */ - break; - - case 1097: -#line 7507 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 35150 "gram.c" /* yacc.c:1646 */ - break; - - case 1098: -#line 7508 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 35156 "gram.c" /* yacc.c:1646 */ - break; - - case 1099: -#line 7512 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 35162 "gram.c" /* yacc.c:1646 */ - break; - - case 1100: -#line 7513 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 35168 "gram.c" /* yacc.c:1646 */ - break; - - case 1101: -#line 7517 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 35174 "gram.c" /* yacc.c:1646 */ - break; - - case 1102: -#line 7518 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = DEFAULT_INDEX_TYPE; } -#line 35180 "gram.c" /* yacc.c:1646 */ - break; - - case 1103: -#line 7521 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].ielem)); } -#line 35186 "gram.c" /* yacc.c:1646 */ - break; - - case 1104: -#line 7522 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].ielem)); } -#line 35192 "gram.c" /* yacc.c:1646 */ - break; - - case 1105: -#line 7531 "gram.y" /* yacc.c:1646 */ - { - (yyval.ielem) = makeNode(IndexElem); - (yyval.ielem)->name = (yyvsp[-4].str); - (yyval.ielem)->expr = NULL; - (yyval.ielem)->indexcolname = NULL; - (yyval.ielem)->collation = (yyvsp[-3].list); - (yyval.ielem)->opclass = (yyvsp[-2].list); - (yyval.ielem)->ordering = (yyvsp[-1].ival); - (yyval.ielem)->nulls_ordering = (yyvsp[0].ival); - } -#line 35207 "gram.c" /* yacc.c:1646 */ - break; - - case 1106: -#line 7542 "gram.y" /* yacc.c:1646 */ - { - (yyval.ielem) = makeNode(IndexElem); - (yyval.ielem)->name = NULL; - (yyval.ielem)->expr = (yyvsp[-4].node); - (yyval.ielem)->indexcolname = NULL; - (yyval.ielem)->collation = (yyvsp[-3].list); - (yyval.ielem)->opclass = (yyvsp[-2].list); - (yyval.ielem)->ordering = (yyvsp[-1].ival); - (yyval.ielem)->nulls_ordering = (yyvsp[0].ival); - } -#line 35222 "gram.c" /* yacc.c:1646 */ - break; - - case 1107: -#line 7553 "gram.y" /* yacc.c:1646 */ - { - (yyval.ielem) = makeNode(IndexElem); - (yyval.ielem)->name = NULL; - (yyval.ielem)->expr = (yyvsp[-5].node); - (yyval.ielem)->indexcolname = NULL; - (yyval.ielem)->collation = (yyvsp[-3].list); - (yyval.ielem)->opclass = (yyvsp[-2].list); - (yyval.ielem)->ordering = (yyvsp[-1].ival); - (yyval.ielem)->nulls_ordering = (yyvsp[0].ival); - } -#line 35237 "gram.c" /* yacc.c:1646 */ - break; - - case 1108: -#line 7565 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 35243 "gram.c" /* yacc.c:1646 */ - break; - - case 1109: -#line 7566 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 35249 "gram.c" /* yacc.c:1646 */ - break; - - case 1110: -#line 7569 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].ielem)); } -#line 35255 "gram.c" /* yacc.c:1646 */ - break; - - case 1111: -#line 7570 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].ielem)); } -#line 35261 "gram.c" /* yacc.c:1646 */ - break; - - case 1112: -#line 7573 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 35267 "gram.c" /* yacc.c:1646 */ - break; - - case 1113: -#line 7574 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 35273 "gram.c" /* yacc.c:1646 */ - break; - - case 1114: -#line 7577 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 35279 "gram.c" /* yacc.c:1646 */ - break; - - case 1115: -#line 7578 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 35285 "gram.c" /* yacc.c:1646 */ - break; - - case 1116: -#line 7581 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = SORTBY_ASC; } -#line 35291 "gram.c" /* yacc.c:1646 */ - break; - - case 1117: -#line 7582 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = SORTBY_DESC; } -#line 35297 "gram.c" /* yacc.c:1646 */ - break; - - case 1118: -#line 7583 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = SORTBY_DEFAULT; } -#line 35303 "gram.c" /* yacc.c:1646 */ - break; - - case 1119: -#line 7586 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = SORTBY_NULLS_FIRST; } -#line 35309 "gram.c" /* yacc.c:1646 */ - break; - - case 1120: -#line 7587 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = SORTBY_NULLS_LAST; } -#line 35315 "gram.c" /* yacc.c:1646 */ - break; - - case 1121: -#line 7588 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = SORTBY_NULLS_DEFAULT; } -#line 35321 "gram.c" /* yacc.c:1646 */ - break; - - case 1122: -#line 7606 "gram.y" /* yacc.c:1646 */ - { - CreateFunctionStmt *n = makeNode(CreateFunctionStmt); - n->is_procedure = false; - n->replace = (yyvsp[-6].boolean); - n->funcname = (yyvsp[-4].list); - n->parameters = (yyvsp[-3].list); - n->returnType = (yyvsp[-1].typnam); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 35336 "gram.c" /* yacc.c:1646 */ - break; - - case 1123: -#line 7618 "gram.y" /* yacc.c:1646 */ - { - CreateFunctionStmt *n = makeNode(CreateFunctionStmt); - n->is_procedure = false; - n->replace = (yyvsp[-9].boolean); - n->funcname = (yyvsp[-7].list); - n->parameters = mergeTableFuncParameters((yyvsp[-6].list), (yyvsp[-2].list)); - n->returnType = TableFuncTypeName((yyvsp[-2].list)); - n->returnType->location = (yylsp[-4]); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 35352 "gram.c" /* yacc.c:1646 */ - break; - - case 1124: -#line 7631 "gram.y" /* yacc.c:1646 */ - { - CreateFunctionStmt *n = makeNode(CreateFunctionStmt); - n->is_procedure = false; - n->replace = (yyvsp[-4].boolean); - n->funcname = (yyvsp[-2].list); - n->parameters = (yyvsp[-1].list); - n->returnType = NULL; - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 35367 "gram.c" /* yacc.c:1646 */ - break; - - case 1125: -#line 7643 "gram.y" /* yacc.c:1646 */ - { - CreateFunctionStmt *n = makeNode(CreateFunctionStmt); - n->is_procedure = true; - n->replace = (yyvsp[-4].boolean); - n->funcname = (yyvsp[-2].list); - n->parameters = (yyvsp[-1].list); - n->returnType = NULL; - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 35382 "gram.c" /* yacc.c:1646 */ - break; - - case 1126: -#line 7656 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 35388 "gram.c" /* yacc.c:1646 */ - break; - - case 1127: -#line 7657 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 35394 "gram.c" /* yacc.c:1646 */ - break; - - case 1128: -#line 7660 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 35400 "gram.c" /* yacc.c:1646 */ - break; - - case 1129: -#line 7661 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 35406 "gram.c" /* yacc.c:1646 */ - break; - - case 1130: -#line 7665 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].fun_param)); } -#line 35412 "gram.c" /* yacc.c:1646 */ - break; - - case 1131: -#line 7666 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].fun_param)); } -#line 35418 "gram.c" /* yacc.c:1646 */ - break; - - case 1132: -#line 7670 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].objwithargs)); } -#line 35424 "gram.c" /* yacc.c:1646 */ - break; - - case 1133: -#line 7672 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].objwithargs)); } -#line 35430 "gram.c" /* yacc.c:1646 */ - break; - - case 1134: -#line 7677 "gram.y" /* yacc.c:1646 */ - { - ObjectWithArgs *n = makeNode(ObjectWithArgs); - n->objname = (yyvsp[-1].list); - n->objargs = extractArgTypes((yyvsp[0].list)); - (yyval.objwithargs) = n; - } -#line 35441 "gram.c" /* yacc.c:1646 */ - break; - - case 1135: -#line 7689 "gram.y" /* yacc.c:1646 */ - { - ObjectWithArgs *n = makeNode(ObjectWithArgs); - n->objname = list_make1(makeString(pstrdup((yyvsp[0].keyword)))); - n->args_unspecified = true; - (yyval.objwithargs) = n; - } -#line 35452 "gram.c" /* yacc.c:1646 */ - break; - - case 1136: -#line 7696 "gram.y" /* yacc.c:1646 */ - { - ObjectWithArgs *n = makeNode(ObjectWithArgs); - n->objname = list_make1(makeString((yyvsp[0].str))); - n->args_unspecified = true; - (yyval.objwithargs) = n; - } -#line 35463 "gram.c" /* yacc.c:1646 */ - break; - - case 1137: -#line 7703 "gram.y" /* yacc.c:1646 */ - { - ObjectWithArgs *n = makeNode(ObjectWithArgs); - n->objname = check_func_name(lcons(makeString((yyvsp[-1].str)), (yyvsp[0].list)), - yyscanner); - n->args_unspecified = true; - (yyval.objwithargs) = n; - } -#line 35475 "gram.c" /* yacc.c:1646 */ - break; - - case 1138: -#line 7717 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 35481 "gram.c" /* yacc.c:1646 */ - break; - - case 1139: -#line 7718 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 35487 "gram.c" /* yacc.c:1646 */ - break; - - case 1140: -#line 7722 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].fun_param)); } -#line 35493 "gram.c" /* yacc.c:1646 */ - break; - - case 1141: -#line 7724 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].fun_param)); } -#line 35499 "gram.c" /* yacc.c:1646 */ - break; - - case 1142: -#line 7739 "gram.y" /* yacc.c:1646 */ - { - FunctionParameter *n = makeNode(FunctionParameter); - n->name = (yyvsp[-1].str); - n->argType = (yyvsp[0].typnam); - n->mode = (yyvsp[-2].fun_param_mode); - n->defexpr = NULL; - (yyval.fun_param) = n; - } -#line 35512 "gram.c" /* yacc.c:1646 */ - break; - - case 1143: -#line 7748 "gram.y" /* yacc.c:1646 */ - { - FunctionParameter *n = makeNode(FunctionParameter); - n->name = (yyvsp[-2].str); - n->argType = (yyvsp[0].typnam); - n->mode = (yyvsp[-1].fun_param_mode); - n->defexpr = NULL; - (yyval.fun_param) = n; - } -#line 35525 "gram.c" /* yacc.c:1646 */ - break; - - case 1144: -#line 7757 "gram.y" /* yacc.c:1646 */ - { - FunctionParameter *n = makeNode(FunctionParameter); - n->name = (yyvsp[-1].str); - n->argType = (yyvsp[0].typnam); - n->mode = FUNC_PARAM_IN; - n->defexpr = NULL; - (yyval.fun_param) = n; - } -#line 35538 "gram.c" /* yacc.c:1646 */ - break; - - case 1145: -#line 7766 "gram.y" /* yacc.c:1646 */ - { - FunctionParameter *n = makeNode(FunctionParameter); - n->name = NULL; - n->argType = (yyvsp[0].typnam); - n->mode = (yyvsp[-1].fun_param_mode); - n->defexpr = NULL; - (yyval.fun_param) = n; - } -#line 35551 "gram.c" /* yacc.c:1646 */ - break; - - case 1146: -#line 7775 "gram.y" /* yacc.c:1646 */ - { - FunctionParameter *n = makeNode(FunctionParameter); - n->name = NULL; - n->argType = (yyvsp[0].typnam); - n->mode = FUNC_PARAM_IN; - n->defexpr = NULL; - (yyval.fun_param) = n; - } -#line 35564 "gram.c" /* yacc.c:1646 */ - break; - - case 1147: -#line 7786 "gram.y" /* yacc.c:1646 */ - { (yyval.fun_param_mode) = FUNC_PARAM_IN; } -#line 35570 "gram.c" /* yacc.c:1646 */ - break; - - case 1148: -#line 7787 "gram.y" /* yacc.c:1646 */ - { (yyval.fun_param_mode) = FUNC_PARAM_OUT; } -#line 35576 "gram.c" /* yacc.c:1646 */ - break; - - case 1149: -#line 7788 "gram.y" /* yacc.c:1646 */ - { (yyval.fun_param_mode) = FUNC_PARAM_INOUT; } -#line 35582 "gram.c" /* yacc.c:1646 */ - break; - - case 1150: -#line 7789 "gram.y" /* yacc.c:1646 */ - { (yyval.fun_param_mode) = FUNC_PARAM_INOUT; } -#line 35588 "gram.c" /* yacc.c:1646 */ - break; - - case 1151: -#line 7790 "gram.y" /* yacc.c:1646 */ - { (yyval.fun_param_mode) = FUNC_PARAM_VARIADIC; } -#line 35594 "gram.c" /* yacc.c:1646 */ - break; - - case 1153: -#line 7801 "gram.y" /* yacc.c:1646 */ - { - /* We can catch over-specified results here if we want to, - * but for now better to silently swallow typmod, etc. - * - thomas 2000-03-22 - */ - (yyval.typnam) = (yyvsp[0].typnam); - } -#line 35606 "gram.c" /* yacc.c:1646 */ - break; - - case 1154: -#line 7815 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 35612 "gram.c" /* yacc.c:1646 */ - break; - - case 1155: -#line 7817 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[-3].str)), (yyvsp[-2].list))); - (yyval.typnam)->pct_type = true; - (yyval.typnam)->location = (yylsp[-3]); - } -#line 35622 "gram.c" /* yacc.c:1646 */ - break; - - case 1156: -#line 7823 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[-3].str)), (yyvsp[-2].list))); - (yyval.typnam)->pct_type = true; - (yyval.typnam)->setof = true; - (yyval.typnam)->location = (yylsp[-3]); - } -#line 35633 "gram.c" /* yacc.c:1646 */ - break; - - case 1157: -#line 7833 "gram.y" /* yacc.c:1646 */ - { - (yyval.fun_param) = (yyvsp[0].fun_param); - } -#line 35641 "gram.c" /* yacc.c:1646 */ - break; - - case 1158: -#line 7837 "gram.y" /* yacc.c:1646 */ - { - (yyval.fun_param) = (yyvsp[-2].fun_param); - (yyval.fun_param)->defexpr = (yyvsp[0].node); - } -#line 35650 "gram.c" /* yacc.c:1646 */ - break; - - case 1159: -#line 7842 "gram.y" /* yacc.c:1646 */ - { - (yyval.fun_param) = (yyvsp[-2].fun_param); - (yyval.fun_param)->defexpr = (yyvsp[0].node); - } -#line 35659 "gram.c" /* yacc.c:1646 */ - break; - - case 1160: -#line 7850 "gram.y" /* yacc.c:1646 */ - { - if (!((yyvsp[0].fun_param)->mode == FUNC_PARAM_IN || - (yyvsp[0].fun_param)->mode == FUNC_PARAM_VARIADIC)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("aggregates cannot have output arguments"), - parser_errposition((yylsp[0])))); - (yyval.fun_param) = (yyvsp[0].fun_param); - } -#line 35673 "gram.c" /* yacc.c:1646 */ - break; - - case 1161: -#line 7891 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2(NIL, makeInteger(-1)); - } -#line 35681 "gram.c" /* yacc.c:1646 */ - break; - - case 1162: -#line 7895 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[-1].list), makeInteger(-1)); - } -#line 35689 "gram.c" /* yacc.c:1646 */ - break; - - case 1163: -#line 7899 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[-1].list), makeInteger(0)); - } -#line 35697 "gram.c" /* yacc.c:1646 */ - break; - - case 1164: -#line 7903 "gram.y" /* yacc.c:1646 */ - { - /* this is the only case requiring consistency checking */ - (yyval.list) = makeOrderedSetArgs((yyvsp[-4].list), (yyvsp[-1].list), yyscanner); - } -#line 35706 "gram.c" /* yacc.c:1646 */ - break; - - case 1165: -#line 7910 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].fun_param)); } -#line 35712 "gram.c" /* yacc.c:1646 */ - break; - - case 1166: -#line 7911 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].fun_param)); } -#line 35718 "gram.c" /* yacc.c:1646 */ - break; - - case 1167: -#line 7916 "gram.y" /* yacc.c:1646 */ - { - ObjectWithArgs *n = makeNode(ObjectWithArgs); - n->objname = (yyvsp[-1].list); - n->objargs = extractAggrArgTypes((yyvsp[0].list)); - (yyval.objwithargs) = n; - } -#line 35729 "gram.c" /* yacc.c:1646 */ - break; - - case 1168: -#line 7925 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].objwithargs)); } -#line 35735 "gram.c" /* yacc.c:1646 */ - break; - - case 1169: -#line 7927 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].objwithargs)); } -#line 35741 "gram.c" /* yacc.c:1646 */ - break; - - case 1170: -#line 7932 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 35747 "gram.c" /* yacc.c:1646 */ - break; - - case 1171: -#line 7933 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 35753 "gram.c" /* yacc.c:1646 */ - break; - - case 1172: -#line 7941 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("strict", (Node *)makeInteger(false), (yylsp[-3])); - } -#line 35761 "gram.c" /* yacc.c:1646 */ - break; - - case 1173: -#line 7945 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("strict", (Node *)makeInteger(true), (yylsp[-4])); - } -#line 35769 "gram.c" /* yacc.c:1646 */ - break; - - case 1174: -#line 7949 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("strict", (Node *)makeInteger(true), (yylsp[0])); - } -#line 35777 "gram.c" /* yacc.c:1646 */ - break; - - case 1175: -#line 7953 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("volatility", (Node *)makeString("immutable"), (yylsp[0])); - } -#line 35785 "gram.c" /* yacc.c:1646 */ - break; - - case 1176: -#line 7957 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("volatility", (Node *)makeString("stable"), (yylsp[0])); - } -#line 35793 "gram.c" /* yacc.c:1646 */ - break; - - case 1177: -#line 7961 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("volatility", (Node *)makeString("volatile"), (yylsp[0])); - } -#line 35801 "gram.c" /* yacc.c:1646 */ - break; - - case 1178: -#line 7965 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("security", (Node *)makeInteger(true), (yylsp[-2])); - } -#line 35809 "gram.c" /* yacc.c:1646 */ - break; - - case 1179: -#line 7969 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("security", (Node *)makeInteger(false), (yylsp[-2])); - } -#line 35817 "gram.c" /* yacc.c:1646 */ - break; - - case 1180: -#line 7973 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("security", (Node *)makeInteger(true), (yylsp[-1])); - } -#line 35825 "gram.c" /* yacc.c:1646 */ - break; - - case 1181: -#line 7977 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("security", (Node *)makeInteger(false), (yylsp[-1])); - } -#line 35833 "gram.c" /* yacc.c:1646 */ - break; - - case 1182: -#line 7981 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("leakproof", (Node *)makeInteger(true), (yylsp[0])); - } -#line 35841 "gram.c" /* yacc.c:1646 */ - break; - - case 1183: -#line 7985 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("leakproof", (Node *)makeInteger(false), (yylsp[-1])); - } -#line 35849 "gram.c" /* yacc.c:1646 */ - break; - - case 1184: -#line 7989 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("cost", (Node *)(yyvsp[0].value), (yylsp[-1])); - } -#line 35857 "gram.c" /* yacc.c:1646 */ - break; - - case 1185: -#line 7993 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("rows", (Node *)(yyvsp[0].value), (yylsp[-1])); - } -#line 35865 "gram.c" /* yacc.c:1646 */ - break; - - case 1186: -#line 7997 "gram.y" /* yacc.c:1646 */ - { - /* we abuse the normal content of a DefElem here */ - (yyval.defelt) = makeDefElem("set", (Node *)(yyvsp[0].vsetstmt), (yylsp[0])); - } -#line 35874 "gram.c" /* yacc.c:1646 */ - break; - - case 1187: -#line 8002 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("parallel", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 35882 "gram.c" /* yacc.c:1646 */ - break; - - case 1188: -#line 8009 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("as", (Node *)(yyvsp[0].list), (yylsp[-1])); - } -#line 35890 "gram.c" /* yacc.c:1646 */ - break; - - case 1189: -#line 8013 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("language", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 35898 "gram.c" /* yacc.c:1646 */ - break; - - case 1190: -#line 8017 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("transform", (Node *)(yyvsp[0].list), (yylsp[-1])); - } -#line 35906 "gram.c" /* yacc.c:1646 */ - break; - - case 1191: -#line 8021 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("window", (Node *)makeInteger(true), (yylsp[0])); - } -#line 35914 "gram.c" /* yacc.c:1646 */ - break; - - case 1192: -#line 8025 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = (yyvsp[0].defelt); - } -#line 35922 "gram.c" /* yacc.c:1646 */ - break; - - case 1193: -#line 8030 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 35928 "gram.c" /* yacc.c:1646 */ - break; - - case 1194: -#line 8032 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2(makeString((yyvsp[-2].str)), makeString((yyvsp[0].str))); - } -#line 35936 "gram.c" /* yacc.c:1646 */ - break; - - case 1195: -#line 8038 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].typnam)); } -#line 35942 "gram.c" /* yacc.c:1646 */ - break; - - case 1196: -#line 8039 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-4].list), (yyvsp[0].typnam)); } -#line 35948 "gram.c" /* yacc.c:1646 */ - break; - - case 1197: -#line 8043 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 35954 "gram.c" /* yacc.c:1646 */ - break; - - case 1198: -#line 8044 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 35960 "gram.c" /* yacc.c:1646 */ - break; - - case 1199: -#line 8048 "gram.y" /* yacc.c:1646 */ - { - FunctionParameter *n = makeNode(FunctionParameter); - n->name = (yyvsp[-1].str); - n->argType = (yyvsp[0].typnam); - n->mode = FUNC_PARAM_TABLE; - n->defexpr = NULL; - (yyval.fun_param) = n; - } -#line 35973 "gram.c" /* yacc.c:1646 */ - break; - - case 1200: -#line 8060 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].fun_param)); - } -#line 35981 "gram.c" /* yacc.c:1646 */ - break; - - case 1201: -#line 8064 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].fun_param)); - } -#line 35989 "gram.c" /* yacc.c:1646 */ - break; - - case 1202: -#line 8079 "gram.y" /* yacc.c:1646 */ - { - AlterFunctionStmt *n = makeNode(AlterFunctionStmt); - n->objtype = OBJECT_FUNCTION; - n->func = (yyvsp[-2].objwithargs); - n->actions = (yyvsp[-1].list); - (yyval.node) = (Node *) n; - } -#line 36001 "gram.c" /* yacc.c:1646 */ - break; - - case 1203: -#line 8087 "gram.y" /* yacc.c:1646 */ - { - AlterFunctionStmt *n = makeNode(AlterFunctionStmt); - n->objtype = OBJECT_PROCEDURE; - n->func = (yyvsp[-2].objwithargs); - n->actions = (yyvsp[-1].list); - (yyval.node) = (Node *) n; - } -#line 36013 "gram.c" /* yacc.c:1646 */ - break; - - case 1204: -#line 8095 "gram.y" /* yacc.c:1646 */ - { - AlterFunctionStmt *n = makeNode(AlterFunctionStmt); - n->objtype = OBJECT_ROUTINE; - n->func = (yyvsp[-2].objwithargs); - n->actions = (yyvsp[-1].list); - (yyval.node) = (Node *) n; - } -#line 36025 "gram.c" /* yacc.c:1646 */ - break; - - case 1205: -#line 8106 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 36031 "gram.c" /* yacc.c:1646 */ - break; - - case 1206: -#line 8107 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 36037 "gram.c" /* yacc.c:1646 */ - break; - - case 1209: -#line 8131 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_FUNCTION; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36051 "gram.c" /* yacc.c:1646 */ - break; - - case 1210: -#line 8141 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_FUNCTION; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36065 "gram.c" /* yacc.c:1646 */ - break; - - case 1211: -#line 8151 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_PROCEDURE; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36079 "gram.c" /* yacc.c:1646 */ - break; - - case 1212: -#line 8161 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_PROCEDURE; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36093 "gram.c" /* yacc.c:1646 */ - break; - - case 1213: -#line 8171 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_ROUTINE; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36107 "gram.c" /* yacc.c:1646 */ - break; - - case 1214: -#line 8181 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_ROUTINE; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36121 "gram.c" /* yacc.c:1646 */ - break; - - case 1215: -#line 8194 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_AGGREGATE; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36135 "gram.c" /* yacc.c:1646 */ - break; - - case 1216: -#line 8204 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_AGGREGATE; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36149 "gram.c" /* yacc.c:1646 */ - break; - - case 1217: -#line 8217 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_OPERATOR; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36163 "gram.c" /* yacc.c:1646 */ - break; - - case 1218: -#line 8227 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_OPERATOR; - n->objects = (yyvsp[-1].list); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36177 "gram.c" /* yacc.c:1646 */ - break; - - case 1219: -#line 8240 "gram.y" /* yacc.c:1646 */ - { - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("missing argument"), - errhint("Use NONE to denote the missing argument of a unary operator."), - parser_errposition((yylsp[0])))); - } -#line 36189 "gram.c" /* yacc.c:1646 */ - break; - - case 1220: -#line 8248 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2((yyvsp[-3].typnam), (yyvsp[-1].typnam)); } -#line 36195 "gram.c" /* yacc.c:1646 */ - break; - - case 1221: -#line 8250 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(NULL, (yyvsp[-1].typnam)); } -#line 36201 "gram.c" /* yacc.c:1646 */ - break; - - case 1222: -#line 8252 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2((yyvsp[-3].typnam), NULL); } -#line 36207 "gram.c" /* yacc.c:1646 */ - break; - - case 1223: -#line 8257 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 36213 "gram.c" /* yacc.c:1646 */ - break; - - case 1224: -#line 8259 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lcons(makeString((yyvsp[-2].str)), (yyvsp[0].list)); } -#line 36219 "gram.c" /* yacc.c:1646 */ - break; - - case 1225: -#line 8263 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].objwithargs)); } -#line 36225 "gram.c" /* yacc.c:1646 */ - break; - - case 1226: -#line 8265 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].objwithargs)); } -#line 36231 "gram.c" /* yacc.c:1646 */ - break; - - case 1227: -#line 8270 "gram.y" /* yacc.c:1646 */ - { - ObjectWithArgs *n = makeNode(ObjectWithArgs); - n->objname = (yyvsp[-1].list); - n->objargs = (yyvsp[0].list); - (yyval.objwithargs) = n; - } -#line 36242 "gram.c" /* yacc.c:1646 */ - break; - - case 1228: -#line 8288 "gram.y" /* yacc.c:1646 */ - { - DoStmt *n = makeNode(DoStmt); - n->args = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 36252 "gram.c" /* yacc.c:1646 */ - break; - - case 1229: -#line 8296 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 36258 "gram.c" /* yacc.c:1646 */ - break; - - case 1230: -#line 8297 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 36264 "gram.c" /* yacc.c:1646 */ - break; - - case 1231: -#line 8302 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("as", (Node *)makeString((yyvsp[0].str)), (yylsp[0])); - } -#line 36272 "gram.c" /* yacc.c:1646 */ - break; - - case 1232: -#line 8306 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem("language", (Node *)makeString((yyvsp[0].str)), (yylsp[-1])); - } -#line 36280 "gram.c" /* yacc.c:1646 */ - break; - - case 1233: -#line 8319 "gram.y" /* yacc.c:1646 */ - { - CreateCastStmt *n = makeNode(CreateCastStmt); - n->sourcetype = (yyvsp[-7].typnam); - n->targettype = (yyvsp[-5].typnam); - n->func = (yyvsp[-1].objwithargs); - n->context = (CoercionContext) (yyvsp[0].ival); - n->inout = false; - (yyval.node) = (Node *)n; - } -#line 36294 "gram.c" /* yacc.c:1646 */ - break; - - case 1234: -#line 8330 "gram.y" /* yacc.c:1646 */ - { - CreateCastStmt *n = makeNode(CreateCastStmt); - n->sourcetype = (yyvsp[-6].typnam); - n->targettype = (yyvsp[-4].typnam); - n->func = NULL; - n->context = (CoercionContext) (yyvsp[0].ival); - n->inout = false; - (yyval.node) = (Node *)n; - } -#line 36308 "gram.c" /* yacc.c:1646 */ - break; - - case 1235: -#line 8341 "gram.y" /* yacc.c:1646 */ - { - CreateCastStmt *n = makeNode(CreateCastStmt); - n->sourcetype = (yyvsp[-6].typnam); - n->targettype = (yyvsp[-4].typnam); - n->func = NULL; - n->context = (CoercionContext) (yyvsp[0].ival); - n->inout = true; - (yyval.node) = (Node *)n; - } -#line 36322 "gram.c" /* yacc.c:1646 */ - break; - - case 1236: -#line 8352 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = COERCION_IMPLICIT; } -#line 36328 "gram.c" /* yacc.c:1646 */ - break; - - case 1237: -#line 8353 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = COERCION_ASSIGNMENT; } -#line 36334 "gram.c" /* yacc.c:1646 */ - break; - - case 1238: -#line 8354 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = COERCION_EXPLICIT; } -#line 36340 "gram.c" /* yacc.c:1646 */ - break; - - case 1239: -#line 8359 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_CAST; - n->objects = list_make1(list_make2((yyvsp[-4].typnam), (yyvsp[-2].typnam))); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = (yyvsp[-6].boolean); - n->concurrent = false; - (yyval.node) = (Node *)n; - } -#line 36354 "gram.c" /* yacc.c:1646 */ - break; - - case 1240: -#line 8370 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 36360 "gram.c" /* yacc.c:1646 */ - break; - - case 1241: -#line 8371 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 36366 "gram.c" /* yacc.c:1646 */ - break; - - case 1242: -#line 8382 "gram.y" /* yacc.c:1646 */ - { - CreateTransformStmt *n = makeNode(CreateTransformStmt); - n->replace = (yyvsp[-8].boolean); - n->type_name = (yyvsp[-5].typnam); - n->lang = (yyvsp[-3].str); - n->fromsql = linitial((yyvsp[-1].list)); - n->tosql = lsecond((yyvsp[-1].list)); - (yyval.node) = (Node *)n; - } -#line 36380 "gram.c" /* yacc.c:1646 */ - break; - - case 1243: -#line 8394 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[-6].objwithargs), (yyvsp[0].objwithargs)); - } -#line 36388 "gram.c" /* yacc.c:1646 */ - break; - - case 1244: -#line 8398 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[0].objwithargs), (yyvsp[-6].objwithargs)); - } -#line 36396 "gram.c" /* yacc.c:1646 */ - break; - - case 1245: -#line 8402 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[0].objwithargs), NULL); - } -#line 36404 "gram.c" /* yacc.c:1646 */ - break; - - case 1246: -#line 8406 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2(NULL, (yyvsp[0].objwithargs)); - } -#line 36412 "gram.c" /* yacc.c:1646 */ - break; - - case 1247: -#line 8413 "gram.y" /* yacc.c:1646 */ - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_TRANSFORM; - n->objects = list_make1(list_make2((yyvsp[-3].typnam), makeString((yyvsp[-1].str)))); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = (yyvsp[-5].boolean); - (yyval.node) = (Node *)n; - } -#line 36425 "gram.c" /* yacc.c:1646 */ - break; - - case 1248: -#line 8433 "gram.y" /* yacc.c:1646 */ - { - ReindexStmt *n = makeNode(ReindexStmt); - n->kind = (yyvsp[-1].ival); - n->relation = (yyvsp[0].range); - n->name = NULL; - n->options = 0; - (yyval.node) = (Node *)n; - } -#line 36438 "gram.c" /* yacc.c:1646 */ - break; - - case 1249: -#line 8442 "gram.y" /* yacc.c:1646 */ - { - ReindexStmt *n = makeNode(ReindexStmt); - n->kind = (yyvsp[-1].ival); - n->name = (yyvsp[0].str); - n->relation = NULL; - n->options = 0; - (yyval.node) = (Node *)n; - } -#line 36451 "gram.c" /* yacc.c:1646 */ - break; - - case 1250: -#line 8451 "gram.y" /* yacc.c:1646 */ - { - ReindexStmt *n = makeNode(ReindexStmt); - n->kind = (yyvsp[-1].ival); - n->relation = (yyvsp[0].range); - n->name = NULL; - n->options = (yyvsp[-3].ival); - (yyval.node) = (Node *)n; - } -#line 36464 "gram.c" /* yacc.c:1646 */ - break; - - case 1251: -#line 8460 "gram.y" /* yacc.c:1646 */ - { - ReindexStmt *n = makeNode(ReindexStmt); - n->kind = (yyvsp[-1].ival); - n->name = (yyvsp[0].str); - n->relation = NULL; - n->options = (yyvsp[-3].ival); - (yyval.node) = (Node *)n; - } -#line 36477 "gram.c" /* yacc.c:1646 */ - break; - - case 1252: -#line 8470 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = REINDEX_OBJECT_INDEX; } -#line 36483 "gram.c" /* yacc.c:1646 */ - break; - - case 1253: -#line 8471 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = REINDEX_OBJECT_TABLE; } -#line 36489 "gram.c" /* yacc.c:1646 */ - break; - - case 1254: -#line 8474 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = REINDEX_OBJECT_SCHEMA; } -#line 36495 "gram.c" /* yacc.c:1646 */ - break; - - case 1255: -#line 8475 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = REINDEX_OBJECT_SYSTEM; } -#line 36501 "gram.c" /* yacc.c:1646 */ - break; - - case 1256: -#line 8476 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = REINDEX_OBJECT_DATABASE; } -#line 36507 "gram.c" /* yacc.c:1646 */ - break; - - case 1257: -#line 8479 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 36513 "gram.c" /* yacc.c:1646 */ - break; - - case 1258: -#line 8480 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-2].ival) | (yyvsp[0].ival); } -#line 36519 "gram.c" /* yacc.c:1646 */ - break; - - case 1259: -#line 8483 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = REINDEXOPT_VERBOSE; } -#line 36525 "gram.c" /* yacc.c:1646 */ - break; - - case 1260: -#line 8494 "gram.y" /* yacc.c:1646 */ - { - AlterTableSpaceOptionsStmt *n = - makeNode(AlterTableSpaceOptionsStmt); - n->tablespacename = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - n->isReset = false; - (yyval.node) = (Node *)n; - } -#line 36538 "gram.c" /* yacc.c:1646 */ - break; - - case 1261: -#line 8503 "gram.y" /* yacc.c:1646 */ - { - AlterTableSpaceOptionsStmt *n = - makeNode(AlterTableSpaceOptionsStmt); - n->tablespacename = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - n->isReset = true; - (yyval.node) = (Node *)n; - } -#line 36551 "gram.c" /* yacc.c:1646 */ - break; - - case 1262: -#line 8520 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_AGGREGATE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36564 "gram.c" /* yacc.c:1646 */ - break; - - case 1263: -#line 8529 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_COLLATION; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36577 "gram.c" /* yacc.c:1646 */ - break; - - case 1264: -#line 8538 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_CONVERSION; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36590 "gram.c" /* yacc.c:1646 */ - break; - - case 1265: -#line 8547 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_DATABASE; - n->subname = (yyvsp[-3].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36603 "gram.c" /* yacc.c:1646 */ - break; - - case 1266: -#line 8556 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_DOMAIN; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36616 "gram.c" /* yacc.c:1646 */ - break; - - case 1267: -#line 8565 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_DOMCONSTRAINT; - n->object = (Node *) (yyvsp[-5].list); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 36629 "gram.c" /* yacc.c:1646 */ - break; - - case 1268: -#line 8574 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_FDW; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36642 "gram.c" /* yacc.c:1646 */ - break; - - case 1269: -#line 8583 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_FUNCTION; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36655 "gram.c" /* yacc.c:1646 */ - break; - - case 1270: -#line 8592 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_ROLE; - n->subname = (yyvsp[-3].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36668 "gram.c" /* yacc.c:1646 */ - break; - - case 1271: -#line 8601 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_LANGUAGE; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36681 "gram.c" /* yacc.c:1646 */ - break; - - case 1272: -#line 8610 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_OPCLASS; - n->object = (Node *) lcons(makeString((yyvsp[-3].str)), (yyvsp[-5].list)); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36694 "gram.c" /* yacc.c:1646 */ - break; - - case 1273: -#line 8619 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_OPFAMILY; - n->object = (Node *) lcons(makeString((yyvsp[-3].str)), (yyvsp[-5].list)); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36707 "gram.c" /* yacc.c:1646 */ - break; - - case 1274: -#line 8628 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_POLICY; - n->relation = (yyvsp[-3].range); - n->subname = (yyvsp[-5].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36721 "gram.c" /* yacc.c:1646 */ - break; - - case 1275: -#line 8638 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_POLICY; - n->relation = (yyvsp[-3].range); - n->subname = (yyvsp[-5].str); - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 36735 "gram.c" /* yacc.c:1646 */ - break; - - case 1276: -#line 8648 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_PROCEDURE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36748 "gram.c" /* yacc.c:1646 */ - break; - - case 1277: -#line 8657 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_PUBLICATION; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36761 "gram.c" /* yacc.c:1646 */ - break; - - case 1278: -#line 8666 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_ROUTINE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36774 "gram.c" /* yacc.c:1646 */ - break; - - case 1279: -#line 8675 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_SCHEMA; - n->subname = (yyvsp[-3].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36787 "gram.c" /* yacc.c:1646 */ - break; - - case 1280: -#line 8684 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_FOREIGN_SERVER; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36800 "gram.c" /* yacc.c:1646 */ - break; - - case 1281: -#line 8693 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_SUBSCRIPTION; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36813 "gram.c" /* yacc.c:1646 */ - break; - - case 1282: -#line 8702 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TABLE; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36827 "gram.c" /* yacc.c:1646 */ - break; - - case 1283: -#line 8712 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TABLE; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 36841 "gram.c" /* yacc.c:1646 */ - break; - - case 1284: -#line 8722 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_SEQUENCE; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36855 "gram.c" /* yacc.c:1646 */ - break; - - case 1285: -#line 8732 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_SEQUENCE; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 36869 "gram.c" /* yacc.c:1646 */ - break; - - case 1286: -#line 8742 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_VIEW; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36883 "gram.c" /* yacc.c:1646 */ - break; - - case 1287: -#line 8752 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_VIEW; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 36897 "gram.c" /* yacc.c:1646 */ - break; - - case 1288: -#line 8762 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_MATVIEW; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36911 "gram.c" /* yacc.c:1646 */ - break; - - case 1289: -#line 8772 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_MATVIEW; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 36925 "gram.c" /* yacc.c:1646 */ - break; - - case 1290: -#line 8782 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_INDEX; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36939 "gram.c" /* yacc.c:1646 */ - break; - - case 1291: -#line 8792 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_INDEX; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 36953 "gram.c" /* yacc.c:1646 */ - break; - - case 1292: -#line 8802 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_FOREIGN_TABLE; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36967 "gram.c" /* yacc.c:1646 */ - break; - - case 1293: -#line 8812 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_FOREIGN_TABLE; - n->relation = (yyvsp[-3].range); - n->subname = NULL; - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 36981 "gram.c" /* yacc.c:1646 */ - break; - - case 1294: -#line 8822 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_COLUMN; - n->relationType = OBJECT_TABLE; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 36996 "gram.c" /* yacc.c:1646 */ - break; - - case 1295: -#line 8833 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_COLUMN; - n->relationType = OBJECT_TABLE; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37011 "gram.c" /* yacc.c:1646 */ - break; - - case 1296: -#line 8844 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_COLUMN; - n->relationType = OBJECT_MATVIEW; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37026 "gram.c" /* yacc.c:1646 */ - break; - - case 1297: -#line 8855 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_COLUMN; - n->relationType = OBJECT_MATVIEW; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37041 "gram.c" /* yacc.c:1646 */ - break; - - case 1298: -#line 8866 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TABCONSTRAINT; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37055 "gram.c" /* yacc.c:1646 */ - break; - - case 1299: -#line 8876 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TABCONSTRAINT; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37069 "gram.c" /* yacc.c:1646 */ - break; - - case 1300: -#line 8886 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_COLUMN; - n->relationType = OBJECT_FOREIGN_TABLE; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37084 "gram.c" /* yacc.c:1646 */ - break; - - case 1301: -#line 8897 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_COLUMN; - n->relationType = OBJECT_FOREIGN_TABLE; - n->relation = (yyvsp[-5].range); - n->subname = (yyvsp[-2].str); - n->newname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37099 "gram.c" /* yacc.c:1646 */ - break; - - case 1302: -#line 8908 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_RULE; - n->relation = (yyvsp[-3].range); - n->subname = (yyvsp[-5].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37113 "gram.c" /* yacc.c:1646 */ - break; - - case 1303: -#line 8918 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TRIGGER; - n->relation = (yyvsp[-3].range); - n->subname = (yyvsp[-5].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37127 "gram.c" /* yacc.c:1646 */ - break; - - case 1304: -#line 8928 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_EVENT_TRIGGER; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newname = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 37139 "gram.c" /* yacc.c:1646 */ - break; - - case 1305: -#line 8936 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_ROLE; - n->subname = (yyvsp[-3].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37152 "gram.c" /* yacc.c:1646 */ - break; - - case 1306: -#line 8945 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_ROLE; - n->subname = (yyvsp[-3].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37165 "gram.c" /* yacc.c:1646 */ - break; - - case 1307: -#line 8954 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TABLESPACE; - n->subname = (yyvsp[-3].str); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37178 "gram.c" /* yacc.c:1646 */ - break; - - case 1308: -#line 8963 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_STATISTIC_EXT; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37191 "gram.c" /* yacc.c:1646 */ - break; - - case 1309: -#line 8972 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TSPARSER; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37204 "gram.c" /* yacc.c:1646 */ - break; - - case 1310: -#line 8981 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TSDICTIONARY; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37217 "gram.c" /* yacc.c:1646 */ - break; - - case 1311: -#line 8990 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TSTEMPLATE; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37230 "gram.c" /* yacc.c:1646 */ - break; - - case 1312: -#line 8999 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TSCONFIGURATION; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37243 "gram.c" /* yacc.c:1646 */ - break; - - case 1313: -#line 9008 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_TYPE; - n->object = (Node *) (yyvsp[-3].list); - n->newname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37256 "gram.c" /* yacc.c:1646 */ - break; - - case 1314: -#line 9017 "gram.y" /* yacc.c:1646 */ - { - RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_ATTRIBUTE; - n->relationType = OBJECT_TYPE; - n->relation = makeRangeVarFromAnyName((yyvsp[-6].list), (yylsp[-6]), yyscanner); - n->subname = (yyvsp[-3].str); - n->newname = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37272 "gram.c" /* yacc.c:1646 */ - break; - - case 1315: -#line 9030 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = COLUMN; } -#line 37278 "gram.c" /* yacc.c:1646 */ - break; - - case 1316: -#line 9031 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 37284 "gram.c" /* yacc.c:1646 */ - break; - - case 1317: -#line 9034 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 1; } -#line 37290 "gram.c" /* yacc.c:1646 */ - break; - - case 1318: -#line 9035 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 37296 "gram.c" /* yacc.c:1646 */ - break; - - case 1319: -#line 9046 "gram.y" /* yacc.c:1646 */ - { - AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); - n->objectType = OBJECT_FUNCTION; - n->object = (Node *) (yyvsp[-4].objwithargs); - n->extname = makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 37308 "gram.c" /* yacc.c:1646 */ - break; - - case 1320: -#line 9054 "gram.y" /* yacc.c:1646 */ - { - AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); - n->objectType = OBJECT_PROCEDURE; - n->object = (Node *) (yyvsp[-4].objwithargs); - n->extname = makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 37320 "gram.c" /* yacc.c:1646 */ - break; - - case 1321: -#line 9062 "gram.y" /* yacc.c:1646 */ - { - AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); - n->objectType = OBJECT_ROUTINE; - n->object = (Node *) (yyvsp[-4].objwithargs); - n->extname = makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 37332 "gram.c" /* yacc.c:1646 */ - break; - - case 1322: -#line 9070 "gram.y" /* yacc.c:1646 */ - { - AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); - n->objectType = OBJECT_TRIGGER; - n->relation = (yyvsp[-4].range); - n->object = (Node *) list_make1(makeString((yyvsp[-6].str))); - n->extname = makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 37345 "gram.c" /* yacc.c:1646 */ - break; - - case 1323: -#line 9079 "gram.y" /* yacc.c:1646 */ - { - AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); - n->objectType = OBJECT_MATVIEW; - n->relation = (yyvsp[-4].range); - n->extname = makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 37357 "gram.c" /* yacc.c:1646 */ - break; - - case 1324: -#line 9087 "gram.y" /* yacc.c:1646 */ - { - AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); - n->objectType = OBJECT_INDEX; - n->relation = (yyvsp[-4].range); - n->extname = makeString((yyvsp[0].str)); - (yyval.node) = (Node *)n; - } -#line 37369 "gram.c" /* yacc.c:1646 */ - break; - - case 1325: -#line 9104 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_AGGREGATE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37382 "gram.c" /* yacc.c:1646 */ - break; - - case 1326: -#line 9113 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_COLLATION; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37395 "gram.c" /* yacc.c:1646 */ - break; - - case 1327: -#line 9122 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_CONVERSION; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37408 "gram.c" /* yacc.c:1646 */ - break; - - case 1328: -#line 9131 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_DOMAIN; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37421 "gram.c" /* yacc.c:1646 */ - break; - - case 1329: -#line 9140 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_EXTENSION; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37434 "gram.c" /* yacc.c:1646 */ - break; - - case 1330: -#line 9149 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_FUNCTION; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37447 "gram.c" /* yacc.c:1646 */ - break; - - case 1331: -#line 9158 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_OPERATOR; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37460 "gram.c" /* yacc.c:1646 */ - break; - - case 1332: -#line 9167 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_OPCLASS; - n->object = (Node *) lcons(makeString((yyvsp[-3].str)), (yyvsp[-5].list)); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37473 "gram.c" /* yacc.c:1646 */ - break; - - case 1333: -#line 9176 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_OPFAMILY; - n->object = (Node *) lcons(makeString((yyvsp[-3].str)), (yyvsp[-5].list)); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37486 "gram.c" /* yacc.c:1646 */ - break; - - case 1334: -#line 9185 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_PROCEDURE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37499 "gram.c" /* yacc.c:1646 */ - break; - - case 1335: -#line 9194 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_ROUTINE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37512 "gram.c" /* yacc.c:1646 */ - break; - - case 1336: -#line 9203 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_TABLE; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37525 "gram.c" /* yacc.c:1646 */ - break; - - case 1337: -#line 9212 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_TABLE; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37538 "gram.c" /* yacc.c:1646 */ - break; - - case 1338: -#line 9221 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_STATISTIC_EXT; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37551 "gram.c" /* yacc.c:1646 */ - break; - - case 1339: -#line 9230 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_TSPARSER; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37564 "gram.c" /* yacc.c:1646 */ - break; - - case 1340: -#line 9239 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_TSDICTIONARY; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37577 "gram.c" /* yacc.c:1646 */ - break; - - case 1341: -#line 9248 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_TSTEMPLATE; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37590 "gram.c" /* yacc.c:1646 */ - break; - - case 1342: -#line 9257 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_TSCONFIGURATION; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37603 "gram.c" /* yacc.c:1646 */ - break; - - case 1343: -#line 9266 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_SEQUENCE; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37616 "gram.c" /* yacc.c:1646 */ - break; - - case 1344: -#line 9275 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_SEQUENCE; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37629 "gram.c" /* yacc.c:1646 */ - break; - - case 1345: -#line 9284 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_VIEW; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37642 "gram.c" /* yacc.c:1646 */ - break; - - case 1346: -#line 9293 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_VIEW; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37655 "gram.c" /* yacc.c:1646 */ - break; - - case 1347: -#line 9302 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_MATVIEW; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37668 "gram.c" /* yacc.c:1646 */ - break; - - case 1348: -#line 9311 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_MATVIEW; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37681 "gram.c" /* yacc.c:1646 */ - break; - - case 1349: -#line 9320 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_FOREIGN_TABLE; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37694 "gram.c" /* yacc.c:1646 */ - break; - - case 1350: -#line 9329 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_FOREIGN_TABLE; - n->relation = (yyvsp[-3].range); - n->newschema = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 37707 "gram.c" /* yacc.c:1646 */ - break; - - case 1351: -#line 9338 "gram.y" /* yacc.c:1646 */ - { - AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); - n->objectType = OBJECT_TYPE; - n->object = (Node *) (yyvsp[-3].list); - n->newschema = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 37720 "gram.c" /* yacc.c:1646 */ - break; - - case 1352: -#line 9356 "gram.y" /* yacc.c:1646 */ - { - AlterOperatorStmt *n = makeNode(AlterOperatorStmt); - n->opername = (yyvsp[-4].objwithargs); - n->options = (yyvsp[-1].list); - (yyval.node) = (Node *)n; - } -#line 37731 "gram.c" /* yacc.c:1646 */ - break; - - case 1353: -#line 9364 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 37737 "gram.c" /* yacc.c:1646 */ - break; - - case 1354: -#line 9365 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); } -#line 37743 "gram.c" /* yacc.c:1646 */ - break; - - case 1355: -#line 9369 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem((yyvsp[-2].str), NULL, (yylsp[-2])); } -#line 37749 "gram.c" /* yacc.c:1646 */ - break; - - case 1356: -#line 9371 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem((yyvsp[-2].str), (Node *) (yyvsp[0].node), (yylsp[-2])); } -#line 37755 "gram.c" /* yacc.c:1646 */ - break; - - case 1357: -#line 9376 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)(yyvsp[0].typnam); } -#line 37761 "gram.c" /* yacc.c:1646 */ - break; - - case 1358: -#line 9377 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)makeString(pstrdup((yyvsp[0].keyword))); } -#line 37767 "gram.c" /* yacc.c:1646 */ - break; - - case 1359: -#line 9378 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)(yyvsp[0].list); } -#line 37773 "gram.c" /* yacc.c:1646 */ - break; - - case 1360: -#line 9379 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)(yyvsp[0].value); } -#line 37779 "gram.c" /* yacc.c:1646 */ - break; - - case 1361: -#line 9380 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)makeString((yyvsp[0].str)); } -#line 37785 "gram.c" /* yacc.c:1646 */ - break; - - case 1362: -#line 9390 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_AGGREGATE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37797 "gram.c" /* yacc.c:1646 */ - break; - - case 1363: -#line 9398 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_COLLATION; - n->object = (Node *) (yyvsp[-3].list); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37809 "gram.c" /* yacc.c:1646 */ - break; - - case 1364: -#line 9406 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_CONVERSION; - n->object = (Node *) (yyvsp[-3].list); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37821 "gram.c" /* yacc.c:1646 */ - break; - - case 1365: -#line 9414 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_DATABASE; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37833 "gram.c" /* yacc.c:1646 */ - break; - - case 1366: -#line 9422 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_DOMAIN; - n->object = (Node *) (yyvsp[-3].list); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37845 "gram.c" /* yacc.c:1646 */ - break; - - case 1367: -#line 9430 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_FUNCTION; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37857 "gram.c" /* yacc.c:1646 */ - break; - - case 1368: -#line 9438 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_LANGUAGE; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37869 "gram.c" /* yacc.c:1646 */ - break; - - case 1369: -#line 9446 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_LARGEOBJECT; - n->object = (Node *) (yyvsp[-3].value); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37881 "gram.c" /* yacc.c:1646 */ - break; - - case 1370: -#line 9454 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_OPERATOR; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37893 "gram.c" /* yacc.c:1646 */ - break; - - case 1371: -#line 9462 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_OPCLASS; - n->object = (Node *) lcons(makeString((yyvsp[-3].str)), (yyvsp[-5].list)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37905 "gram.c" /* yacc.c:1646 */ - break; - - case 1372: -#line 9470 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_OPFAMILY; - n->object = (Node *) lcons(makeString((yyvsp[-3].str)), (yyvsp[-5].list)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37917 "gram.c" /* yacc.c:1646 */ - break; - - case 1373: -#line 9478 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_PROCEDURE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37929 "gram.c" /* yacc.c:1646 */ - break; - - case 1374: -#line 9486 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_ROUTINE; - n->object = (Node *) (yyvsp[-3].objwithargs); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37941 "gram.c" /* yacc.c:1646 */ - break; - - case 1375: -#line 9494 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_SCHEMA; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37953 "gram.c" /* yacc.c:1646 */ - break; - - case 1376: -#line 9502 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_TYPE; - n->object = (Node *) (yyvsp[-3].list); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37965 "gram.c" /* yacc.c:1646 */ - break; - - case 1377: -#line 9510 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_TABLESPACE; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37977 "gram.c" /* yacc.c:1646 */ - break; - - case 1378: -#line 9518 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_STATISTIC_EXT; - n->object = (Node *) (yyvsp[-3].list); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 37989 "gram.c" /* yacc.c:1646 */ - break; - - case 1379: -#line 9526 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_TSDICTIONARY; - n->object = (Node *) (yyvsp[-3].list); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 38001 "gram.c" /* yacc.c:1646 */ - break; - - case 1380: -#line 9534 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_TSCONFIGURATION; - n->object = (Node *) (yyvsp[-3].list); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 38013 "gram.c" /* yacc.c:1646 */ - break; - - case 1381: -#line 9542 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_FDW; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 38025 "gram.c" /* yacc.c:1646 */ - break; - - case 1382: -#line 9550 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_FOREIGN_SERVER; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 38037 "gram.c" /* yacc.c:1646 */ - break; - - case 1383: -#line 9558 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_EVENT_TRIGGER; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 38049 "gram.c" /* yacc.c:1646 */ - break; - - case 1384: -#line 9566 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_PUBLICATION; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 38061 "gram.c" /* yacc.c:1646 */ - break; - - case 1385: -#line 9574 "gram.y" /* yacc.c:1646 */ - { - AlterOwnerStmt *n = makeNode(AlterOwnerStmt); - n->objectType = OBJECT_SUBSCRIPTION; - n->object = (Node *) makeString((yyvsp[-3].str)); - n->newowner = (yyvsp[0].rolespec); - (yyval.node) = (Node *)n; - } -#line 38073 "gram.c" /* yacc.c:1646 */ - break; - - case 1386: -#line 9592 "gram.y" /* yacc.c:1646 */ - { - CreatePublicationStmt *n = makeNode(CreatePublicationStmt); - n->pubname = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - if ((yyvsp[-1].node) != NULL) - { - /* FOR TABLE */ - if (IsA((yyvsp[-1].node), List)) - n->tables = (List *)(yyvsp[-1].node); - /* FOR ALL TABLES */ - else - n->for_all_tables = true; - } - (yyval.node) = (Node *)n; - } -#line 38093 "gram.c" /* yacc.c:1646 */ - break; - - case 1387: -#line 9610 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 38099 "gram.c" /* yacc.c:1646 */ - break; - - case 1388: -#line 9611 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 38105 "gram.c" /* yacc.c:1646 */ - break; - - case 1389: -#line 9616 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) (yyvsp[0].list); - } -#line 38113 "gram.c" /* yacc.c:1646 */ - break; - - case 1390: -#line 9620 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeInteger(true); - } -#line 38121 "gram.c" /* yacc.c:1646 */ - break; - - case 1391: -#line 9640 "gram.y" /* yacc.c:1646 */ - { - AlterPublicationStmt *n = makeNode(AlterPublicationStmt); - n->pubname = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38132 "gram.c" /* yacc.c:1646 */ - break; - - case 1392: -#line 9647 "gram.y" /* yacc.c:1646 */ - { - AlterPublicationStmt *n = makeNode(AlterPublicationStmt); - n->pubname = (yyvsp[-3].str); - n->tables = (yyvsp[0].list); - n->tableAction = DEFELEM_ADD; - (yyval.node) = (Node *)n; - } -#line 38144 "gram.c" /* yacc.c:1646 */ - break; - - case 1393: -#line 9655 "gram.y" /* yacc.c:1646 */ - { - AlterPublicationStmt *n = makeNode(AlterPublicationStmt); - n->pubname = (yyvsp[-3].str); - n->tables = (yyvsp[0].list); - n->tableAction = DEFELEM_SET; - (yyval.node) = (Node *)n; - } -#line 38156 "gram.c" /* yacc.c:1646 */ - break; - - case 1394: -#line 9663 "gram.y" /* yacc.c:1646 */ - { - AlterPublicationStmt *n = makeNode(AlterPublicationStmt); - n->pubname = (yyvsp[-3].str); - n->tables = (yyvsp[0].list); - n->tableAction = DEFELEM_DROP; - (yyval.node) = (Node *)n; - } -#line 38168 "gram.c" /* yacc.c:1646 */ - break; - - case 1395: -#line 9680 "gram.y" /* yacc.c:1646 */ - { - CreateSubscriptionStmt *n = - makeNode(CreateSubscriptionStmt); - n->subname = (yyvsp[-5].str); - n->conninfo = (yyvsp[-3].str); - n->publication = (yyvsp[-1].list); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38182 "gram.c" /* yacc.c:1646 */ - break; - - case 1396: -#line 9693 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].value)); - } -#line 38190 "gram.c" /* yacc.c:1646 */ - break; - - case 1397: -#line 9697 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].value)); - } -#line 38198 "gram.c" /* yacc.c:1646 */ - break; - - case 1398: -#line 9703 "gram.y" /* yacc.c:1646 */ - { (yyval.value) = makeString((yyvsp[0].str)); } -#line 38204 "gram.c" /* yacc.c:1646 */ - break; - - case 1399: -#line 9713 "gram.y" /* yacc.c:1646 */ - { - AlterSubscriptionStmt *n = - makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_OPTIONS; - n->subname = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38217 "gram.c" /* yacc.c:1646 */ - break; - - case 1400: -#line 9722 "gram.y" /* yacc.c:1646 */ - { - AlterSubscriptionStmt *n = - makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_CONNECTION; - n->subname = (yyvsp[-2].str); - n->conninfo = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38230 "gram.c" /* yacc.c:1646 */ - break; - - case 1401: -#line 9731 "gram.y" /* yacc.c:1646 */ - { - AlterSubscriptionStmt *n = - makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_REFRESH; - n->subname = (yyvsp[-3].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38243 "gram.c" /* yacc.c:1646 */ - break; - - case 1402: -#line 9740 "gram.y" /* yacc.c:1646 */ - { - AlterSubscriptionStmt *n = - makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_PUBLICATION; - n->subname = (yyvsp[-4].str); - n->publication = (yyvsp[-1].list); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38257 "gram.c" /* yacc.c:1646 */ - break; - - case 1403: -#line 9750 "gram.y" /* yacc.c:1646 */ - { - AlterSubscriptionStmt *n = - makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_ENABLED; - n->subname = (yyvsp[-1].str); - n->options = list_make1(makeDefElem("enabled", - (Node *)makeInteger(true), (yylsp[-3]))); - (yyval.node) = (Node *)n; - } -#line 38271 "gram.c" /* yacc.c:1646 */ - break; - - case 1404: -#line 9760 "gram.y" /* yacc.c:1646 */ - { - AlterSubscriptionStmt *n = - makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_ENABLED; - n->subname = (yyvsp[-1].str); - n->options = list_make1(makeDefElem("enabled", - (Node *)makeInteger(false), (yylsp[-3]))); - (yyval.node) = (Node *)n; - } -#line 38285 "gram.c" /* yacc.c:1646 */ - break; - - case 1405: -#line 9778 "gram.y" /* yacc.c:1646 */ - { - DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt); - n->subname = (yyvsp[-1].str); - n->missing_ok = false; - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *) n; - } -#line 38297 "gram.c" /* yacc.c:1646 */ - break; - - case 1406: -#line 9786 "gram.y" /* yacc.c:1646 */ - { - DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt); - n->subname = (yyvsp[-1].str); - n->missing_ok = true; - n->behavior = (yyvsp[0].dbehavior); - (yyval.node) = (Node *) n; - } -#line 38309 "gram.c" /* yacc.c:1646 */ - break; - - case 1407: -#line 9804 "gram.y" /* yacc.c:1646 */ - { - RuleStmt *n = makeNode(RuleStmt); - n->replace = (yyvsp[-11].boolean); - n->relation = (yyvsp[-4].range); - n->rulename = (yyvsp[-9].str); - n->whereClause = (yyvsp[-3].node); - n->event = (yyvsp[-6].ival); - n->instead = (yyvsp[-1].boolean); - n->actions = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38325 "gram.c" /* yacc.c:1646 */ - break; - - case 1408: -#line 9818 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 38331 "gram.c" /* yacc.c:1646 */ - break; - - case 1409: -#line 9819 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 38337 "gram.c" /* yacc.c:1646 */ - break; - - case 1410: -#line 9820 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 38343 "gram.c" /* yacc.c:1646 */ - break; - - case 1411: -#line 9826 "gram.y" /* yacc.c:1646 */ - { if ((yyvsp[0].node) != NULL) - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); - else - (yyval.list) = (yyvsp[-2].list); - } -#line 38353 "gram.c" /* yacc.c:1646 */ - break; - - case 1412: -#line 9832 "gram.y" /* yacc.c:1646 */ - { if ((yyvsp[0].node) != NULL) - (yyval.list) = list_make1((yyvsp[0].node)); - else - (yyval.list) = NIL; - } -#line 38363 "gram.c" /* yacc.c:1646 */ - break; - - case 1418: -#line 9848 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 38369 "gram.c" /* yacc.c:1646 */ - break; - - case 1419: -#line 9849 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 38375 "gram.c" /* yacc.c:1646 */ - break; - - case 1420: -#line 9852 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CMD_SELECT; } -#line 38381 "gram.c" /* yacc.c:1646 */ - break; - - case 1421: -#line 9853 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CMD_UPDATE; } -#line 38387 "gram.c" /* yacc.c:1646 */ - break; - - case 1422: -#line 9854 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CMD_DELETE; } -#line 38393 "gram.c" /* yacc.c:1646 */ - break; - - case 1423: -#line 9855 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CMD_INSERT; } -#line 38399 "gram.c" /* yacc.c:1646 */ - break; - - case 1424: -#line 9859 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 38405 "gram.c" /* yacc.c:1646 */ - break; - - case 1425: -#line 9860 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 38411 "gram.c" /* yacc.c:1646 */ - break; - - case 1426: -#line 9861 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 38417 "gram.c" /* yacc.c:1646 */ - break; - - case 1427: -#line 9874 "gram.y" /* yacc.c:1646 */ - { - NotifyStmt *n = makeNode(NotifyStmt); - n->conditionname = (yyvsp[-1].str); - n->payload = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38428 "gram.c" /* yacc.c:1646 */ - break; - - case 1428: -#line 9883 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 38434 "gram.c" /* yacc.c:1646 */ - break; - - case 1429: -#line 9884 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 38440 "gram.c" /* yacc.c:1646 */ - break; - - case 1430: -#line 9888 "gram.y" /* yacc.c:1646 */ - { - ListenStmt *n = makeNode(ListenStmt); - n->conditionname = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38450 "gram.c" /* yacc.c:1646 */ - break; - - case 1431: -#line 9897 "gram.y" /* yacc.c:1646 */ - { - UnlistenStmt *n = makeNode(UnlistenStmt); - n->conditionname = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38460 "gram.c" /* yacc.c:1646 */ - break; - - case 1432: -#line 9903 "gram.y" /* yacc.c:1646 */ - { - UnlistenStmt *n = makeNode(UnlistenStmt); - n->conditionname = NULL; - (yyval.node) = (Node *)n; - } -#line 38470 "gram.c" /* yacc.c:1646 */ - break; - - case 1433: -#line 9922 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_ROLLBACK; - n->options = NIL; - (yyval.node) = (Node *)n; - } -#line 38481 "gram.c" /* yacc.c:1646 */ - break; - - case 1434: -#line 9929 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_BEGIN; - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38492 "gram.c" /* yacc.c:1646 */ - break; - - case 1435: -#line 9936 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_START; - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38503 "gram.c" /* yacc.c:1646 */ - break; - - case 1436: -#line 9943 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_COMMIT; - n->options = NIL; - (yyval.node) = (Node *)n; - } -#line 38514 "gram.c" /* yacc.c:1646 */ - break; - - case 1437: -#line 9950 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_COMMIT; - n->options = NIL; - (yyval.node) = (Node *)n; - } -#line 38525 "gram.c" /* yacc.c:1646 */ - break; - - case 1438: -#line 9957 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_ROLLBACK; - n->options = NIL; - (yyval.node) = (Node *)n; - } -#line 38536 "gram.c" /* yacc.c:1646 */ - break; - - case 1439: -#line 9964 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_SAVEPOINT; - n->savepoint_name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38547 "gram.c" /* yacc.c:1646 */ - break; - - case 1440: -#line 9971 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_RELEASE; - n->savepoint_name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38558 "gram.c" /* yacc.c:1646 */ - break; - - case 1441: -#line 9978 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_RELEASE; - n->savepoint_name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38569 "gram.c" /* yacc.c:1646 */ - break; - - case 1442: -#line 9985 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_ROLLBACK_TO; - n->savepoint_name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38580 "gram.c" /* yacc.c:1646 */ - break; - - case 1443: -#line 9992 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_ROLLBACK_TO; - n->savepoint_name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38591 "gram.c" /* yacc.c:1646 */ - break; - - case 1444: -#line 9999 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_PREPARE; - n->gid = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38602 "gram.c" /* yacc.c:1646 */ - break; - - case 1445: -#line 10006 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_COMMIT_PREPARED; - n->gid = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38613 "gram.c" /* yacc.c:1646 */ - break; - - case 1446: -#line 10013 "gram.y" /* yacc.c:1646 */ - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_ROLLBACK_PREPARED; - n->gid = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38624 "gram.c" /* yacc.c:1646 */ - break; - - case 1447: -#line 10021 "gram.y" /* yacc.c:1646 */ - {} -#line 38630 "gram.c" /* yacc.c:1646 */ - break; - - case 1448: -#line 10022 "gram.y" /* yacc.c:1646 */ - {} -#line 38636 "gram.c" /* yacc.c:1646 */ - break; - - case 1449: -#line 10023 "gram.y" /* yacc.c:1646 */ - {} -#line 38642 "gram.c" /* yacc.c:1646 */ - break; - - case 1450: -#line 10028 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("transaction_isolation", - makeStringConst((yyvsp[0].str), (yylsp[0])), (yylsp[-2])); } -#line 38649 "gram.c" /* yacc.c:1646 */ - break; - - case 1451: -#line 10031 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("transaction_read_only", - makeIntConst(true, (yylsp[-1])), (yylsp[-1])); } -#line 38656 "gram.c" /* yacc.c:1646 */ - break; - - case 1452: -#line 10034 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("transaction_read_only", - makeIntConst(false, (yylsp[-1])), (yylsp[-1])); } -#line 38663 "gram.c" /* yacc.c:1646 */ - break; - - case 1453: -#line 10037 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("transaction_deferrable", - makeIntConst(true, (yylsp[0])), (yylsp[0])); } -#line 38670 "gram.c" /* yacc.c:1646 */ - break; - - case 1454: -#line 10040 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("transaction_deferrable", - makeIntConst(false, (yylsp[-1])), (yylsp[-1])); } -#line 38677 "gram.c" /* yacc.c:1646 */ - break; - - case 1455: -#line 10047 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 38683 "gram.c" /* yacc.c:1646 */ - break; - - case 1456: -#line 10049 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); } -#line 38689 "gram.c" /* yacc.c:1646 */ - break; - - case 1457: -#line 10051 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 38695 "gram.c" /* yacc.c:1646 */ - break; - - case 1459: -#line 10057 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 38701 "gram.c" /* yacc.c:1646 */ - break; - - case 1460: -#line 10071 "gram.y" /* yacc.c:1646 */ - { - ViewStmt *n = makeNode(ViewStmt); - n->view = (yyvsp[-5].range); - n->view->relpersistence = (yyvsp[-7].ival); - n->aliases = (yyvsp[-4].list); - n->query = (yyvsp[-1].node); - n->replace = false; - n->options = (yyvsp[-3].list); - n->withCheckOption = (yyvsp[0].ival); - (yyval.node) = (Node *) n; - } -#line 38717 "gram.c" /* yacc.c:1646 */ - break; - - case 1461: -#line 10084 "gram.y" /* yacc.c:1646 */ - { - ViewStmt *n = makeNode(ViewStmt); - n->view = (yyvsp[-5].range); - n->view->relpersistence = (yyvsp[-7].ival); - n->aliases = (yyvsp[-4].list); - n->query = (yyvsp[-1].node); - n->replace = true; - n->options = (yyvsp[-3].list); - n->withCheckOption = (yyvsp[0].ival); - (yyval.node) = (Node *) n; - } -#line 38733 "gram.c" /* yacc.c:1646 */ - break; - - case 1462: -#line 10097 "gram.y" /* yacc.c:1646 */ - { - ViewStmt *n = makeNode(ViewStmt); - n->view = (yyvsp[-7].range); - n->view->relpersistence = (yyvsp[-10].ival); - n->aliases = (yyvsp[-5].list); - n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, (yyvsp[-1].node)); - n->replace = false; - n->options = (yyvsp[-3].list); - n->withCheckOption = (yyvsp[0].ival); - if (n->withCheckOption != NO_CHECK_OPTION) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("WITH CHECK OPTION not supported on recursive views"), - parser_errposition((yylsp[0])))); - (yyval.node) = (Node *) n; - } -#line 38754 "gram.c" /* yacc.c:1646 */ - break; - - case 1463: -#line 10115 "gram.y" /* yacc.c:1646 */ - { - ViewStmt *n = makeNode(ViewStmt); - n->view = (yyvsp[-7].range); - n->view->relpersistence = (yyvsp[-10].ival); - n->aliases = (yyvsp[-5].list); - n->query = makeRecursiveViewSelect(n->view->relname, n->aliases, (yyvsp[-1].node)); - n->replace = true; - n->options = (yyvsp[-3].list); - n->withCheckOption = (yyvsp[0].ival); - if (n->withCheckOption != NO_CHECK_OPTION) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("WITH CHECK OPTION not supported on recursive views"), - parser_errposition((yylsp[0])))); - (yyval.node) = (Node *) n; - } -#line 38775 "gram.c" /* yacc.c:1646 */ - break; - - case 1464: -#line 10134 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CASCADED_CHECK_OPTION; } -#line 38781 "gram.c" /* yacc.c:1646 */ - break; - - case 1465: -#line 10135 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CASCADED_CHECK_OPTION; } -#line 38787 "gram.c" /* yacc.c:1646 */ - break; - - case 1466: -#line 10136 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LOCAL_CHECK_OPTION; } -#line 38793 "gram.c" /* yacc.c:1646 */ - break; - - case 1467: -#line 10137 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = NO_CHECK_OPTION; } -#line 38799 "gram.c" /* yacc.c:1646 */ - break; - - case 1468: -#line 10148 "gram.y" /* yacc.c:1646 */ - { - LoadStmt *n = makeNode(LoadStmt); - n->filename = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 38809 "gram.c" /* yacc.c:1646 */ - break; - - case 1469: -#line 10164 "gram.y" /* yacc.c:1646 */ - { - CreatedbStmt *n = makeNode(CreatedbStmt); - n->dbname = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38820 "gram.c" /* yacc.c:1646 */ - break; - - case 1470: -#line 10173 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 38826 "gram.c" /* yacc.c:1646 */ - break; - - case 1471: -#line 10174 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 38832 "gram.c" /* yacc.c:1646 */ - break; - - case 1472: -#line 10178 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 38838 "gram.c" /* yacc.c:1646 */ - break; - - case 1473: -#line 10179 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 38844 "gram.c" /* yacc.c:1646 */ - break; - - case 1474: -#line 10184 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-2].str), (Node *)makeInteger((yyvsp[0].ival)), (yylsp[-2])); - } -#line 38852 "gram.c" /* yacc.c:1646 */ - break; - - case 1475: -#line 10188 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-2].str), (Node *)makeString((yyvsp[0].str)), (yylsp[-2])); - } -#line 38860 "gram.c" /* yacc.c:1646 */ - break; - - case 1476: -#line 10192 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-2].str), NULL, (yylsp[-2])); - } -#line 38868 "gram.c" /* yacc.c:1646 */ - break; - - case 1477: -#line 10209 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 38874 "gram.c" /* yacc.c:1646 */ - break; - - case 1478: -#line 10210 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup("connection_limit"); } -#line 38880 "gram.c" /* yacc.c:1646 */ - break; - - case 1479: -#line 10211 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 38886 "gram.c" /* yacc.c:1646 */ - break; - - case 1480: -#line 10212 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 38892 "gram.c" /* yacc.c:1646 */ - break; - - case 1481: -#line 10213 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 38898 "gram.c" /* yacc.c:1646 */ - break; - - case 1482: -#line 10214 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 38904 "gram.c" /* yacc.c:1646 */ - break; - - case 1483: -#line 10215 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 38910 "gram.c" /* yacc.c:1646 */ - break; - - case 1484: -#line 10222 "gram.y" /* yacc.c:1646 */ - {} -#line 38916 "gram.c" /* yacc.c:1646 */ - break; - - case 1485: -#line 10223 "gram.y" /* yacc.c:1646 */ - {} -#line 38922 "gram.c" /* yacc.c:1646 */ - break; - - case 1486: -#line 10235 "gram.y" /* yacc.c:1646 */ - { - AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt); - n->dbname = (yyvsp[-2].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38933 "gram.c" /* yacc.c:1646 */ - break; - - case 1487: -#line 10242 "gram.y" /* yacc.c:1646 */ - { - AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt); - n->dbname = (yyvsp[-1].str); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 38944 "gram.c" /* yacc.c:1646 */ - break; - - case 1488: -#line 10249 "gram.y" /* yacc.c:1646 */ - { - AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt); - n->dbname = (yyvsp[-3].str); - n->options = list_make1(makeDefElem("tablespace", - (Node *)makeString((yyvsp[0].str)), (yylsp[0]))); - (yyval.node) = (Node *)n; - } -#line 38956 "gram.c" /* yacc.c:1646 */ - break; - - case 1489: -#line 10260 "gram.y" /* yacc.c:1646 */ - { - AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt); - n->dbname = (yyvsp[-1].str); - n->setstmt = (yyvsp[0].vsetstmt); - (yyval.node) = (Node *)n; - } -#line 38967 "gram.c" /* yacc.c:1646 */ - break; - - case 1490: -#line 10277 "gram.y" /* yacc.c:1646 */ - { - DropdbStmt *n = makeNode(DropdbStmt); - n->dbname = (yyvsp[0].str); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 38978 "gram.c" /* yacc.c:1646 */ - break; - - case 1491: -#line 10284 "gram.y" /* yacc.c:1646 */ - { - DropdbStmt *n = makeNode(DropdbStmt); - n->dbname = (yyvsp[0].str); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 38989 "gram.c" /* yacc.c:1646 */ - break; - - case 1492: -#line 10300 "gram.y" /* yacc.c:1646 */ - { - AlterCollationStmt *n = makeNode(AlterCollationStmt); - n->collname = (yyvsp[-2].list); - (yyval.node) = (Node *)n; - } -#line 38999 "gram.c" /* yacc.c:1646 */ - break; - - case 1493: -#line 10317 "gram.y" /* yacc.c:1646 */ - { - AlterSystemStmt *n = makeNode(AlterSystemStmt); - n->setstmt = (yyvsp[0].vsetstmt); - (yyval.node) = (Node *)n; - } -#line 39009 "gram.c" /* yacc.c:1646 */ - break; - - case 1494: -#line 10323 "gram.y" /* yacc.c:1646 */ - { - AlterSystemStmt *n = makeNode(AlterSystemStmt); - n->setstmt = (yyvsp[0].vsetstmt); - (yyval.node) = (Node *)n; - } -#line 39019 "gram.c" /* yacc.c:1646 */ - break; - - case 1495: -#line 10339 "gram.y" /* yacc.c:1646 */ - { - CreateDomainStmt *n = makeNode(CreateDomainStmt); - n->domainname = (yyvsp[-3].list); - n->typeName = (yyvsp[-1].typnam); - SplitColQualList((yyvsp[0].list), &n->constraints, &n->collClause, - yyscanner); - (yyval.node) = (Node *)n; - } -#line 39032 "gram.c" /* yacc.c:1646 */ - break; - - case 1496: -#line 10352 "gram.y" /* yacc.c:1646 */ - { - AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'T'; - n->typeName = (yyvsp[-1].list); - n->def = (yyvsp[0].node); - (yyval.node) = (Node *)n; - } -#line 39044 "gram.c" /* yacc.c:1646 */ - break; - - case 1497: -#line 10361 "gram.y" /* yacc.c:1646 */ - { - AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'N'; - n->typeName = (yyvsp[-3].list); - (yyval.node) = (Node *)n; - } -#line 39055 "gram.c" /* yacc.c:1646 */ - break; - - case 1498: -#line 10369 "gram.y" /* yacc.c:1646 */ - { - AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'O'; - n->typeName = (yyvsp[-3].list); - (yyval.node) = (Node *)n; - } -#line 39066 "gram.c" /* yacc.c:1646 */ - break; - - case 1499: -#line 10377 "gram.y" /* yacc.c:1646 */ - { - AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'C'; - n->typeName = (yyvsp[-2].list); - n->def = (yyvsp[0].node); - (yyval.node) = (Node *)n; - } -#line 39078 "gram.c" /* yacc.c:1646 */ - break; - - case 1500: -#line 10386 "gram.y" /* yacc.c:1646 */ - { - AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; - n->typeName = (yyvsp[-4].list); - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = false; - (yyval.node) = (Node *)n; - } -#line 39092 "gram.c" /* yacc.c:1646 */ - break; - - case 1501: -#line 10397 "gram.y" /* yacc.c:1646 */ - { - AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'X'; - n->typeName = (yyvsp[-6].list); - n->name = (yyvsp[-1].str); - n->behavior = (yyvsp[0].dbehavior); - n->missing_ok = true; - (yyval.node) = (Node *)n; - } -#line 39106 "gram.c" /* yacc.c:1646 */ - break; - - case 1502: -#line 10408 "gram.y" /* yacc.c:1646 */ - { - AlterDomainStmt *n = makeNode(AlterDomainStmt); - n->subtype = 'V'; - n->typeName = (yyvsp[-3].list); - n->name = (yyvsp[0].str); - (yyval.node) = (Node *)n; - } -#line 39118 "gram.c" /* yacc.c:1646 */ - break; - - case 1503: -#line 10417 "gram.y" /* yacc.c:1646 */ - {} -#line 39124 "gram.c" /* yacc.c:1646 */ - break; - - case 1504: -#line 10418 "gram.y" /* yacc.c:1646 */ - {} -#line 39130 "gram.c" /* yacc.c:1646 */ - break; - - case 1505: -#line 10430 "gram.y" /* yacc.c:1646 */ - { - AlterTSDictionaryStmt *n = makeNode(AlterTSDictionaryStmt); - n->dictname = (yyvsp[-1].list); - n->options = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 39141 "gram.c" /* yacc.c:1646 */ - break; - - case 1506: -#line 10440 "gram.y" /* yacc.c:1646 */ - { - AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); - n->kind = ALTER_TSCONFIG_ADD_MAPPING; - n->cfgname = (yyvsp[-6].list); - n->tokentype = (yyvsp[-2].list); - n->dicts = (yyvsp[0].list); - n->override = false; - n->replace = false; - (yyval.node) = (Node*)n; - } -#line 39156 "gram.c" /* yacc.c:1646 */ - break; - - case 1507: -#line 10451 "gram.y" /* yacc.c:1646 */ - { - AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); - n->kind = ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN; - n->cfgname = (yyvsp[-6].list); - n->tokentype = (yyvsp[-2].list); - n->dicts = (yyvsp[0].list); - n->override = true; - n->replace = false; - (yyval.node) = (Node*)n; - } -#line 39171 "gram.c" /* yacc.c:1646 */ - break; - - case 1508: -#line 10462 "gram.y" /* yacc.c:1646 */ - { - AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); - n->kind = ALTER_TSCONFIG_REPLACE_DICT; - n->cfgname = (yyvsp[-6].list); - n->tokentype = NIL; - n->dicts = list_make2((yyvsp[-2].list),(yyvsp[0].list)); - n->override = false; - n->replace = true; - (yyval.node) = (Node*)n; - } -#line 39186 "gram.c" /* yacc.c:1646 */ - break; - - case 1509: -#line 10473 "gram.y" /* yacc.c:1646 */ - { - AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); - n->kind = ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN; - n->cfgname = (yyvsp[-8].list); - n->tokentype = (yyvsp[-4].list); - n->dicts = list_make2((yyvsp[-2].list),(yyvsp[0].list)); - n->override = false; - n->replace = true; - (yyval.node) = (Node*)n; - } -#line 39201 "gram.c" /* yacc.c:1646 */ - break; - - case 1510: -#line 10484 "gram.y" /* yacc.c:1646 */ - { - AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); - n->kind = ALTER_TSCONFIG_DROP_MAPPING; - n->cfgname = (yyvsp[-4].list); - n->tokentype = (yyvsp[0].list); - n->missing_ok = false; - (yyval.node) = (Node*)n; - } -#line 39214 "gram.c" /* yacc.c:1646 */ - break; - - case 1511: -#line 10493 "gram.y" /* yacc.c:1646 */ - { - AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); - n->kind = ALTER_TSCONFIG_DROP_MAPPING; - n->cfgname = (yyvsp[-6].list); - n->tokentype = (yyvsp[0].list); - n->missing_ok = true; - (yyval.node) = (Node*)n; - } -#line 39227 "gram.c" /* yacc.c:1646 */ - break; - - case 1512: -#line 10504 "gram.y" /* yacc.c:1646 */ - {} -#line 39233 "gram.c" /* yacc.c:1646 */ - break; - - case 1513: -#line 10505 "gram.y" /* yacc.c:1646 */ - {} -#line 39239 "gram.c" /* yacc.c:1646 */ - break; - - case 1514: -#line 10521 "gram.y" /* yacc.c:1646 */ - { - CreateConversionStmt *n = makeNode(CreateConversionStmt); - n->conversion_name = (yyvsp[-6].list); - n->for_encoding_name = (yyvsp[-4].str); - n->to_encoding_name = (yyvsp[-2].str); - n->func_name = (yyvsp[0].list); - n->def = (yyvsp[-8].boolean); - (yyval.node) = (Node *)n; - } -#line 39253 "gram.c" /* yacc.c:1646 */ - break; - - case 1515: -#line 10543 "gram.y" /* yacc.c:1646 */ - { - ClusterStmt *n = makeNode(ClusterStmt); - n->relation = (yyvsp[-1].range); - n->indexname = (yyvsp[0].str); - n->verbose = (yyvsp[-2].boolean); - (yyval.node) = (Node*)n; - } -#line 39265 "gram.c" /* yacc.c:1646 */ - break; - - case 1516: -#line 10551 "gram.y" /* yacc.c:1646 */ - { - ClusterStmt *n = makeNode(ClusterStmt); - n->relation = NULL; - n->indexname = NULL; - n->verbose = (yyvsp[0].boolean); - (yyval.node) = (Node*)n; - } -#line 39277 "gram.c" /* yacc.c:1646 */ - break; - - case 1517: -#line 10560 "gram.y" /* yacc.c:1646 */ - { - ClusterStmt *n = makeNode(ClusterStmt); - n->relation = (yyvsp[0].range); - n->indexname = (yyvsp[-2].str); - n->verbose = (yyvsp[-3].boolean); - (yyval.node) = (Node*)n; - } -#line 39289 "gram.c" /* yacc.c:1646 */ - break; - - case 1518: -#line 10570 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 39295 "gram.c" /* yacc.c:1646 */ - break; - - case 1519: -#line 10571 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 39301 "gram.c" /* yacc.c:1646 */ - break; - - case 1520: -#line 10584 "gram.y" /* yacc.c:1646 */ - { - VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_VACUUM; - if ((yyvsp[-4].boolean)) - n->options |= VACOPT_FULL; - if ((yyvsp[-3].boolean)) - n->options |= VACOPT_FREEZE; - if ((yyvsp[-2].boolean)) - n->options |= VACOPT_VERBOSE; - if ((yyvsp[-1].boolean)) - n->options |= VACOPT_ANALYZE; - n->rels = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 39320 "gram.c" /* yacc.c:1646 */ - break; - - case 1521: -#line 10599 "gram.y" /* yacc.c:1646 */ - { - VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_VACUUM | (yyvsp[-2].ival); - n->rels = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 39331 "gram.c" /* yacc.c:1646 */ - break; - - case 1522: -#line 10608 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 39337 "gram.c" /* yacc.c:1646 */ - break; - - case 1523: -#line 10609 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-2].ival) | (yyvsp[0].ival); } -#line 39343 "gram.c" /* yacc.c:1646 */ - break; - - case 1524: -#line 10613 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = VACOPT_ANALYZE; } -#line 39349 "gram.c" /* yacc.c:1646 */ - break; - - case 1525: -#line 10614 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = VACOPT_VERBOSE; } -#line 39355 "gram.c" /* yacc.c:1646 */ - break; - - case 1526: -#line 10615 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = VACOPT_FREEZE; } -#line 39361 "gram.c" /* yacc.c:1646 */ - break; - - case 1527: -#line 10616 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = VACOPT_FULL; } -#line 39367 "gram.c" /* yacc.c:1646 */ - break; - - case 1528: -#line 10618 "gram.y" /* yacc.c:1646 */ - { - if (strcmp((yyvsp[0].str), "disable_page_skipping") == 0) - (yyval.ival) = VACOPT_DISABLE_PAGE_SKIPPING; - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized VACUUM option \"%s\"", (yyvsp[0].str)), - parser_errposition((yylsp[0])))); - } -#line 39381 "gram.c" /* yacc.c:1646 */ - break; - - case 1529: -#line 10630 "gram.y" /* yacc.c:1646 */ - { - VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_ANALYZE; - if ((yyvsp[-1].boolean)) - n->options |= VACOPT_VERBOSE; - n->rels = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 39394 "gram.c" /* yacc.c:1646 */ - break; - - case 1530: -#line 10639 "gram.y" /* yacc.c:1646 */ - { - VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_ANALYZE | (yyvsp[-2].ival); - n->rels = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 39405 "gram.c" /* yacc.c:1646 */ - break; - - case 1531: -#line 10648 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 39411 "gram.c" /* yacc.c:1646 */ - break; - - case 1532: -#line 10649 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-2].ival) | (yyvsp[0].ival); } -#line 39417 "gram.c" /* yacc.c:1646 */ - break; - - case 1533: -#line 10653 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = VACOPT_VERBOSE; } -#line 39423 "gram.c" /* yacc.c:1646 */ - break; - - case 1534: -#line 10657 "gram.y" /* yacc.c:1646 */ - {} -#line 39429 "gram.c" /* yacc.c:1646 */ - break; - - case 1535: -#line 10658 "gram.y" /* yacc.c:1646 */ - {} -#line 39435 "gram.c" /* yacc.c:1646 */ - break; - - case 1536: -#line 10662 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 39441 "gram.c" /* yacc.c:1646 */ - break; - - case 1537: -#line 10663 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 39447 "gram.c" /* yacc.c:1646 */ - break; - - case 1538: -#line 10667 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 39453 "gram.c" /* yacc.c:1646 */ - break; - - case 1539: -#line 10668 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 39459 "gram.c" /* yacc.c:1646 */ - break; - - case 1540: -#line 10671 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 39465 "gram.c" /* yacc.c:1646 */ - break; - - case 1541: -#line 10672 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 39471 "gram.c" /* yacc.c:1646 */ - break; - - case 1542: -#line 10675 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 39477 "gram.c" /* yacc.c:1646 */ - break; - - case 1543: -#line 10676 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 39483 "gram.c" /* yacc.c:1646 */ - break; - - case 1544: -#line 10680 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 39489 "gram.c" /* yacc.c:1646 */ - break; - - case 1545: -#line 10681 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 39495 "gram.c" /* yacc.c:1646 */ - break; - - case 1546: -#line 10686 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeVacuumRelation((yyvsp[-1].range), InvalidOid, (yyvsp[0].list)); - } -#line 39503 "gram.c" /* yacc.c:1646 */ - break; - - case 1547: -#line 10693 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 39509 "gram.c" /* yacc.c:1646 */ - break; - - case 1548: -#line 10695 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 39515 "gram.c" /* yacc.c:1646 */ - break; - - case 1549: -#line 10699 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 39521 "gram.c" /* yacc.c:1646 */ - break; - - case 1550: -#line 10700 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 39527 "gram.c" /* yacc.c:1646 */ - break; - - case 1551: -#line 10714 "gram.y" /* yacc.c:1646 */ - { - ExplainStmt *n = makeNode(ExplainStmt); - n->query = (yyvsp[0].node); - n->options = NIL; - (yyval.node) = (Node *) n; - } -#line 39538 "gram.c" /* yacc.c:1646 */ - break; - - case 1552: -#line 10721 "gram.y" /* yacc.c:1646 */ - { - ExplainStmt *n = makeNode(ExplainStmt); - n->query = (yyvsp[0].node); - n->options = list_make1(makeDefElem("analyze", NULL, (yylsp[-2]))); - if ((yyvsp[-1].boolean)) - n->options = lappend(n->options, - makeDefElem("verbose", NULL, (yylsp[-1]))); - (yyval.node) = (Node *) n; - } -#line 39552 "gram.c" /* yacc.c:1646 */ - break; - - case 1553: -#line 10731 "gram.y" /* yacc.c:1646 */ - { - ExplainStmt *n = makeNode(ExplainStmt); - n->query = (yyvsp[0].node); - n->options = list_make1(makeDefElem("verbose", NULL, (yylsp[-1]))); - (yyval.node) = (Node *) n; - } -#line 39563 "gram.c" /* yacc.c:1646 */ - break; - - case 1554: -#line 10738 "gram.y" /* yacc.c:1646 */ - { - ExplainStmt *n = makeNode(ExplainStmt); - n->query = (yyvsp[0].node); - n->options = (yyvsp[-2].list); - (yyval.node) = (Node *) n; - } -#line 39574 "gram.c" /* yacc.c:1646 */ - break; - - case 1564: -#line 10760 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].defelt)); - } -#line 39582 "gram.c" /* yacc.c:1646 */ - break; - - case 1565: -#line 10764 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].defelt)); - } -#line 39590 "gram.c" /* yacc.c:1646 */ - break; - - case 1566: -#line 10771 "gram.y" /* yacc.c:1646 */ - { - (yyval.defelt) = makeDefElem((yyvsp[-1].str), (yyvsp[0].node), (yylsp[-1])); - } -#line 39598 "gram.c" /* yacc.c:1646 */ - break; - - case 1567: -#line 10777 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 39604 "gram.c" /* yacc.c:1646 */ - break; - - case 1568: -#line 10778 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "analyze"; } -#line 39610 "gram.c" /* yacc.c:1646 */ - break; - - case 1569: -#line 10782 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeString((yyvsp[0].str)); } -#line 39616 "gram.c" /* yacc.c:1646 */ - break; - - case 1570: -#line 10783 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) (yyvsp[0].value); } -#line 39622 "gram.c" /* yacc.c:1646 */ - break; - - case 1571: -#line 10784 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 39628 "gram.c" /* yacc.c:1646 */ - break; - - case 1572: -#line 10795 "gram.y" /* yacc.c:1646 */ - { - PrepareStmt *n = makeNode(PrepareStmt); - n->name = (yyvsp[-3].str); - n->argtypes = (yyvsp[-2].list); - n->query = (yyvsp[0].node); - (yyval.node) = (Node *) n; - } -#line 39640 "gram.c" /* yacc.c:1646 */ - break; - - case 1573: -#line 10804 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 39646 "gram.c" /* yacc.c:1646 */ - break; - - case 1574: -#line 10805 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 39652 "gram.c" /* yacc.c:1646 */ - break; - - case 1579: -#line 10823 "gram.y" /* yacc.c:1646 */ - { - ExecuteStmt *n = makeNode(ExecuteStmt); - n->name = (yyvsp[-1].str); - n->params = (yyvsp[0].list); - (yyval.node) = (Node *) n; - } -#line 39663 "gram.c" /* yacc.c:1646 */ - break; - - case 1580: -#line 10831 "gram.y" /* yacc.c:1646 */ - { - CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); - ExecuteStmt *n = makeNode(ExecuteStmt); - n->name = (yyvsp[-2].str); - n->params = (yyvsp[-1].list); - ctas->query = (Node *) n; - ctas->into = (yyvsp[-5].into); - ctas->relkind = OBJECT_TABLE; - ctas->is_select_into = false; - /* cram additional flags into the IntoClause */ - (yyvsp[-5].into)->rel->relpersistence = (yyvsp[-7].ival); - (yyvsp[-5].into)->skipData = !((yyvsp[0].boolean)); - (yyval.node) = (Node *) ctas; - } -#line 39682 "gram.c" /* yacc.c:1646 */ - break; - - case 1581: -#line 10847 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 39688 "gram.c" /* yacc.c:1646 */ - break; - - case 1582: -#line 10848 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 39694 "gram.c" /* yacc.c:1646 */ - break; - - case 1583: -#line 10859 "gram.y" /* yacc.c:1646 */ - { - DeallocateStmt *n = makeNode(DeallocateStmt); - n->name = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 39704 "gram.c" /* yacc.c:1646 */ - break; - - case 1584: -#line 10865 "gram.y" /* yacc.c:1646 */ - { - DeallocateStmt *n = makeNode(DeallocateStmt); - n->name = (yyvsp[0].str); - (yyval.node) = (Node *) n; - } -#line 39714 "gram.c" /* yacc.c:1646 */ - break; - - case 1585: -#line 10871 "gram.y" /* yacc.c:1646 */ - { - DeallocateStmt *n = makeNode(DeallocateStmt); - n->name = NULL; - (yyval.node) = (Node *) n; - } -#line 39724 "gram.c" /* yacc.c:1646 */ - break; - - case 1586: -#line 10877 "gram.y" /* yacc.c:1646 */ - { - DeallocateStmt *n = makeNode(DeallocateStmt); - n->name = NULL; - (yyval.node) = (Node *) n; - } -#line 39734 "gram.c" /* yacc.c:1646 */ - break; - - case 1587: -#line 10894 "gram.y" /* yacc.c:1646 */ - { - (yyvsp[-2].istmt)->relation = (yyvsp[-3].range); - (yyvsp[-2].istmt)->onConflictClause = (yyvsp[-1].onconflict); - (yyvsp[-2].istmt)->returningList = (yyvsp[0].list); - (yyvsp[-2].istmt)->withClause = (yyvsp[-6].with); - (yyval.node) = (Node *) (yyvsp[-2].istmt); - } -#line 39746 "gram.c" /* yacc.c:1646 */ - break; - - case 1588: -#line 10911 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - } -#line 39754 "gram.c" /* yacc.c:1646 */ - break; - - case 1589: -#line 10915 "gram.y" /* yacc.c:1646 */ - { - (yyvsp[-2].range)->alias = makeAlias((yyvsp[0].str), NIL); - (yyval.range) = (yyvsp[-2].range); - } -#line 39763 "gram.c" /* yacc.c:1646 */ - break; - - case 1590: -#line 10923 "gram.y" /* yacc.c:1646 */ - { - (yyval.istmt) = makeNode(InsertStmt); - (yyval.istmt)->cols = NIL; - (yyval.istmt)->selectStmt = (yyvsp[0].node); - } -#line 39773 "gram.c" /* yacc.c:1646 */ - break; - - case 1591: -#line 10929 "gram.y" /* yacc.c:1646 */ - { - (yyval.istmt) = makeNode(InsertStmt); - (yyval.istmt)->cols = NIL; - (yyval.istmt)->override = (yyvsp[-2].ival); - (yyval.istmt)->selectStmt = (yyvsp[0].node); - } -#line 39784 "gram.c" /* yacc.c:1646 */ - break; - - case 1592: -#line 10936 "gram.y" /* yacc.c:1646 */ - { - (yyval.istmt) = makeNode(InsertStmt); - (yyval.istmt)->cols = (yyvsp[-2].list); - (yyval.istmt)->selectStmt = (yyvsp[0].node); - } -#line 39794 "gram.c" /* yacc.c:1646 */ - break; - - case 1593: -#line 10942 "gram.y" /* yacc.c:1646 */ - { - (yyval.istmt) = makeNode(InsertStmt); - (yyval.istmt)->cols = (yyvsp[-5].list); - (yyval.istmt)->override = (yyvsp[-2].ival); - (yyval.istmt)->selectStmt = (yyvsp[0].node); - } -#line 39805 "gram.c" /* yacc.c:1646 */ - break; - - case 1594: -#line 10949 "gram.y" /* yacc.c:1646 */ - { - (yyval.istmt) = makeNode(InsertStmt); - (yyval.istmt)->cols = NIL; - (yyval.istmt)->selectStmt = NULL; - } -#line 39815 "gram.c" /* yacc.c:1646 */ - break; - - case 1595: -#line 10957 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OVERRIDING_USER_VALUE; } -#line 39821 "gram.c" /* yacc.c:1646 */ - break; - - case 1596: -#line 10958 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = OVERRIDING_SYSTEM_VALUE; } -#line 39827 "gram.c" /* yacc.c:1646 */ - break; - - case 1597: -#line 10963 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].target)); } -#line 39833 "gram.c" /* yacc.c:1646 */ - break; - - case 1598: -#line 10965 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].target)); } -#line 39839 "gram.c" /* yacc.c:1646 */ - break; - - case 1599: -#line 10970 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = (yyvsp[-1].str); - (yyval.target)->indirection = check_indirection((yyvsp[0].list), yyscanner); - (yyval.target)->val = NULL; - (yyval.target)->location = (yylsp[-1]); - } -#line 39851 "gram.c" /* yacc.c:1646 */ - break; - - case 1600: -#line 10981 "gram.y" /* yacc.c:1646 */ - { - (yyval.onconflict) = makeNode(OnConflictClause); - (yyval.onconflict)->action = ONCONFLICT_UPDATE; - (yyval.onconflict)->infer = (yyvsp[-5].infer); - (yyval.onconflict)->targetList = (yyvsp[-1].list); - (yyval.onconflict)->whereClause = (yyvsp[0].node); - (yyval.onconflict)->location = (yylsp[-7]); - } -#line 39864 "gram.c" /* yacc.c:1646 */ - break; - - case 1601: -#line 10991 "gram.y" /* yacc.c:1646 */ - { - (yyval.onconflict) = makeNode(OnConflictClause); - (yyval.onconflict)->action = ONCONFLICT_NOTHING; - (yyval.onconflict)->infer = (yyvsp[-2].infer); - (yyval.onconflict)->targetList = NIL; - (yyval.onconflict)->whereClause = NULL; - (yyval.onconflict)->location = (yylsp[-4]); - } -#line 39877 "gram.c" /* yacc.c:1646 */ - break; - - case 1602: -#line 11000 "gram.y" /* yacc.c:1646 */ - { - (yyval.onconflict) = NULL; - } -#line 39885 "gram.c" /* yacc.c:1646 */ - break; - - case 1603: -#line 11007 "gram.y" /* yacc.c:1646 */ - { - (yyval.infer) = makeNode(InferClause); - (yyval.infer)->indexElems = (yyvsp[-2].list); - (yyval.infer)->whereClause = (yyvsp[0].node); - (yyval.infer)->conname = NULL; - (yyval.infer)->location = (yylsp[-3]); - } -#line 39897 "gram.c" /* yacc.c:1646 */ - break; - - case 1604: -#line 11016 "gram.y" /* yacc.c:1646 */ - { - (yyval.infer) = makeNode(InferClause); - (yyval.infer)->indexElems = NIL; - (yyval.infer)->whereClause = NULL; - (yyval.infer)->conname = (yyvsp[0].str); - (yyval.infer)->location = (yylsp[-2]); - } -#line 39909 "gram.c" /* yacc.c:1646 */ - break; - - case 1605: -#line 11024 "gram.y" /* yacc.c:1646 */ - { - (yyval.infer) = NULL; - } -#line 39917 "gram.c" /* yacc.c:1646 */ - break; - - case 1606: -#line 11030 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 39923 "gram.c" /* yacc.c:1646 */ - break; - - case 1607: -#line 11031 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 39929 "gram.c" /* yacc.c:1646 */ - break; - - case 1608: -#line 11044 "gram.y" /* yacc.c:1646 */ - { - DeleteStmt *n = makeNode(DeleteStmt); - n->relation = (yyvsp[-3].range); - n->usingClause = (yyvsp[-2].list); - n->whereClause = (yyvsp[-1].node); - n->returningList = (yyvsp[0].list); - n->withClause = (yyvsp[-6].with); - (yyval.node) = (Node *)n; - } -#line 39943 "gram.c" /* yacc.c:1646 */ - break; - - case 1609: -#line 11056 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 39949 "gram.c" /* yacc.c:1646 */ - break; - - case 1610: -#line 11057 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 39955 "gram.c" /* yacc.c:1646 */ - break; - - case 1611: -#line 11069 "gram.y" /* yacc.c:1646 */ - { - LockStmt *n = makeNode(LockStmt); - - n->relations = (yyvsp[-2].list); - n->mode = (yyvsp[-1].ival); - n->nowait = (yyvsp[0].boolean); - (yyval.node) = (Node *)n; - } -#line 39968 "gram.c" /* yacc.c:1646 */ - break; - - case 1612: -#line 11079 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-1].ival); } -#line 39974 "gram.c" /* yacc.c:1646 */ - break; - - case 1613: -#line 11080 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = AccessExclusiveLock; } -#line 39980 "gram.c" /* yacc.c:1646 */ - break; - - case 1614: -#line 11083 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = AccessShareLock; } -#line 39986 "gram.c" /* yacc.c:1646 */ - break; - - case 1615: -#line 11084 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RowShareLock; } -#line 39992 "gram.c" /* yacc.c:1646 */ - break; - - case 1616: -#line 11085 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = RowExclusiveLock; } -#line 39998 "gram.c" /* yacc.c:1646 */ - break; - - case 1617: -#line 11086 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ShareUpdateExclusiveLock; } -#line 40004 "gram.c" /* yacc.c:1646 */ - break; - - case 1618: -#line 11087 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ShareLock; } -#line 40010 "gram.c" /* yacc.c:1646 */ - break; - - case 1619: -#line 11088 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ShareRowExclusiveLock; } -#line 40016 "gram.c" /* yacc.c:1646 */ - break; - - case 1620: -#line 11089 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ExclusiveLock; } -#line 40022 "gram.c" /* yacc.c:1646 */ - break; - - case 1621: -#line 11090 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = AccessExclusiveLock; } -#line 40028 "gram.c" /* yacc.c:1646 */ - break; - - case 1622: -#line 11093 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 40034 "gram.c" /* yacc.c:1646 */ - break; - - case 1623: -#line 11094 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 40040 "gram.c" /* yacc.c:1646 */ - break; - - case 1624: -#line 11098 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LockWaitError; } -#line 40046 "gram.c" /* yacc.c:1646 */ - break; - - case 1625: -#line 11099 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LockWaitSkip; } -#line 40052 "gram.c" /* yacc.c:1646 */ - break; - - case 1626: -#line 11100 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LockWaitBlock; } -#line 40058 "gram.c" /* yacc.c:1646 */ - break; - - case 1627: -#line 11116 "gram.y" /* yacc.c:1646 */ - { - UpdateStmt *n = makeNode(UpdateStmt); - n->relation = (yyvsp[-5].range); - n->targetList = (yyvsp[-3].list); - n->fromClause = (yyvsp[-2].list); - n->whereClause = (yyvsp[-1].node); - n->returningList = (yyvsp[0].list); - n->withClause = (yyvsp[-7].with); - (yyval.node) = (Node *)n; - } -#line 40073 "gram.c" /* yacc.c:1646 */ - break; - - case 1628: -#line 11129 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 40079 "gram.c" /* yacc.c:1646 */ - break; - - case 1629: -#line 11130 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_concat((yyvsp[-2].list),(yyvsp[0].list)); } -#line 40085 "gram.c" /* yacc.c:1646 */ - break; - - case 1630: -#line 11135 "gram.y" /* yacc.c:1646 */ - { - (yyvsp[-2].target)->val = (Node *) (yyvsp[0].node); - (yyval.list) = list_make1((yyvsp[-2].target)); - } -#line 40094 "gram.c" /* yacc.c:1646 */ - break; - - case 1631: -#line 11140 "gram.y" /* yacc.c:1646 */ - { - int ncolumns = list_length((yyvsp[-3].list)); - int i = 1; - ListCell *col_cell; - - /* Create a MultiAssignRef source for each target */ - foreach(col_cell, (yyvsp[-3].list)) - { - ResTarget *res_col = (ResTarget *) lfirst(col_cell); - MultiAssignRef *r = makeNode(MultiAssignRef); - - r->source = (Node *) (yyvsp[0].node); - r->colno = i; - r->ncolumns = ncolumns; - res_col->val = (Node *) r; - i++; - } - - (yyval.list) = (yyvsp[-3].list); - } -#line 40119 "gram.c" /* yacc.c:1646 */ - break; - - case 1632: -#line 11164 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = (yyvsp[-1].str); - (yyval.target)->indirection = check_indirection((yyvsp[0].list), yyscanner); - (yyval.target)->val = NULL; /* upper production sets this */ - (yyval.target)->location = (yylsp[-1]); - } -#line 40131 "gram.c" /* yacc.c:1646 */ - break; - - case 1633: -#line 11174 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].target)); } -#line 40137 "gram.c" /* yacc.c:1646 */ - break; - - case 1634: -#line 11175 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list),(yyvsp[0].target)); } -#line 40143 "gram.c" /* yacc.c:1646 */ - break; - - case 1635: -#line 11186 "gram.y" /* yacc.c:1646 */ - { - DeclareCursorStmt *n = makeNode(DeclareCursorStmt); - n->portalname = (yyvsp[-5].str); - /* currently we always set FAST_PLAN option */ - n->options = (yyvsp[-4].ival) | (yyvsp[-2].ival) | CURSOR_OPT_FAST_PLAN; - n->query = (yyvsp[0].node); - (yyval.node) = (Node *)n; - } -#line 40156 "gram.c" /* yacc.c:1646 */ - break; - - case 1636: -#line 11196 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 40162 "gram.c" /* yacc.c:1646 */ - break; - - case 1637: -#line 11199 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 40168 "gram.c" /* yacc.c:1646 */ - break; - - case 1638: -#line 11200 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-2].ival) | CURSOR_OPT_NO_SCROLL; } -#line 40174 "gram.c" /* yacc.c:1646 */ - break; - - case 1639: -#line 11201 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-1].ival) | CURSOR_OPT_SCROLL; } -#line 40180 "gram.c" /* yacc.c:1646 */ - break; - - case 1640: -#line 11202 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-1].ival) | CURSOR_OPT_BINARY; } -#line 40186 "gram.c" /* yacc.c:1646 */ - break; - - case 1641: -#line 11203 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[-1].ival) | CURSOR_OPT_INSENSITIVE; } -#line 40192 "gram.c" /* yacc.c:1646 */ - break; - - case 1642: -#line 11206 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 40198 "gram.c" /* yacc.c:1646 */ - break; - - case 1643: -#line 11207 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = CURSOR_OPT_HOLD; } -#line 40204 "gram.c" /* yacc.c:1646 */ - break; - - case 1644: -#line 11208 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 40210 "gram.c" /* yacc.c:1646 */ - break; - - case 1647: -#line 11261 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 40216 "gram.c" /* yacc.c:1646 */ - break; - - case 1648: -#line 11262 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 40222 "gram.c" /* yacc.c:1646 */ - break; - - case 1649: -#line 11277 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40228 "gram.c" /* yacc.c:1646 */ - break; - - case 1650: -#line 11279 "gram.y" /* yacc.c:1646 */ - { - insertSelectOptions((SelectStmt *) (yyvsp[-1].node), (yyvsp[0].list), NIL, - NULL, NULL, NULL, - yyscanner); - (yyval.node) = (yyvsp[-1].node); - } -#line 40239 "gram.c" /* yacc.c:1646 */ - break; - - case 1651: -#line 11286 "gram.y" /* yacc.c:1646 */ - { - insertSelectOptions((SelectStmt *) (yyvsp[-3].node), (yyvsp[-2].list), (yyvsp[-1].list), - list_nth((yyvsp[0].list), 0), list_nth((yyvsp[0].list), 1), - NULL, - yyscanner); - (yyval.node) = (yyvsp[-3].node); - } -#line 40251 "gram.c" /* yacc.c:1646 */ - break; - - case 1652: -#line 11294 "gram.y" /* yacc.c:1646 */ - { - insertSelectOptions((SelectStmt *) (yyvsp[-3].node), (yyvsp[-2].list), (yyvsp[0].list), - list_nth((yyvsp[-1].list), 0), list_nth((yyvsp[-1].list), 1), - NULL, - yyscanner); - (yyval.node) = (yyvsp[-3].node); - } -#line 40263 "gram.c" /* yacc.c:1646 */ - break; - - case 1653: -#line 11302 "gram.y" /* yacc.c:1646 */ - { - insertSelectOptions((SelectStmt *) (yyvsp[0].node), NULL, NIL, - NULL, NULL, - (yyvsp[-1].with), - yyscanner); - (yyval.node) = (yyvsp[0].node); - } -#line 40275 "gram.c" /* yacc.c:1646 */ - break; - - case 1654: -#line 11310 "gram.y" /* yacc.c:1646 */ - { - insertSelectOptions((SelectStmt *) (yyvsp[-1].node), (yyvsp[0].list), NIL, - NULL, NULL, - (yyvsp[-2].with), - yyscanner); - (yyval.node) = (yyvsp[-1].node); - } -#line 40287 "gram.c" /* yacc.c:1646 */ - break; - - case 1655: -#line 11318 "gram.y" /* yacc.c:1646 */ - { - insertSelectOptions((SelectStmt *) (yyvsp[-3].node), (yyvsp[-2].list), (yyvsp[-1].list), - list_nth((yyvsp[0].list), 0), list_nth((yyvsp[0].list), 1), - (yyvsp[-4].with), - yyscanner); - (yyval.node) = (yyvsp[-3].node); - } -#line 40299 "gram.c" /* yacc.c:1646 */ - break; - - case 1656: -#line 11326 "gram.y" /* yacc.c:1646 */ - { - insertSelectOptions((SelectStmt *) (yyvsp[-3].node), (yyvsp[-2].list), (yyvsp[0].list), - list_nth((yyvsp[-1].list), 0), list_nth((yyvsp[-1].list), 1), - (yyvsp[-4].with), - yyscanner); - (yyval.node) = (yyvsp[-3].node); - } -#line 40311 "gram.c" /* yacc.c:1646 */ - break; - - case 1657: -#line 11336 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40317 "gram.c" /* yacc.c:1646 */ - break; - - case 1658: -#line 11337 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40323 "gram.c" /* yacc.c:1646 */ - break; - - case 1659: -#line 11367 "gram.y" /* yacc.c:1646 */ - { - SelectStmt *n = makeNode(SelectStmt); - n->targetList = (yyvsp[-6].list); - n->intoClause = (yyvsp[-5].into); - n->fromClause = (yyvsp[-4].list); - n->whereClause = (yyvsp[-3].node); - n->groupClause = (yyvsp[-2].list); - n->havingClause = (yyvsp[-1].node); - n->windowClause = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 40339 "gram.c" /* yacc.c:1646 */ - break; - - case 1660: -#line 11381 "gram.y" /* yacc.c:1646 */ - { - SelectStmt *n = makeNode(SelectStmt); - n->distinctClause = (yyvsp[-7].list); - n->targetList = (yyvsp[-6].list); - n->intoClause = (yyvsp[-5].into); - n->fromClause = (yyvsp[-4].list); - n->whereClause = (yyvsp[-3].node); - n->groupClause = (yyvsp[-2].list); - n->havingClause = (yyvsp[-1].node); - n->windowClause = (yyvsp[0].list); - (yyval.node) = (Node *)n; - } -#line 40356 "gram.c" /* yacc.c:1646 */ - break; - - case 1661: -#line 11393 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40362 "gram.c" /* yacc.c:1646 */ - break; - - case 1662: -#line 11395 "gram.y" /* yacc.c:1646 */ - { - /* same as SELECT * FROM relation_expr */ - ColumnRef *cr = makeNode(ColumnRef); - ResTarget *rt = makeNode(ResTarget); - SelectStmt *n = makeNode(SelectStmt); - - cr->fields = list_make1(makeNode(A_Star)); - cr->location = -1; - - rt->name = NULL; - rt->indirection = NIL; - rt->val = (Node *)cr; - rt->location = -1; - - n->targetList = list_make1(rt); - n->fromClause = list_make1((yyvsp[0].range)); - (yyval.node) = (Node *)n; - } -#line 40385 "gram.c" /* yacc.c:1646 */ - break; - - case 1663: -#line 11414 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSetOp(SETOP_UNION, (yyvsp[-1].boolean), (yyvsp[-3].node), (yyvsp[0].node)); - } -#line 40393 "gram.c" /* yacc.c:1646 */ - break; - - case 1664: -#line 11418 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSetOp(SETOP_INTERSECT, (yyvsp[-1].boolean), (yyvsp[-3].node), (yyvsp[0].node)); - } -#line 40401 "gram.c" /* yacc.c:1646 */ - break; - - case 1665: -#line 11422 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSetOp(SETOP_EXCEPT, (yyvsp[-1].boolean), (yyvsp[-3].node), (yyvsp[0].node)); - } -#line 40409 "gram.c" /* yacc.c:1646 */ - break; - - case 1666: -#line 11439 "gram.y" /* yacc.c:1646 */ - { - (yyval.with) = makeNode(WithClause); - (yyval.with)->ctes = (yyvsp[0].list); - (yyval.with)->recursive = false; - (yyval.with)->location = (yylsp[-1]); - } -#line 40420 "gram.c" /* yacc.c:1646 */ - break; - - case 1667: -#line 11446 "gram.y" /* yacc.c:1646 */ - { - (yyval.with) = makeNode(WithClause); - (yyval.with)->ctes = (yyvsp[0].list); - (yyval.with)->recursive = false; - (yyval.with)->location = (yylsp[-1]); - } -#line 40431 "gram.c" /* yacc.c:1646 */ - break; - - case 1668: -#line 11453 "gram.y" /* yacc.c:1646 */ - { - (yyval.with) = makeNode(WithClause); - (yyval.with)->ctes = (yyvsp[0].list); - (yyval.with)->recursive = true; - (yyval.with)->location = (yylsp[-2]); - } -#line 40442 "gram.c" /* yacc.c:1646 */ - break; - - case 1669: -#line 11462 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 40448 "gram.c" /* yacc.c:1646 */ - break; - - case 1670: -#line 11463 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 40454 "gram.c" /* yacc.c:1646 */ - break; - - case 1671: -#line 11467 "gram.y" /* yacc.c:1646 */ - { - CommonTableExpr *n = makeNode(CommonTableExpr); - n->ctename = (yyvsp[-5].str); - n->aliascolnames = (yyvsp[-4].list); - n->ctequery = (yyvsp[-1].node); - n->location = (yylsp[-5]); - (yyval.node) = (Node *) n; - } -#line 40467 "gram.c" /* yacc.c:1646 */ - break; - - case 1672: -#line 11478 "gram.y" /* yacc.c:1646 */ - { (yyval.with) = (yyvsp[0].with); } -#line 40473 "gram.c" /* yacc.c:1646 */ - break; - - case 1673: -#line 11479 "gram.y" /* yacc.c:1646 */ - { (yyval.with) = NULL; } -#line 40479 "gram.c" /* yacc.c:1646 */ - break; - - case 1674: -#line 11484 "gram.y" /* yacc.c:1646 */ - { - (yyval.into) = makeNode(IntoClause); - (yyval.into)->rel = (yyvsp[0].range); - (yyval.into)->colNames = NIL; - (yyval.into)->options = NIL; - (yyval.into)->onCommit = ONCOMMIT_NOOP; - (yyval.into)->tableSpaceName = NULL; - (yyval.into)->viewQuery = NULL; - (yyval.into)->skipData = false; - } -#line 40494 "gram.c" /* yacc.c:1646 */ - break; - - case 1675: -#line 11495 "gram.y" /* yacc.c:1646 */ - { (yyval.into) = NULL; } -#line 40500 "gram.c" /* yacc.c:1646 */ - break; - - case 1676: -#line 11504 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_TEMP; - } -#line 40509 "gram.c" /* yacc.c:1646 */ - break; - - case 1677: -#line 11509 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_TEMP; - } -#line 40518 "gram.c" /* yacc.c:1646 */ - break; - - case 1678: -#line 11514 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_TEMP; - } -#line 40527 "gram.c" /* yacc.c:1646 */ - break; - - case 1679: -#line 11519 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_TEMP; - } -#line 40536 "gram.c" /* yacc.c:1646 */ - break; - - case 1680: -#line 11524 "gram.y" /* yacc.c:1646 */ - { - ereport(WARNING, - (errmsg("GLOBAL is deprecated in temporary table creation"), - parser_errposition((yylsp[-3])))); - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_TEMP; - } -#line 40548 "gram.c" /* yacc.c:1646 */ - break; - - case 1681: -#line 11532 "gram.y" /* yacc.c:1646 */ - { - ereport(WARNING, - (errmsg("GLOBAL is deprecated in temporary table creation"), - parser_errposition((yylsp[-3])))); - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_TEMP; - } -#line 40560 "gram.c" /* yacc.c:1646 */ - break; - - case 1682: -#line 11540 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_UNLOGGED; - } -#line 40569 "gram.c" /* yacc.c:1646 */ - break; - - case 1683: -#line 11545 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT; - } -#line 40578 "gram.c" /* yacc.c:1646 */ - break; - - case 1684: -#line 11550 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - (yyval.range)->relpersistence = RELPERSISTENCE_PERMANENT; - } -#line 40587 "gram.c" /* yacc.c:1646 */ - break; - - case 1685: -#line 11556 "gram.y" /* yacc.c:1646 */ - {} -#line 40593 "gram.c" /* yacc.c:1646 */ - break; - - case 1686: -#line 11557 "gram.y" /* yacc.c:1646 */ - {} -#line 40599 "gram.c" /* yacc.c:1646 */ - break; - - case 1687: -#line 11561 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 40605 "gram.c" /* yacc.c:1646 */ - break; - - case 1688: -#line 11562 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 40611 "gram.c" /* yacc.c:1646 */ - break; - - case 1689: -#line 11563 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 40617 "gram.c" /* yacc.c:1646 */ - break; - - case 1690: -#line 11570 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(NIL); } -#line 40623 "gram.c" /* yacc.c:1646 */ - break; - - case 1691: -#line 11571 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 40629 "gram.c" /* yacc.c:1646 */ - break; - - case 1692: -#line 11575 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL;} -#line 40635 "gram.c" /* yacc.c:1646 */ - break; - - case 1693: -#line 11576 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 40641 "gram.c" /* yacc.c:1646 */ - break; - - case 1694: -#line 11580 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list);} -#line 40647 "gram.c" /* yacc.c:1646 */ - break; - - case 1695: -#line 11581 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 40653 "gram.c" /* yacc.c:1646 */ - break; - - case 1696: -#line 11585 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 40659 "gram.c" /* yacc.c:1646 */ - break; - - case 1697: -#line 11589 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].sortby)); } -#line 40665 "gram.c" /* yacc.c:1646 */ - break; - - case 1698: -#line 11590 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].sortby)); } -#line 40671 "gram.c" /* yacc.c:1646 */ - break; - - case 1699: -#line 11594 "gram.y" /* yacc.c:1646 */ - { - (yyval.sortby) = makeNode(SortBy); - (yyval.sortby)->node = (yyvsp[-3].node); - (yyval.sortby)->sortby_dir = SORTBY_USING; - (yyval.sortby)->sortby_nulls = (yyvsp[0].ival); - (yyval.sortby)->useOp = (yyvsp[-1].list); - (yyval.sortby)->location = (yylsp[-1]); - } -#line 40684 "gram.c" /* yacc.c:1646 */ - break; - - case 1700: -#line 11603 "gram.y" /* yacc.c:1646 */ - { - (yyval.sortby) = makeNode(SortBy); - (yyval.sortby)->node = (yyvsp[-2].node); - (yyval.sortby)->sortby_dir = (yyvsp[-1].ival); - (yyval.sortby)->sortby_nulls = (yyvsp[0].ival); - (yyval.sortby)->useOp = NIL; - (yyval.sortby)->location = -1; /* no operator */ - } -#line 40697 "gram.c" /* yacc.c:1646 */ - break; - - case 1701: -#line 11615 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2((yyvsp[0].node), (yyvsp[-1].node)); } -#line 40703 "gram.c" /* yacc.c:1646 */ - break; - - case 1702: -#line 11616 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2((yyvsp[-1].node), (yyvsp[0].node)); } -#line 40709 "gram.c" /* yacc.c:1646 */ - break; - - case 1703: -#line 11617 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(NULL, (yyvsp[0].node)); } -#line 40715 "gram.c" /* yacc.c:1646 */ - break; - - case 1704: -#line 11618 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2((yyvsp[0].node), NULL); } -#line 40721 "gram.c" /* yacc.c:1646 */ - break; - - case 1705: -#line 11622 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 40727 "gram.c" /* yacc.c:1646 */ - break; - - case 1706: -#line 11623 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2(NULL,NULL); } -#line 40733 "gram.c" /* yacc.c:1646 */ - break; - - case 1707: -#line 11628 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40739 "gram.c" /* yacc.c:1646 */ - break; - - case 1708: -#line 11630 "gram.y" /* yacc.c:1646 */ - { - /* Disabled because it was too confusing, bjm 2002-02-18 */ - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("LIMIT #,# syntax is not supported"), - errhint("Use separate LIMIT and OFFSET clauses."), - parser_errposition((yylsp[-3])))); - } -#line 40752 "gram.c" /* yacc.c:1646 */ - break; - - case 1709: -#line 11646 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-2].node); } -#line 40758 "gram.c" /* yacc.c:1646 */ - break; - - case 1710: -#line 11648 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeIntConst(1, -1); } -#line 40764 "gram.c" /* yacc.c:1646 */ - break; - - case 1711: -#line 11653 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40770 "gram.c" /* yacc.c:1646 */ - break; - - case 1712: -#line 11656 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 40776 "gram.c" /* yacc.c:1646 */ - break; - - case 1713: -#line 11660 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40782 "gram.c" /* yacc.c:1646 */ - break; - - case 1714: -#line 11662 "gram.y" /* yacc.c:1646 */ - { - /* LIMIT ALL is represented as a NULL constant */ - (yyval.node) = makeNullAConst((yylsp[0])); - } -#line 40791 "gram.c" /* yacc.c:1646 */ - break; - - case 1715: -#line 11669 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40797 "gram.c" /* yacc.c:1646 */ - break; - - case 1716: -#line 11689 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40803 "gram.c" /* yacc.c:1646 */ - break; - - case 1717: -#line 11691 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, (yyvsp[0].node), (yylsp[-1])); } -#line 40809 "gram.c" /* yacc.c:1646 */ - break; - - case 1718: -#line 11693 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = doNegate((yyvsp[0].node), (yylsp[-1])); } -#line 40815 "gram.c" /* yacc.c:1646 */ - break; - - case 1719: -#line 11697 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeIntConst((yyvsp[0].ival),(yylsp[0])); } -#line 40821 "gram.c" /* yacc.c:1646 */ - break; - - case 1720: -#line 11698 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeFloatConst((yyvsp[0].str),(yylsp[0])); } -#line 40827 "gram.c" /* yacc.c:1646 */ - break; - - case 1721: -#line 11702 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 40833 "gram.c" /* yacc.c:1646 */ - break; - - case 1722: -#line 11703 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 40839 "gram.c" /* yacc.c:1646 */ - break; - - case 1723: -#line 11706 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 40845 "gram.c" /* yacc.c:1646 */ - break; - - case 1724: -#line 11707 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 40851 "gram.c" /* yacc.c:1646 */ - break; - - case 1725: -#line 11732 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 40857 "gram.c" /* yacc.c:1646 */ - break; - - case 1726: -#line 11733 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 40863 "gram.c" /* yacc.c:1646 */ - break; - - case 1727: -#line 11737 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 40869 "gram.c" /* yacc.c:1646 */ - break; - - case 1728: -#line 11738 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list),(yyvsp[0].node)); } -#line 40875 "gram.c" /* yacc.c:1646 */ - break; - - case 1729: -#line 11742 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40881 "gram.c" /* yacc.c:1646 */ - break; - - case 1730: -#line 11743 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40887 "gram.c" /* yacc.c:1646 */ - break; - - case 1731: -#line 11744 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40893 "gram.c" /* yacc.c:1646 */ - break; - - case 1732: -#line 11745 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40899 "gram.c" /* yacc.c:1646 */ - break; - - case 1733: -#line 11746 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40905 "gram.c" /* yacc.c:1646 */ - break; - - case 1734: -#line 11751 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeGroupingSet(GROUPING_SET_EMPTY, NIL, (yylsp[-1])); - } -#line 40913 "gram.c" /* yacc.c:1646 */ - break; - - case 1735: -#line 11764 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeGroupingSet(GROUPING_SET_ROLLUP, (yyvsp[-1].list), (yylsp[-3])); - } -#line 40921 "gram.c" /* yacc.c:1646 */ - break; - - case 1736: -#line 11771 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeGroupingSet(GROUPING_SET_CUBE, (yyvsp[-1].list), (yylsp[-3])); - } -#line 40929 "gram.c" /* yacc.c:1646 */ - break; - - case 1737: -#line 11778 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeGroupingSet(GROUPING_SET_SETS, (yyvsp[-1].list), (yylsp[-4])); - } -#line 40937 "gram.c" /* yacc.c:1646 */ - break; - - case 1738: -#line 11784 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 40943 "gram.c" /* yacc.c:1646 */ - break; - - case 1739: -#line 11785 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 40949 "gram.c" /* yacc.c:1646 */ - break; - - case 1740: -#line 11789 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 40955 "gram.c" /* yacc.c:1646 */ - break; - - case 1741: -#line 11790 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 40961 "gram.c" /* yacc.c:1646 */ - break; - - case 1742: -#line 11794 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 40967 "gram.c" /* yacc.c:1646 */ - break; - - case 1743: -#line 11795 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 40973 "gram.c" /* yacc.c:1646 */ - break; - - case 1744: -#line 11799 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 40979 "gram.c" /* yacc.c:1646 */ - break; - - case 1745: -#line 11800 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].node)); } -#line 40985 "gram.c" /* yacc.c:1646 */ - break; - - case 1746: -#line 11805 "gram.y" /* yacc.c:1646 */ - { - LockingClause *n = makeNode(LockingClause); - n->lockedRels = (yyvsp[-1].list); - n->strength = (yyvsp[-2].ival); - n->waitPolicy = (yyvsp[0].ival); - (yyval.node) = (Node *) n; - } -#line 40997 "gram.c" /* yacc.c:1646 */ - break; - - case 1747: -#line 11815 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LCS_FORUPDATE; } -#line 41003 "gram.c" /* yacc.c:1646 */ - break; - - case 1748: -#line 11816 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LCS_FORNOKEYUPDATE; } -#line 41009 "gram.c" /* yacc.c:1646 */ - break; - - case 1749: -#line 11817 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LCS_FORSHARE; } -#line 41015 "gram.c" /* yacc.c:1646 */ - break; - - case 1750: -#line 11818 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = LCS_FORKEYSHARE; } -#line 41021 "gram.c" /* yacc.c:1646 */ - break; - - case 1751: -#line 11822 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 41027 "gram.c" /* yacc.c:1646 */ - break; - - case 1752: -#line 11823 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 41033 "gram.c" /* yacc.c:1646 */ - break; - - case 1753: -#line 11834 "gram.y" /* yacc.c:1646 */ - { - SelectStmt *n = makeNode(SelectStmt); - n->valuesLists = list_make1((yyvsp[-1].list)); - (yyval.node) = (Node *) n; - } -#line 41043 "gram.c" /* yacc.c:1646 */ - break; - - case 1754: -#line 11840 "gram.y" /* yacc.c:1646 */ - { - SelectStmt *n = (SelectStmt *) (yyvsp[-4].node); - n->valuesLists = lappend(n->valuesLists, (yyvsp[-1].list)); - (yyval.node) = (Node *) n; - } -#line 41053 "gram.c" /* yacc.c:1646 */ - break; - - case 1755: -#line 11857 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 41059 "gram.c" /* yacc.c:1646 */ - break; - - case 1756: -#line 11858 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 41065 "gram.c" /* yacc.c:1646 */ - break; - - case 1757: -#line 11862 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 41071 "gram.c" /* yacc.c:1646 */ - break; - - case 1758: -#line 11863 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 41077 "gram.c" /* yacc.c:1646 */ - break; - - case 1759: -#line 11870 "gram.y" /* yacc.c:1646 */ - { - (yyvsp[-1].range)->alias = (yyvsp[0].alias); - (yyval.node) = (Node *) (yyvsp[-1].range); - } -#line 41086 "gram.c" /* yacc.c:1646 */ - break; - - case 1760: -#line 11875 "gram.y" /* yacc.c:1646 */ - { - RangeTableSample *n = (RangeTableSample *) (yyvsp[0].node); - (yyvsp[-2].range)->alias = (yyvsp[-1].alias); - /* relation_expr goes inside the RangeTableSample node */ - n->relation = (Node *) (yyvsp[-2].range); - (yyval.node) = (Node *) n; - } -#line 41098 "gram.c" /* yacc.c:1646 */ - break; - - case 1761: -#line 11883 "gram.y" /* yacc.c:1646 */ - { - RangeFunction *n = (RangeFunction *) (yyvsp[-1].node); - n->alias = linitial((yyvsp[0].list)); - n->coldeflist = lsecond((yyvsp[0].list)); - (yyval.node) = (Node *) n; - } -#line 41109 "gram.c" /* yacc.c:1646 */ - break; - - case 1762: -#line 11890 "gram.y" /* yacc.c:1646 */ - { - RangeFunction *n = (RangeFunction *) (yyvsp[-1].node); - n->lateral = true; - n->alias = linitial((yyvsp[0].list)); - n->coldeflist = lsecond((yyvsp[0].list)); - (yyval.node) = (Node *) n; - } -#line 41121 "gram.c" /* yacc.c:1646 */ - break; - - case 1763: -#line 11898 "gram.y" /* yacc.c:1646 */ - { - RangeTableFunc *n = (RangeTableFunc *) (yyvsp[-1].node); - n->alias = (yyvsp[0].alias); - (yyval.node) = (Node *) n; - } -#line 41131 "gram.c" /* yacc.c:1646 */ - break; - - case 1764: -#line 11904 "gram.y" /* yacc.c:1646 */ - { - RangeTableFunc *n = (RangeTableFunc *) (yyvsp[-1].node); - n->lateral = true; - n->alias = (yyvsp[0].alias); - (yyval.node) = (Node *) n; - } -#line 41142 "gram.c" /* yacc.c:1646 */ - break; - - case 1765: -#line 11911 "gram.y" /* yacc.c:1646 */ - { - RangeSubselect *n = makeNode(RangeSubselect); - n->lateral = false; - n->subquery = (yyvsp[-1].node); - n->alias = (yyvsp[0].alias); - /* - * The SQL spec does not permit a subselect - * () without an alias clause, - * so we don't either. This avoids the problem - * of needing to invent a unique refname for it. - * That could be surmounted if there's sufficient - * popular demand, but for now let's just implement - * the spec and see if anyone complains. - * However, it does seem like a good idea to emit - * an error message that's better than "syntax error". - */ - if ((yyvsp[0].alias) == NULL) - { - if (IsA((yyvsp[-1].node), SelectStmt) && - ((SelectStmt *) (yyvsp[-1].node))->valuesLists) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("VALUES in FROM must have an alias"), - errhint("For example, FROM (VALUES ...) [AS] foo."), - parser_errposition((yylsp[-1])))); - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("subquery in FROM must have an alias"), - errhint("For example, FROM (SELECT ...) [AS] foo."), - parser_errposition((yylsp[-1])))); - } - (yyval.node) = (Node *) n; - } -#line 41181 "gram.c" /* yacc.c:1646 */ - break; - - case 1766: -#line 11946 "gram.y" /* yacc.c:1646 */ - { - RangeSubselect *n = makeNode(RangeSubselect); - n->lateral = true; - n->subquery = (yyvsp[-1].node); - n->alias = (yyvsp[0].alias); - /* same comment as above */ - if ((yyvsp[0].alias) == NULL) - { - if (IsA((yyvsp[-1].node), SelectStmt) && - ((SelectStmt *) (yyvsp[-1].node))->valuesLists) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("VALUES in FROM must have an alias"), - errhint("For example, FROM (VALUES ...) [AS] foo."), - parser_errposition((yylsp[-1])))); - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("subquery in FROM must have an alias"), - errhint("For example, FROM (SELECT ...) [AS] foo."), - parser_errposition((yylsp[-1])))); - } - (yyval.node) = (Node *) n; - } -#line 41210 "gram.c" /* yacc.c:1646 */ - break; - - case 1767: -#line 11971 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) (yyvsp[0].jexpr); - } -#line 41218 "gram.c" /* yacc.c:1646 */ - break; - - case 1768: -#line 11975 "gram.y" /* yacc.c:1646 */ - { - (yyvsp[-2].jexpr)->alias = (yyvsp[0].alias); - (yyval.node) = (Node *) (yyvsp[-2].jexpr); - } -#line 41227 "gram.c" /* yacc.c:1646 */ - break; - - case 1769: -#line 12001 "gram.y" /* yacc.c:1646 */ - { - (yyval.jexpr) = (yyvsp[-1].jexpr); - } -#line 41235 "gram.c" /* yacc.c:1646 */ - break; - - case 1770: -#line 12005 "gram.y" /* yacc.c:1646 */ - { - /* CROSS JOIN is same as unqualified inner join */ - JoinExpr *n = makeNode(JoinExpr); - n->jointype = JOIN_INNER; - n->isNatural = false; - n->larg = (yyvsp[-3].node); - n->rarg = (yyvsp[0].node); - n->usingClause = NIL; - n->quals = NULL; - (yyval.jexpr) = n; - } -#line 41251 "gram.c" /* yacc.c:1646 */ - break; - - case 1771: -#line 12017 "gram.y" /* yacc.c:1646 */ - { - JoinExpr *n = makeNode(JoinExpr); - n->jointype = (yyvsp[-3].jtype); - n->isNatural = false; - n->larg = (yyvsp[-4].node); - n->rarg = (yyvsp[-1].node); - if ((yyvsp[0].node) != NULL && IsA((yyvsp[0].node), List)) - n->usingClause = (List *) (yyvsp[0].node); /* USING clause */ - else - n->quals = (yyvsp[0].node); /* ON clause */ - (yyval.jexpr) = n; - } -#line 41268 "gram.c" /* yacc.c:1646 */ - break; - - case 1772: -#line 12030 "gram.y" /* yacc.c:1646 */ - { - /* letting join_type reduce to empty doesn't work */ - JoinExpr *n = makeNode(JoinExpr); - n->jointype = JOIN_INNER; - n->isNatural = false; - n->larg = (yyvsp[-3].node); - n->rarg = (yyvsp[-1].node); - if ((yyvsp[0].node) != NULL && IsA((yyvsp[0].node), List)) - n->usingClause = (List *) (yyvsp[0].node); /* USING clause */ - else - n->quals = (yyvsp[0].node); /* ON clause */ - (yyval.jexpr) = n; - } -#line 41286 "gram.c" /* yacc.c:1646 */ - break; - - case 1773: -#line 12044 "gram.y" /* yacc.c:1646 */ - { - JoinExpr *n = makeNode(JoinExpr); - n->jointype = (yyvsp[-2].jtype); - n->isNatural = true; - n->larg = (yyvsp[-4].node); - n->rarg = (yyvsp[0].node); - n->usingClause = NIL; /* figure out which columns later... */ - n->quals = NULL; /* fill later */ - (yyval.jexpr) = n; - } -#line 41301 "gram.c" /* yacc.c:1646 */ - break; - - case 1774: -#line 12055 "gram.y" /* yacc.c:1646 */ - { - /* letting join_type reduce to empty doesn't work */ - JoinExpr *n = makeNode(JoinExpr); - n->jointype = JOIN_INNER; - n->isNatural = true; - n->larg = (yyvsp[-3].node); - n->rarg = (yyvsp[0].node); - n->usingClause = NIL; /* figure out which columns later... */ - n->quals = NULL; /* fill later */ - (yyval.jexpr) = n; - } -#line 41317 "gram.c" /* yacc.c:1646 */ - break; - - case 1775: -#line 12070 "gram.y" /* yacc.c:1646 */ - { - (yyval.alias) = makeNode(Alias); - (yyval.alias)->aliasname = (yyvsp[-3].str); - (yyval.alias)->colnames = (yyvsp[-1].list); - } -#line 41327 "gram.c" /* yacc.c:1646 */ - break; - - case 1776: -#line 12076 "gram.y" /* yacc.c:1646 */ - { - (yyval.alias) = makeNode(Alias); - (yyval.alias)->aliasname = (yyvsp[0].str); - } -#line 41336 "gram.c" /* yacc.c:1646 */ - break; - - case 1777: -#line 12081 "gram.y" /* yacc.c:1646 */ - { - (yyval.alias) = makeNode(Alias); - (yyval.alias)->aliasname = (yyvsp[-3].str); - (yyval.alias)->colnames = (yyvsp[-1].list); - } -#line 41346 "gram.c" /* yacc.c:1646 */ - break; - - case 1778: -#line 12087 "gram.y" /* yacc.c:1646 */ - { - (yyval.alias) = makeNode(Alias); - (yyval.alias)->aliasname = (yyvsp[0].str); - } -#line 41355 "gram.c" /* yacc.c:1646 */ - break; - - case 1779: -#line 12093 "gram.y" /* yacc.c:1646 */ - { (yyval.alias) = (yyvsp[0].alias); } -#line 41361 "gram.c" /* yacc.c:1646 */ - break; - - case 1780: -#line 12094 "gram.y" /* yacc.c:1646 */ - { (yyval.alias) = NULL; } -#line 41367 "gram.c" /* yacc.c:1646 */ - break; - - case 1781: -#line 12103 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[0].alias), NIL); - } -#line 41375 "gram.c" /* yacc.c:1646 */ - break; - - case 1782: -#line 12107 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2(NULL, (yyvsp[-1].list)); - } -#line 41383 "gram.c" /* yacc.c:1646 */ - break; - - case 1783: -#line 12111 "gram.y" /* yacc.c:1646 */ - { - Alias *a = makeNode(Alias); - a->aliasname = (yyvsp[-3].str); - (yyval.list) = list_make2(a, (yyvsp[-1].list)); - } -#line 41393 "gram.c" /* yacc.c:1646 */ - break; - - case 1784: -#line 12117 "gram.y" /* yacc.c:1646 */ - { - Alias *a = makeNode(Alias); - a->aliasname = (yyvsp[-3].str); - (yyval.list) = list_make2(a, (yyvsp[-1].list)); - } -#line 41403 "gram.c" /* yacc.c:1646 */ - break; - - case 1785: -#line 12123 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2(NULL, NIL); - } -#line 41411 "gram.c" /* yacc.c:1646 */ - break; - - case 1786: -#line 12128 "gram.y" /* yacc.c:1646 */ - { (yyval.jtype) = JOIN_FULL; } -#line 41417 "gram.c" /* yacc.c:1646 */ - break; - - case 1787: -#line 12129 "gram.y" /* yacc.c:1646 */ - { (yyval.jtype) = JOIN_LEFT; } -#line 41423 "gram.c" /* yacc.c:1646 */ - break; - - case 1788: -#line 12130 "gram.y" /* yacc.c:1646 */ - { (yyval.jtype) = JOIN_RIGHT; } -#line 41429 "gram.c" /* yacc.c:1646 */ - break; - - case 1789: -#line 12131 "gram.y" /* yacc.c:1646 */ - { (yyval.jtype) = JOIN_INNER; } -#line 41435 "gram.c" /* yacc.c:1646 */ - break; - - case 1790: -#line 12135 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 41441 "gram.c" /* yacc.c:1646 */ - break; - - case 1791: -#line 12136 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 41447 "gram.c" /* yacc.c:1646 */ - break; - - case 1792: -#line 12148 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) (yyvsp[-1].list); } -#line 41453 "gram.c" /* yacc.c:1646 */ - break; - - case 1793: -#line 12149 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 41459 "gram.c" /* yacc.c:1646 */ - break; - - case 1794: -#line 12155 "gram.y" /* yacc.c:1646 */ - { - /* inheritance query, implicitly */ - (yyval.range) = (yyvsp[0].range); - (yyval.range)->inh = true; - (yyval.range)->alias = NULL; - } -#line 41470 "gram.c" /* yacc.c:1646 */ - break; - - case 1795: -#line 12162 "gram.y" /* yacc.c:1646 */ - { - /* inheritance query, explicitly */ - (yyval.range) = (yyvsp[-1].range); - (yyval.range)->inh = true; - (yyval.range)->alias = NULL; - } -#line 41481 "gram.c" /* yacc.c:1646 */ - break; - - case 1796: -#line 12169 "gram.y" /* yacc.c:1646 */ - { - /* no inheritance */ - (yyval.range) = (yyvsp[0].range); - (yyval.range)->inh = false; - (yyval.range)->alias = NULL; - } -#line 41492 "gram.c" /* yacc.c:1646 */ - break; - - case 1797: -#line 12176 "gram.y" /* yacc.c:1646 */ - { - /* no inheritance, SQL99-style syntax */ - (yyval.range) = (yyvsp[-1].range); - (yyval.range)->inh = false; - (yyval.range)->alias = NULL; - } -#line 41503 "gram.c" /* yacc.c:1646 */ - break; - - case 1798: -#line 12186 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].range)); } -#line 41509 "gram.c" /* yacc.c:1646 */ - break; - - case 1799: -#line 12187 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].range)); } -#line 41515 "gram.c" /* yacc.c:1646 */ - break; - - case 1800: -#line 12201 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = (yyvsp[0].range); - } -#line 41523 "gram.c" /* yacc.c:1646 */ - break; - - case 1801: -#line 12205 "gram.y" /* yacc.c:1646 */ - { - Alias *alias = makeNode(Alias); - alias->aliasname = (yyvsp[0].str); - (yyvsp[-1].range)->alias = alias; - (yyval.range) = (yyvsp[-1].range); - } -#line 41534 "gram.c" /* yacc.c:1646 */ - break; - - case 1802: -#line 12212 "gram.y" /* yacc.c:1646 */ - { - Alias *alias = makeNode(Alias); - alias->aliasname = (yyvsp[0].str); - (yyvsp[-2].range)->alias = alias; - (yyval.range) = (yyvsp[-2].range); - } -#line 41545 "gram.c" /* yacc.c:1646 */ - break; - - case 1803: -#line 12225 "gram.y" /* yacc.c:1646 */ - { - RangeTableSample *n = makeNode(RangeTableSample); - /* n->relation will be filled in later */ - n->method = (yyvsp[-4].list); - n->args = (yyvsp[-2].list); - n->repeatable = (yyvsp[0].node); - n->location = (yylsp[-4]); - (yyval.node) = (Node *) n; - } -#line 41559 "gram.c" /* yacc.c:1646 */ - break; - - case 1804: -#line 12237 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) (yyvsp[-1].node); } -#line 41565 "gram.c" /* yacc.c:1646 */ - break; - - case 1805: -#line 12238 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 41571 "gram.c" /* yacc.c:1646 */ - break; - - case 1806: -#line 12254 "gram.y" /* yacc.c:1646 */ - { - RangeFunction *n = makeNode(RangeFunction); - n->lateral = false; - n->ordinality = (yyvsp[0].boolean); - n->is_rowsfrom = false; - n->functions = list_make1(list_make2((yyvsp[-1].node), NIL)); - /* alias and coldeflist are set by table_ref production */ - (yyval.node) = (Node *) n; - } -#line 41585 "gram.c" /* yacc.c:1646 */ - break; - - case 1807: -#line 12264 "gram.y" /* yacc.c:1646 */ - { - RangeFunction *n = makeNode(RangeFunction); - n->lateral = false; - n->ordinality = (yyvsp[0].boolean); - n->is_rowsfrom = true; - n->functions = (yyvsp[-2].list); - /* alias and coldeflist are set by table_ref production */ - (yyval.node) = (Node *) n; - } -#line 41599 "gram.c" /* yacc.c:1646 */ - break; - - case 1808: -#line 12276 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2((yyvsp[-1].node), (yyvsp[0].list)); } -#line 41605 "gram.c" /* yacc.c:1646 */ - break; - - case 1809: -#line 12280 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].list)); } -#line 41611 "gram.c" /* yacc.c:1646 */ - break; - - case 1810: -#line 12281 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].list)); } -#line 41617 "gram.c" /* yacc.c:1646 */ - break; - - case 1811: -#line 12284 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 41623 "gram.c" /* yacc.c:1646 */ - break; - - case 1812: -#line 12285 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 41629 "gram.c" /* yacc.c:1646 */ - break; - - case 1813: -#line 12288 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 41635 "gram.c" /* yacc.c:1646 */ - break; - - case 1814: -#line 12289 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 41641 "gram.c" /* yacc.c:1646 */ - break; - - case 1815: -#line 12294 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 41647 "gram.c" /* yacc.c:1646 */ - break; - - case 1816: -#line 12295 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 41653 "gram.c" /* yacc.c:1646 */ - break; - - case 1817: -#line 12300 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 41659 "gram.c" /* yacc.c:1646 */ - break; - - case 1818: -#line 12302 "gram.y" /* yacc.c:1646 */ - { - CurrentOfExpr *n = makeNode(CurrentOfExpr); - /* cvarno is filled in by parse analysis */ - n->cursor_name = (yyvsp[0].str); - n->cursor_param = 0; - (yyval.node) = (Node *) n; - } -#line 41671 "gram.c" /* yacc.c:1646 */ - break; - - case 1819: -#line 12309 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 41677 "gram.c" /* yacc.c:1646 */ - break; - - case 1820: -#line 12314 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 41683 "gram.c" /* yacc.c:1646 */ - break; - - case 1821: -#line 12315 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 41689 "gram.c" /* yacc.c:1646 */ - break; - - case 1822: -#line 12320 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].node)); - } -#line 41697 "gram.c" /* yacc.c:1646 */ - break; - - case 1823: -#line 12324 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); - } -#line 41705 "gram.c" /* yacc.c:1646 */ - break; - - case 1824: -#line 12330 "gram.y" /* yacc.c:1646 */ - { - ColumnDef *n = makeNode(ColumnDef); - n->colname = (yyvsp[-2].str); - n->typeName = (yyvsp[-1].typnam); - n->inhcount = 0; - 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; - n->collClause = (CollateClause *) (yyvsp[0].node); - n->collOid = InvalidOid; - n->constraints = NIL; - n->location = (yylsp[-2]); - (yyval.node) = (Node *)n; - } -#line 41728 "gram.c" /* yacc.c:1646 */ - break; - - case 1825: -#line 12355 "gram.y" /* yacc.c:1646 */ - { - RangeTableFunc *n = makeNode(RangeTableFunc); - n->rowexpr = (yyvsp[-4].node); - n->docexpr = (yyvsp[-3].node); - n->columns = (yyvsp[-1].list); - n->namespaces = NIL; - n->location = (yylsp[-6]); - (yyval.node) = (Node *)n; - } -#line 41742 "gram.c" /* yacc.c:1646 */ - break; - - case 1826: -#line 12366 "gram.y" /* yacc.c:1646 */ - { - RangeTableFunc *n = makeNode(RangeTableFunc); - n->rowexpr = (yyvsp[-4].node); - n->docexpr = (yyvsp[-3].node); - n->columns = (yyvsp[-1].list); - n->namespaces = (yyvsp[-7].list); - n->location = (yylsp[-11]); - (yyval.node) = (Node *)n; - } -#line 41756 "gram.c" /* yacc.c:1646 */ - break; - - case 1827: -#line 12377 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 41762 "gram.c" /* yacc.c:1646 */ - break; - - case 1828: -#line 12378 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 41768 "gram.c" /* yacc.c:1646 */ - break; - - case 1829: -#line 12383 "gram.y" /* yacc.c:1646 */ - { - RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); - - fc->colname = (yyvsp[-1].str); - fc->for_ordinality = false; - fc->typeName = (yyvsp[0].typnam); - fc->is_not_null = false; - fc->colexpr = NULL; - fc->coldefexpr = NULL; - fc->location = (yylsp[-1]); - - (yyval.node) = (Node *) fc; - } -#line 41786 "gram.c" /* yacc.c:1646 */ - break; - - case 1830: -#line 12397 "gram.y" /* yacc.c:1646 */ - { - RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); - ListCell *option; - bool nullability_seen = false; - - fc->colname = (yyvsp[-2].str); - fc->typeName = (yyvsp[-1].typnam); - fc->for_ordinality = false; - fc->is_not_null = false; - fc->colexpr = NULL; - fc->coldefexpr = NULL; - fc->location = (yylsp[-2]); - - foreach(option, (yyvsp[0].list)) - { - DefElem *defel = (DefElem *) lfirst(option); - - if (strcmp(defel->defname, "default") == 0) - { - if (fc->coldefexpr != NULL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("only one DEFAULT value is allowed"), - parser_errposition(defel->location))); - fc->coldefexpr = defel->arg; - } - else if (strcmp(defel->defname, "path") == 0) - { - if (fc->colexpr != NULL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("only one PATH value per column is allowed"), - parser_errposition(defel->location))); - fc->colexpr = defel->arg; - } - else if (strcmp(defel->defname, "is_not_null") == 0) - { - if (nullability_seen) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant NULL / NOT NULL declarations for column \"%s\"", fc->colname), - parser_errposition(defel->location))); - fc->is_not_null = intVal(defel->arg); - nullability_seen = true; - } - else - { - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized column option \"%s\"", - defel->defname), - parser_errposition(defel->location))); - } - } - (yyval.node) = (Node *) fc; - } -#line 41847 "gram.c" /* yacc.c:1646 */ - break; - - case 1831: -#line 12454 "gram.y" /* yacc.c:1646 */ - { - RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); - - fc->colname = (yyvsp[-2].str); - fc->for_ordinality = true; - /* other fields are ignored, initialized by makeNode */ - fc->location = (yylsp[-2]); - - (yyval.node) = (Node *) fc; - } -#line 41862 "gram.c" /* yacc.c:1646 */ - break; - - case 1832: -#line 12468 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].defelt)); } -#line 41868 "gram.c" /* yacc.c:1646 */ - break; - - case 1833: -#line 12470 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].defelt)); } -#line 41874 "gram.c" /* yacc.c:1646 */ - break; - - case 1834: -#line 12475 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem((yyvsp[-1].str), (yyvsp[0].node), (yylsp[-1])); } -#line 41880 "gram.c" /* yacc.c:1646 */ - break; - - case 1835: -#line 12477 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("default", (yyvsp[0].node), (yylsp[-1])); } -#line 41886 "gram.c" /* yacc.c:1646 */ - break; - - case 1836: -#line 12479 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("is_not_null", (Node *) makeInteger(true), (yylsp[-1])); } -#line 41892 "gram.c" /* yacc.c:1646 */ - break; - - case 1837: -#line 12481 "gram.y" /* yacc.c:1646 */ - { (yyval.defelt) = makeDefElem("is_not_null", (Node *) makeInteger(false), (yylsp[0])); } -#line 41898 "gram.c" /* yacc.c:1646 */ - break; - - case 1838: -#line 12486 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].target)); } -#line 41904 "gram.c" /* yacc.c:1646 */ - break; - - case 1839: -#line 12488 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].target)); } -#line 41910 "gram.c" /* yacc.c:1646 */ - break; - - case 1840: -#line 12493 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = (yyvsp[0].str); - (yyval.target)->indirection = NIL; - (yyval.target)->val = (yyvsp[-2].node); - (yyval.target)->location = (yylsp[-2]); - } -#line 41922 "gram.c" /* yacc.c:1646 */ - break; - - case 1841: -#line 12501 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = NULL; - (yyval.target)->indirection = NIL; - (yyval.target)->val = (yyvsp[0].node); - (yyval.target)->location = (yylsp[-1]); - } -#line 41934 "gram.c" /* yacc.c:1646 */ - break; - - case 1842: -#line 12521 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-1].typnam); - (yyval.typnam)->arrayBounds = (yyvsp[0].list); - } -#line 41943 "gram.c" /* yacc.c:1646 */ - break; - - case 1843: -#line 12526 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-1].typnam); - (yyval.typnam)->arrayBounds = (yyvsp[0].list); - (yyval.typnam)->setof = true; - } -#line 41953 "gram.c" /* yacc.c:1646 */ - break; - - case 1844: -#line 12533 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-4].typnam); - (yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[-1].ival))); - } -#line 41962 "gram.c" /* yacc.c:1646 */ - break; - - case 1845: -#line 12538 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-4].typnam); - (yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[-1].ival))); - (yyval.typnam)->setof = true; - } -#line 41972 "gram.c" /* yacc.c:1646 */ - break; - - case 1846: -#line 12544 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-1].typnam); - (yyval.typnam)->arrayBounds = list_make1(makeInteger(-1)); - } -#line 41981 "gram.c" /* yacc.c:1646 */ - break; - - case 1847: -#line 12549 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-1].typnam); - (yyval.typnam)->arrayBounds = list_make1(makeInteger(-1)); - (yyval.typnam)->setof = true; - } -#line 41991 "gram.c" /* yacc.c:1646 */ - break; - - case 1848: -#line 12558 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), makeInteger(-1)); } -#line 41997 "gram.c" /* yacc.c:1646 */ - break; - - case 1849: -#line 12560 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-3].list), makeInteger((yyvsp[-1].ival))); } -#line 42003 "gram.c" /* yacc.c:1646 */ - break; - - case 1850: -#line 12562 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 42009 "gram.c" /* yacc.c:1646 */ - break; - - case 1851: -#line 12566 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42015 "gram.c" /* yacc.c:1646 */ - break; - - case 1852: -#line 12567 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42021 "gram.c" /* yacc.c:1646 */ - break; - - case 1853: -#line 12568 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42027 "gram.c" /* yacc.c:1646 */ - break; - - case 1854: -#line 12569 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42033 "gram.c" /* yacc.c:1646 */ - break; - - case 1855: -#line 12570 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42039 "gram.c" /* yacc.c:1646 */ - break; - - case 1856: -#line 12572 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-1].typnam); - (yyval.typnam)->typmods = (yyvsp[0].list); - } -#line 42048 "gram.c" /* yacc.c:1646 */ - break; - - case 1857: -#line 12577 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[-3].typnam); - (yyval.typnam)->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), - makeIntConst((yyvsp[-1].ival), (yylsp[-1]))); - } -#line 42058 "gram.c" /* yacc.c:1646 */ - break; - - case 1858: -#line 12596 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42064 "gram.c" /* yacc.c:1646 */ - break; - - case 1859: -#line 12597 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42070 "gram.c" /* yacc.c:1646 */ - break; - - case 1860: -#line 12598 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42076 "gram.c" /* yacc.c:1646 */ - break; - - case 1861: -#line 12599 "gram.y" /* yacc.c:1646 */ - { (yyval.typnam) = (yyvsp[0].typnam); } -#line 42082 "gram.c" /* yacc.c:1646 */ - break; - - case 1862: -#line 12611 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = makeTypeName((yyvsp[-1].str)); - (yyval.typnam)->typmods = (yyvsp[0].list); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42092 "gram.c" /* yacc.c:1646 */ - break; - - case 1863: -#line 12617 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[-2].str)), (yyvsp[-1].list))); - (yyval.typnam)->typmods = (yyvsp[0].list); - (yyval.typnam)->location = (yylsp[-2]); - } -#line 42102 "gram.c" /* yacc.c:1646 */ - break; - - case 1864: -#line 12624 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 42108 "gram.c" /* yacc.c:1646 */ - break; - - case 1865: -#line 12625 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 42114 "gram.c" /* yacc.c:1646 */ - break; - - case 1866: -#line 12632 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("int4"); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42123 "gram.c" /* yacc.c:1646 */ - break; - - case 1867: -#line 12637 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("int4"); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42132 "gram.c" /* yacc.c:1646 */ - break; - - case 1868: -#line 12642 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("int2"); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42141 "gram.c" /* yacc.c:1646 */ - break; - - case 1869: -#line 12647 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("int8"); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42150 "gram.c" /* yacc.c:1646 */ - break; - - case 1870: -#line 12652 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("float4"); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42159 "gram.c" /* yacc.c:1646 */ - break; - - case 1871: -#line 12657 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42168 "gram.c" /* yacc.c:1646 */ - break; - - case 1872: -#line 12662 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("float8"); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42177 "gram.c" /* yacc.c:1646 */ - break; - - case 1873: -#line 12667 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("numeric"); - (yyval.typnam)->typmods = (yyvsp[0].list); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42187 "gram.c" /* yacc.c:1646 */ - break; - - case 1874: -#line 12673 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("numeric"); - (yyval.typnam)->typmods = (yyvsp[0].list); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42197 "gram.c" /* yacc.c:1646 */ - break; - - case 1875: -#line 12679 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("numeric"); - (yyval.typnam)->typmods = (yyvsp[0].list); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42207 "gram.c" /* yacc.c:1646 */ - break; - - case 1876: -#line 12685 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("bool"); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42216 "gram.c" /* yacc.c:1646 */ - break; - - case 1877: -#line 12692 "gram.y" /* yacc.c:1646 */ - { - /* - * Check FLOAT() precision limits assuming IEEE floating - * types - thomas 1997-09-18 - */ - if ((yyvsp[-1].ival) < 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("precision for type float must be at least 1 bit"), - parser_errposition((yylsp[-1])))); - else if ((yyvsp[-1].ival) <= 24) - (yyval.typnam) = SystemTypeName("float4"); - else if ((yyvsp[-1].ival) <= 53) - (yyval.typnam) = SystemTypeName("float8"); - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("precision for type float must be less than 54 bits"), - parser_errposition((yylsp[-1])))); - } -#line 42241 "gram.c" /* yacc.c:1646 */ - break; - - case 1878: -#line 12713 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("float8"); - } -#line 42249 "gram.c" /* yacc.c:1646 */ - break; - - case 1879: -#line 12723 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - } -#line 42257 "gram.c" /* yacc.c:1646 */ - break; - - case 1880: -#line 12727 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - } -#line 42265 "gram.c" /* yacc.c:1646 */ - break; - - case 1881: -#line 12735 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - } -#line 42273 "gram.c" /* yacc.c:1646 */ - break; - - case 1882: -#line 12739 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - (yyval.typnam)->typmods = NIL; - } -#line 42282 "gram.c" /* yacc.c:1646 */ - break; - - case 1883: -#line 12747 "gram.y" /* yacc.c:1646 */ - { - char *typname; - - typname = (yyvsp[-3].boolean) ? "varbit" : "bit"; - (yyval.typnam) = SystemTypeName(typname); - (yyval.typnam)->typmods = (yyvsp[-1].list); - (yyval.typnam)->location = (yylsp[-4]); - } -#line 42295 "gram.c" /* yacc.c:1646 */ - break; - - case 1884: -#line 12759 "gram.y" /* yacc.c:1646 */ - { - /* bit defaults to bit(1), varbit to no limit */ - if ((yyvsp[0].boolean)) - { - (yyval.typnam) = SystemTypeName("varbit"); - } - else - { - (yyval.typnam) = SystemTypeName("bit"); - (yyval.typnam)->typmods = list_make1(makeIntConst(1, -1)); - } - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42313 "gram.c" /* yacc.c:1646 */ - break; - - case 1885: -#line 12780 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - } -#line 42321 "gram.c" /* yacc.c:1646 */ - break; - - case 1886: -#line 12784 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - } -#line 42329 "gram.c" /* yacc.c:1646 */ - break; - - case 1887: -#line 12790 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = (yyvsp[0].typnam); - } -#line 42337 "gram.c" /* yacc.c:1646 */ - break; - - case 1888: -#line 12794 "gram.y" /* yacc.c:1646 */ - { - /* Length was not specified so allow to be unrestricted. - * This handles problems with fixed-length (bpchar) strings - * which in column definitions must default to a length - * of one, but should not be constrained if the length - * was not specified. - */ - (yyval.typnam) = (yyvsp[0].typnam); - (yyval.typnam)->typmods = NIL; - } -#line 42352 "gram.c" /* yacc.c:1646 */ - break; - - case 1889: -#line 12807 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName((yyvsp[-3].str)); - (yyval.typnam)->typmods = list_make1(makeIntConst((yyvsp[-1].ival), (yylsp[-1]))); - (yyval.typnam)->location = (yylsp[-3]); - } -#line 42362 "gram.c" /* yacc.c:1646 */ - break; - - case 1890: -#line 12815 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName((yyvsp[0].str)); - /* char defaults to char(1), varchar to no limit */ - if (strcmp((yyvsp[0].str), "bpchar") == 0) - (yyval.typnam)->typmods = list_make1(makeIntConst(1, -1)); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42374 "gram.c" /* yacc.c:1646 */ - break; - - case 1891: -#line 12825 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].boolean) ? "varchar": "bpchar"; } -#line 42380 "gram.c" /* yacc.c:1646 */ - break; - - case 1892: -#line 12827 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].boolean) ? "varchar": "bpchar"; } -#line 42386 "gram.c" /* yacc.c:1646 */ - break; - - case 1893: -#line 12829 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "varchar"; } -#line 42392 "gram.c" /* yacc.c:1646 */ - break; - - case 1894: -#line 12831 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].boolean) ? "varchar": "bpchar"; } -#line 42398 "gram.c" /* yacc.c:1646 */ - break; - - case 1895: -#line 12833 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].boolean) ? "varchar": "bpchar"; } -#line 42404 "gram.c" /* yacc.c:1646 */ - break; - - case 1896: -#line 12835 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].boolean) ? "varchar": "bpchar"; } -#line 42410 "gram.c" /* yacc.c:1646 */ - break; - - case 1897: -#line 12839 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 42416 "gram.c" /* yacc.c:1646 */ - break; - - case 1898: -#line 12840 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 42422 "gram.c" /* yacc.c:1646 */ - break; - - case 1899: -#line 12848 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].boolean)) - (yyval.typnam) = SystemTypeName("timestamptz"); - else - (yyval.typnam) = SystemTypeName("timestamp"); - (yyval.typnam)->typmods = list_make1(makeIntConst((yyvsp[-2].ival), (yylsp[-2]))); - (yyval.typnam)->location = (yylsp[-4]); - } -#line 42435 "gram.c" /* yacc.c:1646 */ - break; - - case 1900: -#line 12857 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].boolean)) - (yyval.typnam) = SystemTypeName("timestamptz"); - else - (yyval.typnam) = SystemTypeName("timestamp"); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42447 "gram.c" /* yacc.c:1646 */ - break; - - case 1901: -#line 12865 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].boolean)) - (yyval.typnam) = SystemTypeName("timetz"); - else - (yyval.typnam) = SystemTypeName("time"); - (yyval.typnam)->typmods = list_make1(makeIntConst((yyvsp[-2].ival), (yylsp[-2]))); - (yyval.typnam)->location = (yylsp[-4]); - } -#line 42460 "gram.c" /* yacc.c:1646 */ - break; - - case 1902: -#line 12874 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].boolean)) - (yyval.typnam) = SystemTypeName("timetz"); - else - (yyval.typnam) = SystemTypeName("time"); - (yyval.typnam)->location = (yylsp[-1]); - } -#line 42472 "gram.c" /* yacc.c:1646 */ - break; - - case 1903: -#line 12885 "gram.y" /* yacc.c:1646 */ - { - (yyval.typnam) = SystemTypeName("interval"); - (yyval.typnam)->location = (yylsp[0]); - } -#line 42481 "gram.c" /* yacc.c:1646 */ - break; - - case 1904: -#line 12892 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 42487 "gram.c" /* yacc.c:1646 */ - break; - - case 1905: -#line 12893 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 42493 "gram.c" /* yacc.c:1646 */ - break; - - case 1906: -#line 12894 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 42499 "gram.c" /* yacc.c:1646 */ - break; - - case 1907: -#line 12899 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR), (yylsp[0]))); } -#line 42505 "gram.c" /* yacc.c:1646 */ - break; - - case 1908: -#line 12901 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MONTH), (yylsp[0]))); } -#line 42511 "gram.c" /* yacc.c:1646 */ - break; - - case 1909: -#line 12903 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY), (yylsp[0]))); } -#line 42517 "gram.c" /* yacc.c:1646 */ - break; - - case 1910: -#line 12905 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR), (yylsp[0]))); } -#line 42523 "gram.c" /* yacc.c:1646 */ - break; - - case 1911: -#line 12907 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), (yylsp[0]))); } -#line 42529 "gram.c" /* yacc.c:1646 */ - break; - - case 1912: -#line 12909 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 42535 "gram.c" /* yacc.c:1646 */ - break; - - case 1913: -#line 12911 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR) | - INTERVAL_MASK(MONTH), (yylsp[-2]))); - } -#line 42544 "gram.c" /* yacc.c:1646 */ - break; - - case 1914: -#line 12916 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | - INTERVAL_MASK(HOUR), (yylsp[-2]))); - } -#line 42553 "gram.c" /* yacc.c:1646 */ - break; - - case 1915: -#line 12921 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | - INTERVAL_MASK(HOUR) | - INTERVAL_MASK(MINUTE), (yylsp[-2]))); - } -#line 42563 "gram.c" /* yacc.c:1646 */ - break; - - case 1916: -#line 12927 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = (yyvsp[0].list); - linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(DAY) | - INTERVAL_MASK(HOUR) | - INTERVAL_MASK(MINUTE) | - INTERVAL_MASK(SECOND), (yylsp[-2])); - } -#line 42575 "gram.c" /* yacc.c:1646 */ - break; - - case 1917: -#line 12935 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | - INTERVAL_MASK(MINUTE), (yylsp[-2]))); - } -#line 42584 "gram.c" /* yacc.c:1646 */ - break; - - case 1918: -#line 12940 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = (yyvsp[0].list); - linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(HOUR) | - INTERVAL_MASK(MINUTE) | - INTERVAL_MASK(SECOND), (yylsp[-2])); - } -#line 42595 "gram.c" /* yacc.c:1646 */ - break; - - case 1919: -#line 12947 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = (yyvsp[0].list); - linitial((yyval.list)) = makeIntConst(INTERVAL_MASK(MINUTE) | - INTERVAL_MASK(SECOND), (yylsp[-2])); - } -#line 42605 "gram.c" /* yacc.c:1646 */ - break; - - case 1920: -#line 12953 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 42611 "gram.c" /* yacc.c:1646 */ - break; - - case 1921: -#line 12958 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[0]))); - } -#line 42619 "gram.c" /* yacc.c:1646 */ - break; - - case 1922: -#line 12962 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[-3])), - makeIntConst((yyvsp[-1].ival), (yylsp[-1]))); - } -#line 42628 "gram.c" /* yacc.c:1646 */ - break; - - case 1923: -#line 12997 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 42634 "gram.c" /* yacc.c:1646 */ - break; - - case 1924: -#line 12999 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeTypeCast((yyvsp[-2].node), (yyvsp[0].typnam), (yylsp[-1])); } -#line 42640 "gram.c" /* yacc.c:1646 */ - break; - - case 1925: -#line 13001 "gram.y" /* yacc.c:1646 */ - { - CollateClause *n = makeNode(CollateClause); - n->arg = (yyvsp[-2].node); - n->collname = (yyvsp[0].list); - n->location = (yylsp[-1]); - (yyval.node) = (Node *) n; - } -#line 42652 "gram.c" /* yacc.c:1646 */ - break; - - case 1926: -#line 13009 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("timezone"), - list_make2((yyvsp[0].node), (yyvsp[-4].node)), - (yylsp[-3])); - } -#line 42662 "gram.c" /* yacc.c:1646 */ - break; - - case 1927: -#line 13024 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, (yyvsp[0].node), (yylsp[-1])); } -#line 42668 "gram.c" /* yacc.c:1646 */ - break; - - case 1928: -#line 13026 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = doNegate((yyvsp[0].node), (yylsp[-1])); } -#line 42674 "gram.c" /* yacc.c:1646 */ - break; - - case 1929: -#line 13028 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42680 "gram.c" /* yacc.c:1646 */ - break; - - case 1930: -#line 13030 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42686 "gram.c" /* yacc.c:1646 */ - break; - - case 1931: -#line 13032 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42692 "gram.c" /* yacc.c:1646 */ - break; - - case 1932: -#line 13034 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42698 "gram.c" /* yacc.c:1646 */ - break; - - case 1933: -#line 13036 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42704 "gram.c" /* yacc.c:1646 */ - break; - - case 1934: -#line 13038 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42710 "gram.c" /* yacc.c:1646 */ - break; - - case 1935: -#line 13040 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42716 "gram.c" /* yacc.c:1646 */ - break; - - case 1936: -#line 13042 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42722 "gram.c" /* yacc.c:1646 */ - break; - - case 1937: -#line 13044 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42728 "gram.c" /* yacc.c:1646 */ - break; - - case 1938: -#line 13046 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42734 "gram.c" /* yacc.c:1646 */ - break; - - case 1939: -#line 13048 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42740 "gram.c" /* yacc.c:1646 */ - break; - - case 1940: -#line 13050 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42746 "gram.c" /* yacc.c:1646 */ - break; - - case 1941: -#line 13053 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[-1].list), (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42752 "gram.c" /* yacc.c:1646 */ - break; - - case 1942: -#line 13055 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[-1].list), NULL, (yyvsp[0].node), (yylsp[-1])); } -#line 42758 "gram.c" /* yacc.c:1646 */ - break; - - case 1943: -#line 13057 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[0].list), (yyvsp[-1].node), NULL, (yylsp[0])); } -#line 42764 "gram.c" /* yacc.c:1646 */ - break; - - case 1944: -#line 13060 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeAndExpr((yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42770 "gram.c" /* yacc.c:1646 */ - break; - - case 1945: -#line 13062 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeOrExpr((yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 42776 "gram.c" /* yacc.c:1646 */ - break; - - case 1946: -#line 13064 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeNotExpr((yyvsp[0].node), (yylsp[-1])); } -#line 42782 "gram.c" /* yacc.c:1646 */ - break; - - case 1947: -#line 13066 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeNotExpr((yyvsp[0].node), (yylsp[-1])); } -#line 42788 "gram.c" /* yacc.c:1646 */ - break; - - case 1948: -#line 13069 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~", - (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); - } -#line 42797 "gram.c" /* yacc.c:1646 */ - break; - - case 1949: -#line 13074 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-3])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~", - (yyvsp[-4].node), (Node *) n, (yylsp[-3])); - } -#line 42809 "gram.c" /* yacc.c:1646 */ - break; - - case 1950: -#line 13082 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~", - (yyvsp[-3].node), (yyvsp[0].node), (yylsp[-2])); - } -#line 42818 "gram.c" /* yacc.c:1646 */ - break; - - case 1951: -#line 13087 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-4])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~", - (yyvsp[-5].node), (Node *) n, (yylsp[-4])); - } -#line 42830 "gram.c" /* yacc.c:1646 */ - break; - - case 1952: -#line 13095 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*", - (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); - } -#line 42839 "gram.c" /* yacc.c:1646 */ - break; - - case 1953: -#line 13100 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-3])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*", - (yyvsp[-4].node), (Node *) n, (yylsp[-3])); - } -#line 42851 "gram.c" /* yacc.c:1646 */ - break; - - case 1954: -#line 13108 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*", - (yyvsp[-3].node), (yyvsp[0].node), (yylsp[-2])); - } -#line 42860 "gram.c" /* yacc.c:1646 */ - break; - - case 1955: -#line 13113 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-4])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*", - (yyvsp[-5].node), (Node *) n, (yylsp[-4])); - } -#line 42872 "gram.c" /* yacc.c:1646 */ - break; - - case 1956: -#line 13122 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2((yyvsp[0].node), makeNullAConst(-1)), - (yylsp[-2])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", - (yyvsp[-3].node), (Node *) n, (yylsp[-2])); - } -#line 42884 "gram.c" /* yacc.c:1646 */ - break; - - case 1957: -#line 13130 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-4])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", - (yyvsp[-5].node), (Node *) n, (yylsp[-4])); - } -#line 42896 "gram.c" /* yacc.c:1646 */ - break; - - case 1958: -#line 13138 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2((yyvsp[0].node), makeNullAConst(-1)), - (yylsp[-3])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", - (yyvsp[-4].node), (Node *) n, (yylsp[-3])); - } -#line 42908 "gram.c" /* yacc.c:1646 */ - break; - - case 1959: -#line 13146 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-5])); - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", - (yyvsp[-6].node), (Node *) n, (yylsp[-5])); - } -#line 42920 "gram.c" /* yacc.c:1646 */ - break; - - case 1960: -#line 13164 "gram.y" /* yacc.c:1646 */ - { - NullTest *n = makeNode(NullTest); - n->arg = (Expr *) (yyvsp[-2].node); - n->nulltesttype = IS_NULL; - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 42932 "gram.c" /* yacc.c:1646 */ - break; - - case 1961: -#line 13172 "gram.y" /* yacc.c:1646 */ - { - NullTest *n = makeNode(NullTest); - n->arg = (Expr *) (yyvsp[-1].node); - n->nulltesttype = IS_NULL; - n->location = (yylsp[0]); - (yyval.node) = (Node *)n; - } -#line 42944 "gram.c" /* yacc.c:1646 */ - break; - - case 1962: -#line 13180 "gram.y" /* yacc.c:1646 */ - { - NullTest *n = makeNode(NullTest); - n->arg = (Expr *) (yyvsp[-3].node); - n->nulltesttype = IS_NOT_NULL; - n->location = (yylsp[-2]); - (yyval.node) = (Node *)n; - } -#line 42956 "gram.c" /* yacc.c:1646 */ - break; - - case 1963: -#line 13188 "gram.y" /* yacc.c:1646 */ - { - NullTest *n = makeNode(NullTest); - n->arg = (Expr *) (yyvsp[-1].node); - n->nulltesttype = IS_NOT_NULL; - n->location = (yylsp[0]); - (yyval.node) = (Node *)n; - } -#line 42968 "gram.c" /* yacc.c:1646 */ - break; - - case 1964: -#line 13196 "gram.y" /* yacc.c:1646 */ - { - if (list_length((yyvsp[-2].list)) != 2) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("wrong number of parameters on left side of OVERLAPS expression"), - parser_errposition((yylsp[-2])))); - if (list_length((yyvsp[0].list)) != 2) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("wrong number of parameters on right side of OVERLAPS expression"), - parser_errposition((yylsp[0])))); - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("overlaps"), - list_concat((yyvsp[-2].list), (yyvsp[0].list)), - (yylsp[-1])); - } -#line 42988 "gram.c" /* yacc.c:1646 */ - break; - - case 1965: -#line 13212 "gram.y" /* yacc.c:1646 */ - { - BooleanTest *b = makeNode(BooleanTest); - b->arg = (Expr *) (yyvsp[-2].node); - b->booltesttype = IS_TRUE; - b->location = (yylsp[-1]); - (yyval.node) = (Node *)b; - } -#line 43000 "gram.c" /* yacc.c:1646 */ - break; - - case 1966: -#line 13220 "gram.y" /* yacc.c:1646 */ - { - BooleanTest *b = makeNode(BooleanTest); - b->arg = (Expr *) (yyvsp[-3].node); - b->booltesttype = IS_NOT_TRUE; - b->location = (yylsp[-2]); - (yyval.node) = (Node *)b; - } -#line 43012 "gram.c" /* yacc.c:1646 */ - break; - - case 1967: -#line 13228 "gram.y" /* yacc.c:1646 */ - { - BooleanTest *b = makeNode(BooleanTest); - b->arg = (Expr *) (yyvsp[-2].node); - b->booltesttype = IS_FALSE; - b->location = (yylsp[-1]); - (yyval.node) = (Node *)b; - } -#line 43024 "gram.c" /* yacc.c:1646 */ - break; - - case 1968: -#line 13236 "gram.y" /* yacc.c:1646 */ - { - BooleanTest *b = makeNode(BooleanTest); - b->arg = (Expr *) (yyvsp[-3].node); - b->booltesttype = IS_NOT_FALSE; - b->location = (yylsp[-2]); - (yyval.node) = (Node *)b; - } -#line 43036 "gram.c" /* yacc.c:1646 */ - break; - - case 1969: -#line 13244 "gram.y" /* yacc.c:1646 */ - { - BooleanTest *b = makeNode(BooleanTest); - b->arg = (Expr *) (yyvsp[-2].node); - b->booltesttype = IS_UNKNOWN; - b->location = (yylsp[-1]); - (yyval.node) = (Node *)b; - } -#line 43048 "gram.c" /* yacc.c:1646 */ - break; - - case 1970: -#line 13252 "gram.y" /* yacc.c:1646 */ - { - BooleanTest *b = makeNode(BooleanTest); - b->arg = (Expr *) (yyvsp[-3].node); - b->booltesttype = IS_NOT_UNKNOWN; - b->location = (yylsp[-2]); - (yyval.node) = (Node *)b; - } -#line 43060 "gram.c" /* yacc.c:1646 */ - break; - - case 1971: -#line 13260 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", (yyvsp[-4].node), (yyvsp[0].node), (yylsp[-3])); - } -#line 43068 "gram.c" /* yacc.c:1646 */ - break; - - case 1972: -#line 13264 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", (yyvsp[-5].node), (yyvsp[0].node), (yylsp[-4])); - } -#line 43076 "gram.c" /* yacc.c:1646 */ - break; - - case 1973: -#line 13268 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", (yyvsp[-5].node), (Node *) (yyvsp[-1].list), (yylsp[-4])); - } -#line 43084 "gram.c" /* yacc.c:1646 */ - break; - - case 1974: -#line 13272 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", (yyvsp[-6].node), (Node *) (yyvsp[-1].list), (yylsp[-5])); - } -#line 43092 "gram.c" /* yacc.c:1646 */ - break; - - case 1975: -#line 13276 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_BETWEEN, - "BETWEEN", - (yyvsp[-5].node), - (Node *) list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-4])); - } -#line 43104 "gram.c" /* yacc.c:1646 */ - break; - - case 1976: -#line 13284 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_NOT_BETWEEN, - "NOT BETWEEN", - (yyvsp[-6].node), - (Node *) list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-5])); - } -#line 43116 "gram.c" /* yacc.c:1646 */ - break; - - case 1977: -#line 13292 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_BETWEEN_SYM, - "BETWEEN SYMMETRIC", - (yyvsp[-5].node), - (Node *) list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-4])); - } -#line 43128 "gram.c" /* yacc.c:1646 */ - break; - - case 1978: -#line 13300 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_NOT_BETWEEN_SYM, - "NOT BETWEEN SYMMETRIC", - (yyvsp[-6].node), - (Node *) list_make2((yyvsp[-2].node), (yyvsp[0].node)), - (yylsp[-5])); - } -#line 43140 "gram.c" /* yacc.c:1646 */ - break; - - case 1979: -#line 13308 "gram.y" /* yacc.c:1646 */ - { - /* in_expr returns a SubLink or a list of a_exprs */ - if (IsA((yyvsp[0].node), SubLink)) - { - /* generate foo = ANY (subquery) */ - SubLink *n = (SubLink *) (yyvsp[0].node); - n->subLinkType = ANY_SUBLINK; - n->subLinkId = 0; - n->testexpr = (yyvsp[-2].node); - n->operName = NIL; /* show it's IN not = ANY */ - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } - else - { - /* generate scalar IN expression */ - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); - } - } -#line 43164 "gram.c" /* yacc.c:1646 */ - break; - - case 1980: -#line 13328 "gram.y" /* yacc.c:1646 */ - { - /* in_expr returns a SubLink or a list of a_exprs */ - if (IsA((yyvsp[0].node), SubLink)) - { - /* generate NOT (foo = ANY (subquery)) */ - /* Make an = ANY node */ - SubLink *n = (SubLink *) (yyvsp[0].node); - n->subLinkType = ANY_SUBLINK; - n->subLinkId = 0; - n->testexpr = (yyvsp[-3].node); - n->operName = NIL; /* show it's IN not = ANY */ - n->location = (yylsp[-2]); - /* Stick a NOT on top; must have same parse location */ - (yyval.node) = makeNotExpr((Node *) n, (yylsp[-2])); - } - else - { - /* generate scalar NOT IN expression */ - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", (yyvsp[-3].node), (yyvsp[0].node), (yylsp[-2])); - } - } -#line 43190 "gram.c" /* yacc.c:1646 */ - break; - - case 1981: -#line 13350 "gram.y" /* yacc.c:1646 */ - { - SubLink *n = makeNode(SubLink); - n->subLinkType = (yyvsp[-1].ival); - n->subLinkId = 0; - n->testexpr = (yyvsp[-3].node); - n->operName = (yyvsp[-2].list); - n->subselect = (yyvsp[0].node); - n->location = (yylsp[-2]); - (yyval.node) = (Node *)n; - } -#line 43205 "gram.c" /* yacc.c:1646 */ - break; - - case 1982: -#line 13361 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[-3].ival) == ANY_SUBLINK) - (yyval.node) = (Node *) makeA_Expr(AEXPR_OP_ANY, (yyvsp[-4].list), (yyvsp[-5].node), (yyvsp[-1].node), (yylsp[-4])); - else - (yyval.node) = (Node *) makeA_Expr(AEXPR_OP_ALL, (yyvsp[-4].list), (yyvsp[-5].node), (yyvsp[-1].node), (yylsp[-4])); - } -#line 43216 "gram.c" /* yacc.c:1646 */ - break; - - case 1983: -#line 13368 "gram.y" /* yacc.c:1646 */ - { - /* Not sure how to get rid of the parentheses - * but there are lots of shift/reduce errors without them. - * - * Should be able to implement this by plopping the entire - * select into a node, then transforming the target expressions - * from whatever they are into count(*), and testing the - * entire result equal to one. - * But, will probably implement a separate node in the executor. - */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("UNIQUE predicate is not yet implemented"), - parser_errposition((yylsp[-1])))); - } -#line 43236 "gram.c" /* yacc.c:1646 */ - break; - - case 1984: -#line 13384 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_DOCUMENT, NULL, NIL, - list_make1((yyvsp[-2].node)), (yylsp[-1])); - } -#line 43245 "gram.c" /* yacc.c:1646 */ - break; - - case 1985: -#line 13389 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL, - list_make1((yyvsp[-3].node)), (yylsp[-2])), - (yylsp[-2])); - } -#line 43255 "gram.c" /* yacc.c:1646 */ - break; - - case 1986: -#line 13395 "gram.y" /* yacc.c:1646 */ - { - /* - * The SQL spec only allows DEFAULT in "contextually typed - * expressions", but for us, it's easier to allow it in - * any a_expr and then throw error during parse analysis - * if it's in an inappropriate context. This way also - * lets us say something smarter than "syntax error". - */ - SetToDefault *n = makeNode(SetToDefault); - /* parse analysis will fill in the rest */ - n->location = (yylsp[0]); - (yyval.node) = (Node *)n; - } -#line 43273 "gram.c" /* yacc.c:1646 */ - break; - - case 1987: -#line 13420 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43279 "gram.c" /* yacc.c:1646 */ - break; - - case 1988: -#line 13422 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeTypeCast((yyvsp[-2].node), (yyvsp[0].typnam), (yylsp[-1])); } -#line 43285 "gram.c" /* yacc.c:1646 */ - break; - - case 1989: -#line 13424 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, (yyvsp[0].node), (yylsp[-1])); } -#line 43291 "gram.c" /* yacc.c:1646 */ - break; - - case 1990: -#line 13426 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = doNegate((yyvsp[0].node), (yylsp[-1])); } -#line 43297 "gram.c" /* yacc.c:1646 */ - break; - - case 1991: -#line 13428 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43303 "gram.c" /* yacc.c:1646 */ - break; - - case 1992: -#line 13430 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43309 "gram.c" /* yacc.c:1646 */ - break; - - case 1993: -#line 13432 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43315 "gram.c" /* yacc.c:1646 */ - break; - - case 1994: -#line 13434 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43321 "gram.c" /* yacc.c:1646 */ - break; - - case 1995: -#line 13436 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43327 "gram.c" /* yacc.c:1646 */ - break; - - case 1996: -#line 13438 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43333 "gram.c" /* yacc.c:1646 */ - break; - - case 1997: -#line 13440 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43339 "gram.c" /* yacc.c:1646 */ - break; - - case 1998: -#line 13442 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43345 "gram.c" /* yacc.c:1646 */ - break; - - case 1999: -#line 13444 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43351 "gram.c" /* yacc.c:1646 */ - break; - - case 2000: -#line 13446 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43357 "gram.c" /* yacc.c:1646 */ - break; - - case 2001: -#line 13448 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43363 "gram.c" /* yacc.c:1646 */ - break; - - case 2002: -#line 13450 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43369 "gram.c" /* yacc.c:1646 */ - break; - - case 2003: -#line 13452 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[-1].list), (yyvsp[-2].node), (yyvsp[0].node), (yylsp[-1])); } -#line 43375 "gram.c" /* yacc.c:1646 */ - break; - - case 2004: -#line 13454 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[-1].list), NULL, (yyvsp[0].node), (yylsp[-1])); } -#line 43381 "gram.c" /* yacc.c:1646 */ - break; - - case 2005: -#line 13456 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *) makeA_Expr(AEXPR_OP, (yyvsp[0].list), (yyvsp[-1].node), NULL, (yylsp[0])); } -#line 43387 "gram.c" /* yacc.c:1646 */ - break; - - case 2006: -#line 13458 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", (yyvsp[-4].node), (yyvsp[0].node), (yylsp[-3])); - } -#line 43395 "gram.c" /* yacc.c:1646 */ - break; - - case 2007: -#line 13462 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", (yyvsp[-5].node), (yyvsp[0].node), (yylsp[-4])); - } -#line 43403 "gram.c" /* yacc.c:1646 */ - break; - - case 2008: -#line 13466 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", (yyvsp[-5].node), (Node *) (yyvsp[-1].list), (yylsp[-4])); - } -#line 43411 "gram.c" /* yacc.c:1646 */ - break; - - case 2009: -#line 13470 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", (yyvsp[-6].node), (Node *) (yyvsp[-1].list), (yylsp[-5])); - } -#line 43419 "gram.c" /* yacc.c:1646 */ - break; - - case 2010: -#line 13474 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_DOCUMENT, NULL, NIL, - list_make1((yyvsp[-2].node)), (yylsp[-1])); - } -#line 43428 "gram.c" /* yacc.c:1646 */ - break; - - case 2011: -#line 13479 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL, - list_make1((yyvsp[-3].node)), (yylsp[-2])), - (yylsp[-2])); - } -#line 43438 "gram.c" /* yacc.c:1646 */ - break; - - case 2012: -#line 13494 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43444 "gram.c" /* yacc.c:1646 */ - break; - - case 2013: -#line 13495 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43450 "gram.c" /* yacc.c:1646 */ - break; - - case 2014: -#line 13497 "gram.y" /* yacc.c:1646 */ - { - ParamRef *p = makeNode(ParamRef); - p->number = (yyvsp[-1].ival); - p->location = (yylsp[-1]); - if ((yyvsp[0].list)) - { - A_Indirection *n = makeNode(A_Indirection); - n->arg = (Node *) p; - n->indirection = check_indirection((yyvsp[0].list), yyscanner); - (yyval.node) = (Node *) n; - } - else - (yyval.node) = (Node *) p; - } -#line 43469 "gram.c" /* yacc.c:1646 */ - break; - - case 2015: -#line 13512 "gram.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].list)) - { - A_Indirection *n = makeNode(A_Indirection); - n->arg = (yyvsp[-2].node); - n->indirection = check_indirection((yyvsp[0].list), yyscanner); - (yyval.node) = (Node *)n; - } - else if (operator_precedence_warning) - { - /* - * If precedence warnings are enabled, insert - * AEXPR_PAREN nodes wrapping all explicitly - * parenthesized subexpressions; this prevents bogus - * warnings from being issued when the ordering has - * been forced by parentheses. Take care that an - * AEXPR_PAREN node has the same exprLocation as its - * child, so as not to cause surprising changes in - * error cursor positioning. - * - * In principle we should not be relying on a GUC to - * decide whether to insert AEXPR_PAREN nodes. - * However, since they have no effect except to - * suppress warnings, it's probably safe enough; and - * we'd just as soon not waste cycles on dummy parse - * nodes if we don't have to. - */ - (yyval.node) = (Node *) makeA_Expr(AEXPR_PAREN, NIL, (yyvsp[-2].node), NULL, - exprLocation((yyvsp[-2].node))); - } - else - (yyval.node) = (yyvsp[-2].node); - } -#line 43507 "gram.c" /* yacc.c:1646 */ - break; - - case 2016: -#line 13546 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43513 "gram.c" /* yacc.c:1646 */ - break; - - case 2017: -#line 13548 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43519 "gram.c" /* yacc.c:1646 */ - break; - - case 2018: -#line 13550 "gram.y" /* yacc.c:1646 */ - { - SubLink *n = makeNode(SubLink); - n->subLinkType = EXPR_SUBLINK; - n->subLinkId = 0; - n->testexpr = NULL; - n->operName = NIL; - n->subselect = (yyvsp[0].node); - n->location = (yylsp[0]); - (yyval.node) = (Node *)n; - } -#line 43534 "gram.c" /* yacc.c:1646 */ - break; - - case 2019: -#line 13561 "gram.y" /* yacc.c:1646 */ - { - /* - * Because the select_with_parens nonterminal is designed - * to "eat" as many levels of parens as possible, the - * '(' a_expr ')' opt_indirection production above will - * fail to match a sub-SELECT with indirection decoration; - * the sub-SELECT won't be regarded as an a_expr as long - * as there are parens around it. To support applying - * subscripting or field selection to a sub-SELECT result, - * we need this redundant-looking production. - */ - SubLink *n = makeNode(SubLink); - A_Indirection *a = makeNode(A_Indirection); - n->subLinkType = EXPR_SUBLINK; - n->subLinkId = 0; - n->testexpr = NULL; - n->operName = NIL; - n->subselect = (yyvsp[-1].node); - n->location = (yylsp[-1]); - a->arg = (Node *)n; - a->indirection = check_indirection((yyvsp[0].list), yyscanner); - (yyval.node) = (Node *)a; - } -#line 43562 "gram.c" /* yacc.c:1646 */ - break; - - case 2020: -#line 13585 "gram.y" /* yacc.c:1646 */ - { - SubLink *n = makeNode(SubLink); - n->subLinkType = EXISTS_SUBLINK; - n->subLinkId = 0; - n->testexpr = NULL; - n->operName = NIL; - n->subselect = (yyvsp[0].node); - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 43577 "gram.c" /* yacc.c:1646 */ - break; - - case 2021: -#line 13596 "gram.y" /* yacc.c:1646 */ - { - SubLink *n = makeNode(SubLink); - n->subLinkType = ARRAY_SUBLINK; - n->subLinkId = 0; - n->testexpr = NULL; - n->operName = NIL; - n->subselect = (yyvsp[0].node); - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 43592 "gram.c" /* yacc.c:1646 */ - break; - - case 2022: -#line 13607 "gram.y" /* yacc.c:1646 */ - { - A_ArrayExpr *n = castNode(A_ArrayExpr, (yyvsp[0].node)); - /* point outermost A_ArrayExpr to the ARRAY keyword */ - n->location = (yylsp[-1]); - (yyval.node) = (Node *)n; - } -#line 43603 "gram.c" /* yacc.c:1646 */ - break; - - case 2023: -#line 13614 "gram.y" /* yacc.c:1646 */ - { - RowExpr *r = makeNode(RowExpr); - r->args = (yyvsp[0].list); - r->row_typeid = InvalidOid; /* not analyzed yet */ - r->colnames = NIL; /* to be filled in during analysis */ - r->row_format = COERCE_EXPLICIT_CALL; /* abuse */ - r->location = (yylsp[0]); - (yyval.node) = (Node *)r; - } -#line 43617 "gram.c" /* yacc.c:1646 */ - break; - - case 2024: -#line 13624 "gram.y" /* yacc.c:1646 */ - { - RowExpr *r = makeNode(RowExpr); - r->args = (yyvsp[0].list); - r->row_typeid = InvalidOid; /* not analyzed yet */ - r->colnames = NIL; /* to be filled in during analysis */ - r->row_format = COERCE_IMPLICIT_CAST; /* abuse */ - r->location = (yylsp[0]); - (yyval.node) = (Node *)r; - } -#line 43631 "gram.c" /* yacc.c:1646 */ - break; - - case 2025: -#line 13634 "gram.y" /* yacc.c:1646 */ - { - GroupingFunc *g = makeNode(GroupingFunc); - g->args = (yyvsp[-1].list); - g->location = (yylsp[-3]); - (yyval.node) = (Node *)g; - } -#line 43642 "gram.c" /* yacc.c:1646 */ - break; - - case 2026: -#line 13643 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeFuncCall((yyvsp[-2].list), NIL, (yylsp[-2])); - } -#line 43650 "gram.c" /* yacc.c:1646 */ - break; - - case 2027: -#line 13647 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall((yyvsp[-4].list), (yyvsp[-2].list), (yylsp[-4])); - n->agg_order = (yyvsp[-1].list); - (yyval.node) = (Node *)n; - } -#line 43660 "gram.c" /* yacc.c:1646 */ - break; - - case 2028: -#line 13653 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall((yyvsp[-5].list), list_make1((yyvsp[-2].node)), (yylsp[-5])); - n->func_variadic = true; - n->agg_order = (yyvsp[-1].list); - (yyval.node) = (Node *)n; - } -#line 43671 "gram.c" /* yacc.c:1646 */ - break; - - case 2029: -#line 13660 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall((yyvsp[-7].list), lappend((yyvsp[-5].list), (yyvsp[-2].node)), (yylsp[-7])); - n->func_variadic = true; - n->agg_order = (yyvsp[-1].list); - (yyval.node) = (Node *)n; - } -#line 43682 "gram.c" /* yacc.c:1646 */ - break; - - case 2030: -#line 13667 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall((yyvsp[-5].list), (yyvsp[-2].list), (yylsp[-5])); - n->agg_order = (yyvsp[-1].list); - /* Ideally we'd mark the FuncCall node to indicate - * "must be an aggregate", but there's no provision - * for that in FuncCall at the moment. - */ - (yyval.node) = (Node *)n; - } -#line 43696 "gram.c" /* yacc.c:1646 */ - break; - - case 2031: -#line 13677 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = makeFuncCall((yyvsp[-5].list), (yyvsp[-2].list), (yylsp[-5])); - n->agg_order = (yyvsp[-1].list); - n->agg_distinct = true; - (yyval.node) = (Node *)n; - } -#line 43707 "gram.c" /* yacc.c:1646 */ - break; - - case 2032: -#line 13684 "gram.y" /* yacc.c:1646 */ - { - /* - * We consider AGGREGATE(*) to invoke a parameterless - * aggregate. This does the right thing for COUNT(*), - * and there are no other aggregates in SQL that accept - * '*' as parameter. - * - * The FuncCall node is also marked agg_star = true, - * so that later processing can detect what the argument - * really was. - */ - FuncCall *n = makeFuncCall((yyvsp[-3].list), NIL, (yylsp[-3])); - n->agg_star = true; - (yyval.node) = (Node *)n; - } -#line 43727 "gram.c" /* yacc.c:1646 */ - break; - - case 2033: -#line 13712 "gram.y" /* yacc.c:1646 */ - { - FuncCall *n = (FuncCall *) (yyvsp[-3].node); - /* - * The order clause for WITHIN GROUP and the one for - * plain-aggregate ORDER BY share a field, so we have to - * check here that at most one is present. We also check - * for DISTINCT and VARIADIC here to give a better error - * location. Other consistency checks are deferred to - * parse analysis. - */ - if ((yyvsp[-2].list) != NIL) - { - if (n->agg_order != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("cannot use multiple ORDER BY clauses with WITHIN GROUP"), - parser_errposition((yylsp[-2])))); - if (n->agg_distinct) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("cannot use DISTINCT with WITHIN GROUP"), - parser_errposition((yylsp[-2])))); - if (n->func_variadic) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("cannot use VARIADIC with WITHIN GROUP"), - parser_errposition((yylsp[-2])))); - n->agg_order = (yyvsp[-2].list); - n->agg_within_group = true; - } - n->agg_filter = (yyvsp[-1].node); - n->over = (yyvsp[0].windef); - (yyval.node) = (Node *) n; - } -#line 43766 "gram.c" /* yacc.c:1646 */ - break; - - case 2034: -#line 13747 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43772 "gram.c" /* yacc.c:1646 */ - break; - - case 2035: -#line 13757 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43778 "gram.c" /* yacc.c:1646 */ - break; - - case 2036: -#line 13758 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 43784 "gram.c" /* yacc.c:1646 */ - break; - - case 2037: -#line 13766 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("pg_collation_for"), - list_make1((yyvsp[-1].node)), - (yylsp[-4])); - } -#line 43794 "gram.c" /* yacc.c:1646 */ - break; - - case 2038: -#line 13772 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_DATE, -1, (yylsp[0])); - } -#line 43802 "gram.c" /* yacc.c:1646 */ - break; - - case 2039: -#line 13776 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_TIME, -1, (yylsp[0])); - } -#line 43810 "gram.c" /* yacc.c:1646 */ - break; - - case 2040: -#line 13780 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_TIME_N, (yyvsp[-1].ival), (yylsp[-3])); - } -#line 43818 "gram.c" /* yacc.c:1646 */ - break; - - case 2041: -#line 13784 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_TIMESTAMP, -1, (yylsp[0])); - } -#line 43826 "gram.c" /* yacc.c:1646 */ - break; - - case 2042: -#line 13788 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_TIMESTAMP_N, (yyvsp[-1].ival), (yylsp[-3])); - } -#line 43834 "gram.c" /* yacc.c:1646 */ - break; - - case 2043: -#line 13792 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_LOCALTIME, -1, (yylsp[0])); - } -#line 43842 "gram.c" /* yacc.c:1646 */ - break; - - case 2044: -#line 13796 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_LOCALTIME_N, (yyvsp[-1].ival), (yylsp[-3])); - } -#line 43850 "gram.c" /* yacc.c:1646 */ - break; - - case 2045: -#line 13800 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_LOCALTIMESTAMP, -1, (yylsp[0])); - } -#line 43858 "gram.c" /* yacc.c:1646 */ - break; - - case 2046: -#line 13804 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_LOCALTIMESTAMP_N, (yyvsp[-1].ival), (yylsp[-3])); - } -#line 43866 "gram.c" /* yacc.c:1646 */ - break; - - case 2047: -#line 13808 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_ROLE, -1, (yylsp[0])); - } -#line 43874 "gram.c" /* yacc.c:1646 */ - break; - - case 2048: -#line 13812 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_USER, -1, (yylsp[0])); - } -#line 43882 "gram.c" /* yacc.c:1646 */ - break; - - case 2049: -#line 13816 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_SESSION_USER, -1, (yylsp[0])); - } -#line 43890 "gram.c" /* yacc.c:1646 */ - break; - - case 2050: -#line 13820 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_USER, -1, (yylsp[0])); - } -#line 43898 "gram.c" /* yacc.c:1646 */ - break; - - case 2051: -#line 13824 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_CATALOG, -1, (yylsp[0])); - } -#line 43906 "gram.c" /* yacc.c:1646 */ - break; - - case 2052: -#line 13828 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeSQLValueFunction(SVFOP_CURRENT_SCHEMA, -1, (yylsp[0])); - } -#line 43914 "gram.c" /* yacc.c:1646 */ - break; - - case 2053: -#line 13832 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeTypeCast((yyvsp[-3].node), (yyvsp[-1].typnam), (yylsp[-5])); } -#line 43920 "gram.c" /* yacc.c:1646 */ - break; - - case 2054: -#line 13834 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("date_part"), (yyvsp[-1].list), (yylsp[-3])); - } -#line 43928 "gram.c" /* yacc.c:1646 */ - break; - - case 2055: -#line 13838 "gram.y" /* yacc.c:1646 */ - { - /* overlay(A PLACING B FROM C FOR D) is converted to - * overlay(A, B, C, D) - * overlay(A PLACING B FROM C) is converted to - * overlay(A, B, C) - */ - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("overlay"), (yyvsp[-1].list), (yylsp[-3])); - } -#line 43941 "gram.c" /* yacc.c:1646 */ - break; - - case 2056: -#line 13847 "gram.y" /* yacc.c:1646 */ - { - /* position(A in B) is converted to position(B, A) */ - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("position"), (yyvsp[-1].list), (yylsp[-3])); - } -#line 43950 "gram.c" /* yacc.c:1646 */ - break; - - case 2057: -#line 13852 "gram.y" /* yacc.c:1646 */ - { - /* substring(A from B for C) is converted to - * substring(A, B, C) - thomas 2000-11-28 - */ - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("substring"), (yyvsp[-1].list), (yylsp[-3])); - } -#line 43961 "gram.c" /* yacc.c:1646 */ - break; - - case 2058: -#line 13859 "gram.y" /* yacc.c:1646 */ - { - /* TREAT(expr AS target) converts expr of a particular type to target, - * which is defined to be a subtype of the original expression. - * In SQL99, this is intended for use with structured UDTs, - * but let's make this a generally useful form allowing stronger - * coercions than are handled by implicit casting. - * - * Convert SystemTypeName() to SystemFuncName() even though - * at the moment they result in the same thing. - */ - (yyval.node) = (Node *) makeFuncCall(SystemFuncName(((Value *)llast((yyvsp[-1].typnam)->names))->val.str), - list_make1((yyvsp[-3].node)), - (yylsp[-5])); - } -#line 43980 "gram.c" /* yacc.c:1646 */ - break; - - case 2059: -#line 13874 "gram.y" /* yacc.c:1646 */ - { - /* various trim expressions are defined in SQL - * - thomas 1997-07-19 - */ - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("btrim"), (yyvsp[-1].list), (yylsp[-4])); - } -#line 43991 "gram.c" /* yacc.c:1646 */ - break; - - case 2060: -#line 13881 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("ltrim"), (yyvsp[-1].list), (yylsp[-4])); - } -#line 43999 "gram.c" /* yacc.c:1646 */ - break; - - case 2061: -#line 13885 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("rtrim"), (yyvsp[-1].list), (yylsp[-4])); - } -#line 44007 "gram.c" /* yacc.c:1646 */ - break; - - case 2062: -#line 13889 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("btrim"), (yyvsp[-1].list), (yylsp[-3])); - } -#line 44015 "gram.c" /* yacc.c:1646 */ - break; - - case 2063: -#line 13893 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", (yyvsp[-3].node), (yyvsp[-1].node), (yylsp[-5])); - } -#line 44023 "gram.c" /* yacc.c:1646 */ - break; - - case 2064: -#line 13897 "gram.y" /* yacc.c:1646 */ - { - CoalesceExpr *c = makeNode(CoalesceExpr); - c->args = (yyvsp[-1].list); - c->location = (yylsp[-3]); - (yyval.node) = (Node *)c; - } -#line 44034 "gram.c" /* yacc.c:1646 */ - break; - - case 2065: -#line 13904 "gram.y" /* yacc.c:1646 */ - { - MinMaxExpr *v = makeNode(MinMaxExpr); - v->args = (yyvsp[-1].list); - v->op = IS_GREATEST; - v->location = (yylsp[-3]); - (yyval.node) = (Node *)v; - } -#line 44046 "gram.c" /* yacc.c:1646 */ - break; - - case 2066: -#line 13912 "gram.y" /* yacc.c:1646 */ - { - MinMaxExpr *v = makeNode(MinMaxExpr); - v->args = (yyvsp[-1].list); - v->op = IS_LEAST; - v->location = (yylsp[-3]); - (yyval.node) = (Node *)v; - } -#line 44058 "gram.c" /* yacc.c:1646 */ - break; - - case 2067: -#line 13920 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, (yyvsp[-1].list), (yylsp[-3])); - } -#line 44066 "gram.c" /* yacc.c:1646 */ - break; - - case 2068: -#line 13924 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[-1].str), NIL, NIL, (yylsp[-4])); - } -#line 44074 "gram.c" /* yacc.c:1646 */ - break; - - case 2069: -#line 13928 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[-3].str), (yyvsp[-1].list), NIL, (yylsp[-6])); - } -#line 44082 "gram.c" /* yacc.c:1646 */ - break; - - case 2070: -#line 13932 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[-3].str), NIL, (yyvsp[-1].list), (yylsp[-6])); - } -#line 44090 "gram.c" /* yacc.c:1646 */ - break; - - case 2071: -#line 13936 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLELEMENT, (yyvsp[-5].str), (yyvsp[-3].list), (yyvsp[-1].list), (yylsp[-8])); - } -#line 44098 "gram.c" /* yacc.c:1646 */ - break; - - case 2072: -#line 13940 "gram.y" /* yacc.c:1646 */ - { - /* xmlexists(A PASSING [BY REF] B [BY REF]) is - * converted to xmlexists(A, B)*/ - (yyval.node) = (Node *) makeFuncCall(SystemFuncName("xmlexists"), list_make2((yyvsp[-2].node), (yyvsp[-1].node)), (yylsp[-4])); - } -#line 44108 "gram.c" /* yacc.c:1646 */ - break; - - case 2073: -#line 13946 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLFOREST, NULL, (yyvsp[-1].list), NIL, (yylsp[-3])); - } -#line 44116 "gram.c" /* yacc.c:1646 */ - break; - - case 2074: -#line 13950 "gram.y" /* yacc.c:1646 */ - { - XmlExpr *x = (XmlExpr *) - makeXmlExpr(IS_XMLPARSE, NULL, NIL, - list_make2((yyvsp[-2].node), makeBoolAConst((yyvsp[-1].boolean), -1)), - (yylsp[-5])); - x->xmloption = (yyvsp[-3].ival); - (yyval.node) = (Node *)x; - } -#line 44129 "gram.c" /* yacc.c:1646 */ - break; - - case 2075: -#line 13959 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLPI, (yyvsp[-1].str), NULL, NIL, (yylsp[-4])); - } -#line 44137 "gram.c" /* yacc.c:1646 */ - break; - - case 2076: -#line 13963 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLPI, (yyvsp[-3].str), NULL, list_make1((yyvsp[-1].node)), (yylsp[-6])); - } -#line 44145 "gram.c" /* yacc.c:1646 */ - break; - - case 2077: -#line 13967 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeXmlExpr(IS_XMLROOT, NULL, NIL, - list_make3((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[-1].node)), (yylsp[-6])); - } -#line 44154 "gram.c" /* yacc.c:1646 */ - break; - - case 2078: -#line 13972 "gram.y" /* yacc.c:1646 */ - { - XmlSerialize *n = makeNode(XmlSerialize); - n->xmloption = (yyvsp[-4].ival); - n->expr = (yyvsp[-3].node); - n->typeName = (yyvsp[-1].typnam); - n->location = (yylsp[-6]); - (yyval.node) = (Node *)n; - } -#line 44167 "gram.c" /* yacc.c:1646 */ - break; - - case 2079: -#line 13986 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 44173 "gram.c" /* yacc.c:1646 */ - break; - - case 2080: -#line 13988 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeNullAConst(-1); } -#line 44179 "gram.c" /* yacc.c:1646 */ - break; - - case 2081: -#line 13992 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeIntConst(XML_STANDALONE_YES, -1); } -#line 44185 "gram.c" /* yacc.c:1646 */ - break; - - case 2082: -#line 13994 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeIntConst(XML_STANDALONE_NO, -1); } -#line 44191 "gram.c" /* yacc.c:1646 */ - break; - - case 2083: -#line 13996 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeIntConst(XML_STANDALONE_NO_VALUE, -1); } -#line 44197 "gram.c" /* yacc.c:1646 */ - break; - - case 2084: -#line 13998 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = makeIntConst(XML_STANDALONE_OMITTED, -1); } -#line 44203 "gram.c" /* yacc.c:1646 */ - break; - - case 2085: -#line 14001 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 44209 "gram.c" /* yacc.c:1646 */ - break; - - case 2086: -#line 14004 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].target)); } -#line 44215 "gram.c" /* yacc.c:1646 */ - break; - - case 2087: -#line 14005 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].target)); } -#line 44221 "gram.c" /* yacc.c:1646 */ - break; - - case 2088: -#line 14009 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = (yyvsp[0].str); - (yyval.target)->indirection = NIL; - (yyval.target)->val = (Node *) (yyvsp[-2].node); - (yyval.target)->location = (yylsp[-2]); - } -#line 44233 "gram.c" /* yacc.c:1646 */ - break; - - case 2089: -#line 14017 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = NULL; - (yyval.target)->indirection = NIL; - (yyval.target)->val = (Node *) (yyvsp[0].node); - (yyval.target)->location = (yylsp[0]); - } -#line 44245 "gram.c" /* yacc.c:1646 */ - break; - - case 2090: -#line 14026 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = XMLOPTION_DOCUMENT; } -#line 44251 "gram.c" /* yacc.c:1646 */ - break; - - case 2091: -#line 14027 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = XMLOPTION_CONTENT; } -#line 44257 "gram.c" /* yacc.c:1646 */ - break; - - case 2092: -#line 14030 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = true; } -#line 44263 "gram.c" /* yacc.c:1646 */ - break; - - case 2093: -#line 14031 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 44269 "gram.c" /* yacc.c:1646 */ - break; - - case 2094: -#line 14032 "gram.y" /* yacc.c:1646 */ - { (yyval.boolean) = false; } -#line 44275 "gram.c" /* yacc.c:1646 */ - break; - - case 2095: -#line 14038 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 44283 "gram.c" /* yacc.c:1646 */ - break; - - case 2096: -#line 14042 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[-2].node); - } -#line 44291 "gram.c" /* yacc.c:1646 */ - break; - - case 2097: -#line 14046 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 44299 "gram.c" /* yacc.c:1646 */ - break; - - case 2098: -#line 14050 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[-2].node); - } -#line 44307 "gram.c" /* yacc.c:1646 */ - break; - - case 2099: -#line 14060 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 44313 "gram.c" /* yacc.c:1646 */ - break; - - case 2100: -#line 14061 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 44319 "gram.c" /* yacc.c:1646 */ - break; - - case 2101: -#line 14065 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[-1].node); } -#line 44325 "gram.c" /* yacc.c:1646 */ - break; - - case 2102: -#line 14066 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 44331 "gram.c" /* yacc.c:1646 */ - break; - - case 2103: -#line 14074 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 44337 "gram.c" /* yacc.c:1646 */ - break; - - case 2104: -#line 14075 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 44343 "gram.c" /* yacc.c:1646 */ - break; - - case 2105: -#line 14079 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].windef)); } -#line 44349 "gram.c" /* yacc.c:1646 */ - break; - - case 2106: -#line 14081 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].windef)); } -#line 44355 "gram.c" /* yacc.c:1646 */ - break; - - case 2107: -#line 14086 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = (yyvsp[0].windef); - n->name = (yyvsp[-2].str); - (yyval.windef) = n; - } -#line 44365 "gram.c" /* yacc.c:1646 */ - break; - - case 2108: -#line 14094 "gram.y" /* yacc.c:1646 */ - { (yyval.windef) = (yyvsp[0].windef); } -#line 44371 "gram.c" /* yacc.c:1646 */ - break; - - case 2109: -#line 14096 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->name = (yyvsp[0].str); - n->refname = NULL; - n->partitionClause = NIL; - n->orderClause = NIL; - n->frameOptions = FRAMEOPTION_DEFAULTS; - n->startOffset = NULL; - n->endOffset = NULL; - n->location = (yylsp[0]); - (yyval.windef) = n; - } -#line 44388 "gram.c" /* yacc.c:1646 */ - break; - - case 2110: -#line 14109 "gram.y" /* yacc.c:1646 */ - { (yyval.windef) = NULL; } -#line 44394 "gram.c" /* yacc.c:1646 */ - break; - - case 2111: -#line 14114 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->name = NULL; - n->refname = (yyvsp[-4].str); - n->partitionClause = (yyvsp[-3].list); - n->orderClause = (yyvsp[-2].list); - /* copy relevant fields of opt_frame_clause */ - n->frameOptions = (yyvsp[-1].windef)->frameOptions; - n->startOffset = (yyvsp[-1].windef)->startOffset; - n->endOffset = (yyvsp[-1].windef)->endOffset; - n->location = (yylsp[-5]); - (yyval.windef) = n; - } -#line 44412 "gram.c" /* yacc.c:1646 */ - break; - - case 2112: -#line 14139 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 44418 "gram.c" /* yacc.c:1646 */ - break; - - case 2113: -#line 14140 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 44424 "gram.c" /* yacc.c:1646 */ - break; - - case 2114: -#line 14143 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 44430 "gram.c" /* yacc.c:1646 */ - break; - - case 2115: -#line 14144 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 44436 "gram.c" /* yacc.c:1646 */ - break; - - case 2116: -#line 14153 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = (yyvsp[-1].windef); - n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE; - n->frameOptions |= (yyvsp[0].ival); - (yyval.windef) = n; - } -#line 44447 "gram.c" /* yacc.c:1646 */ - break; - - case 2117: -#line 14160 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = (yyvsp[-1].windef); - n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS; - n->frameOptions |= (yyvsp[0].ival); - (yyval.windef) = n; - } -#line 44458 "gram.c" /* yacc.c:1646 */ - break; - - case 2118: -#line 14167 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = (yyvsp[-1].windef); - n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_GROUPS; - n->frameOptions |= (yyvsp[0].ival); - (yyval.windef) = n; - } -#line 44469 "gram.c" /* yacc.c:1646 */ - break; - - case 2119: -#line 14174 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->frameOptions = FRAMEOPTION_DEFAULTS; - n->startOffset = NULL; - n->endOffset = NULL; - (yyval.windef) = n; - } -#line 44481 "gram.c" /* yacc.c:1646 */ - break; - - case 2120: -#line 14184 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = (yyvsp[0].windef); - /* reject invalid cases */ - if (n->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) - ereport(ERROR, - (errcode(ERRCODE_WINDOWING_ERROR), - errmsg("frame start cannot be UNBOUNDED FOLLOWING"), - parser_errposition((yylsp[0])))); - if (n->frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING) - ereport(ERROR, - (errcode(ERRCODE_WINDOWING_ERROR), - errmsg("frame starting from following row cannot end with current row"), - parser_errposition((yylsp[0])))); - n->frameOptions |= FRAMEOPTION_END_CURRENT_ROW; - (yyval.windef) = n; - } -#line 44502 "gram.c" /* yacc.c:1646 */ - break; - - case 2121: -#line 14201 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n1 = (yyvsp[-2].windef); - WindowDef *n2 = (yyvsp[0].windef); - /* form merged options */ - int frameOptions = n1->frameOptions; - /* shift converts START_ options to END_ options */ - frameOptions |= n2->frameOptions << 1; - frameOptions |= FRAMEOPTION_BETWEEN; - /* reject invalid cases */ - if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) - ereport(ERROR, - (errcode(ERRCODE_WINDOWING_ERROR), - errmsg("frame start cannot be UNBOUNDED FOLLOWING"), - parser_errposition((yylsp[-2])))); - if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) - ereport(ERROR, - (errcode(ERRCODE_WINDOWING_ERROR), - errmsg("frame end cannot be UNBOUNDED PRECEDING"), - parser_errposition((yylsp[0])))); - if ((frameOptions & FRAMEOPTION_START_CURRENT_ROW) && - (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING)) - ereport(ERROR, - (errcode(ERRCODE_WINDOWING_ERROR), - errmsg("frame starting from current row cannot have preceding rows"), - parser_errposition((yylsp[0])))); - if ((frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING) && - (frameOptions & (FRAMEOPTION_END_OFFSET_PRECEDING | - FRAMEOPTION_END_CURRENT_ROW))) - ereport(ERROR, - (errcode(ERRCODE_WINDOWING_ERROR), - errmsg("frame starting from following row cannot have preceding rows"), - parser_errposition((yylsp[0])))); - n1->frameOptions = frameOptions; - n1->endOffset = n2->startOffset; - (yyval.windef) = n1; - } -#line 44543 "gram.c" /* yacc.c:1646 */ - break; - - case 2122: -#line 14246 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING; - n->startOffset = NULL; - n->endOffset = NULL; - (yyval.windef) = n; - } -#line 44555 "gram.c" /* yacc.c:1646 */ - break; - - case 2123: -#line 14254 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING; - n->startOffset = NULL; - n->endOffset = NULL; - (yyval.windef) = n; - } -#line 44567 "gram.c" /* yacc.c:1646 */ - break; - - case 2124: -#line 14262 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->frameOptions = FRAMEOPTION_START_CURRENT_ROW; - n->startOffset = NULL; - n->endOffset = NULL; - (yyval.windef) = n; - } -#line 44579 "gram.c" /* yacc.c:1646 */ - break; - - case 2125: -#line 14270 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->frameOptions = FRAMEOPTION_START_OFFSET_PRECEDING; - n->startOffset = (yyvsp[-1].node); - n->endOffset = NULL; - (yyval.windef) = n; - } -#line 44591 "gram.c" /* yacc.c:1646 */ - break; - - case 2126: -#line 14278 "gram.y" /* yacc.c:1646 */ - { - WindowDef *n = makeNode(WindowDef); - n->frameOptions = FRAMEOPTION_START_OFFSET_FOLLOWING; - n->startOffset = (yyvsp[-1].node); - n->endOffset = NULL; - (yyval.windef) = n; - } -#line 44603 "gram.c" /* yacc.c:1646 */ - break; - - case 2127: -#line 14288 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FRAMEOPTION_EXCLUDE_CURRENT_ROW; } -#line 44609 "gram.c" /* yacc.c:1646 */ - break; - - case 2128: -#line 14289 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FRAMEOPTION_EXCLUDE_GROUP; } -#line 44615 "gram.c" /* yacc.c:1646 */ - break; - - case 2129: -#line 14290 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = FRAMEOPTION_EXCLUDE_TIES; } -#line 44621 "gram.c" /* yacc.c:1646 */ - break; - - case 2130: -#line 14291 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 44627 "gram.c" /* yacc.c:1646 */ - break; - - case 2131: -#line 14292 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 44633 "gram.c" /* yacc.c:1646 */ - break; - - case 2132: -#line 14306 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 44639 "gram.c" /* yacc.c:1646 */ - break; - - case 2133: -#line 14307 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 44645 "gram.c" /* yacc.c:1646 */ - break; - - case 2134: -#line 14308 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-3].list), (yyvsp[-1].node)); } -#line 44651 "gram.c" /* yacc.c:1646 */ - break; - - case 2135: -#line 14311 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 44657 "gram.c" /* yacc.c:1646 */ - break; - - case 2136: -#line 14312 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 44663 "gram.c" /* yacc.c:1646 */ - break; - - case 2137: -#line 14315 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-3].list), (yyvsp[-1].node)); } -#line 44669 "gram.c" /* yacc.c:1646 */ - break; - - case 2138: -#line 14318 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ANY_SUBLINK; } -#line 44675 "gram.c" /* yacc.c:1646 */ - break; - - case 2139: -#line 14319 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ANY_SUBLINK; } -#line 44681 "gram.c" /* yacc.c:1646 */ - break; - - case 2140: -#line 14320 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = ALL_SUBLINK; } -#line 44687 "gram.c" /* yacc.c:1646 */ - break; - - case 2141: -#line 14323 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 44693 "gram.c" /* yacc.c:1646 */ - break; - - case 2142: -#line 14324 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 44699 "gram.c" /* yacc.c:1646 */ - break; - - case 2143: -#line 14327 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "+"; } -#line 44705 "gram.c" /* yacc.c:1646 */ - break; - - case 2144: -#line 14328 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "-"; } -#line 44711 "gram.c" /* yacc.c:1646 */ - break; - - case 2145: -#line 14329 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "*"; } -#line 44717 "gram.c" /* yacc.c:1646 */ - break; - - case 2146: -#line 14330 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "/"; } -#line 44723 "gram.c" /* yacc.c:1646 */ - break; - - case 2147: -#line 14331 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "%"; } -#line 44729 "gram.c" /* yacc.c:1646 */ - break; - - case 2148: -#line 14332 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "^"; } -#line 44735 "gram.c" /* yacc.c:1646 */ - break; - - case 2149: -#line 14333 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "<"; } -#line 44741 "gram.c" /* yacc.c:1646 */ - break; - - case 2150: -#line 14334 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = ">"; } -#line 44747 "gram.c" /* yacc.c:1646 */ - break; - - case 2151: -#line 14335 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "="; } -#line 44753 "gram.c" /* yacc.c:1646 */ - break; - - case 2152: -#line 14336 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "<="; } -#line 44759 "gram.c" /* yacc.c:1646 */ - break; - - case 2153: -#line 14337 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = ">="; } -#line 44765 "gram.c" /* yacc.c:1646 */ - break; - - case 2154: -#line 14338 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "<>"; } -#line 44771 "gram.c" /* yacc.c:1646 */ - break; - - case 2155: -#line 14342 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 44777 "gram.c" /* yacc.c:1646 */ - break; - - case 2156: -#line 14344 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 44783 "gram.c" /* yacc.c:1646 */ - break; - - case 2157: -#line 14349 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 44789 "gram.c" /* yacc.c:1646 */ - break; - - case 2158: -#line 14351 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 44795 "gram.c" /* yacc.c:1646 */ - break; - - case 2159: -#line 14356 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 44801 "gram.c" /* yacc.c:1646 */ - break; - - case 2160: -#line 14358 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[-1].list); } -#line 44807 "gram.c" /* yacc.c:1646 */ - break; - - case 2161: -#line 14360 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString("~~")); } -#line 44813 "gram.c" /* yacc.c:1646 */ - break; - - case 2162: -#line 14362 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString("!~~")); } -#line 44819 "gram.c" /* yacc.c:1646 */ - break; - - case 2163: -#line 14364 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString("~~*")); } -#line 44825 "gram.c" /* yacc.c:1646 */ - break; - - case 2164: -#line 14366 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString("!~~*")); } -#line 44831 "gram.c" /* yacc.c:1646 */ - break; - - case 2165: -#line 14378 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].node)); - } -#line 44839 "gram.c" /* yacc.c:1646 */ - break; - - case 2166: -#line 14382 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); - } -#line 44847 "gram.c" /* yacc.c:1646 */ - break; - - case 2167: -#line 14389 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make1((yyvsp[0].node)); - } -#line 44855 "gram.c" /* yacc.c:1646 */ - break; - - case 2168: -#line 14393 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); - } -#line 44863 "gram.c" /* yacc.c:1646 */ - break; - - case 2169: -#line 14399 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 44871 "gram.c" /* yacc.c:1646 */ - break; - - case 2170: -#line 14403 "gram.y" /* yacc.c:1646 */ - { - NamedArgExpr *na = makeNode(NamedArgExpr); - na->name = (yyvsp[-2].str); - na->arg = (Expr *) (yyvsp[0].node); - na->argnumber = -1; /* until determined */ - na->location = (yylsp[-2]); - (yyval.node) = (Node *) na; - } -#line 44884 "gram.c" /* yacc.c:1646 */ - break; - - case 2171: -#line 14412 "gram.y" /* yacc.c:1646 */ - { - NamedArgExpr *na = makeNode(NamedArgExpr); - na->name = (yyvsp[-2].str); - na->arg = (Expr *) (yyvsp[0].node); - na->argnumber = -1; /* until determined */ - na->location = (yylsp[-2]); - (yyval.node) = (Node *) na; - } -#line 44897 "gram.c" /* yacc.c:1646 */ - break; - - case 2172: -#line 14422 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].typnam)); } -#line 44903 "gram.c" /* yacc.c:1646 */ - break; - - case 2173: -#line 14423 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].typnam)); } -#line 44909 "gram.c" /* yacc.c:1646 */ - break; - - case 2174: -#line 14427 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeAArrayExpr((yyvsp[-1].list), (yylsp[-2])); - } -#line 44917 "gram.c" /* yacc.c:1646 */ - break; - - case 2175: -#line 14431 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeAArrayExpr((yyvsp[-1].list), (yylsp[-2])); - } -#line 44925 "gram.c" /* yacc.c:1646 */ - break; - - case 2176: -#line 14435 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeAArrayExpr(NIL, (yylsp[-1])); - } -#line 44933 "gram.c" /* yacc.c:1646 */ - break; - - case 2177: -#line 14440 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 44939 "gram.c" /* yacc.c:1646 */ - break; - - case 2178: -#line 14441 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].node)); } -#line 44945 "gram.c" /* yacc.c:1646 */ - break; - - case 2179: -#line 14447 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2(makeStringConst((yyvsp[-2].str), (yylsp[-2])), (yyvsp[0].node)); - } -#line 44953 "gram.c" /* yacc.c:1646 */ - break; - - case 2180: -#line 14450 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 44959 "gram.c" /* yacc.c:1646 */ - break; - - case 2181: -#line 14457 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 44965 "gram.c" /* yacc.c:1646 */ - break; - - case 2182: -#line 14458 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "year"; } -#line 44971 "gram.c" /* yacc.c:1646 */ - break; - - case 2183: -#line 14459 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "month"; } -#line 44977 "gram.c" /* yacc.c:1646 */ - break; - - case 2184: -#line 14460 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "day"; } -#line 44983 "gram.c" /* yacc.c:1646 */ - break; - - case 2185: -#line 14461 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "hour"; } -#line 44989 "gram.c" /* yacc.c:1646 */ - break; - - case 2186: -#line 14462 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "minute"; } -#line 44995 "gram.c" /* yacc.c:1646 */ - break; - - case 2187: -#line 14463 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = "second"; } -#line 45001 "gram.c" /* yacc.c:1646 */ - break; - - case 2188: -#line 14464 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45007 "gram.c" /* yacc.c:1646 */ - break; - - case 2189: -#line 14475 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make4((yyvsp[-3].node), (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); - } -#line 45015 "gram.c" /* yacc.c:1646 */ - break; - - case 2190: -#line 14479 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make3((yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); - } -#line 45023 "gram.c" /* yacc.c:1646 */ - break; - - case 2191: -#line 14486 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 45029 "gram.c" /* yacc.c:1646 */ - break; - - case 2192: -#line 14492 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make2((yyvsp[0].node), (yyvsp[-2].node)); } -#line 45035 "gram.c" /* yacc.c:1646 */ - break; - - case 2193: -#line 14493 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 45041 "gram.c" /* yacc.c:1646 */ - break; - - case 2194: -#line 14510 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make3((yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); - } -#line 45049 "gram.c" /* yacc.c:1646 */ - break; - - case 2195: -#line 14514 "gram.y" /* yacc.c:1646 */ - { - /* not legal per SQL99, but might as well allow it */ - (yyval.list) = list_make3((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].node)); - } -#line 45058 "gram.c" /* yacc.c:1646 */ - break; - - case 2196: -#line 14519 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = list_make2((yyvsp[-1].node), (yyvsp[0].node)); - } -#line 45066 "gram.c" /* yacc.c:1646 */ - break; - - case 2197: -#line 14523 "gram.y" /* yacc.c:1646 */ - { - /* - * Since there are no cases where this syntax allows - * a textual FOR value, we forcibly cast the argument - * to int4. The possible matches in pg_proc are - * substring(text,int4) and substring(text,text), - * and we don't want the parser to choose the latter, - * which it is likely to do if the second argument - * is unknown or doesn't have an implicit cast to int4. - */ - (yyval.list) = list_make3((yyvsp[-1].node), makeIntConst(1, -1), - makeTypeCast((yyvsp[0].node), - SystemTypeName("int4"), -1)); - } -#line 45085 "gram.c" /* yacc.c:1646 */ - break; - - case 2198: -#line 14538 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = (yyvsp[0].list); - } -#line 45093 "gram.c" /* yacc.c:1646 */ - break; - - case 2199: -#line 14542 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 45099 "gram.c" /* yacc.c:1646 */ - break; - - case 2200: -#line 14546 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 45105 "gram.c" /* yacc.c:1646 */ - break; - - case 2201: -#line 14549 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 45111 "gram.c" /* yacc.c:1646 */ - break; - - case 2202: -#line 14552 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[0].list), (yyvsp[-2].node)); } -#line 45117 "gram.c" /* yacc.c:1646 */ - break; - - case 2203: -#line 14553 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 45123 "gram.c" /* yacc.c:1646 */ - break; - - case 2204: -#line 14554 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 45129 "gram.c" /* yacc.c:1646 */ - break; - - case 2205: -#line 14558 "gram.y" /* yacc.c:1646 */ - { - SubLink *n = makeNode(SubLink); - n->subselect = (yyvsp[0].node); - /* other fields will be filled later */ - (yyval.node) = (Node *)n; - } -#line 45140 "gram.c" /* yacc.c:1646 */ - break; - - case 2206: -#line 14564 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (Node *)(yyvsp[-1].list); } -#line 45146 "gram.c" /* yacc.c:1646 */ - break; - - case 2207: -#line 14575 "gram.y" /* yacc.c:1646 */ - { - CaseExpr *c = makeNode(CaseExpr); - c->casetype = InvalidOid; /* not analyzed yet */ - c->arg = (Expr *) (yyvsp[-3].node); - c->args = (yyvsp[-2].list); - c->defresult = (Expr *) (yyvsp[-1].node); - c->location = (yylsp[-4]); - (yyval.node) = (Node *)c; - } -#line 45160 "gram.c" /* yacc.c:1646 */ - break; - - case 2208: -#line 14588 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 45166 "gram.c" /* yacc.c:1646 */ - break; - - case 2209: -#line 14589 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].node)); } -#line 45172 "gram.c" /* yacc.c:1646 */ - break; - - case 2210: -#line 14594 "gram.y" /* yacc.c:1646 */ - { - CaseWhen *w = makeNode(CaseWhen); - w->expr = (Expr *) (yyvsp[-2].node); - w->result = (Expr *) (yyvsp[0].node); - w->location = (yylsp[-3]); - (yyval.node) = (Node *)w; - } -#line 45184 "gram.c" /* yacc.c:1646 */ - break; - - case 2211: -#line 14604 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 45190 "gram.c" /* yacc.c:1646 */ - break; - - case 2212: -#line 14605 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 45196 "gram.c" /* yacc.c:1646 */ - break; - - case 2213: -#line 14608 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 45202 "gram.c" /* yacc.c:1646 */ - break; - - case 2214: -#line 14609 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 45208 "gram.c" /* yacc.c:1646 */ - break; - - case 2215: -#line 14613 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeColumnRef((yyvsp[0].str), NIL, (yylsp[0]), yyscanner); - } -#line 45216 "gram.c" /* yacc.c:1646 */ - break; - - case 2216: -#line 14617 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeColumnRef((yyvsp[-1].str), (yyvsp[0].list), (yylsp[-1]), yyscanner); - } -#line 45224 "gram.c" /* yacc.c:1646 */ - break; - - case 2217: -#line 14624 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeString((yyvsp[0].str)); - } -#line 45232 "gram.c" /* yacc.c:1646 */ - break; - - case 2218: -#line 14628 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = (Node *) makeNode(A_Star); - } -#line 45240 "gram.c" /* yacc.c:1646 */ - break; - - case 2219: -#line 14632 "gram.y" /* yacc.c:1646 */ - { - A_Indices *ai = makeNode(A_Indices); - ai->is_slice = false; - ai->lidx = NULL; - ai->uidx = (yyvsp[-1].node); - (yyval.node) = (Node *) ai; - } -#line 45252 "gram.c" /* yacc.c:1646 */ - break; - - case 2220: -#line 14640 "gram.y" /* yacc.c:1646 */ - { - A_Indices *ai = makeNode(A_Indices); - ai->is_slice = true; - ai->lidx = (yyvsp[-3].node); - ai->uidx = (yyvsp[-1].node); - (yyval.node) = (Node *) ai; - } -#line 45264 "gram.c" /* yacc.c:1646 */ - break; - - case 2221: -#line 14650 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = (yyvsp[0].node); } -#line 45270 "gram.c" /* yacc.c:1646 */ - break; - - case 2222: -#line 14651 "gram.y" /* yacc.c:1646 */ - { (yyval.node) = NULL; } -#line 45276 "gram.c" /* yacc.c:1646 */ - break; - - case 2223: -#line 14655 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].node)); } -#line 45282 "gram.c" /* yacc.c:1646 */ - break; - - case 2224: -#line 14656 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].node)); } -#line 45288 "gram.c" /* yacc.c:1646 */ - break; - - case 2225: -#line 14660 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 45294 "gram.c" /* yacc.c:1646 */ - break; - - case 2226: -#line 14661 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-1].list), (yyvsp[0].node)); } -#line 45300 "gram.c" /* yacc.c:1646 */ - break; - - case 2229: -#line 14675 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = (yyvsp[0].list); } -#line 45306 "gram.c" /* yacc.c:1646 */ - break; - - case 2230: -#line 14676 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = NIL; } -#line 45312 "gram.c" /* yacc.c:1646 */ - break; - - case 2231: -#line 14680 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].target)); } -#line 45318 "gram.c" /* yacc.c:1646 */ - break; - - case 2232: -#line 14681 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].target)); } -#line 45324 "gram.c" /* yacc.c:1646 */ - break; - - case 2233: -#line 14685 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = (yyvsp[0].str); - (yyval.target)->indirection = NIL; - (yyval.target)->val = (Node *)(yyvsp[-2].node); - (yyval.target)->location = (yylsp[-2]); - } -#line 45336 "gram.c" /* yacc.c:1646 */ - break; - - case 2234: -#line 14701 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = (yyvsp[0].str); - (yyval.target)->indirection = NIL; - (yyval.target)->val = (Node *)(yyvsp[-1].node); - (yyval.target)->location = (yylsp[-1]); - } -#line 45348 "gram.c" /* yacc.c:1646 */ - break; - - case 2235: -#line 14709 "gram.y" /* yacc.c:1646 */ - { - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = NULL; - (yyval.target)->indirection = NIL; - (yyval.target)->val = (Node *)(yyvsp[0].node); - (yyval.target)->location = (yylsp[0]); - } -#line 45360 "gram.c" /* yacc.c:1646 */ - break; - - case 2236: -#line 14717 "gram.y" /* yacc.c:1646 */ - { - ColumnRef *n = makeNode(ColumnRef); - n->fields = list_make1(makeNode(A_Star)); - n->location = (yylsp[0]); - - (yyval.target) = makeNode(ResTarget); - (yyval.target)->name = NULL; - (yyval.target)->indirection = NIL; - (yyval.target)->val = (Node *)n; - (yyval.target)->location = (yylsp[0]); - } -#line 45376 "gram.c" /* yacc.c:1646 */ - break; - - case 2237: -#line 14738 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].range)); } -#line 45382 "gram.c" /* yacc.c:1646 */ - break; - - case 2238: -#line 14739 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].range)); } -#line 45388 "gram.c" /* yacc.c:1646 */ - break; - - case 2239: -#line 14751 "gram.y" /* yacc.c:1646 */ - { - (yyval.range) = makeRangeVar(NULL, (yyvsp[0].str), (yylsp[0])); - } -#line 45396 "gram.c" /* yacc.c:1646 */ - break; - - case 2240: -#line 14755 "gram.y" /* yacc.c:1646 */ - { - check_qualified_name((yyvsp[0].list), yyscanner); - (yyval.range) = makeRangeVar(NULL, NULL, (yylsp[-1])); - switch (list_length((yyvsp[0].list))) - { - case 1: - (yyval.range)->catalogname = NULL; - (yyval.range)->schemaname = (yyvsp[-1].str); - (yyval.range)->relname = strVal(linitial((yyvsp[0].list))); - break; - case 2: - (yyval.range)->catalogname = (yyvsp[-1].str); - (yyval.range)->schemaname = strVal(linitial((yyvsp[0].list))); - (yyval.range)->relname = strVal(lsecond((yyvsp[0].list))); - break; - default: - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("improper qualified name (too many dotted names): %s", - NameListToString(lcons(makeString((yyvsp[-1].str)), (yyvsp[0].list)))), - parser_errposition((yylsp[-1])))); - break; - } - } -#line 45425 "gram.c" /* yacc.c:1646 */ - break; - - case 2241: -#line 14782 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 45431 "gram.c" /* yacc.c:1646 */ - break; - - case 2242: -#line 14784 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), makeString((yyvsp[0].str))); } -#line 45437 "gram.c" /* yacc.c:1646 */ - break; - - case 2243: -#line 14788 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45443 "gram.c" /* yacc.c:1646 */ - break; - - case 2244: -#line 14791 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45449 "gram.c" /* yacc.c:1646 */ - break; - - case 2245: -#line 14794 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45455 "gram.c" /* yacc.c:1646 */ - break; - - case 2246: -#line 14796 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45461 "gram.c" /* yacc.c:1646 */ - break; - - case 2247: -#line 14798 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45467 "gram.c" /* yacc.c:1646 */ - break; - - case 2248: -#line 14800 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45473 "gram.c" /* yacc.c:1646 */ - break; - - case 2249: -#line 14811 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1(makeString((yyvsp[0].str))); } -#line 45479 "gram.c" /* yacc.c:1646 */ - break; - - case 2250: -#line 14813 "gram.y" /* yacc.c:1646 */ - { - (yyval.list) = check_func_name(lcons(makeString((yyvsp[-1].str)), (yyvsp[0].list)), - yyscanner); - } -#line 45488 "gram.c" /* yacc.c:1646 */ - break; - - case 2251: -#line 14824 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeIntConst((yyvsp[0].ival), (yylsp[0])); - } -#line 45496 "gram.c" /* yacc.c:1646 */ - break; - - case 2252: -#line 14828 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeFloatConst((yyvsp[0].str), (yylsp[0])); - } -#line 45504 "gram.c" /* yacc.c:1646 */ - break; - - case 2253: -#line 14832 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeStringConst((yyvsp[0].str), (yylsp[0])); - } -#line 45512 "gram.c" /* yacc.c:1646 */ - break; - - case 2254: -#line 14836 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeBitStringConst((yyvsp[0].str), (yylsp[0])); - } -#line 45520 "gram.c" /* yacc.c:1646 */ - break; - - case 2255: -#line 14840 "gram.y" /* yacc.c:1646 */ - { - /* This is a bit constant per SQL99: - * Without Feature F511, "BIT data type", - * a shall not be a - * or a . - */ - (yyval.node) = makeBitStringConst((yyvsp[0].str), (yylsp[0])); - } -#line 45533 "gram.c" /* yacc.c:1646 */ - break; - - case 2256: -#line 14849 "gram.y" /* yacc.c:1646 */ - { - /* generic type 'literal' syntax */ - TypeName *t = makeTypeNameFromNameList((yyvsp[-1].list)); - t->location = (yylsp[-1]); - (yyval.node) = makeStringConstCast((yyvsp[0].str), (yylsp[0]), t); - } -#line 45544 "gram.c" /* yacc.c:1646 */ - break; - - case 2257: -#line 14856 "gram.y" /* yacc.c:1646 */ - { - /* generic syntax with a type modifier */ - TypeName *t = makeTypeNameFromNameList((yyvsp[-5].list)); - ListCell *lc; - - /* - * We must use func_arg_list and opt_sort_clause in the - * production to avoid reduce/reduce conflicts, but we - * don't actually wish to allow NamedArgExpr in this - * context, nor ORDER BY. - */ - foreach(lc, (yyvsp[-3].list)) - { - NamedArgExpr *arg = (NamedArgExpr *) lfirst(lc); - - if (IsA(arg, NamedArgExpr)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("type modifier cannot have parameter name"), - parser_errposition(arg->location))); - } - if ((yyvsp[-2].list) != NIL) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("type modifier cannot have ORDER BY"), - parser_errposition((yylsp[-2])))); - - t->typmods = (yyvsp[-3].list); - t->location = (yylsp[-5]); - (yyval.node) = makeStringConstCast((yyvsp[0].str), (yylsp[0]), t); - } -#line 45580 "gram.c" /* yacc.c:1646 */ - break; - - case 2258: -#line 14888 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeStringConstCast((yyvsp[0].str), (yylsp[0]), (yyvsp[-1].typnam)); - } -#line 45588 "gram.c" /* yacc.c:1646 */ - break; - - case 2259: -#line 14892 "gram.y" /* yacc.c:1646 */ - { - TypeName *t = (yyvsp[-2].typnam); - t->typmods = (yyvsp[0].list); - (yyval.node) = makeStringConstCast((yyvsp[-1].str), (yylsp[-1]), t); - } -#line 45598 "gram.c" /* yacc.c:1646 */ - break; - - case 2260: -#line 14898 "gram.y" /* yacc.c:1646 */ - { - TypeName *t = (yyvsp[-4].typnam); - t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), - makeIntConst((yyvsp[-2].ival), (yylsp[-2]))); - (yyval.node) = makeStringConstCast((yyvsp[0].str), (yylsp[0]), t); - } -#line 45609 "gram.c" /* yacc.c:1646 */ - break; - - case 2261: -#line 14905 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeBoolAConst(true, (yylsp[0])); - } -#line 45617 "gram.c" /* yacc.c:1646 */ - break; - - case 2262: -#line 14909 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeBoolAConst(false, (yylsp[0])); - } -#line 45625 "gram.c" /* yacc.c:1646 */ - break; - - case 2263: -#line 14913 "gram.y" /* yacc.c:1646 */ - { - (yyval.node) = makeNullAConst((yylsp[0])); - } -#line 45633 "gram.c" /* yacc.c:1646 */ - break; - - case 2264: -#line 14918 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 45639 "gram.c" /* yacc.c:1646 */ - break; - - case 2265: -#line 14919 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45645 "gram.c" /* yacc.c:1646 */ - break; - - case 2266: -#line 14921 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 45651 "gram.c" /* yacc.c:1646 */ - break; - - case 2267: -#line 14922 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = + (yyvsp[0].ival); } -#line 45657 "gram.c" /* yacc.c:1646 */ - break; - - case 2268: -#line 14923 "gram.y" /* yacc.c:1646 */ - { (yyval.ival) = - (yyvsp[0].ival); } -#line 45663 "gram.c" /* yacc.c:1646 */ - break; - - case 2269: -#line 14928 "gram.y" /* yacc.c:1646 */ - { - RoleSpec *spc = (RoleSpec *) (yyvsp[0].rolespec); - switch (spc->roletype) - { - case ROLESPEC_CSTRING: - (yyval.str) = spc->rolename; - break; - case ROLESPEC_PUBLIC: - ereport(ERROR, - (errcode(ERRCODE_RESERVED_NAME), - errmsg("role name \"%s\" is reserved", - "public"), - parser_errposition((yylsp[0])))); - 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((yylsp[0])))); - 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((yylsp[0])))); - break; - } - } -#line 45698 "gram.c" /* yacc.c:1646 */ - break; - - case 2270: -#line 14961 "gram.y" /* yacc.c:1646 */ - { - /* - * "public" and "none" are not keywords, but they must - * be treated specially here. - */ - RoleSpec *n; - if (strcmp((yyvsp[0].str), "public") == 0) - { - n = (RoleSpec *) makeRoleSpec(ROLESPEC_PUBLIC, (yylsp[0])); - n->roletype = ROLESPEC_PUBLIC; - } - else if (strcmp((yyvsp[0].str), "none") == 0) - { - ereport(ERROR, - (errcode(ERRCODE_RESERVED_NAME), - errmsg("role name \"%s\" is reserved", - "none"), - parser_errposition((yylsp[0])))); - } - else - { - n = makeRoleSpec(ROLESPEC_CSTRING, (yylsp[0])); - n->rolename = pstrdup((yyvsp[0].str)); - } - (yyval.rolespec) = n; - } -#line 45729 "gram.c" /* yacc.c:1646 */ - break; - - case 2271: -#line 14988 "gram.y" /* yacc.c:1646 */ - { - (yyval.rolespec) = makeRoleSpec(ROLESPEC_CURRENT_USER, (yylsp[0])); - } -#line 45737 "gram.c" /* yacc.c:1646 */ - break; - - case 2272: -#line 14992 "gram.y" /* yacc.c:1646 */ - { - (yyval.rolespec) = makeRoleSpec(ROLESPEC_SESSION_USER, (yylsp[0])); - } -#line 45745 "gram.c" /* yacc.c:1646 */ - break; - - case 2273: -#line 14998 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = list_make1((yyvsp[0].rolespec)); } -#line 45751 "gram.c" /* yacc.c:1646 */ - break; - - case 2274: -#line 15000 "gram.y" /* yacc.c:1646 */ - { (yyval.list) = lappend((yyvsp[-2].list), (yyvsp[0].rolespec)); } -#line 45757 "gram.c" /* yacc.c:1646 */ - break; - - case 2275: -#line 15016 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45763 "gram.c" /* yacc.c:1646 */ - break; - - case 2276: -#line 15017 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45769 "gram.c" /* yacc.c:1646 */ - break; - - case 2277: -#line 15018 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45775 "gram.c" /* yacc.c:1646 */ - break; - - case 2278: -#line 15023 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45781 "gram.c" /* yacc.c:1646 */ - break; - - case 2279: -#line 15024 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45787 "gram.c" /* yacc.c:1646 */ - break; - - case 2280: -#line 15025 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45793 "gram.c" /* yacc.c:1646 */ - break; - - case 2281: -#line 15030 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45799 "gram.c" /* yacc.c:1646 */ - break; - - case 2282: -#line 15031 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45805 "gram.c" /* yacc.c:1646 */ - break; - - case 2283: -#line 15032 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45811 "gram.c" /* yacc.c:1646 */ - break; - - case 2284: -#line 15033 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45817 "gram.c" /* yacc.c:1646 */ - break; - - case 2285: -#line 15039 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 45823 "gram.c" /* yacc.c:1646 */ - break; - - case 2286: -#line 15040 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45829 "gram.c" /* yacc.c:1646 */ - break; - - case 2287: -#line 15041 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45835 "gram.c" /* yacc.c:1646 */ - break; - - case 2288: -#line 15042 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45841 "gram.c" /* yacc.c:1646 */ - break; - - case 2289: -#line 15043 "gram.y" /* yacc.c:1646 */ - { (yyval.str) = pstrdup((yyvsp[0].keyword)); } -#line 45847 "gram.c" /* yacc.c:1646 */ - break; - - -#line 45851 "gram.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (&yylloc, yyscanner, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (&yylloc, yyscanner, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, yyscanner); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, yyscanner); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, yyscanner, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, yyscanner); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, yyscanner); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - return yyresult; -} -#line 15540 "gram.y" /* yacc.c:1906 */ - - -/* - * The signature of this function is required by bison. However, we - * ignore the passed yylloc and instead use the last token position - * available from the scanner. - */ -static void -base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg) -{ - parser_yyerror(msg); -} - -static RawStmt * -makeRawStmt(Node *stmt, int stmt_location) -{ - RawStmt *rs = makeNode(RawStmt); - - rs->stmt = stmt; - rs->stmt_location = stmt_location; - rs->stmt_len = 0; /* might get changed later */ - return rs; -} - -/* Adjust a RawStmt to reflect that it doesn't run to the end of the string */ -static void -updateRawStmtEnd(RawStmt *rs, int end_location) -{ - /* - * If we already set the length, don't change it. This is for situations - * like "select foo ;; select bar" where the same statement will be last - * in the string for more than one semicolon. - */ - if (rs->stmt_len > 0) - return; - - /* OK, update length of RawStmt */ - rs->stmt_len = end_location - rs->stmt_location; -} - -static Node * -makeColumnRef(char *colname, List *indirection, - int location, core_yyscan_t yyscanner) -{ - /* - * Generate a ColumnRef node, with an A_Indirection node added if there - * is any subscripting in the specified indirection list. However, - * any field selection at the start of the indirection list must be - * transposed into the "fields" part of the ColumnRef node. - */ - ColumnRef *c = makeNode(ColumnRef); - int nfields = 0; - ListCell *l; - - c->location = location; - foreach(l, indirection) - { - if (IsA(lfirst(l), A_Indices)) - { - A_Indirection *i = makeNode(A_Indirection); - - if (nfields == 0) - { - /* easy case - all indirection goes to A_Indirection */ - c->fields = list_make1(makeString(colname)); - i->indirection = check_indirection(indirection, yyscanner); - } - else - { - /* got to split the list in two */ - i->indirection = check_indirection(list_copy_tail(indirection, - nfields), - yyscanner); - indirection = list_truncate(indirection, nfields); - c->fields = lcons(makeString(colname), indirection); - } - i->arg = (Node *) c; - return (Node *) i; - } - else if (IsA(lfirst(l), A_Star)) - { - /* We only allow '*' at the end of a ColumnRef */ - if (lnext(l) != NULL) - parser_yyerror("improper use of \"*\""); - } - nfields++; - } - /* No subscripting, so all indirection gets added to field list */ - c->fields = lcons(makeString(colname), indirection); - return (Node *) c; -} - -Node * -makeTypeCast(Node *arg, TypeName *typename, int location) -{ - TypeCast *n = makeNode(TypeCast); - n->arg = arg; - n->typeName = typename; - n->location = location; - return (Node *) n; -} - -static Node * -makeStringConst(char *str, int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_String; - n->val.val.str = str; - n->location = location; - - return (Node *)n; -} - -Node * -makeStringConstCast(char *str, int location, TypeName *typename) -{ - Node *s = makeStringConst(str, location); - - return makeTypeCast(s, typename, -1); -} - -Node * -makeIntConst(int val, int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_Integer; - n->val.val.ival = val; - n->location = location; - - return (Node *)n; -} - -static Node * -makeFloatConst(char *str, int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_Float; - n->val.val.str = str; - n->location = location; - - return (Node *)n; -} - -static Node * -makeBitStringConst(char *str, int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_BitString; - n->val.val.str = str; - n->location = location; - - return (Node *)n; -} - -static Node * -makeNullAConst(int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_Null; - n->location = location; - - return (Node *)n; -} - -static Node * -makeAConst(Value *v, int location) -{ - Node *n; - - switch (v->type) - { - case T_Float: - n = makeFloatConst(v->val.str, location); - break; - - case T_Integer: - n = makeIntConst(v->val.ival, location); - break; - - case T_String: - default: - n = makeStringConst(v->val.str, location); - break; - } - - return n; -} - -/* makeBoolAConst() - * Create an A_Const string node and put it inside a boolean cast. - */ -static Node * -makeBoolAConst(bool state, int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_String; - n->val.val.str = (state ? "t" : "f"); - n->location = location; - - return makeTypeCast((Node *)n, SystemTypeName("bool"), -1); -} - -/* makeRoleSpec - * Create a RoleSpec with the given type - */ -static RoleSpec * -makeRoleSpec(RoleSpecType type, int location) -{ - RoleSpec *spec = makeNode(RoleSpec); - - spec->roletype = type; - spec->location = location; - - return spec; -} - -/* check_qualified_name --- check the result of qualified_name production - * - * It's easiest to let the grammar production for qualified_name allow - * subscripts and '*', which we then must reject here. - */ -static void -check_qualified_name(List *names, core_yyscan_t yyscanner) -{ - ListCell *i; - - foreach(i, names) - { - if (!IsA(lfirst(i), String)) - parser_yyerror("syntax error"); - } -} - -/* check_func_name --- check the result of func_name production - * - * It's easiest to let the grammar production for func_name allow subscripts - * and '*', which we then must reject here. - */ -static List * -check_func_name(List *names, core_yyscan_t yyscanner) -{ - ListCell *i; - - foreach(i, names) - { - if (!IsA(lfirst(i), String)) - parser_yyerror("syntax error"); - } - return names; -} - -/* check_indirection --- check the result of indirection production - * - * We only allow '*' at the end of the list, but it's hard to enforce that - * in the grammar, so do it here. - */ -static List * -check_indirection(List *indirection, core_yyscan_t yyscanner) -{ - ListCell *l; - - foreach(l, indirection) - { - if (IsA(lfirst(l), A_Star)) - { - if (lnext(l) != NULL) - parser_yyerror("improper use of \"*\""); - } - } - return indirection; -} - -/* extractArgTypes() - * Given a list of FunctionParameter nodes, extract a list of just the - * argument types (TypeNames) for input parameters only. This is what - * is needed to look up an existing function, which is what is wanted by - * the productions that use this call. - */ -static List * -extractArgTypes(List *parameters) -{ - List *result = NIL; - ListCell *i; - - foreach(i, parameters) - { - FunctionParameter *p = (FunctionParameter *) lfirst(i); - - if (p->mode != FUNC_PARAM_OUT && p->mode != FUNC_PARAM_TABLE) - result = lappend(result, p->argType); - } - return result; -} - -/* extractAggrArgTypes() - * As above, but work from the output of the aggr_args production. - */ -static List * -extractAggrArgTypes(List *aggrargs) -{ - Assert(list_length(aggrargs) == 2); - return extractArgTypes((List *) linitial(aggrargs)); -} - -/* makeOrderedSetArgs() - * Build the result of the aggr_args production (which see the comments for). - * This handles only the case where both given lists are nonempty, so that - * we have to deal with multiple VARIADIC arguments. - */ -static List * -makeOrderedSetArgs(List *directargs, List *orderedargs, - core_yyscan_t yyscanner) -{ - FunctionParameter *lastd = (FunctionParameter *) llast(directargs); - int ndirectargs; - - /* No restriction unless last direct arg is VARIADIC */ - if (lastd->mode == FUNC_PARAM_VARIADIC) - { - FunctionParameter *firsto = (FunctionParameter *) linitial(orderedargs); - - /* - * We ignore the names, though the aggr_arg production allows them; - * it doesn't allow default values, so those need not be checked. - */ - if (list_length(orderedargs) != 1 || - firsto->mode != FUNC_PARAM_VARIADIC) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type"), - parser_errposition(exprLocation((Node *) firsto)))); - - /* OK, drop the duplicate VARIADIC argument from the internal form */ - orderedargs = NIL; - } - - /* don't merge into the next line, as list_concat changes directargs */ - ndirectargs = list_length(directargs); - - return list_make2(list_concat(directargs, orderedargs), - makeInteger(ndirectargs)); -} - -/* insertSelectOptions() - * Insert ORDER BY, etc into an already-constructed SelectStmt. - * - * This routine is just to avoid duplicating code in SelectStmt productions. - */ -static void -insertSelectOptions(SelectStmt *stmt, - List *sortClause, List *lockingClause, - Node *limitOffset, Node *limitCount, - WithClause *withClause, - core_yyscan_t yyscanner) -{ - Assert(IsA(stmt, SelectStmt)); - - /* - * Tests here are to reject constructs like - * (SELECT foo ORDER BY bar) ORDER BY baz - */ - if (sortClause) - { - if (stmt->sortClause) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple ORDER BY clauses not allowed"), - parser_errposition(exprLocation((Node *) sortClause)))); - stmt->sortClause = sortClause; - } - /* We can handle multiple locking clauses, though */ - stmt->lockingClause = list_concat(stmt->lockingClause, lockingClause); - if (limitOffset) - { - if (stmt->limitOffset) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple OFFSET clauses not allowed"), - parser_errposition(exprLocation(limitOffset)))); - stmt->limitOffset = limitOffset; - } - if (limitCount) - { - if (stmt->limitCount) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple LIMIT clauses not allowed"), - parser_errposition(exprLocation(limitCount)))); - stmt->limitCount = limitCount; - } - if (withClause) - { - if (stmt->withClause) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple WITH clauses not allowed"), - parser_errposition(exprLocation((Node *) withClause)))); - stmt->withClause = withClause; - } -} - -static Node * -makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg) -{ - SelectStmt *n = makeNode(SelectStmt); - - n->op = op; - n->all = all; - n->larg = (SelectStmt *) larg; - n->rarg = (SelectStmt *) rarg; - return (Node *) n; -} - -/* SystemFuncName() - * Build a properly-qualified reference to a built-in function. - */ -List * -SystemFuncName(char *name) -{ - return list_make2(makeString("pg_catalog"), makeString(name)); -} - -/* SystemTypeName() - * Build a properly-qualified reference to a built-in type. - * - * typmod is defaulted, but may be changed afterwards by caller. - * Likewise for the location. - */ -TypeName * -SystemTypeName(char *name) -{ - return makeTypeNameFromNameList(list_make2(makeString("pg_catalog"), - makeString(name))); -} - -/* doNegate() - * Handle negation of a numeric constant. - * - * Formerly, we did this here because the optimizer couldn't cope with - * indexquals that looked like "var = -4" --- it wants "var = const" - * and a unary minus operator applied to a constant didn't qualify. - * As of Postgres 7.0, that problem doesn't exist anymore because there - * is a constant-subexpression simplifier in the optimizer. However, - * there's still a good reason for doing this here, which is that we can - * postpone committing to a particular internal representation for simple - * negative constants. It's better to leave "-123.456" in string form - * until we know what the desired type is. - */ -static Node * -doNegate(Node *n, int location) -{ - if (IsA(n, A_Const)) - { - A_Const *con = (A_Const *)n; - - /* report the constant's location as that of the '-' sign */ - con->location = location; - - if (con->val.type == T_Integer) - { - con->val.val.ival = -con->val.val.ival; - return n; - } - if (con->val.type == T_Float) - { - doNegateFloat(&con->val); - return n; - } - } - - return (Node *) makeSimpleA_Expr(AEXPR_OP, "-", NULL, n, location); -} - -static void -doNegateFloat(Value *v) -{ - char *oldval = v->val.str; - - Assert(IsA(v, Float)); - if (*oldval == '+') - oldval++; - if (*oldval == '-') - v->val.str = oldval+1; /* just strip the '-' */ - else - v->val.str = psprintf("-%s", oldval); -} - -static Node * -makeAndExpr(Node *lexpr, Node *rexpr, int location) -{ - Node *lexp = lexpr; - - /* Look through AEXPR_PAREN nodes so they don't affect flattening */ - while (IsA(lexp, A_Expr) && - ((A_Expr *) lexp)->kind == AEXPR_PAREN) - lexp = ((A_Expr *) lexp)->lexpr; - /* Flatten "a AND b AND c ..." to a single BoolExpr on sight */ - if (IsA(lexp, BoolExpr)) - { - BoolExpr *blexpr = (BoolExpr *) lexp; - - if (blexpr->boolop == AND_EXPR) - { - blexpr->args = lappend(blexpr->args, rexpr); - return (Node *) blexpr; - } - } - return (Node *) makeBoolExpr(AND_EXPR, list_make2(lexpr, rexpr), location); -} - -static Node * -makeOrExpr(Node *lexpr, Node *rexpr, int location) -{ - Node *lexp = lexpr; - - /* Look through AEXPR_PAREN nodes so they don't affect flattening */ - while (IsA(lexp, A_Expr) && - ((A_Expr *) lexp)->kind == AEXPR_PAREN) - lexp = ((A_Expr *) lexp)->lexpr; - /* Flatten "a OR b OR c ..." to a single BoolExpr on sight */ - if (IsA(lexp, BoolExpr)) - { - BoolExpr *blexpr = (BoolExpr *) lexp; - - if (blexpr->boolop == OR_EXPR) - { - blexpr->args = lappend(blexpr->args, rexpr); - return (Node *) blexpr; - } - } - return (Node *) makeBoolExpr(OR_EXPR, list_make2(lexpr, rexpr), location); -} - -static Node * -makeNotExpr(Node *expr, int location) -{ - return (Node *) makeBoolExpr(NOT_EXPR, list_make1(expr), location); -} - -static Node * -makeAArrayExpr(List *elements, int location) -{ - A_ArrayExpr *n = makeNode(A_ArrayExpr); - - n->elements = elements; - n->location = location; - return (Node *) n; -} - -static Node * -makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, int location) -{ - SQLValueFunction *svf = makeNode(SQLValueFunction); - - svf->op = op; - /* svf->type will be filled during parse analysis */ - svf->typmod = typmod; - svf->location = location; - return (Node *) svf; -} - -static Node * -makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, - int location) -{ - XmlExpr *x = makeNode(XmlExpr); - - x->op = op; - x->name = name; - /* - * named_args is a list of ResTarget; it'll be split apart into separate - * expression and name lists in transformXmlExpr(). - */ - x->named_args = named_args; - x->arg_names = NIL; - x->args = args; - /* xmloption, if relevant, must be filled in by caller */ - /* type and typmod will be filled in during parse analysis */ - x->type = InvalidOid; /* marks the node as not analyzed */ - x->location = location; - return (Node *) x; -} - -/* - * Merge the input and output parameters of a table function. - */ -static List * -mergeTableFuncParameters(List *func_args, List *columns) -{ - ListCell *lc; - - /* Explicit OUT and INOUT parameters shouldn't be used in this syntax */ - foreach(lc, func_args) - { - FunctionParameter *p = (FunctionParameter *) lfirst(lc); - - if (p->mode != FUNC_PARAM_IN && p->mode != FUNC_PARAM_VARIADIC) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("OUT and INOUT arguments aren't allowed in TABLE functions"))); - } - - return list_concat(func_args, columns); -} - -/* - * Determine return type of a TABLE function. A single result column - * returns setof that column's type; otherwise return setof record. - */ -static TypeName * -TableFuncTypeName(List *columns) -{ - TypeName *result; - - if (list_length(columns) == 1) - { - FunctionParameter *p = (FunctionParameter *) linitial(columns); - - result = copyObject(p->argType); - } - else - result = SystemTypeName("record"); - - result->setof = true; - - return result; -} - -/* - * Convert a list of (dotted) names to a RangeVar (like - * makeRangeVarFromNameList, but with position support). The - * "AnyName" refers to the any_name production in the grammar. - */ -static RangeVar * -makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner) -{ - RangeVar *r = makeNode(RangeVar); - - switch (list_length(names)) - { - case 1: - r->catalogname = NULL; - r->schemaname = NULL; - r->relname = strVal(linitial(names)); - break; - case 2: - r->catalogname = NULL; - r->schemaname = strVal(linitial(names)); - r->relname = strVal(lsecond(names)); - break; - case 3: - r->catalogname = strVal(linitial(names)); - r->schemaname = strVal(lsecond(names)); - r->relname = strVal(lthird(names)); - break; - default: - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("improper qualified name (too many dotted names): %s", - NameListToString(names)), - parser_errposition(position))); - break; - } - - r->relpersistence = RELPERSISTENCE_PERMANENT; - r->location = position; - - return r; -} - -/* Separate Constraint nodes from COLLATE clauses in a ColQualList */ -static void -SplitColQualList(List *qualList, - List **constraintList, CollateClause **collClause, - core_yyscan_t yyscanner) -{ - ListCell *cell; - ListCell *prev; - ListCell *next; - - *collClause = NULL; - prev = NULL; - for (cell = list_head(qualList); cell; cell = next) - { - Node *n = (Node *) lfirst(cell); - - next = lnext(cell); - if (IsA(n, Constraint)) - { - /* keep it in list */ - prev = cell; - continue; - } - if (IsA(n, CollateClause)) - { - CollateClause *c = (CollateClause *) n; - - if (*collClause) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple COLLATE clauses not allowed"), - parser_errposition(c->location))); - *collClause = c; - } - else - elog(ERROR, "unexpected node type %d", (int) n->type); - /* remove non-Constraint nodes from qualList */ - qualList = list_delete_cell(qualList, cell, prev); - } - *constraintList = qualList; -} - -/* - * Process result of ConstraintAttributeSpec, and set appropriate bool flags - * in the output command node. Pass NULL for any flags the particular - * command doesn't support. - */ -static void -processCASbits(int cas_bits, int location, const char *constrType, - bool *deferrable, bool *initdeferred, bool *not_valid, - bool *no_inherit, core_yyscan_t yyscanner) -{ - /* defaults */ - if (deferrable) - *deferrable = false; - if (initdeferred) - *initdeferred = false; - if (not_valid) - *not_valid = false; - - if (cas_bits & (CAS_DEFERRABLE | CAS_INITIALLY_DEFERRED)) - { - if (deferrable) - *deferrable = true; - else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ - errmsg("%s constraints cannot be marked DEFERRABLE", - constrType), - parser_errposition(location))); - } - - if (cas_bits & CAS_INITIALLY_DEFERRED) - { - if (initdeferred) - *initdeferred = true; - else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ - errmsg("%s constraints cannot be marked DEFERRABLE", - constrType), - parser_errposition(location))); - } - - if (cas_bits & CAS_NOT_VALID) - { - if (not_valid) - *not_valid = true; - else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ - errmsg("%s constraints cannot be marked NOT VALID", - constrType), - parser_errposition(location))); - } - - if (cas_bits & CAS_NO_INHERIT) - { - if (no_inherit) - *no_inherit = true; - else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ - errmsg("%s constraints cannot be marked NO INHERIT", - constrType), - parser_errposition(location))); - } -} - -/*---------- - * Recursive view transformation - * - * Convert - * - * CREATE RECURSIVE VIEW relname (aliases) AS query - * - * to - * - * CREATE VIEW relname (aliases) AS - * WITH RECURSIVE relname (aliases) AS (query) - * SELECT aliases FROM relname - * - * Actually, just the WITH ... part, which is then inserted into the original - * view definition as the query. - * ---------- - */ -static Node * -makeRecursiveViewSelect(char *relname, List *aliases, Node *query) -{ - SelectStmt *s = makeNode(SelectStmt); - WithClause *w = makeNode(WithClause); - CommonTableExpr *cte = makeNode(CommonTableExpr); - List *tl = NIL; - ListCell *lc; - - /* create common table expression */ - cte->ctename = relname; - cte->aliascolnames = aliases; - cte->ctequery = query; - cte->location = -1; - - /* create WITH clause and attach CTE */ - w->recursive = true; - w->ctes = list_make1(cte); - w->location = -1; - - /* create target list for the new SELECT from the alias list of the - * recursive view specification */ - foreach (lc, aliases) - { - ResTarget *rt = makeNode(ResTarget); - - rt->name = NULL; - rt->indirection = NIL; - rt->val = makeColumnRef(strVal(lfirst(lc)), NIL, -1, 0); - rt->location = -1; - - tl = lappend(tl, rt); - } - - /* create new SELECT combining WITH clause, target list, and fake FROM - * clause */ - s->withClause = w; - s->targetList = tl; - s->fromClause = list_make1(makeRangeVar(NULL, relname, -1)); - - return (Node *) s; -} - -/* parser_init() - * Initialize to parse one query string - */ -void -parser_init(base_yy_extra_type *yyext) -{ - yyext->parsetree = NIL; /* in case grammar forgets to set it */ -} - diff --git a/src/parser/gram.h b/src/parser/gram.h deleted file mode 100644 index c8c9576bc..000000000 --- a/src/parser/gram.h +++ /dev/null @@ -1,1049 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - 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. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY_BASE_YY_GRAM_H_INCLUDED -# define YY_BASE_YY_GRAM_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int base_yydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - IDENT = 258, - FCONST = 259, - SCONST = 260, - BCONST = 261, - XCONST = 262, - Op = 263, - ICONST = 264, - PARAM = 265, - TYPECAST = 266, - DOT_DOT = 267, - COLON_EQUALS = 268, - EQUALS_GREATER = 269, - LESS_EQUALS = 270, - GREATER_EQUALS = 271, - NOT_EQUALS = 272, - ABORT_P = 273, - ABSOLUTE_P = 274, - ACCESS = 275, - ACTION = 276, - ADD_P = 277, - ADMIN = 278, - AFTER = 279, - AGGREGATE = 280, - ALL = 281, - ALSO = 282, - ALTER = 283, - ALWAYS = 284, - ANALYSE = 285, - ANALYZE = 286, - AND = 287, - ANY = 288, - ARRAY = 289, - AS = 290, - ASC = 291, - ASSERTION = 292, - ASSIGNMENT = 293, - ASYMMETRIC = 294, - AT = 295, - ATTACH = 296, - ATTRIBUTE = 297, - AUTHORIZATION = 298, - BACKWARD = 299, - BEFORE = 300, - BEGIN_P = 301, - BETWEEN = 302, - BIGINT = 303, - BINARY = 304, - BIT = 305, - BOOLEAN_P = 306, - BOTH = 307, - BY = 308, - CACHE = 309, - CALL = 310, - CALLED = 311, - CASCADE = 312, - CASCADED = 313, - CASE = 314, - CAST = 315, - CATALOG_P = 316, - CHAIN = 317, - CHAR_P = 318, - CHARACTER = 319, - CHARACTERISTICS = 320, - CHECK = 321, - CHECKPOINT = 322, - CLASS = 323, - CLOSE = 324, - CLUSTER = 325, - COALESCE = 326, - COLLATE = 327, - COLLATION = 328, - COLUMN = 329, - COLUMNS = 330, - COMMENT = 331, - COMMENTS = 332, - COMMIT = 333, - COMMITTED = 334, - CONCURRENTLY = 335, - CONFIGURATION = 336, - CONFLICT = 337, - CONNECTION = 338, - CONSTRAINT = 339, - CONSTRAINTS = 340, - CONTENT_P = 341, - CONTINUE_P = 342, - CONVERSION_P = 343, - COPY = 344, - COST = 345, - CREATE = 346, - CROSS = 347, - CSV = 348, - CUBE = 349, - CURRENT_P = 350, - CURRENT_CATALOG = 351, - CURRENT_DATE = 352, - CURRENT_ROLE = 353, - CURRENT_SCHEMA = 354, - CURRENT_TIME = 355, - CURRENT_TIMESTAMP = 356, - CURRENT_USER = 357, - CURSOR = 358, - CYCLE = 359, - DATA_P = 360, - DATABASE = 361, - DAY_P = 362, - DEALLOCATE = 363, - DEC = 364, - DECIMAL_P = 365, - DECLARE = 366, - DEFAULT = 367, - DEFAULTS = 368, - DEFERRABLE = 369, - DEFERRED = 370, - DEFINER = 371, - DELETE_P = 372, - DELIMITER = 373, - DELIMITERS = 374, - DEPENDS = 375, - DESC = 376, - DETACH = 377, - DICTIONARY = 378, - DISABLE_P = 379, - DISCARD = 380, - DISTINCT = 381, - DO = 382, - DOCUMENT_P = 383, - DOMAIN_P = 384, - DOUBLE_P = 385, - DROP = 386, - EACH = 387, - ELSE = 388, - ENABLE_P = 389, - ENCODING = 390, - ENCRYPTED = 391, - END_P = 392, - ENUM_P = 393, - ESCAPE = 394, - EVENT = 395, - EXCEPT = 396, - EXCLUDE = 397, - EXCLUDING = 398, - EXCLUSIVE = 399, - EXECUTE = 400, - EXISTS = 401, - EXPLAIN = 402, - EXTENSION = 403, - EXTERNAL = 404, - EXTRACT = 405, - FALSE_P = 406, - FAMILY = 407, - FETCH = 408, - FILTER = 409, - FIRST_P = 410, - FLOAT_P = 411, - FOLLOWING = 412, - FOR = 413, - FORCE = 414, - FOREIGN = 415, - FORWARD = 416, - FREEZE = 417, - FROM = 418, - FULL = 419, - FUNCTION = 420, - FUNCTIONS = 421, - GENERATED = 422, - GLOBAL = 423, - GRANT = 424, - GRANTED = 425, - GREATEST = 426, - GROUP_P = 427, - GROUPING = 428, - GROUPS = 429, - HANDLER = 430, - HAVING = 431, - HEADER_P = 432, - HOLD = 433, - HOUR_P = 434, - IDENTITY_P = 435, - IF_P = 436, - ILIKE = 437, - IMMEDIATE = 438, - IMMUTABLE = 439, - IMPLICIT_P = 440, - IMPORT_P = 441, - IN_P = 442, - INCLUDE = 443, - INCLUDING = 444, - INCREMENT = 445, - INDEX = 446, - INDEXES = 447, - INHERIT = 448, - INHERITS = 449, - INITIALLY = 450, - INLINE_P = 451, - INNER_P = 452, - INOUT = 453, - INPUT_P = 454, - INSENSITIVE = 455, - INSERT = 456, - INSTEAD = 457, - INT_P = 458, - INTEGER = 459, - INTERSECT = 460, - INTERVAL = 461, - INTO = 462, - INVOKER = 463, - IS = 464, - ISNULL = 465, - ISOLATION = 466, - JOIN = 467, - KEY = 468, - LABEL = 469, - LANGUAGE = 470, - LARGE_P = 471, - LAST_P = 472, - LATERAL_P = 473, - LEADING = 474, - LEAKPROOF = 475, - LEAST = 476, - LEFT = 477, - LEVEL = 478, - LIKE = 479, - LIMIT = 480, - LISTEN = 481, - LOAD = 482, - LOCAL = 483, - LOCALTIME = 484, - LOCALTIMESTAMP = 485, - LOCATION = 486, - LOCK_P = 487, - LOCKED = 488, - LOGGED = 489, - MAPPING = 490, - MATCH = 491, - MATERIALIZED = 492, - MAXVALUE = 493, - METHOD = 494, - MINUTE_P = 495, - MINVALUE = 496, - MODE = 497, - MONTH_P = 498, - MOVE = 499, - NAME_P = 500, - NAMES = 501, - NATIONAL = 502, - NATURAL = 503, - NCHAR = 504, - NEW = 505, - NEXT = 506, - NO = 507, - NONE = 508, - NOT = 509, - NOTHING = 510, - NOTIFY = 511, - NOTNULL = 512, - NOWAIT = 513, - NULL_P = 514, - NULLIF = 515, - NULLS_P = 516, - NUMERIC = 517, - OBJECT_P = 518, - OF = 519, - OFF = 520, - OFFSET = 521, - OIDS = 522, - OLD = 523, - ON = 524, - ONLY = 525, - OPERATOR = 526, - OPTION = 527, - OPTIONS = 528, - OR = 529, - ORDER = 530, - ORDINALITY = 531, - OTHERS = 532, - OUT_P = 533, - OUTER_P = 534, - OVER = 535, - OVERLAPS = 536, - OVERLAY = 537, - OVERRIDING = 538, - OWNED = 539, - OWNER = 540, - PARALLEL = 541, - PARSER = 542, - PARTIAL = 543, - PARTITION = 544, - PASSING = 545, - PASSWORD = 546, - PGPOOL = 547, - PLACING = 548, - PLANS = 549, - POLICY = 550, - POSITION = 551, - PRECEDING = 552, - PRECISION = 553, - PRESERVE = 554, - PREPARE = 555, - PREPARED = 556, - PRIMARY = 557, - PRIOR = 558, - PRIVILEGES = 559, - PROCEDURAL = 560, - PROCEDURE = 561, - PROCEDURES = 562, - PROGRAM = 563, - PUBLICATION = 564, - QUOTE = 565, - RANGE = 566, - READ = 567, - REAL = 568, - REASSIGN = 569, - RECHECK = 570, - RECURSIVE = 571, - REF = 572, - REFERENCES = 573, - REFERENCING = 574, - REFRESH = 575, - REINDEX = 576, - RELATIVE_P = 577, - RELEASE = 578, - RENAME = 579, - REPEATABLE = 580, - REPLACE = 581, - REPLICA = 582, - RESET = 583, - RESTART = 584, - RESTRICT = 585, - RETURNING = 586, - RETURNS = 587, - REVOKE = 588, - RIGHT = 589, - ROLE = 590, - ROLLBACK = 591, - ROLLUP = 592, - ROUTINE = 593, - ROUTINES = 594, - ROW = 595, - ROWS = 596, - RULE = 597, - SAVEPOINT = 598, - SCHEMA = 599, - SCHEMAS = 600, - SCROLL = 601, - SEARCH = 602, - SECOND_P = 603, - SECURITY = 604, - SELECT = 605, - SEQUENCE = 606, - SEQUENCES = 607, - SERIALIZABLE = 608, - SERVER = 609, - SESSION = 610, - SESSION_USER = 611, - SET = 612, - SETS = 613, - SETOF = 614, - SHARE = 615, - SHOW = 616, - SIMILAR = 617, - SIMPLE = 618, - SKIP = 619, - SMALLINT = 620, - SNAPSHOT = 621, - SOME = 622, - SQL_P = 623, - STABLE = 624, - STANDALONE_P = 625, - START = 626, - STATEMENT = 627, - STATISTICS = 628, - STDIN = 629, - STDOUT = 630, - STORAGE = 631, - STRICT_P = 632, - STRIP_P = 633, - SUBSCRIPTION = 634, - SUBSTRING = 635, - SYMMETRIC = 636, - SYSID = 637, - SYSTEM_P = 638, - TABLE = 639, - TABLES = 640, - TABLESAMPLE = 641, - TABLESPACE = 642, - TEMP = 643, - TEMPLATE = 644, - TEMPORARY = 645, - TEXT_P = 646, - THEN = 647, - TIES = 648, - TIME = 649, - TIMESTAMP = 650, - TO = 651, - TRAILING = 652, - TRANSACTION = 653, - TRANSFORM = 654, - TREAT = 655, - TRIGGER = 656, - TRIM = 657, - TRUE_P = 658, - TRUNCATE = 659, - TRUSTED = 660, - TYPE_P = 661, - TYPES_P = 662, - UNBOUNDED = 663, - UNCOMMITTED = 664, - UNENCRYPTED = 665, - UNION = 666, - UNIQUE = 667, - UNKNOWN = 668, - UNLISTEN = 669, - UNLOGGED = 670, - UNTIL = 671, - UPDATE = 672, - USER = 673, - USING = 674, - VACUUM = 675, - VALID = 676, - VALIDATE = 677, - VALIDATOR = 678, - VALUE_P = 679, - VALUES = 680, - VARCHAR = 681, - VARIADIC = 682, - VARYING = 683, - VERBOSE = 684, - VERSION_P = 685, - VIEW = 686, - VIEWS = 687, - VOLATILE = 688, - WHEN = 689, - WHERE = 690, - WHITESPACE_P = 691, - WINDOW = 692, - WITH = 693, - WITHIN = 694, - WITHOUT = 695, - WORK = 696, - WRAPPER = 697, - WRITE = 698, - XML_P = 699, - XMLATTRIBUTES = 700, - XMLCONCAT = 701, - XMLELEMENT = 702, - XMLEXISTS = 703, - XMLFOREST = 704, - XMLNAMESPACES = 705, - XMLPARSE = 706, - XMLPI = 707, - XMLROOT = 708, - XMLSERIALIZE = 709, - XMLTABLE = 710, - YEAR_P = 711, - YES_P = 712, - ZONE = 713, - NOT_LA = 714, - NULLS_LA = 715, - WITH_LA = 716, - POSTFIXOP = 717, - UMINUS = 718 - }; -#endif -/* Tokens. */ -#define IDENT 258 -#define FCONST 259 -#define SCONST 260 -#define BCONST 261 -#define XCONST 262 -#define Op 263 -#define ICONST 264 -#define PARAM 265 -#define TYPECAST 266 -#define DOT_DOT 267 -#define COLON_EQUALS 268 -#define EQUALS_GREATER 269 -#define LESS_EQUALS 270 -#define GREATER_EQUALS 271 -#define NOT_EQUALS 272 -#define ABORT_P 273 -#define ABSOLUTE_P 274 -#define ACCESS 275 -#define ACTION 276 -#define ADD_P 277 -#define ADMIN 278 -#define AFTER 279 -#define AGGREGATE 280 -#define ALL 281 -#define ALSO 282 -#define ALTER 283 -#define ALWAYS 284 -#define ANALYSE 285 -#define ANALYZE 286 -#define AND 287 -#define ANY 288 -#define ARRAY 289 -#define AS 290 -#define ASC 291 -#define ASSERTION 292 -#define ASSIGNMENT 293 -#define ASYMMETRIC 294 -#define AT 295 -#define ATTACH 296 -#define ATTRIBUTE 297 -#define AUTHORIZATION 298 -#define BACKWARD 299 -#define BEFORE 300 -#define BEGIN_P 301 -#define BETWEEN 302 -#define BIGINT 303 -#define BINARY 304 -#define BIT 305 -#define BOOLEAN_P 306 -#define BOTH 307 -#define BY 308 -#define CACHE 309 -#define CALL 310 -#define CALLED 311 -#define CASCADE 312 -#define CASCADED 313 -#define CASE 314 -#define CAST 315 -#define CATALOG_P 316 -#define CHAIN 317 -#define CHAR_P 318 -#define CHARACTER 319 -#define CHARACTERISTICS 320 -#define CHECK 321 -#define CHECKPOINT 322 -#define CLASS 323 -#define CLOSE 324 -#define CLUSTER 325 -#define COALESCE 326 -#define COLLATE 327 -#define COLLATION 328 -#define COLUMN 329 -#define COLUMNS 330 -#define COMMENT 331 -#define COMMENTS 332 -#define COMMIT 333 -#define COMMITTED 334 -#define CONCURRENTLY 335 -#define CONFIGURATION 336 -#define CONFLICT 337 -#define CONNECTION 338 -#define CONSTRAINT 339 -#define CONSTRAINTS 340 -#define CONTENT_P 341 -#define CONTINUE_P 342 -#define CONVERSION_P 343 -#define COPY 344 -#define COST 345 -#define CREATE 346 -#define CROSS 347 -#define CSV 348 -#define CUBE 349 -#define CURRENT_P 350 -#define CURRENT_CATALOG 351 -#define CURRENT_DATE 352 -#define CURRENT_ROLE 353 -#define CURRENT_SCHEMA 354 -#define CURRENT_TIME 355 -#define CURRENT_TIMESTAMP 356 -#define CURRENT_USER 357 -#define CURSOR 358 -#define CYCLE 359 -#define DATA_P 360 -#define DATABASE 361 -#define DAY_P 362 -#define DEALLOCATE 363 -#define DEC 364 -#define DECIMAL_P 365 -#define DECLARE 366 -#define DEFAULT 367 -#define DEFAULTS 368 -#define DEFERRABLE 369 -#define DEFERRED 370 -#define DEFINER 371 -#define DELETE_P 372 -#define DELIMITER 373 -#define DELIMITERS 374 -#define DEPENDS 375 -#define DESC 376 -#define DETACH 377 -#define DICTIONARY 378 -#define DISABLE_P 379 -#define DISCARD 380 -#define DISTINCT 381 -#define DO 382 -#define DOCUMENT_P 383 -#define DOMAIN_P 384 -#define DOUBLE_P 385 -#define DROP 386 -#define EACH 387 -#define ELSE 388 -#define ENABLE_P 389 -#define ENCODING 390 -#define ENCRYPTED 391 -#define END_P 392 -#define ENUM_P 393 -#define ESCAPE 394 -#define EVENT 395 -#define EXCEPT 396 -#define EXCLUDE 397 -#define EXCLUDING 398 -#define EXCLUSIVE 399 -#define EXECUTE 400 -#define EXISTS 401 -#define EXPLAIN 402 -#define EXTENSION 403 -#define EXTERNAL 404 -#define EXTRACT 405 -#define FALSE_P 406 -#define FAMILY 407 -#define FETCH 408 -#define FILTER 409 -#define FIRST_P 410 -#define FLOAT_P 411 -#define FOLLOWING 412 -#define FOR 413 -#define FORCE 414 -#define FOREIGN 415 -#define FORWARD 416 -#define FREEZE 417 -#define FROM 418 -#define FULL 419 -#define FUNCTION 420 -#define FUNCTIONS 421 -#define GENERATED 422 -#define GLOBAL 423 -#define GRANT 424 -#define GRANTED 425 -#define GREATEST 426 -#define GROUP_P 427 -#define GROUPING 428 -#define GROUPS 429 -#define HANDLER 430 -#define HAVING 431 -#define HEADER_P 432 -#define HOLD 433 -#define HOUR_P 434 -#define IDENTITY_P 435 -#define IF_P 436 -#define ILIKE 437 -#define IMMEDIATE 438 -#define IMMUTABLE 439 -#define IMPLICIT_P 440 -#define IMPORT_P 441 -#define IN_P 442 -#define INCLUDE 443 -#define INCLUDING 444 -#define INCREMENT 445 -#define INDEX 446 -#define INDEXES 447 -#define INHERIT 448 -#define INHERITS 449 -#define INITIALLY 450 -#define INLINE_P 451 -#define INNER_P 452 -#define INOUT 453 -#define INPUT_P 454 -#define INSENSITIVE 455 -#define INSERT 456 -#define INSTEAD 457 -#define INT_P 458 -#define INTEGER 459 -#define INTERSECT 460 -#define INTERVAL 461 -#define INTO 462 -#define INVOKER 463 -#define IS 464 -#define ISNULL 465 -#define ISOLATION 466 -#define JOIN 467 -#define KEY 468 -#define LABEL 469 -#define LANGUAGE 470 -#define LARGE_P 471 -#define LAST_P 472 -#define LATERAL_P 473 -#define LEADING 474 -#define LEAKPROOF 475 -#define LEAST 476 -#define LEFT 477 -#define LEVEL 478 -#define LIKE 479 -#define LIMIT 480 -#define LISTEN 481 -#define LOAD 482 -#define LOCAL 483 -#define LOCALTIME 484 -#define LOCALTIMESTAMP 485 -#define LOCATION 486 -#define LOCK_P 487 -#define LOCKED 488 -#define LOGGED 489 -#define MAPPING 490 -#define MATCH 491 -#define MATERIALIZED 492 -#define MAXVALUE 493 -#define METHOD 494 -#define MINUTE_P 495 -#define MINVALUE 496 -#define MODE 497 -#define MONTH_P 498 -#define MOVE 499 -#define NAME_P 500 -#define NAMES 501 -#define NATIONAL 502 -#define NATURAL 503 -#define NCHAR 504 -#define NEW 505 -#define NEXT 506 -#define NO 507 -#define NONE 508 -#define NOT 509 -#define NOTHING 510 -#define NOTIFY 511 -#define NOTNULL 512 -#define NOWAIT 513 -#define NULL_P 514 -#define NULLIF 515 -#define NULLS_P 516 -#define NUMERIC 517 -#define OBJECT_P 518 -#define OF 519 -#define OFF 520 -#define OFFSET 521 -#define OIDS 522 -#define OLD 523 -#define ON 524 -#define ONLY 525 -#define OPERATOR 526 -#define OPTION 527 -#define OPTIONS 528 -#define OR 529 -#define ORDER 530 -#define ORDINALITY 531 -#define OTHERS 532 -#define OUT_P 533 -#define OUTER_P 534 -#define OVER 535 -#define OVERLAPS 536 -#define OVERLAY 537 -#define OVERRIDING 538 -#define OWNED 539 -#define OWNER 540 -#define PARALLEL 541 -#define PARSER 542 -#define PARTIAL 543 -#define PARTITION 544 -#define PASSING 545 -#define PASSWORD 546 -#define PGPOOL 547 -#define PLACING 548 -#define PLANS 549 -#define POLICY 550 -#define POSITION 551 -#define PRECEDING 552 -#define PRECISION 553 -#define PRESERVE 554 -#define PREPARE 555 -#define PREPARED 556 -#define PRIMARY 557 -#define PRIOR 558 -#define PRIVILEGES 559 -#define PROCEDURAL 560 -#define PROCEDURE 561 -#define PROCEDURES 562 -#define PROGRAM 563 -#define PUBLICATION 564 -#define QUOTE 565 -#define RANGE 566 -#define READ 567 -#define REAL 568 -#define REASSIGN 569 -#define RECHECK 570 -#define RECURSIVE 571 -#define REF 572 -#define REFERENCES 573 -#define REFERENCING 574 -#define REFRESH 575 -#define REINDEX 576 -#define RELATIVE_P 577 -#define RELEASE 578 -#define RENAME 579 -#define REPEATABLE 580 -#define REPLACE 581 -#define REPLICA 582 -#define RESET 583 -#define RESTART 584 -#define RESTRICT 585 -#define RETURNING 586 -#define RETURNS 587 -#define REVOKE 588 -#define RIGHT 589 -#define ROLE 590 -#define ROLLBACK 591 -#define ROLLUP 592 -#define ROUTINE 593 -#define ROUTINES 594 -#define ROW 595 -#define ROWS 596 -#define RULE 597 -#define SAVEPOINT 598 -#define SCHEMA 599 -#define SCHEMAS 600 -#define SCROLL 601 -#define SEARCH 602 -#define SECOND_P 603 -#define SECURITY 604 -#define SELECT 605 -#define SEQUENCE 606 -#define SEQUENCES 607 -#define SERIALIZABLE 608 -#define SERVER 609 -#define SESSION 610 -#define SESSION_USER 611 -#define SET 612 -#define SETS 613 -#define SETOF 614 -#define SHARE 615 -#define SHOW 616 -#define SIMILAR 617 -#define SIMPLE 618 -#define SKIP 619 -#define SMALLINT 620 -#define SNAPSHOT 621 -#define SOME 622 -#define SQL_P 623 -#define STABLE 624 -#define STANDALONE_P 625 -#define START 626 -#define STATEMENT 627 -#define STATISTICS 628 -#define STDIN 629 -#define STDOUT 630 -#define STORAGE 631 -#define STRICT_P 632 -#define STRIP_P 633 -#define SUBSCRIPTION 634 -#define SUBSTRING 635 -#define SYMMETRIC 636 -#define SYSID 637 -#define SYSTEM_P 638 -#define TABLE 639 -#define TABLES 640 -#define TABLESAMPLE 641 -#define TABLESPACE 642 -#define TEMP 643 -#define TEMPLATE 644 -#define TEMPORARY 645 -#define TEXT_P 646 -#define THEN 647 -#define TIES 648 -#define TIME 649 -#define TIMESTAMP 650 -#define TO 651 -#define TRAILING 652 -#define TRANSACTION 653 -#define TRANSFORM 654 -#define TREAT 655 -#define TRIGGER 656 -#define TRIM 657 -#define TRUE_P 658 -#define TRUNCATE 659 -#define TRUSTED 660 -#define TYPE_P 661 -#define TYPES_P 662 -#define UNBOUNDED 663 -#define UNCOMMITTED 664 -#define UNENCRYPTED 665 -#define UNION 666 -#define UNIQUE 667 -#define UNKNOWN 668 -#define UNLISTEN 669 -#define UNLOGGED 670 -#define UNTIL 671 -#define UPDATE 672 -#define USER 673 -#define USING 674 -#define VACUUM 675 -#define VALID 676 -#define VALIDATE 677 -#define VALIDATOR 678 -#define VALUE_P 679 -#define VALUES 680 -#define VARCHAR 681 -#define VARIADIC 682 -#define VARYING 683 -#define VERBOSE 684 -#define VERSION_P 685 -#define VIEW 686 -#define VIEWS 687 -#define VOLATILE 688 -#define WHEN 689 -#define WHERE 690 -#define WHITESPACE_P 691 -#define WINDOW 692 -#define WITH 693 -#define WITHIN 694 -#define WITHOUT 695 -#define WORK 696 -#define WRAPPER 697 -#define WRITE 698 -#define XML_P 699 -#define XMLATTRIBUTES 700 -#define XMLCONCAT 701 -#define XMLELEMENT 702 -#define XMLEXISTS 703 -#define XMLFOREST 704 -#define XMLNAMESPACES 705 -#define XMLPARSE 706 -#define XMLPI 707 -#define XMLROOT 708 -#define XMLSERIALIZE 709 -#define XMLTABLE 710 -#define YEAR_P 711 -#define YES_P 712 -#define ZONE 713 -#define NOT_LA 714 -#define NULLS_LA 715 -#define WITH_LA 716 -#define POSTFIXOP 717 -#define UMINUS 718 - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE -{ -#line 239 "gram.y" /* yacc.c:1909 */ - - core_YYSTYPE core_yystype; - /* these fields must match core_YYSTYPE: */ - int ival; - char *str; - const char *keyword; - - char chr; - bool boolean; - JoinType jtype; - DropBehavior dbehavior; - OnCommitAction oncommit; - List *list; - Node *node; - Value *value; - ObjectType objtype; - TypeName *typnam; - FunctionParameter *fun_param; - FunctionParameterMode fun_param_mode; - ObjectWithArgs *objwithargs; - DefElem *defelt; - SortBy *sortby; - WindowDef *windef; - JoinExpr *jexpr; - IndexElem *ielem; - Alias *alias; - RangeVar *range; - IntoClause *into; - WithClause *with; - InferClause *infer; - OnConflictClause *onconflict; - A_Indices *aind; - ResTarget *target; - struct PrivTarget *privtarget; - AccessPriv *accesspriv; - struct ImportQual *importqual; - InsertStmt *istmt; - VariableSetStmt *vsetstmt; - PartitionElem *partelem; - PartitionSpec *partspec; - PartitionBoundSpec *partboundspec; - RoleSpec *rolespec; - -#line 1024 "gram.h" /* yacc.c:1909 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - -int base_yyparse (core_yyscan_t yyscanner); - -#endif /* !YY_BASE_YY_GRAM_H_INCLUDED */ diff --git a/src/parser/gram.y b/src/parser/gram.y index c8e5ca420..8052ced8d 100644 --- a/src/parser/gram.y +++ b/src/parser/gram.y @@ -6,8 +6,8 @@ * gram.y * POSTGRESQL BISON rules/actions * - * Portions Copyright (c) 2003-2018, PgPool Global Development Group - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -48,6 +48,7 @@ #include "pool_parser.h" #include "utils/elog.h" #include "utils/palloc.h" +#include "utils/pgstrcasecmp.h" #include #include #include @@ -58,16 +59,10 @@ #include "keywords.h" #include "gramparse.h" #include "makefuncs.h" -#include "pool_string.h" #include "parser.h" #include "pg_class.h" #include "pg_trigger.h" -/* This is a configuration parameter since PostgreSQL 9.5. - * We set this false in pgpool-II. This is default in PostgreSQL. - */ -bool operator_precedence_warning = false; - /* * Definition taken from * postgreSQL source code file: src/include/commands/trigger.h @@ -94,6 +89,8 @@ bool operator_precedence_warning = false; #define ATTRIBUTE_IDENTITY_ALWAYS 'a' #define ATTRIBUTE_IDENTITY_BY_DEFAULT 'd' +#define ATTRIBUTE_GENERATED_STORED 's' +#define ATTRIBUTE_GENERATED_VIRTUAL 'v' /* * Definition taken from * postgreSQL source code file: src/include/utils/xml.h @@ -107,46 +104,29 @@ typedef enum } XmlStandaloneType; /* - * Location tracking support --- simpler than bison's default, since we only - * want to track the start position not the end position of each nonterminal. + * Location tracking support. Unlike bison's default, we only want + * to track the start position not the end position of each nonterminal. + * Nonterminals that reduce to empty receive position "-1". Since a + * production's leading RHS nonterminal(s) may have reduced to empty, + * we have to scan to find the first one that's not -1. */ #define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ - if ((N) > 0) \ - (Current) = (Rhs)[1]; \ - else \ - (Current) = (-1); \ + (Current) = (-1); \ + for (int _i = 1; _i <= (N); _i++) \ + { \ + if ((Rhs)[_i] >= 0) \ + { \ + (Current) = (Rhs)[_i]; \ + break; \ + } \ + } \ } while (0) -/* - * The above macro assigns -1 (unknown) as the parse location of any - * nonterminal that was reduced from an empty rule, or whose leftmost - * component was reduced from an empty rule. This is problematic - * for nonterminals defined like - * OptFooList: / * EMPTY * / { ... } | OptFooList Foo { ... } ; - * because we'll set -1 as the location during the first reduction and then - * copy it during each subsequent reduction, leaving us with -1 for the - * location even when the list is not empty. To fix that, do this in the - * action for the nonempty rule(s): - * if (@$ < 0) @$ = @2; - * (Although we have many nonterminals that follow this pattern, we only - * bother with fixing @$ like this when the nonterminal's parse location - * is actually referenced in some rule.) - * - * A cleaner answer would be to make YYLLOC_DEFAULT scan all the Rhs - * locations until it's found one that's not -1. Then we'd get a correct - * location for any nonterminal that isn't entirely empty. But this way - * would add overhead to every rule reduction, and so far there's not been - * a compelling reason to pay that overhead. - */ - /* * 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. + * memory leaks if we error out during parsing. */ #define YYMALLOC palloc #define YYFREE pfree @@ -166,6 +146,37 @@ typedef struct ImportQual List *table_names; } ImportQual; +/* Private struct for the result of select_limit & limit_clause productions */ +typedef struct SelectLimit +{ + Node *limitOffset; + Node *limitCount; + LimitOption limitOption; /* indicates presence of WITH TIES */ + ParseLoc offsetLoc; /* location of OFFSET token, if present */ + ParseLoc countLoc; /* location of LIMIT/FETCH token, if present */ + ParseLoc optionLoc; /* location of WITH TIES, if present */ +} SelectLimit; + +/* Private struct for the result of group_clause production */ +typedef struct GroupClause +{ + bool distinct; + List *list; +} GroupClause; + +/* Private structs for the result of key_actions and key_action productions */ +typedef struct KeyAction +{ + char action; + List *cols; +} KeyAction; + +typedef struct KeyActions +{ + KeyAction *updateAction; + KeyAction *deleteAction; +} KeyActions; + /* ConstraintAttributeSpec yields an integer bitmask of these flags: */ #define CAS_NOT_DEFERRABLE 0x01 #define CAS_DEFERRABLE 0x02 @@ -173,6 +184,8 @@ typedef struct ImportQual #define CAS_INITIALLY_DEFERRED 0x08 #define CAS_NOT_VALID 0x10 #define CAS_NO_INHERIT 0x20 +#define CAS_NOT_ENFORCED 0x40 +#define CAS_ENFORCED 0x80 #define parser_yyerror(msg) scanner_yyerror(msg, yyscanner) @@ -184,12 +197,11 @@ static RawStmt *makeRawStmt(Node *stmt, int stmt_location); static void updateRawStmtEnd(RawStmt *rs, int end_location); static Node *makeColumnRef(char *colname, List *indirection, int location, core_yyscan_t yyscanner); -static Node *makeStringConst(char *str, int location); static Node *makeFloatConst(char *str, int location); +static Node *makeBoolAConst(bool state, int location); static Node *makeBitStringConst(char *str, int location); static Node *makeNullAConst(int location); -static Node *makeAConst(Value *v, int location); -static Node *makeBoolAConst(bool state, int location); +static Node *makeAConst(Node *v, int location); static RoleSpec *makeRoleSpec(RoleSpecType type, int location); static void check_qualified_name(List *names, core_yyscan_t yyscanner); static List *check_func_name(List *names, core_yyscan_t yyscanner); @@ -200,29 +212,35 @@ static List *makeOrderedSetArgs(List *directargs, List *orderedargs, core_yyscan_t yyscanner); static void insertSelectOptions(SelectStmt *stmt, List *sortClause, List *lockingClause, - Node *limitOffset, Node *limitCount, + SelectLimit *limitClause, WithClause *withClause, core_yyscan_t yyscanner); static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg); static Node *doNegate(Node *n, int location); -static void doNegateFloat(Value *v); +static void doNegateFloat(Float *v); static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location); static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location); static Node *makeNotExpr(Node *expr, int location); -static Node *makeAArrayExpr(List *elements, int location); +static Node *makeAArrayExpr(List *elements, int location, int end_location); static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, int location); static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, int location); -static List *mergeTableFuncParameters(List *func_args, List *columns); +static List *mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner); static TypeName *TableFuncTypeName(List *columns); static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner); +static RangeVar *makeRangeVarFromQualifiedName(char *name, List *namelist, int location, + core_yyscan_t yyscanner); static void SplitColQualList(List *qualList, List **constraintList, CollateClause **collClause, core_yyscan_t yyscanner); static void processCASbits(int cas_bits, int location, const char *constrType, - bool *deferrable, bool *initdeferred, bool *not_valid, - bool *no_inherit, core_yyscan_t yyscanner); + bool *deferrable, bool *initdeferred, bool *is_enforced, + bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner); +static PartitionStrategy parsePartitionStrategy(char *strategy, int location, + core_yyscan_t yyscanner); +static void preprocess_pubobj_list(List *pubobjspec_list, + core_yyscan_t yyscanner); static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %} @@ -237,58 +255,68 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %union { - core_YYSTYPE core_yystype; + core_YYSTYPE core_yystype; /* these fields must match core_YYSTYPE: */ - int ival; - char *str; - const char *keyword; - - char chr; - bool boolean; - JoinType jtype; - DropBehavior dbehavior; - OnCommitAction oncommit; - List *list; - Node *node; - Value *value; - ObjectType objtype; - TypeName *typnam; - FunctionParameter *fun_param; + int ival; + char *str; + const char *keyword; + + char chr; + bool boolean; + JoinType jtype; + DropBehavior dbehavior; + OnCommitAction oncommit; + List *list; + Node *node; + ObjectType objtype; + TypeName *typnam; + FunctionParameter *fun_param; FunctionParameterMode fun_param_mode; - ObjectWithArgs *objwithargs; - DefElem *defelt; - SortBy *sortby; - WindowDef *windef; - JoinExpr *jexpr; - IndexElem *ielem; - Alias *alias; - RangeVar *range; - IntoClause *into; - WithClause *with; - InferClause *infer; - OnConflictClause *onconflict; - A_Indices *aind; - ResTarget *target; - struct PrivTarget *privtarget; - AccessPriv *accesspriv; - struct ImportQual *importqual; - InsertStmt *istmt; - VariableSetStmt *vsetstmt; - PartitionElem *partelem; - PartitionSpec *partspec; - PartitionBoundSpec *partboundspec; - RoleSpec *rolespec; + ObjectWithArgs *objwithargs; + DefElem *defelt; + SortBy *sortby; + WindowDef *windef; + JoinExpr *jexpr; + IndexElem *ielem; + StatsElem *selem; + Alias *alias; + RangeVar *range; + IntoClause *into; + WithClause *with; + InferClause *infer; + OnConflictClause *onconflict; + A_Indices *aind; + ResTarget *target; + struct PrivTarget *privtarget; + AccessPriv *accesspriv; + struct ImportQual *importqual; + InsertStmt *istmt; + VariableSetStmt *vsetstmt; + PartitionElem *partelem; + PartitionSpec *partspec; + PartitionBoundSpec *partboundspec; + RoleSpec *rolespec; + PublicationObjSpec *publicationobjectspec; + struct SelectLimit *selectlimit; + SetQuantifier setquantifier; + struct GroupClause *groupclause; + MergeMatchKind mergematch; + MergeWhenClause *mergewhen; + struct KeyActions *keyactions; + struct KeyAction *keyaction; + ReturningClause *retclause; + ReturningOptionKind retoptionkind; } -%type stmt schema_stmt +%type stmt toplevel_stmt schema_stmt routine_body_stmt AlterEventTrigStmt AlterCollationStmt AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt AlterFdwStmt AlterForeignServerStmt AlterGroupStmt AlterObjectDependsStmt AlterObjectSchemaStmt AlterOwnerStmt - AlterOperatorStmt AlterSeqStmt AlterSystemStmt AlterTableStmt - AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt AlterForeignTableStmt + AlterOperatorStmt AlterTypeStmt AlterSeqStmt AlterSystemStmt AlterTableStmt + AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt AlterCompositeTypeStmt AlterUserMappingStmt - AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt + AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt AlterDefaultPrivilegesStmt DefACLAction AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt @@ -296,21 +324,22 @@ 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 + DropOpClassStmt DropOpFamilyStmt DropStmt + DropCastStmt DropRoleStmt DropdbStmt DropTableSpaceStmt DropTransformStmt DropUserMappingStmt ExplainStmt FetchStmt GrantStmt GrantRoleStmt ImportForeignSchemaStmt IndexStmt InsertStmt - ListenStmt LoadStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt + ListenStmt LoadStmt LockStmt MergeStmt NotifyStmt ExplainableStmt PreparableStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt - RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt + RemoveFuncStmt RemoveOperStmt RenameStmt ReturnStmt RevokeStmt RevokeRoleStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt - SecLabelStmt SelectStmt TransactionStmt TruncateStmt - UnlistenStmt UpdateStmt VacuumStmt + SecLabelStmt SelectStmt TransactionStmt TransactionStmtLegacy TruncateStmt + UnlistenStmt UpdateStmt + VacuumStmt VariableResetStmt VariableSetStmt VariableShowStmt ViewStmt CheckPointStmt CreateConversionStmt DeallocateStmt PrepareStmt ExecuteStmt @@ -322,6 +351,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type select_no_parens select_with_parens select_clause simple_select values_clause + PLpgSQL_Expr PLAssignStmt + +%type opt_single_name +%type opt_qualified_name +%type opt_concurrently +%type opt_drop_behavior %type alter_column_default opclass_item opclass_drop alter_using %type add_drop opt_asc_desc opt_nulls_order @@ -331,8 +366,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type alter_table_cmds alter_type_cmds %type alter_identity_column_option_list %type alter_identity_column_option - -%type opt_drop_behavior +%type set_statistics_value +%type set_access_method_name %type createdb_opt_list createdb_opt_items copy_opt_list transaction_mode_list @@ -342,11 +377,18 @@ 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 opt_or_replace - opt_grant_grant_option opt_grant_admin_option +%type utility_option_name +%type utility_option_elem +%type utility_option_list +%type utility_option_arg +%type drop_option +%type opt_or_replace opt_no + opt_grant_grant_option opt_nowait opt_if_exists opt_with_data + opt_transaction_chain +%type grant_role_opt_list +%type grant_role_opt +%type grant_role_opt_value %type opt_nowait_or_skip %type OptRoleList AlterOptRoleList @@ -356,13 +398,15 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type foreign_server_version opt_foreign_server_version %type opt_in_database -%type OptSchemaName -%type OptSchemaEltList +%type parameter_name +%type OptSchemaEltList parameter_name_list + +%type am_type %type TriggerForSpec TriggerForType %type TriggerActionTime %type TriggerEvents TriggerOneEvent -%type TriggerFuncArg +%type TriggerFuncArg %type TriggerWhen %type TransitionRelName %type TransitionRowOrTable TransitionOldOrNew @@ -373,12 +417,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type enable_trigger %type copy_file_name - database_name access_method_clause access_method attr_name - name cursor_name file_name - index_name opt_index_name cluster_index_specification + access_method_clause attr_name + table_access_method_clause name cursor_name file_name + cluster_index_specification %type func_name handler_name qual_Op qual_all_Op subquery_Op - opt_class opt_inline_handler opt_validator validator_clause + opt_inline_handler opt_validator validator_clause opt_collate %type qualified_name insert_target OptConstrFromTable @@ -404,45 +448,52 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type import_qualification_type %type import_qualification %type vacuum_relation +%type opt_select_limit select_limit limit_clause -%type stmtblock stmtmulti +%type parse_toplevel stmtmulti routine_body_stmt_list OptTableElementList TableElementList OptInherit definition OptTypedTableElementList TypedTableElementList reloptions opt_reloptions - OptWith distinct_clause opt_all_clause opt_definition func_args func_args_list + OptWith opt_definition func_args func_args_list func_args_with_defaults func_args_with_defaults_list aggr_args aggr_args_list - func_as createfunc_opt_list alterfunc_opt_list + func_as createfunc_opt_list opt_createfunc_opt_list alterfunc_opt_list old_aggr_definition old_aggr_list oper_argtypes RuleActionList RuleActionMulti opt_column_list columnList opt_name_list sort_clause opt_sort_clause sortby_list index_params + stats_params opt_include opt_c_include index_including_params name_list role_list from_clause from_list opt_array_bounds qualified_name_list any_name any_name_list type_name_list any_operator expr_list attrs + distinct_clause opt_distinct_clause target_list opt_target_list insert_column_list set_target_list + merge_values_clause set_clause_list set_clause def_list operator_def_list indirection opt_indirection - reloption_list group_clause TriggerFuncArgs select_limit - opt_select_limit opclass_item_list opclass_drop_list + reloption_list TriggerFuncArgs opclass_item_list opclass_drop_list opclass_purpose opt_opfamily transaction_mode_list_or_empty OptTableFuncElementList TableFuncElementList opt_type_modifiers prep_type_clause - execute_param_clause using_clause returning_clause + execute_param_clause using_clause + returning_with_clause returning_options opt_enum_val_list enum_val_list table_func_column_list create_generic_options alter_generic_options relation_expr_list dostmt_opt_list transform_element_list transform_type_list TriggerTransitions TriggerReferencing - publication_name_list vacuum_relation_list opt_vacuum_relation_list + drop_option_list pub_obj_list +%type returning_clause +%type returning_option +%type returning_option_kind +%type opt_routine_body +%type group_clause %type group_by_list %type group_by_item empty_grouping_set rollup_clause cube_clause %type grouping_sets_clause -%type opt_publication_for_tables publication_for_tables -%type publication_name_item %type opt_fdw_options fdw_options %type fdw_option @@ -464,29 +515,28 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type for_locking_item %type for_locking_clause opt_for_locking_clause for_locking_items %type locked_rels_list -%type all_or_distinct +%type set_quantifier -%type join_outer join_qual +%type join_qual %type join_type %type extract_list overlay_list position_list %type substr_list trim_list %type opt_interval interval_second -%type overlay_placing substr_from substr_for +%type unicode_normal_form %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_unique opt_verbose opt_full +%type opt_freeze opt_analyze opt_default +%type opt_binary copy_delimiter %type copy_from opt_program -%type opt_column event cursor_options opt_hold opt_set_data -%type drop_type_any_name drop_type_name drop_type_name_on_any_name - comment_type_any_name comment_type_name - security_label_type_any_name security_label_type_name +%type event cursor_options opt_hold opt_set_data +%type object_type_any_name object_type_name object_type_name_on_any_name + drop_type_name -%type fetch_args limit_clause select_limit_value +%type fetch_args select_limit_value offset_clause select_offset_value select_fetch_first_value I_or_F_const %type row_or_rows first_or_next @@ -497,35 +547,44 @@ 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 merge_when_tgt_matched merge_when_tgt_not_matched +%type merge_when_clause opt_merge_when_condition +%type merge_when_list %type generic_set set_rest set_rest_more generic_reset reset_rest SetResetClause FunctionSetResetClause -%type TableElement TypedTableElement ConstraintElem TableFuncElement -%type columnDef columnOptions +%type TableElement TypedTableElement ConstraintElem DomainConstraintElem TableFuncElement +%type columnDef columnOptions optionalPeriodName %type def_elem reloption_elem old_aggr_elem operator_def_elem %type def_arg columnElem where_clause where_or_current_clause a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound - columnref in_expr having_clause func_table xmltable array_expr - ExclusionWhereClause operator_def_arg + columnref having_clause func_table xmltable array_expr + OptWhereClause operator_def_arg +%type opt_column_and_period_list %type rowsfrom_item rowsfrom_list opt_col_def_list -%type opt_ordinality +%type opt_ordinality opt_without_overlaps %type ExclusionConstraintList ExclusionConstraintElem -%type func_arg_list +%type func_arg_list func_arg_list_opt %type func_arg_expr %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 NumericOnly +%type opt_search_clause opt_cycle_clause +%type sub_type opt_materialized +%type NumericOnly %type NumericOnly_list -%type alias_clause opt_alias_clause +%type alias_clause opt_alias_clause opt_alias_clause_for_join_using %type func_alias_clause %type sortby -%type index_elem +%type index_elem index_elem_options +%type stats_param %type table_ref %type joined_table %type relation_expr +%type extended_relation_expr %type relation_expr_opt_alias %type tablesample_clause opt_repeatable_clause %type target_el set_target insert_column_item @@ -534,13 +593,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type generic_option_arg %type generic_option_elem alter_generic_option_elem %type generic_option_list alter_generic_option_list -%type explain_option_name -%type explain_option_arg -%type explain_option_elem -%type explain_option_list -%type reindex_target_type reindex_target_multitable -%type reindex_option_list reindex_option_elem +%type reindex_target_relation reindex_target_all +%type opt_reindex_option_list %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem @@ -548,7 +603,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type copy_options %type Typename SimpleTypename ConstTypename - GenericType Numeric opt_float + GenericType Numeric opt_float JsonType Character ConstCharacter CharacterWithLength CharacterWithoutLength ConstDatetime ConstInterval @@ -561,20 +616,26 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type Sconst comment_text notify_payload %type RoleId opt_boolean_or_string %type var_list -%type ColId ColLabel var_name type_function_name param_name +%type ColId ColLabel BareColLabel %type NonReservedWord NonReservedWord_or_Sconst -%type createdb_opt_name +%type var_name type_function_name param_name +%type createdb_opt_name plassign_target %type var_value zone_value %type auth_ident RoleSpec opt_granted_by +%type PublicationObjSpec %type unreserved_keyword type_func_name_keyword %type col_name_keyword reserved_keyword +%type bare_label_keyword -%type TableConstraint TableLikeClause +%type DomainConstraint TableConstraint TableLikeClause %type TableLikeOptionList TableLikeOption +%type column_compression opt_column_compression column_storage opt_column_storage %type ColQualList %type ColConstraint ColConstraintElem ConstraintAttr -%type key_actions key_delete key_match key_update key_action +%type key_match +%type key_delete key_update key_action +%type key_actions %type ConstraintAttributeSpec ConstraintAttributeElem %type ExistingIndex @@ -591,7 +652,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type xml_root_version opt_xml_root_standalone %type xmlexists_argument %type document_or_content -%type xml_whitespace_option +%type xml_indent_option xml_whitespace_option %type xmltable_column_list xmltable_column_option_list %type xmltable_column_el %type xmltable_column_option_el @@ -612,26 +673,57 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type opt_window_exclusion_clause %type opt_existing_window_name %type opt_if_not_exists -%type generated_when override_kind +%type opt_unique_null_treatment +%type generated_when override_kind opt_virtual_or_stored %type PartitionSpec OptPartitionSpec -%type part_strategy %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 json_format_clause + json_format_clause_opt + json_value_expr + json_returning_clause_opt + json_name_and_value + json_aggregate_func + json_argument + json_behavior + json_on_error_clause_opt + json_table + json_table_column_definition + json_table_column_path_clause_opt +%type json_name_and_value_list + json_value_expr_list + json_array_aggregate_order_by_clause_opt + json_arguments + json_behavior_clause_opt + json_passing_clause_opt + json_table_column_definition_list +%type json_table_path_name_opt +%type json_behavior_type + json_predicate_type_constraint + json_quotes_clause_opt + json_wrapper_behavior +%type json_key_uniqueness_constraint_opt + json_object_constructor_null_clause_opt + json_array_constructor_null_clause_opt + + /* * 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 * the set of keywords. PL/pgSQL depends on this so that it can share the * same lexer. If you add/change tokens here, fix PL/pgSQL to match! * + * UIDENT and USCONST are reduced to IDENT and SCONST in parser.c, so that + * they need no productions here; but we must assign token codes to them. + * * DOT_DOT is unused in the core SQL grammar, and so will always provoke * parse errors. It is needed by PL/pgSQL. */ -%token IDENT FCONST SCONST BCONST XCONST Op +%token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op %token ICONST PARAM %token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER %token LESS_EQUALS GREATER_EQUALS NOT_EQUALS @@ -644,88 +736,93 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); */ /* ordinary key words in alphabetical order */ -%token ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER +%token ABORT_P ABSENT ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC - ASSERTION ASSIGNMENT ASYMMETRIC AT ATTACH ATTRIBUTE AUTHORIZATION + ASENSITIVE ASSERTION ASSIGNMENT ASYMMETRIC ATOMIC AT ATTACH ATTRIBUTE AUTHORIZATION BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT - BOOLEAN_P BOTH BY + BOOLEAN_P BOTH BREADTH BY CACHE CALL CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMNS COMMENT COMMENTS COMMIT - COMMITTED CONCURRENTLY CONFIGURATION CONFLICT CONNECTION CONSTRAINT - CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE - CROSS CSV CUBE CURRENT_P + COMMITTED COMPRESSION CONCURRENTLY CONDITIONAL CONFIGURATION CONFLICT + CONNECTION CONSTRAINT CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY + COST CREATE CROSS CSV CUBE CURRENT_P CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS - DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DESC + DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP - EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EVENT EXCEPT - EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN - EXTENSION EXTERNAL EXTRACT + EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P ERROR_P + ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN + EXPRESSION EXTENSION EXTERNAL EXTRACT - FALSE_P FAMILY FETCH FILTER FIRST_P FLOAT_P FOLLOWING FOR - FORCE FOREIGN FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS + FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR + FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS HANDLER HAVING HEADER_P HOLD HOUR_P IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE - INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P + INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION - JOIN + JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_EXISTS JSON_OBJECT JSON_OBJECTAGG + JSON_QUERY JSON_SCALAR JSON_SERIALIZE JSON_TABLE JSON_VALUE - KEY + KEEP KEY KEYS LABEL LANGUAGE LARGE_P LAST_P LATERAL_P LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED - MAPPING MATCH MATERIALIZED MAXVALUE METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE + MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE MERGE_ACTION METHOD + MINUTE_P MINVALUE MODE MONTH_P MOVE - NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NONE + NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO + NONE NORMALIZE NORMALIZED NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC - OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OPTIONS OR + OBJECT_P OBJECTS_P OF OFF OFFSET OIDS OLD OMIT ON ONLY OPERATOR OPTION OPTIONS OR ORDER ORDINALITY OTHERS OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER - PARALLEL PARSER PARTIAL PARTITION PASSING PASSWORD PGPOOL PLACING PLANS POLICY + PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH PGPOOL + PERIOD PLACING PLAN PLANS POLICY POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION - QUOTE + QUOTE QUOTES - RANGE READ REAL REASSIGN RECHECK RECURSIVE REF REFERENCES REFERENCING + RANGE READ REAL REASSIGN RECURSIVE REF_P REFERENCES REFERENCING REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA - RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP ROUTINE ROUTINES ROW ROWS RULE - SAVEPOINT SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES + SAVEPOINT SCALAR 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 + SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SOURCE SQL_P STABLE STANDALONE_P + START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P + SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER - TABLE TABLES TABLESAMPLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN + TABLE TABLES TABLESAMPLE TABLESPACE TARGET TEMP TEMPLATE TEMPORARY TEXT_P THEN TIES TIME TIMESTAMP TO TRAILING TRANSACTION TRANSFORM TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P TYPES_P - UNBOUNDED UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNLOGGED - UNTIL UPDATE USER USING + UESCAPE UNBOUNDED UNCONDITIONAL UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN + UNLISTEN UNLOGGED UNTIL UPDATE USER USING VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING - VERBOSE VERSION_P VIEW VIEWS VOLATILE + VERBOSE VERSION_P VIEW VIEWS VIRTUAL VOLATILE WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE @@ -744,13 +841,26 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); * NOT_LA exists so that productions such as NOT LIKE can be given the same * precedence as LIKE; otherwise they'd effectively have the same precedence * as NOT, at least with respect to their left-hand subexpression. - * NULLS_LA and WITH_LA are needed to make the grammar LALR(1). + * FORMAT_LA, NULLS_LA, WITH_LA, and WITHOUT_LA are needed to make the grammar + * LALR(1). */ -%token NOT_LA NULLS_LA WITH_LA +%token FORMAT_LA NOT_LA NULLS_LA WITH_LA WITHOUT_LA + +/* + * The grammar likewise thinks these tokens are keywords, but they are never + * generated by the scanner. Rather, they can be injected by parser.c as + * the initial token of the string (using the lookahead-token mechanism + * implemented there). This provides a way to tell the grammar to parse + * something other than the usual list of SQL commands. + */ +%token MODE_TYPE_NAME +%token MODE_PLPGSQL_EXPR +%token MODE_PLPGSQL_ASSIGN1 +%token MODE_PLPGSQL_ASSIGN2 +%token MODE_PLPGSQL_ASSIGN3 /* Precedence: lowest to highest */ -%nonassoc SET /* see relation_expr_opt_alias */ %left UNION EXCEPT %left INTERSECT %left OR @@ -760,24 +870,27 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS %nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA %nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */ -%left POSTFIXOP /* dummy for postfix Op rules */ + /* - * To support target_el without AS, we must give IDENT an explicit priority - * between POSTFIXOP and Op. We can safely assign the same priority to - * various unreserved keywords as needed to resolve ambiguities (this can't - * have any bad effects since obviously the keywords will still behave the - * same as if they weren't keywords). We need to do this: - * for PARTITION, RANGE, ROWS, GROUPS to support opt_existing_window_name; - * for RANGE, ROWS, GROUPS so that they can follow a_expr without creating - * postfix-operator problems; - * for GENERATED so that it can follow b_expr; - * and for NULL so that it can follow b_expr in ColQualList without creating - * postfix-operator problems. - * - * To support CUBE and ROLLUP in GROUP BY without reserving them, we give them - * an explicit priority lower than '(', so that a rule with CUBE '(' will shift - * rather than reducing a conflicting rule that takes CUBE as a function name. - * Using the same precedence as IDENT seems right for the reasons given above. + * Sometimes it is necessary to assign precedence to keywords that are not + * really part of the operator hierarchy, in order to resolve grammar + * ambiguities. It's best to avoid doing so whenever possible, because such + * assignments have global effect and may hide ambiguities besides the one + * you intended to solve. (Attaching a precedence to a single rule with + * %prec is far safer and should be preferred.) If you must give precedence + * to a new keyword, try very hard to give it the same precedence as IDENT. + * If the keyword has IDENT's precedence then it clearly acts the same as + * non-keywords and other similar keywords, thus reducing the risk of + * unexpected precedence effects. + * + * We used to need to assign IDENT an explicit precedence just less than Op, + * to support target_el without AS. While that's not really necessary since + * we removed postfix operators, we continue to do so because it provides a + * reference point for a precedence level that we can assign to other + * keywords that lack a natural precedence level. + * + * We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support + * opt_existing_window_name (see comment there). * * The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING * are even messier: since UNBOUNDED is an unreserved keyword (per spec!), @@ -787,15 +900,32 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); * appear to cause UNBOUNDED to be treated differently from other unreserved * keywords anywhere else in the grammar, but it's definitely risky. We can * blame any funny behavior of UNBOUNDED on the SQL standard, though. + * + * To support CUBE and ROLLUP in GROUP BY without reserving them, we give them + * an explicit priority lower than '(', so that a rule with CUBE '(' will shift + * rather than reducing a conflicting rule that takes CUBE as a function name. + * Using the same precedence as IDENT seems right for the reasons given above. + * + * SET is likewise assigned the same precedence as IDENT, to support the + * relation_expr_opt_alias production (see comment there). + * + * KEYS, OBJECT_P, SCALAR, VALUE_P, WITH, and WITHOUT are similarly assigned + * the same precedence as IDENT. This allows resolving conflicts in the + * json_predicate_type_constraint and json_key_uniqueness_constraint_opt + * productions (see comments there). + * + * Like the UNBOUNDED PRECEDING/FOLLOWING case, NESTED is assigned a lower + * precedence than PATH to fix ambiguity in the json_table production. */ -%nonassoc UNBOUNDED /* ideally should have same precedence as IDENT */ -%nonassoc IDENT GENERATED NULL_P PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP +%nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */ +%nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP + SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH %left Op OPERATOR /* multi-character ops and user-defined operators */ %left '+' '-' %left '*' '/' '%' %left '^' /* Unary Operators */ -%left AT /* sets precedence for AT TIME ZONE */ +%left AT /* sets precedence for AT TIME ZONE, AT LOCAL */ %left COLLATE %right UMINUS %left '[' ']' @@ -810,31 +940,64 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); * left-associativity among the JOIN rules themselves. */ %left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL -/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */ -%right PRESERVE STRIP_P %% /* * The target production for the whole parse. + * + * Ordinarily we parse a list of statements, but if we see one of the + * special MODE_XXX symbols as first token, we parse something else. + * The options here correspond to enum RawParseMode, which see for details. */ -stmtblock: stmtmulti +parse_toplevel: + stmtmulti { pg_yyget_extra(yyscanner)->parsetree = $1; + (void) yynerrs; /* suppress compiler warning */ + } + | MODE_TYPE_NAME Typename + { + pg_yyget_extra(yyscanner)->parsetree = list_make1($2); + } + | MODE_PLPGSQL_EXPR PLpgSQL_Expr + { + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt($2, @2)); + } + | MODE_PLPGSQL_ASSIGN1 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + + n->nnames = 1; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, @2)); + } + | MODE_PLPGSQL_ASSIGN2 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + + n->nnames = 2; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, @2)); + } + | MODE_PLPGSQL_ASSIGN3 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + + n->nnames = 3; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, @2)); } ; /* * At top level, we wrap each stmt with a RawStmt node carrying start location - * and length of the stmt's text. Notice that the start loc/len are driven - * entirely from semicolon locations (@2). It would seem natural to use - * @1 or @3 to get the true start location of a stmt, but that doesn't work - * for statements that can start with empty nonterminals (opt_with_clause is - * the main offender here); as noted in the comments for YYLLOC_DEFAULT, - * we'd get -1 for the location in such cases. - * We also take care to discard empty statements entirely. + * and length of the stmt's text. + * We also take care to discard empty statements entirely (which among other + * things dodges the problem of assigning them a location). */ -stmtmulti: stmtmulti ';' stmt +stmtmulti: stmtmulti ';' toplevel_stmt { if ($1 != NIL) { @@ -842,20 +1005,29 @@ stmtmulti: stmtmulti ';' stmt updateRawStmtEnd(llast_node(RawStmt, $1), @2); } if ($3 != NULL) - $$ = lappend($1, makeRawStmt($3, @2 + 1)); + $$ = lappend($1, makeRawStmt($3, @3)); else $$ = $1; } - | stmt + | toplevel_stmt { if ($1 != NULL) - $$ = list_make1(makeRawStmt($1, 0)); + $$ = list_make1(makeRawStmt($1, @1)); else $$ = NIL; } ; -stmt : +/* + * toplevel_stmt includes BEGIN and END. stmt does not include them, because + * those words have different meanings in function bodies. + */ +toplevel_stmt: + stmt + | TransactionStmtLegacy + ; + +stmt: AlterEventTrigStmt | AlterCollationStmt | AlterDatabaseStmt @@ -867,13 +1039,13 @@ stmt : | AlterExtensionContentsStmt | AlterFdwStmt | AlterForeignServerStmt - | AlterForeignTableStmt | AlterFunctionStmt | AlterGroupStmt | AlterObjectDependsStmt | AlterObjectSchemaStmt | AlterOwnerStmt | AlterOperatorStmt + | AlterTypeStmt | AlterPolicyStmt | AlterSeqStmt | AlterSystemStmt @@ -884,6 +1056,7 @@ stmt : | AlterRoleSetStmt | AlterRoleStmt | AlterSubscriptionStmt + | AlterStatsStmt | AlterTSConfigurationStmt | AlterTSDictionaryStmt | AlterUserMappingStmt @@ -897,7 +1070,7 @@ stmt : | CopyStmt | CreateAmStmt | CreateAsStmt - | CreateAssertStmt + | CreateAssertionStmt | CreateCastStmt | CreateConversionStmt | CreateDomainStmt @@ -933,12 +1106,10 @@ stmt : | DeleteStmt | DiscardStmt | DoStmt - | DropAssertStmt | DropCastStmt | DropOpClassStmt | DropOpFamilyStmt | DropOwnedStmt - | DropPLangStmt | DropStmt | DropSubscriptionStmt | DropTableSpaceStmt @@ -958,6 +1129,7 @@ stmt : | RefreshMatViewStmt | LoadStmt | LockStmt + | MergeStmt | NotifyStmt | PrepareStmt | ReassignOwnedStmt @@ -984,6 +1156,30 @@ stmt : { $$ = NULL; } ; +/* + * Generic supporting productions for DDL + */ +opt_single_name: + ColId { $$ = $1; } + | /* EMPTY */ { $$ = NULL; } + ; + +opt_qualified_name: + any_name { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +opt_concurrently: + CONCURRENTLY { $$ = true; } + | /*EMPTY*/ { $$ = false; } + ; + +opt_drop_behavior: + CASCADE { $$ = DROP_CASCADE; } + | RESTRICT { $$ = DROP_RESTRICT; } + | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ } + ; + /***************************************************************************** * * CALL statement @@ -992,9 +1188,10 @@ stmt : CallStmt: CALL func_application { - CallStmt *n = makeNode(CallStmt); + CallStmt *n = makeNode(CallStmt); + n->funccall = castNode(FuncCall, $2); - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -1008,17 +1205,18 @@ CreateRoleStmt: CREATE ROLE RoleId opt_with OptRoleList { CreateRoleStmt *n = makeNode(CreateRoleStmt); + n->stmt_type = ROLESTMT_ROLE; n->role = $3; n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; -opt_with: WITH {} - | WITH_LA {} - | /*EMPTY*/ {} +opt_with: WITH + | WITH_LA + | /*EMPTY*/ ; /* @@ -1040,7 +1238,7 @@ AlterOptRoleElem: PASSWORD Sconst { $$ = makeDefElem("password", - (Node *)makeString($2), @1); + (Node *) makeString($2), @1); } | PASSWORD NULL_P { @@ -1054,7 +1252,7 @@ AlterOptRoleElem: * ENCRYPTED PASSWORD. */ $$ = makeDefElem("password", - (Node *)makeString($3), @1); + (Node *) makeString($3), @1); } | UNENCRYPTED PASSWORD Sconst { @@ -1066,20 +1264,20 @@ AlterOptRoleElem: } | INHERIT { - $$ = makeDefElem("inherit", (Node *)makeInteger(true), @1); + $$ = makeDefElem("inherit", (Node *) makeBoolean(true), @1); } | CONNECTION LIMIT SignedIconst { - $$ = makeDefElem("connectionlimit", (Node *)makeInteger($3), @1); + $$ = makeDefElem("connectionlimit", (Node *) makeInteger($3), @1); } | VALID UNTIL Sconst { - $$ = makeDefElem("validUntil", (Node *)makeString($3), @1); + $$ = makeDefElem("validUntil", (Node *) makeString($3), @1); } /* Supported but not documented for roles, for use by ALTER GROUP. */ | USER role_list { - $$ = makeDefElem("rolemembers", (Node *)$2, @1); + $$ = makeDefElem("rolemembers", (Node *) $2, @1); } | IDENT { @@ -1089,36 +1287,36 @@ AlterOptRoleElem: * size of the main parser. */ if (strcmp($1, "superuser") == 0) - $$ = makeDefElem("superuser", (Node *)makeInteger(true), @1); + $$ = makeDefElem("superuser", (Node *) makeBoolean(true), @1); else if (strcmp($1, "nosuperuser") == 0) - $$ = makeDefElem("superuser", (Node *)makeInteger(false), @1); + $$ = makeDefElem("superuser", (Node *) makeBoolean(false), @1); else if (strcmp($1, "createrole") == 0) - $$ = makeDefElem("createrole", (Node *)makeInteger(true), @1); + $$ = makeDefElem("createrole", (Node *) makeBoolean(true), @1); else if (strcmp($1, "nocreaterole") == 0) - $$ = makeDefElem("createrole", (Node *)makeInteger(false), @1); + $$ = makeDefElem("createrole", (Node *) makeBoolean(false), @1); else if (strcmp($1, "replication") == 0) - $$ = makeDefElem("isreplication", (Node *)makeInteger(true), @1); + $$ = makeDefElem("isreplication", (Node *) makeBoolean(true), @1); else if (strcmp($1, "noreplication") == 0) - $$ = makeDefElem("isreplication", (Node *)makeInteger(false), @1); + $$ = makeDefElem("isreplication", (Node *) makeBoolean(false), @1); else if (strcmp($1, "createdb") == 0) - $$ = makeDefElem("createdb", (Node *)makeInteger(true), @1); + $$ = makeDefElem("createdb", (Node *) makeBoolean(true), @1); else if (strcmp($1, "nocreatedb") == 0) - $$ = makeDefElem("createdb", (Node *)makeInteger(false), @1); + $$ = makeDefElem("createdb", (Node *) makeBoolean(false), @1); else if (strcmp($1, "login") == 0) - $$ = makeDefElem("canlogin", (Node *)makeInteger(true), @1); + $$ = makeDefElem("canlogin", (Node *) makeBoolean(true), @1); else if (strcmp($1, "nologin") == 0) - $$ = makeDefElem("canlogin", (Node *)makeInteger(false), @1); + $$ = makeDefElem("canlogin", (Node *) makeBoolean(false), @1); else if (strcmp($1, "bypassrls") == 0) - $$ = makeDefElem("bypassrls", (Node *)makeInteger(true), @1); + $$ = makeDefElem("bypassrls", (Node *) makeBoolean(true), @1); else if (strcmp($1, "nobypassrls") == 0) - $$ = makeDefElem("bypassrls", (Node *)makeInteger(false), @1); + $$ = makeDefElem("bypassrls", (Node *) makeBoolean(false), @1); else if (strcmp($1, "noinherit") == 0) { /* * Note that INHERIT is a keyword, so it's handled by main parser, but * NOINHERIT is handled here. */ - $$ = makeDefElem("inherit", (Node *)makeInteger(false), @1); + $$ = makeDefElem("inherit", (Node *) makeBoolean(false), @1); } else ereport(ERROR, @@ -1133,23 +1331,23 @@ CreateOptRoleElem: /* The following are not supported by ALTER ROLE/USER/GROUP */ | SYSID Iconst { - $$ = makeDefElem("sysid", (Node *)makeInteger($2), @1); + $$ = makeDefElem("sysid", (Node *) makeInteger($2), @1); } | ADMIN role_list { - $$ = makeDefElem("adminmembers", (Node *)$2, @1); + $$ = makeDefElem("adminmembers", (Node *) $2, @1); } | ROLE role_list { - $$ = makeDefElem("rolemembers", (Node *)$2, @1); + $$ = makeDefElem("rolemembers", (Node *) $2, @1); } | IN_P ROLE role_list { - $$ = makeDefElem("addroleto", (Node *)$3, @1); + $$ = makeDefElem("addroleto", (Node *) $3, @1); } | IN_P GROUP_P role_list { - $$ = makeDefElem("addroleto", (Node *)$3, @1); + $$ = makeDefElem("addroleto", (Node *) $3, @1); } ; @@ -1164,10 +1362,11 @@ CreateUserStmt: CREATE USER RoleId opt_with OptRoleList { CreateRoleStmt *n = makeNode(CreateRoleStmt); + n->stmt_type = ROLESTMT_USER; n->role = $3; n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -1182,58 +1381,64 @@ AlterRoleStmt: ALTER ROLE RoleSpec opt_with AlterOptRoleList { AlterRoleStmt *n = makeNode(AlterRoleStmt); + n->role = $3; n->action = +1; /* add, if there are members */ n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER USER RoleSpec opt_with AlterOptRoleList { AlterRoleStmt *n = makeNode(AlterRoleStmt); + n->role = $3; n->action = +1; /* add, if there are members */ n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; opt_in_database: /* EMPTY */ { $$ = NULL; } - | IN_P DATABASE database_name { $$ = $3; } + | IN_P DATABASE name { $$ = $3; } ; AlterRoleSetStmt: ALTER ROLE RoleSpec opt_in_database SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = $3; n->database = $4; n->setstmt = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER ROLE ALL opt_in_database SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = NULL; n->database = $4; n->setstmt = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER USER RoleSpec opt_in_database SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = $3; n->database = $4; n->setstmt = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER USER ALL opt_in_database SetResetClause { AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = NULL; n->database = $4; n->setstmt = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -1251,44 +1456,50 @@ DropRoleStmt: DROP ROLE role_list { DropRoleStmt *n = makeNode(DropRoleStmt); + n->missing_ok = false; n->roles = $3; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP ROLE IF_P EXISTS role_list { DropRoleStmt *n = makeNode(DropRoleStmt); + n->missing_ok = true; n->roles = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP USER role_list { DropRoleStmt *n = makeNode(DropRoleStmt); + n->missing_ok = false; n->roles = $3; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP USER IF_P EXISTS role_list { DropRoleStmt *n = makeNode(DropRoleStmt); + n->roles = $5; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP GROUP_P role_list { DropRoleStmt *n = makeNode(DropRoleStmt); + n->missing_ok = false; n->roles = $3; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP GROUP_P IF_P EXISTS role_list { DropRoleStmt *n = makeNode(DropRoleStmt); + n->missing_ok = true; n->roles = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -1303,10 +1514,11 @@ CreateGroupStmt: CREATE GROUP_P RoleId opt_with OptRoleList { CreateRoleStmt *n = makeNode(CreateRoleStmt); + n->stmt_type = ROLESTMT_GROUP; n->role = $3; n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -1321,11 +1533,12 @@ AlterGroupStmt: ALTER GROUP_P RoleSpec add_drop USER role_list { AlterRoleStmt *n = makeNode(AlterRoleStmt); + n->role = $3; n->action = $4; n->options = list_make1(makeDefElem("rolemembers", - (Node *)$6, @6)); - $$ = (Node *)n; + (Node *) $6, @6)); + $$ = (Node *) n; } ; @@ -1341,29 +1554,32 @@ add_drop: ADD_P { $$ = +1; } *****************************************************************************/ CreateSchemaStmt: - CREATE SCHEMA OptSchemaName AUTHORIZATION RoleSpec OptSchemaEltList + CREATE SCHEMA opt_single_name AUTHORIZATION RoleSpec OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + /* One can omit the schema name or the authorization id. */ n->schemaname = $3; n->authrole = $5; n->schemaElts = $6; n->if_not_exists = false; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE SCHEMA ColId OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + /* ...but not both */ n->schemaname = $3; n->authrole = NULL; n->schemaElts = $4; n->if_not_exists = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | CREATE SCHEMA IF_P NOT EXISTS OptSchemaName AUTHORIZATION RoleSpec OptSchemaEltList + | CREATE SCHEMA IF_P NOT EXISTS opt_single_name AUTHORIZATION RoleSpec OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + /* schema name can be omitted here, too */ n->schemaname = $6; n->authrole = $8; @@ -1374,11 +1590,12 @@ CreateSchemaStmt: parser_errposition(@9))); n->schemaElts = $9; n->if_not_exists = true; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE SCHEMA IF_P NOT EXISTS ColId OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + /* ...but not here */ n->schemaname = $6; n->authrole = NULL; @@ -1389,20 +1606,13 @@ CreateSchemaStmt: parser_errposition(@7))); n->schemaElts = $7; n->if_not_exists = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; -OptSchemaName: - ColId { $$ = $1; } - | /* EMPTY */ { $$ = NULL; } - ; - OptSchemaEltList: OptSchemaEltList schema_stmt { - if (@$ < 0) /* see comments for YYLLOC_DEFAULT */ - @$ = @2; $$ = lappend($1, $2); } | /* EMPTY */ @@ -1436,25 +1646,35 @@ VariableSetStmt: PGPOOL SET generic_set { VariableSetStmt *n = $3; - n->type = T_PgpoolVariableSetStmt; /* Hack to keep changes minumum */ + n->type = T_PgpoolVariableSetStmt; /* Hack to keep changes minimum */ + n->is_local = false; + $$ = (Node *) n; + } + | PGPOOL set_rest_more + { + VariableSetStmt *n = $2; + n->type = T_PgpoolQueryCacheStmt; /* Hack to keep changes minimum */ n->is_local = false; $$ = (Node *) n; } | SET set_rest { VariableSetStmt *n = $2; + n->is_local = false; $$ = (Node *) n; } | SET LOCAL set_rest { VariableSetStmt *n = $3; + n->is_local = true; $$ = (Node *) n; } | SET SESSION set_rest { VariableSetStmt *n = $3; + n->is_local = false; $$ = (Node *) n; } @@ -1464,17 +1684,23 @@ set_rest: TRANSACTION transaction_mode_list { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_MULTI; n->name = "TRANSACTION"; n->args = $2; + n->jumble_args = true; + n->location = -1; $$ = n; } | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_MULTI; n->name = "SESSION CHARACTERISTICS"; n->args = $5; + n->jumble_args = true; + n->location = -1; $$ = n; } | set_rest_more @@ -1484,49 +1710,63 @@ generic_set: var_name TO var_list { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = $1; n->args = $3; + n->location = @3; $$ = n; } | var_name '=' var_list { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = $1; n->args = $3; + n->location = @3; $$ = n; } | var_name TO DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_DEFAULT; n->name = $1; + n->location = -1; $$ = n; } | var_name '=' DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_DEFAULT; n->name = $1; + n->location = -1; $$ = n; } + ; set_rest_more: /* Generic SET syntaxes: */ - generic_set {$$ = $1;} + generic_set {$$ = $1;} | var_name FROM CURRENT_P { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_CURRENT; n->name = $1; + n->location = -1; $$ = n; } /* Special syntaxes mandated by SQL standard: */ | TIME ZONE zone_value { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = "timezone"; + n->location = -1; + n->jumble_args = true; if ($3 != NULL) n->args = list_make1($3); else @@ -1544,16 +1784,20 @@ set_rest_more: /* Generic SET syntaxes: */ | SCHEMA Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = "search_path"; n->args = list_make1(makeStringConst($2, @2)); + n->location = @2; $$ = n; } | NAMES opt_encoding { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = "client_encoding"; + n->location = @2; if ($2 != NULL) n->args = list_make1(makeStringConst($2, @2)); else @@ -1563,41 +1807,59 @@ set_rest_more: /* Generic SET syntaxes: */ | ROLE NonReservedWord_or_Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = "role"; n->args = list_make1(makeStringConst($2, @2)); + n->location = @2; $$ = n; } | SESSION AUTHORIZATION NonReservedWord_or_Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = "session_authorization"; n->args = list_make1(makeStringConst($3, @3)); + n->location = @3; $$ = n; } | SESSION AUTHORIZATION DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_DEFAULT; n->name = "session_authorization"; + n->location = -1; $$ = n; } | XML_P OPTION document_or_content { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_VALUE; n->name = "xmloption"; n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3)); + n->jumble_args = true; + n->location = -1; $$ = n; } /* Special syntaxes invented by PostgreSQL: */ | TRANSACTION SNAPSHOT Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_SET_MULTI; n->name = "TRANSACTION SNAPSHOT"; n->args = list_make1(makeStringConst($3, @3)); + n->location = @3; + $$ = n; + } + /* PGPOOL CACHE DELETE */ + | SET CACHE DELETE_P Sconst + { + VariableSetStmt *n = makeNode(VariableSetStmt); + n->name = $4; /* query to delete query cache */ $$ = n; } ; @@ -1654,11 +1916,13 @@ zone_value: } | ConstInterval Sconst opt_interval { - TypeName *t = $1; + TypeName *t = $1; + if ($3 != NIL) { - A_Const *n = (A_Const *) linitial($3); - if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) + A_Const *n = (A_Const *) linitial($3); + + if ((n->val.ival.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("time zone interval must be HOUR or HOUR TO MINUTE"), @@ -1669,7 +1933,8 @@ zone_value: } | ConstInterval '(' Iconst ')' Sconst { - TypeName *t = $1; + TypeName *t = $1; + t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), makeIntConst($3, @3)); $$ = makeStringConstCast($5, @5, t); @@ -1695,7 +1960,7 @@ VariableResetStmt: | PGPOOL RESET generic_reset { VariableSetStmt *n = $3; - n->type = T_PgpoolVariableSetStmt; /* Hack to keep the changes minumum */ + n->type = T_PgpoolVariableSetStmt; /* Hack to keep the changes minimum */ $$ = (Node *) n; } ; @@ -1705,22 +1970,28 @@ reset_rest: | TIME ZONE { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; n->name = "timezone"; + n->location = -1; $$ = n; } | TRANSACTION ISOLATION LEVEL { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; n->name = "transaction_isolation"; + n->location = -1; $$ = n; } | SESSION AUTHORIZATION { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; n->name = "session_authorization"; + n->location = -1; $$ = n; } ; @@ -1729,14 +2000,18 @@ generic_reset: var_name { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET; n->name = $1; + n->location = -1; $$ = n; } | ALL { VariableSetStmt *n = makeNode(VariableSetStmt); + n->kind = VAR_RESET_ALL; + n->location = -1; $$ = n; } ; @@ -1771,30 +2046,35 @@ VariableShowStmt: | SHOW var_name { VariableShowStmt *n = makeNode(VariableShowStmt); + n->name = $2; $$ = (Node *) n; } | SHOW TIME ZONE { VariableShowStmt *n = makeNode(VariableShowStmt); + n->name = "timezone"; $$ = (Node *) n; } | SHOW TRANSACTION ISOLATION LEVEL { VariableShowStmt *n = makeNode(VariableShowStmt); + n->name = "transaction_isolation"; $$ = (Node *) n; } | SHOW SESSION AUTHORIZATION { VariableShowStmt *n = makeNode(VariableShowStmt); + n->name = "session_authorization"; $$ = (Node *) n; } | SHOW ALL { VariableShowStmt *n = makeNode(VariableShowStmt); + n->name = "all"; $$ = (Node *) n; } @@ -1805,6 +2085,7 @@ ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode { ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt); + n->constraints = $3; n->deferred = $4; $$ = (Node *) n; @@ -1829,7 +2110,8 @@ CheckPointStmt: CHECKPOINT { CheckPointStmt *n = makeNode(CheckPointStmt); - $$ = (Node *)n; + + $$ = (Node *) n; } ; @@ -1844,30 +2126,35 @@ DiscardStmt: DISCARD ALL { DiscardStmt *n = makeNode(DiscardStmt); + n->target = DISCARD_ALL; $$ = (Node *) n; } | DISCARD TEMP { DiscardStmt *n = makeNode(DiscardStmt); + n->target = DISCARD_TEMP; $$ = (Node *) n; } | DISCARD TEMPORARY { DiscardStmt *n = makeNode(DiscardStmt); + n->target = DISCARD_TEMP; $$ = (Node *) n; } | DISCARD PLANS { DiscardStmt *n = makeNode(DiscardStmt); + n->target = DISCARD_PLANS; $$ = (Node *) n; } | DISCARD SEQUENCES { DiscardStmt *n = makeNode(DiscardStmt); + n->target = DISCARD_SEQUENCES; $$ = (Node *) n; } @@ -1877,9 +2164,9 @@ DiscardStmt: /***************************************************************************** * - * ALTER [ TABLE | INDEX | SEQUENCE | VIEW | MATERIALIZED VIEW ] variations + * ALTER [ TABLE | INDEX | SEQUENCE | VIEW | MATERIALIZED VIEW | FOREIGN TABLE ] variations * - * Note: we accept all subcommands for each of the five variants, and sort + * Note: we accept all subcommands for each of the variants, and sort * out what's really legal at execution time. *****************************************************************************/ @@ -1887,185 +2174,224 @@ AlterTableStmt: ALTER TABLE relation_expr alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $3; n->cmds = $4; - n->relkind = OBJECT_TABLE; + n->objtype = OBJECT_TABLE; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE IF_P EXISTS relation_expr alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $5; n->cmds = $6; - n->relkind = OBJECT_TABLE; + n->objtype = OBJECT_TABLE; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE relation_expr partition_cmd { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $3; n->cmds = list_make1($4); - n->relkind = OBJECT_TABLE; + n->objtype = OBJECT_TABLE; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE IF_P EXISTS relation_expr partition_cmd { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $5; n->cmds = list_make1($6); - n->relkind = OBJECT_TABLE; + n->objtype = OBJECT_TABLE; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait { AlterTableMoveAllStmt *n = makeNode(AlterTableMoveAllStmt); + n->orig_tablespacename = $6; n->objtype = OBJECT_TABLE; n->roles = NIL; n->new_tablespacename = $9; n->nowait = $10; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait { AlterTableMoveAllStmt *n = makeNode(AlterTableMoveAllStmt); + n->orig_tablespacename = $6; n->objtype = OBJECT_TABLE; n->roles = $9; n->new_tablespacename = $12; n->nowait = $13; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER INDEX qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $3; n->cmds = $4; - n->relkind = OBJECT_INDEX; + n->objtype = OBJECT_INDEX; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER INDEX IF_P EXISTS qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $5; n->cmds = $6; - n->relkind = OBJECT_INDEX; + n->objtype = OBJECT_INDEX; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER INDEX qualified_name index_partition_cmd { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $3; n->cmds = list_make1($4); - n->relkind = OBJECT_INDEX; + n->objtype = OBJECT_INDEX; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER INDEX ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait { AlterTableMoveAllStmt *n = makeNode(AlterTableMoveAllStmt); + n->orig_tablespacename = $6; n->objtype = OBJECT_INDEX; n->roles = NIL; n->new_tablespacename = $9; n->nowait = $10; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER INDEX ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait { AlterTableMoveAllStmt *n = makeNode(AlterTableMoveAllStmt); + n->orig_tablespacename = $6; n->objtype = OBJECT_INDEX; n->roles = $9; n->new_tablespacename = $12; n->nowait = $13; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SEQUENCE qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $3; n->cmds = $4; - n->relkind = OBJECT_SEQUENCE; + n->objtype = OBJECT_SEQUENCE; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SEQUENCE IF_P EXISTS qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $5; n->cmds = $6; - n->relkind = OBJECT_SEQUENCE; + n->objtype = OBJECT_SEQUENCE; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER VIEW qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $3; n->cmds = $4; - n->relkind = OBJECT_VIEW; + n->objtype = OBJECT_VIEW; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER VIEW IF_P EXISTS qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $5; n->cmds = $6; - n->relkind = OBJECT_VIEW; + n->objtype = OBJECT_VIEW; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $4; n->cmds = $5; - n->relkind = OBJECT_MATVIEW; + n->objtype = OBJECT_MATVIEW; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name alter_table_cmds { AlterTableStmt *n = makeNode(AlterTableStmt); + n->relation = $6; n->cmds = $7; - n->relkind = OBJECT_MATVIEW; + n->objtype = OBJECT_MATVIEW; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait { AlterTableMoveAllStmt *n = makeNode(AlterTableMoveAllStmt); + n->orig_tablespacename = $7; n->objtype = OBJECT_MATVIEW; n->roles = NIL; n->new_tablespacename = $10; n->nowait = $11; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait { AlterTableMoveAllStmt *n = makeNode(AlterTableMoveAllStmt); + n->orig_tablespacename = $7; n->objtype = OBJECT_MATVIEW; n->roles = $10; n->new_tablespacename = $13; n->nowait = $14; - $$ = (Node *)n; + $$ = (Node *) n; + } + | ALTER FOREIGN TABLE relation_expr alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $4; + n->cmds = $5; + n->objtype = OBJECT_FOREIGN_TABLE; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER FOREIGN TABLE IF_P EXISTS relation_expr alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $6; + n->cmds = $7; + n->objtype = OBJECT_FOREIGN_TABLE; + n->missing_ok = true; + $$ = (Node *) n; } ; @@ -2084,12 +2410,13 @@ partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = $4; + cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; } - /* ALTER TABLE DETACH PARTITION */ - | DETACH PARTITION qualified_name + /* ALTER TABLE DETACH PARTITION [CONCURRENTLY] */ + | DETACH PARTITION qualified_name opt_concurrently { AlterTableCmd *n = makeNode(AlterTableCmd); PartitionCmd *cmd = makeNode(PartitionCmd); @@ -2097,8 +2424,21 @@ partition_cmd: n->subtype = AT_DetachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->concurrent = $4; n->def = (Node *) cmd; + $$ = (Node *) n; + } + | DETACH PARTITION qualified_name FINALIZE + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_DetachPartitionFinalize; + cmd->name = $3; + cmd->bound = NULL; + cmd->concurrent = false; + n->def = (Node *) cmd; $$ = (Node *) n; } ; @@ -2113,6 +2453,7 @@ index_partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; @@ -2124,74 +2465,111 @@ alter_table_cmd: ADD_P columnDef { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddColumn; n->def = $2; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ADD IF NOT EXISTS */ | ADD_P IF_P NOT EXISTS columnDef { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddColumn; n->def = $5; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ADD COLUMN */ | ADD_P COLUMN columnDef { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddColumn; n->def = $3; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ADD COLUMN IF NOT EXISTS */ | ADD_P COLUMN IF_P NOT EXISTS columnDef { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddColumn; n->def = $6; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] {SET DEFAULT |DROP DEFAULT} */ | ALTER opt_column ColId alter_column_default { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ColumnDefault; n->name = $3; n->def = $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] DROP NOT NULL */ | ALTER opt_column ColId DROP NOT NULL_P { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropNotNull; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] SET NOT NULL */ | ALTER opt_column ColId SET NOT NULL_P { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetNotNull; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET EXPRESSION AS */ + | ALTER opt_column ColId SET EXPRESSION AS '(' a_expr ')' + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetExpression; + n->name = $3; + n->def = $8; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] DROP EXPRESSION */ + | ALTER opt_column ColId DROP EXPRESSION + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropExpression; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] DROP EXPRESSION IF EXISTS */ + | ALTER opt_column ColId DROP EXPRESSION IF_P EXISTS + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropExpression; + n->name = $3; + n->missing_ok = true; + $$ = (Node *) n; } - /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ - | ALTER opt_column ColId SET STATISTICS SignedIconst + /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ + | ALTER opt_column ColId SET STATISTICS set_statistics_value { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetStatistics; n->name = $3; - n->def = (Node *) makeInteger($6); - $$ = (Node *)n; + n->def = $6; + $$ = (Node *) n; } - /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ - | ALTER opt_column Iconst SET STATISTICS SignedIconst + /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ + | ALTER opt_column Iconst SET STATISTICS set_statistics_value { AlterTableCmd *n = makeNode(AlterTableCmd); @@ -2203,35 +2581,48 @@ alter_table_cmd: n->subtype = AT_SetStatistics; n->num = (int16) $3; - n->def = (Node *) makeInteger($6); - $$ = (Node *)n; + n->def = $6; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] SET ( column_parameter = value [, ... ] ) */ | ALTER opt_column ColId SET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetOptions; n->name = $3; n->def = (Node *) $5; - $$ = (Node *)n; + $$ = (Node *) n; } - /* ALTER TABLE ALTER [COLUMN] RESET ( column_parameter = value [, ... ] ) */ + /* ALTER TABLE ALTER [COLUMN] RESET ( column_parameter [, ... ] ) */ | ALTER opt_column ColId RESET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ResetOptions; n->name = $3; n->def = (Node *) $5; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] SET STORAGE */ - | ALTER opt_column ColId SET STORAGE ColId + | ALTER opt_column ColId SET column_storage { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetStorage; n->name = $3; - n->def = (Node *) makeString($6); - $$ = (Node *)n; + n->def = (Node *) makeString($5); + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET COMPRESSION */ + | ALTER opt_column ColId SET column_compression + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetCompression; + n->name = $3; + n->def = (Node *) makeString($5); + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] ADD GENERATED ... AS IDENTITY ... */ | ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList @@ -2248,54 +2639,59 @@ alter_table_cmd: n->name = $3; n->def = (Node *) c; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] SET /RESET */ | ALTER opt_column ColId alter_identity_column_option_list { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetIdentity; n->name = $3; n->def = (Node *) $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] DROP IDENTITY */ | ALTER opt_column ColId DROP IDENTITY_P { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropIdentity; n->name = $3; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER [COLUMN] DROP IDENTITY IF EXISTS */ | ALTER opt_column ColId DROP IDENTITY_P IF_P EXISTS { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropIdentity; n->name = $3; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DROP [COLUMN] IF EXISTS [RESTRICT|CASCADE] */ | DROP opt_column IF_P EXISTS ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropColumn; n->name = $5; n->behavior = $6; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DROP [COLUMN] [RESTRICT|CASCADE] */ | DROP opt_column ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropColumn; n->name = $3; n->behavior = $4; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } /* * ALTER TABLE ALTER [COLUMN] [SET DATA] TYPE @@ -2305,6 +2701,7 @@ alter_table_cmd: { AlterTableCmd *n = makeNode(AlterTableCmd); ColumnDef *def = makeNode(ColumnDef); + n->subtype = AT_AlterColumnType; n->name = $3; n->def = (Node *) def; @@ -2313,7 +2710,7 @@ alter_table_cmd: def->collClause = (CollateClause *) $7; def->raw_default = $8; def->location = @3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER FOREIGN TABLE ALTER [COLUMN] OPTIONS */ | ALTER opt_column ColId alter_generic_options @@ -2322,7 +2719,7 @@ alter_table_cmd: n->subtype = AT_AlterColumnGenericOptions; n->name = $3; n->def = (Node *) $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ADD CONSTRAINT ... */ | ADD_P TableConstraint @@ -2331,293 +2728,359 @@ alter_table_cmd: n->subtype = AT_AddConstraint; n->def = $2; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ALTER CONSTRAINT ... */ | ALTER CONSTRAINT name ConstraintAttributeSpec { AlterTableCmd *n = makeNode(AlterTableCmd); - Constraint *c = makeNode(Constraint); + ATAlterConstraint *c = makeNode(ATAlterConstraint); + n->subtype = AT_AlterConstraint; n->def = (Node *) c; - c->contype = CONSTR_FOREIGN; /* others not supported, yet */ c->conname = $3; - processCASbits($4, @4, "ALTER CONSTRAINT statement", + if ($4 & (CAS_NOT_ENFORCED | CAS_ENFORCED)) + c->alterEnforceability = true; + if ($4 & (CAS_DEFERRABLE | CAS_NOT_DEFERRABLE | + CAS_INITIALLY_DEFERRED | CAS_INITIALLY_IMMEDIATE)) + c->alterDeferrability = true; + if ($4 & CAS_NO_INHERIT) + c->alterInheritability = true; + /* handle unsupported case with specific error message */ + if ($4 & CAS_NOT_VALID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraints cannot be altered to be NOT VALID"), + parser_errposition(@4))); + processCASbits($4, @4, "FOREIGN KEY", &c->deferrable, &c->initdeferred, - NULL, NULL, yyscanner); - $$ = (Node *)n; + &c->is_enforced, + NULL, + &c->noinherit, + yyscanner); + $$ = (Node *) n; + } + /* ALTER TABLE ALTER CONSTRAINT INHERIT */ + | ALTER CONSTRAINT name INHERIT + { + AlterTableCmd *n = makeNode(AlterTableCmd); + ATAlterConstraint *c = makeNode(ATAlterConstraint); + + n->subtype = AT_AlterConstraint; + n->def = (Node *) c; + c->conname = $3; + c->alterInheritability = true; + c->noinherit = false; + + $$ = (Node *) n; } /* ALTER TABLE VALIDATE CONSTRAINT ... */ | VALIDATE CONSTRAINT name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ValidateConstraint; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DROP CONSTRAINT IF EXISTS [RESTRICT|CASCADE] */ | DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropConstraint; n->name = $5; n->behavior = $6; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DROP CONSTRAINT [RESTRICT|CASCADE] */ | DROP CONSTRAINT name opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropConstraint; n->name = $3; n->behavior = $4; n->missing_ok = false; - $$ = (Node *)n; - } - /* ALTER TABLE SET WITH OIDS */ - | SET WITH OIDS - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddOids; - $$ = (Node *)n; + $$ = (Node *) n; } - /* ALTER TABLE SET WITHOUT OIDS */ + /* ALTER TABLE SET WITHOUT OIDS, for backward compat */ | SET WITHOUT OIDS { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropOids; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE CLUSTER ON */ | CLUSTER ON name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ClusterOn; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE SET WITHOUT CLUSTER */ | SET WITHOUT CLUSTER { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropCluster; n->name = NULL; - $$ = (Node *)n; + $$ = (Node *) n; } - /* ALTER TABLE SET LOGGED */ + /* ALTER TABLE SET LOGGED */ | SET LOGGED { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetLogged; - $$ = (Node *)n; + $$ = (Node *) n; } - /* ALTER TABLE SET UNLOGGED */ + /* ALTER TABLE SET UNLOGGED */ | SET UNLOGGED { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetUnLogged; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE TRIGGER */ | ENABLE_P TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableTrig; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE ALWAYS TRIGGER */ | ENABLE_P ALWAYS TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableAlwaysTrig; n->name = $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE REPLICA TRIGGER */ | ENABLE_P REPLICA TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableReplicaTrig; n->name = $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE TRIGGER ALL */ | ENABLE_P TRIGGER ALL { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableTrigAll; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE TRIGGER USER */ | ENABLE_P TRIGGER USER { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableTrigUser; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DISABLE TRIGGER */ | DISABLE_P TRIGGER name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableTrig; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DISABLE TRIGGER ALL */ | DISABLE_P TRIGGER ALL { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableTrigAll; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DISABLE TRIGGER USER */ | DISABLE_P TRIGGER USER { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableTrigUser; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE RULE */ | ENABLE_P RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableRule; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE ALWAYS RULE */ | ENABLE_P ALWAYS RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableAlwaysRule; n->name = $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE REPLICA RULE */ | ENABLE_P REPLICA RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableReplicaRule; n->name = $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DISABLE RULE */ | DISABLE_P RULE name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableRule; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE INHERIT */ | INHERIT qualified_name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddInherit; n->def = (Node *) $2; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE NO INHERIT */ | NO INHERIT qualified_name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropInherit; n->def = (Node *) $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE OF */ | OF any_name { AlterTableCmd *n = makeNode(AlterTableCmd); - TypeName *def = makeTypeNameFromNameList($2); + TypeName *def = makeTypeNameFromNameList($2); + def->location = @2; n->subtype = AT_AddOf; n->def = (Node *) def; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE NOT OF */ | NOT OF { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropOf; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE OWNER TO RoleSpec */ | OWNER TO RoleSpec { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ChangeOwner; n->newowner = $3; - $$ = (Node *)n; + $$ = (Node *) n; + } + /* ALTER TABLE SET ACCESS METHOD { | DEFAULT } */ + | SET ACCESS METHOD set_access_method_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetAccessMethod; + n->name = $4; + $$ = (Node *) n; } /* ALTER TABLE SET TABLESPACE */ | SET TABLESPACE name { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetTableSpace; n->name = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE SET (...) */ | SET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetRelOptions; - n->def = (Node *)$2; - $$ = (Node *)n; + n->def = (Node *) $2; + $$ = (Node *) n; } /* ALTER TABLE RESET (...) */ | RESET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ResetRelOptions; - n->def = (Node *)$2; - $$ = (Node *)n; + n->def = (Node *) $2; + $$ = (Node *) n; } - /* ALTER TABLE REPLICA IDENTITY */ + /* ALTER TABLE REPLICA IDENTITY */ | REPLICA IDENTITY_P replica_identity { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ReplicaIdentity; n->def = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE ENABLE ROW LEVEL SECURITY */ | ENABLE_P ROW LEVEL SECURITY { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_EnableRowSecurity; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE DISABLE ROW LEVEL SECURITY */ | DISABLE_P ROW LEVEL SECURITY { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DisableRowSecurity; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE FORCE ROW LEVEL SECURITY */ | FORCE ROW LEVEL SECURITY { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_ForceRowSecurity; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TABLE NO FORCE ROW LEVEL SECURITY */ | NO FORCE ROW LEVEL SECURITY { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_NoForceRowSecurity; - $$ = (Node *)n; + $$ = (Node *) n; } | alter_generic_options { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_GenericOptions; - n->def = (Node *)$1; + n->def = (Node *) $1; $$ = (Node *) n; } ; @@ -2627,16 +3090,11 @@ alter_column_default: | DROP DEFAULT { $$ = NULL; } ; -opt_drop_behavior: - CASCADE { $$ = DROP_CASCADE; } - | RESTRICT { $$ = DROP_RESTRICT; } - | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ } - ; - opt_collate_clause: COLLATE any_name { CollateClause *n = makeNode(CollateClause); + n->arg = NULL; n->collname = $2; n->location = @1; @@ -2654,6 +3112,7 @@ replica_identity: NOTHING { ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + n->identity_type = REPLICA_IDENTITY_NOTHING; n->name = NULL; $$ = (Node *) n; @@ -2661,6 +3120,7 @@ replica_identity: | FULL { ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + n->identity_type = REPLICA_IDENTITY_FULL; n->name = NULL; $$ = (Node *) n; @@ -2668,6 +3128,7 @@ replica_identity: | DEFAULT { ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + n->identity_type = REPLICA_IDENTITY_DEFAULT; n->name = NULL; $$ = (Node *) n; @@ -2675,6 +3136,7 @@ replica_identity: | USING INDEX name { ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + n->identity_type = REPLICA_IDENTITY_INDEX; n->name = $3; $$ = (Node *) n; @@ -2729,7 +3191,7 @@ alter_identity_column_option: } | RESTART opt_with NumericOnly { - $$ = makeDefElem("restart", (Node *)$3, @1); + $$ = makeDefElem("restart", (Node *) $3, @1); } | SET SeqOptElem { @@ -2748,8 +3210,18 @@ alter_identity_column_option: } ; +set_statistics_value: + SignedIconst { $$ = (Node *) makeInteger($1); } + | DEFAULT { $$ = NULL; } + ; + +set_access_method_name: + ColId { $$ = $1; } + | DEFAULT { $$ = NULL; } + ; + PartitionBoundSpec: - /* a HASH partition*/ + /* a HASH partition */ FOR VALUES WITH '(' hash_partbound ')' { ListCell *lc; @@ -2791,11 +3263,13 @@ PartitionBoundSpec: if (n->modulus == -1) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("modulus for hash partition must be specified"))); + errmsg("modulus for hash partition must be specified"), + parser_errposition(@3))); if (n->remainder == -1) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("remainder for hash partition must be specified"))); + errmsg("remainder for hash partition must be specified"), + parser_errposition(@3))); n->location = @3; @@ -2803,7 +3277,7 @@ PartitionBoundSpec: } /* a LIST partition */ - | FOR VALUES IN_P '(' partbound_datum_list ')' + | FOR VALUES IN_P '(' expr_list ')' { PartitionBoundSpec *n = makeNode(PartitionBoundSpec); @@ -2816,7 +3290,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); @@ -2844,7 +3318,7 @@ PartitionBoundSpec: hash_partbound_elem: NonReservedWord Iconst { - $$ = makeDefElem($1, (Node *)makeInteger($2), @1); + $$ = makeDefElem($1, (Node *) makeInteger($2), @1); } ; @@ -2859,59 +3333,6 @@ hash_partbound: } ; -partbound_datum: - Sconst { $$ = makeStringConst($1, @1); } - | NumericOnly { $$ = makeAConst($1, @1); } - | TRUE_P { $$ = makeStringConst(pstrdup("true"), @1); } - | FALSE_P { $$ = makeStringConst(pstrdup("false"), @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 @@ -2927,8 +3348,8 @@ AlterCompositeTypeStmt: /* can't use qualified_name, sigh */ n->relation = makeRangeVarFromAnyName($3, @3, yyscanner); n->cmds = $4; - n->relkind = OBJECT_TYPE; - $$ = (Node *)n; + n->objtype = OBJECT_TYPE; + $$ = (Node *) n; } ; @@ -2942,36 +3363,40 @@ alter_type_cmd: ADD_P ATTRIBUTE TableFuncElement opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddColumn; n->def = $3; n->behavior = $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TYPE DROP ATTRIBUTE IF EXISTS [RESTRICT|CASCADE] */ | DROP ATTRIBUTE IF_P EXISTS ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropColumn; n->name = $5; n->behavior = $6; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TYPE DROP ATTRIBUTE [RESTRICT|CASCADE] */ | DROP ATTRIBUTE ColId opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_DropColumn; n->name = $3; n->behavior = $4; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER TYPE ALTER ATTRIBUTE [SET DATA] TYPE [RESTRICT|CASCADE] */ | ALTER ATTRIBUTE ColId opt_set_data TYPE_P Typename opt_collate_clause opt_drop_behavior { AlterTableCmd *n = makeNode(AlterTableCmd); ColumnDef *def = makeNode(ColumnDef); + n->subtype = AT_AlterColumnType; n->name = $3; n->def = (Node *) def; @@ -2981,7 +3406,7 @@ alter_type_cmd: def->collClause = (CollateClause *) $7; def->raw_default = NULL; def->location = @3; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -2997,14 +3422,16 @@ ClosePortalStmt: CLOSE cursor_name { ClosePortalStmt *n = makeNode(ClosePortalStmt); + n->portalname = $2; - $$ = (Node *)n; + $$ = (Node *) n; } | CLOSE ALL { ClosePortalStmt *n = makeNode(ClosePortalStmt); + n->portalname = NULL; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -3026,23 +3453,26 @@ 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, @@ -3050,21 +3480,26 @@ 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); - $$ = (Node *)n; + 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 { CopyStmt *n = makeNode(CopyStmt); + n->relation = NULL; n->query = $3; n->attlist = NIL; @@ -3079,7 +3514,7 @@ CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids errmsg("STDIN/STDOUT not allowed with PROGRAM"), parser_errposition(@5))); - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -3117,59 +3552,63 @@ copy_opt_list: copy_opt_item: BINARY { - $$ = makeDefElem("format", (Node *)makeString("binary"), @1); - } - | OIDS - { - $$ = makeDefElem("oids", (Node *)makeInteger(true), @1); + $$ = makeDefElem("format", (Node *) makeString("binary"), @1); } | FREEZE { - $$ = makeDefElem("freeze", (Node *)makeInteger(true), @1); + $$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1); } | DELIMITER opt_as Sconst { - $$ = makeDefElem("delimiter", (Node *)makeString($3), @1); + $$ = makeDefElem("delimiter", (Node *) makeString($3), @1); } | NULL_P opt_as Sconst { - $$ = makeDefElem("null", (Node *)makeString($3), @1); + $$ = makeDefElem("null", (Node *) makeString($3), @1); } | CSV { - $$ = makeDefElem("format", (Node *)makeString("csv"), @1); + $$ = makeDefElem("format", (Node *) makeString("csv"), @1); } | HEADER_P { - $$ = makeDefElem("header", (Node *)makeInteger(true), @1); + $$ = makeDefElem("header", (Node *) makeBoolean(true), @1); } | QUOTE opt_as Sconst { - $$ = makeDefElem("quote", (Node *)makeString($3), @1); + $$ = makeDefElem("quote", (Node *) makeString($3), @1); } | ESCAPE opt_as Sconst { - $$ = makeDefElem("escape", (Node *)makeString($3), @1); + $$ = makeDefElem("escape", (Node *) makeString($3), @1); } | FORCE QUOTE columnList { - $$ = makeDefElem("force_quote", (Node *)$3, @1); + $$ = makeDefElem("force_quote", (Node *) $3, @1); } | FORCE QUOTE '*' { - $$ = makeDefElem("force_quote", (Node *)makeNode(A_Star), @1); + $$ = makeDefElem("force_quote", (Node *) makeNode(A_Star), @1); } | FORCE NOT NULL_P columnList { - $$ = makeDefElem("force_not_null", (Node *)$4, @1); + $$ = makeDefElem("force_not_null", (Node *) $4, @1); + } + | FORCE NOT NULL_P '*' + { + $$ = makeDefElem("force_not_null", (Node *) makeNode(A_Star), @1); } | FORCE NULL_P columnList { - $$ = makeDefElem("force_null", (Node *)$3, @1); + $$ = makeDefElem("force_null", (Node *) $3, @1); + } + | FORCE NULL_P '*' + { + $$ = makeDefElem("force_null", (Node *) makeNode(A_Star), @1); } | ENCODING Sconst { - $$ = makeDefElem("encoding", (Node *)makeString($2), @1); + $$ = makeDefElem("encoding", (Node *) makeString($2), @1); } ; @@ -3178,15 +3617,7 @@ copy_opt_item: opt_binary: BINARY { - $$ = makeDefElem("format", (Node *)makeString("binary"), @1); - } - | /*EMPTY*/ { $$ = NULL; } - ; - -opt_oids: - WITH OIDS - { - $$ = makeDefElem("oids", (Node *)makeInteger(true), @1); + $$ = makeDefElem("format", (Node *) makeString("binary"), @1); } | /*EMPTY*/ { $$ = NULL; } ; @@ -3194,14 +3625,14 @@ opt_oids: copy_delimiter: opt_using DELIMITERS Sconst { - $$ = makeDefElem("delimiter", (Node *)makeString($3), @2); + $$ = makeDefElem("delimiter", (Node *) makeString($3), @2); } | /*EMPTY*/ { $$ = NULL; } ; opt_using: - USING {} - | /*EMPTY*/ {} + USING + | /*EMPTY*/ ; /* new COPY option syntax */ @@ -3227,6 +3658,7 @@ copy_generic_opt_arg: opt_boolean_or_string { $$ = (Node *) makeString($1); } | NumericOnly { $$ = (Node *) $1; } | '*' { $$ = (Node *) makeNode(A_Star); } + | DEFAULT { $$ = (Node *) makeString("default"); } | '(' copy_generic_opt_arg_list ')' { $$ = (Node *) $2; } | /* EMPTY */ { $$ = NULL; } ; @@ -3256,9 +3688,11 @@ 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; n->relation = $4; n->tableElts = $6; @@ -3266,17 +3700,19 @@ 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; + $$ = (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; n->relation = $7; n->tableElts = $9; @@ -3284,17 +3720,19 @@ 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; + $$ = (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; n->relation = $4; n->tableElts = $7; @@ -3303,17 +3741,19 @@ 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; + $$ = (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; n->relation = $7; n->tableElts = $10; @@ -3322,17 +3762,19 @@ 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; + $$ = (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; n->relation = $4; n->tableElts = $8; @@ -3341,17 +3783,19 @@ 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; + $$ = (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; n->relation = $7; n->tableElts = $11; @@ -3360,11 +3804,12 @@ 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; + $$ = (Node *) n; } ; @@ -3444,38 +3889,40 @@ TypedTableElement: | TableConstraint { $$ = $1; } ; -columnDef: ColId Typename create_generic_options ColQualList +columnDef: ColId Typename opt_column_storage opt_column_compression create_generic_options ColQualList { ColumnDef *n = makeNode(ColumnDef); + n->colname = $1; n->typeName = $2; + n->storage_name = $3; + n->compression = $4; n->inhcount = 0; 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; n->collOid = InvalidOid; - n->fdwoptions = $3; - SplitColQualList($4, &n->constraints, &n->collClause, + n->fdwoptions = $5; + SplitColQualList($6, &n->constraints, &n->collClause, yyscanner); n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } ; columnOptions: ColId ColQualList { ColumnDef *n = makeNode(ColumnDef); + n->colname = $1; n->typeName = NULL; n->inhcount = 0; 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; @@ -3483,18 +3930,18 @@ columnOptions: ColId ColQualList SplitColQualList($2, &n->constraints, &n->collClause, yyscanner); n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | ColId WITH OPTIONS ColQualList { ColumnDef *n = makeNode(ColumnDef); + n->colname = $1; n->typeName = NULL; n->inhcount = 0; 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; @@ -3502,10 +3949,30 @@ columnOptions: ColId ColQualList SplitColQualList($4, &n->constraints, &n->collClause, yyscanner); n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } ; +column_compression: + COMPRESSION ColId { $$ = $2; } + | COMPRESSION DEFAULT { $$ = pstrdup("default"); } + ; + +opt_column_compression: + column_compression { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +column_storage: + STORAGE ColId { $$ = $2; } + | STORAGE DEFAULT { $$ = pstrdup("default"); } + ; + +opt_column_storage: + column_storage { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + ColQualList: ColQualList ColConstraint { $$ = lappend($1, $2); } | /*EMPTY*/ { $$ = NIL; } @@ -3515,6 +3982,7 @@ ColConstraint: CONSTRAINT name ColConstraintElem { Constraint *n = castNode(Constraint, $3); + n->conname = $2; n->location = @1; $$ = (Node *) n; @@ -3529,6 +3997,7 @@ ColConstraint: * again in SplitColQualList. */ CollateClause *n = makeNode(CollateClause); + n->arg = NULL; n->collname = $2; n->location = @1; @@ -3552,96 +4021,149 @@ ColConstraint: * or be part of a_expr NOT LIKE or similar constructs). */ ColConstraintElem: - NOT NULL_P + NOT NULL_P opt_no_inherit { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_NOTNULL; n->location = @1; - $$ = (Node *)n; + n->is_no_inherit = $3; + n->is_enforced = true; + n->skip_validation = false; + n->initially_valid = true; + $$ = (Node *) n; } | NULL_P { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_NULL; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } - | UNIQUE opt_definition OptConsTableSpace + | UNIQUE opt_unique_null_treatment opt_definition OptConsTableSpace { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_UNIQUE; n->location = @1; + n->nulls_not_distinct = !$2; n->keys = NULL; - n->options = $2; + n->options = $3; n->indexname = NULL; - n->indexspace = $3; - $$ = (Node *)n; + n->indexspace = $4; + $$ = (Node *) n; } | PRIMARY KEY opt_definition OptConsTableSpace { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = NULL; n->options = $3; n->indexname = NULL; n->indexspace = $4; - $$ = (Node *)n; + $$ = (Node *) n; } | CHECK '(' a_expr ')' opt_no_inherit { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_CHECK; n->location = @1; n->is_no_inherit = $5; n->raw_expr = $3; n->cooked_expr = NULL; + n->is_enforced = true; n->skip_validation = false; n->initially_valid = true; - $$ = (Node *)n; + $$ = (Node *) n; } | DEFAULT b_expr { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_DEFAULT; n->location = @1; n->raw_expr = $2; n->cooked_expr = NULL; n->skip_validation = false; n->initially_valid = true; - $$ = (Node *)n; + $$ = (Node *) n; } | GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_IDENTITY; n->generated_when = $2; n->options = $5; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; + } + | GENERATED generated_when AS '(' a_expr ')' opt_virtual_or_stored + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_GENERATED; + n->generated_when = $2; + n->raw_expr = $5; + n->cooked_expr = NULL; + n->generated_kind = $7; + 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); + n->contype = CONSTR_FOREIGN; n->location = @1; - n->pktable = $2; - n->fk_attrs = NIL; - n->pk_attrs = $3; - n->fk_matchtype = $4; - n->fk_upd_action = (char) ($5 >> 8); - n->fk_del_action = (char) ($5 & 0xFF); - n->skip_validation = false; - n->initially_valid = true; - $$ = (Node *)n; + n->pktable = $2; + n->fk_attrs = NIL; + n->pk_attrs = $3; + n->fk_matchtype = $4; + n->fk_upd_action = ($5)->updateAction->action; + n->fk_del_action = ($5)->deleteAction->action; + n->fk_del_set_cols = ($5)->deleteAction->cols; + n->is_enforced = true; + n->skip_validation = false; + n->initially_valid = true; + $$ = (Node *) n; } ; +opt_unique_null_treatment: + NULLS_P DISTINCT { $$ = true; } + | NULLS_P NOT DISTINCT { $$ = false; } + | /*EMPTY*/ { $$ = true; } + ; + generated_when: ALWAYS { $$ = ATTRIBUTE_IDENTITY_ALWAYS; } | BY DEFAULT { $$ = ATTRIBUTE_IDENTITY_BY_DEFAULT; } ; +opt_virtual_or_stored: + STORED { $$ = ATTRIBUTE_GENERATED_STORED; } + | VIRTUAL { $$ = ATTRIBUTE_GENERATED_VIRTUAL; } + | /*EMPTY*/ { $$ = ATTRIBUTE_GENERATED_VIRTUAL; } + ; + /* * ConstraintAttr represents constraint attributes, which we parse as if * they were independent constraint clauses, in order to avoid shift/reduce @@ -3661,30 +4183,50 @@ ConstraintAttr: DEFERRABLE { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_ATTR_DEFERRABLE; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | NOT DEFERRABLE { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_ATTR_NOT_DEFERRABLE; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | INITIALLY DEFERRED { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_ATTR_DEFERRED; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | INITIALLY IMMEDIATE { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_ATTR_IMMEDIATE; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; + } + | ENFORCED + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_ENFORCED; + n->location = @1; + $$ = (Node *) n; + } + | NOT ENFORCED + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_NOT_ENFORCED; + n->location = @1; + $$ = (Node *) n; } ; @@ -3693,9 +4235,11 @@ TableLikeClause: LIKE qualified_name TableLikeOptionList { TableLikeClause *n = makeNode(TableLikeClause); + n->relation = $2; n->options = $3; - $$ = (Node *)n; + n->relationOid = InvalidOid; + $$ = (Node *) n; } ; @@ -3707,9 +4251,11 @@ TableLikeOptionList: TableLikeOption: COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; } + | COMPRESSION { $$ = CREATE_TABLE_LIKE_COMPRESSION; } | 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; } @@ -3725,6 +4271,7 @@ TableConstraint: CONSTRAINT name ConstraintElem { Constraint *n = castNode(Constraint, $3); + n->conname = $2; n->location = @1; $$ = (Node *) n; @@ -3736,35 +4283,53 @@ ConstraintElem: CHECK '(' a_expr ')' ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_CHECK; n->location = @1; n->raw_expr = $3; n->cooked_expr = NULL; processCASbits($5, @5, "CHECK", - NULL, NULL, &n->skip_validation, + NULL, NULL, &n->is_enforced, &n->skip_validation, + &n->is_no_inherit, yyscanner); + n->initially_valid = !n->skip_validation; + $$ = (Node *) n; + } + | NOT NULL_P ColId ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_NOTNULL; + n->location = @1; + n->keys = list_make1(makeString($3)); + processCASbits($4, @4, "NOT NULL", + NULL, NULL, NULL, &n->skip_validation, &n->is_no_inherit, yyscanner); n->initially_valid = !n->skip_validation; - $$ = (Node *)n; + $$ = (Node *) n; } - | UNIQUE '(' columnList ')' opt_c_include opt_definition OptConsTableSpace + | UNIQUE opt_unique_null_treatment '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_UNIQUE; n->location = @1; - n->keys = $3; - n->including = $5; - n->options = $6; + n->nulls_not_distinct = !$2; + n->keys = $4; + n->without_overlaps = $5; + n->including = $7; + n->options = $8; n->indexname = NULL; - n->indexspace = $7; - processCASbits($8, @8, "UNIQUE", + n->indexspace = $9; + processCASbits($10, @10, "UNIQUE", &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - $$ = (Node *)n; + NULL, NULL, yyscanner); + $$ = (Node *) n; } | UNIQUE ExistingIndex ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_UNIQUE; n->location = @1; n->keys = NIL; @@ -3774,28 +4339,31 @@ ConstraintElem: n->indexspace = NULL; processCASbits($3, @3, "UNIQUE", &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - $$ = (Node *)n; + NULL, NULL, yyscanner); + $$ = (Node *) n; } - | PRIMARY KEY '(' columnList ')' opt_c_include opt_definition OptConsTableSpace + | PRIMARY KEY '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = $4; - n->including = $6; - n->options = $7; + n->without_overlaps = $5; + n->including = $7; + n->options = $8; n->indexname = NULL; - n->indexspace = $8; - processCASbits($9, @9, "PRIMARY KEY", + n->indexspace = $9; + processCASbits($10, @10, "PRIMARY KEY", &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - $$ = (Node *)n; + NULL, NULL, yyscanner); + $$ = (Node *) n; } | PRIMARY KEY ExistingIndex ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_PRIMARY; n->location = @1; n->keys = NIL; @@ -3805,46 +4373,114 @@ ConstraintElem: n->indexspace = NULL; processCASbits($4, @4, "PRIMARY KEY", &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - $$ = (Node *)n; + NULL, NULL, yyscanner); + $$ = (Node *) n; } | EXCLUDE access_method_clause '(' ExclusionConstraintList ')' - opt_c_include opt_definition OptConsTableSpace ExclusionWhereClause + opt_c_include opt_definition OptConsTableSpace OptWhereClause ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_EXCLUSION; n->location = @1; - n->access_method = $2; - n->exclusions = $4; - n->including = $6; - n->options = $7; - n->indexname = NULL; - n->indexspace = $8; - n->where_clause = $9; + n->access_method = $2; + n->exclusions = $4; + n->including = $6; + n->options = $7; + n->indexname = NULL; + n->indexspace = $8; + n->where_clause = $9; processCASbits($10, @10, "EXCLUDE", &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - $$ = (Node *)n; + NULL, NULL, yyscanner); + $$ = (Node *) n; } - | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name - opt_column_list key_match key_actions ConstraintAttributeSpec + | FOREIGN KEY '(' columnList optionalPeriodName ')' REFERENCES qualified_name + opt_column_and_period_list key_match key_actions ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); + n->contype = CONSTR_FOREIGN; n->location = @1; - n->pktable = $7; - n->fk_attrs = $4; - n->pk_attrs = $8; - n->fk_matchtype = $9; - n->fk_upd_action = (char) ($10 >> 8); - n->fk_del_action = (char) ($10 & 0xFF); - processCASbits($11, @11, "FOREIGN KEY", + n->pktable = $8; + n->fk_attrs = $4; + if ($5) + { + n->fk_attrs = lappend(n->fk_attrs, $5); + n->fk_with_period = true; + } + n->pk_attrs = linitial($9); + if (lsecond($9)) + { + n->pk_attrs = lappend(n->pk_attrs, lsecond($9)); + n->pk_with_period = true; + } + n->fk_matchtype = $10; + n->fk_upd_action = ($11)->updateAction->action; + n->fk_del_action = ($11)->deleteAction->action; + n->fk_del_set_cols = ($11)->deleteAction->cols; + processCASbits($12, @12, "FOREIGN KEY", &n->deferrable, &n->initdeferred, - &n->skip_validation, NULL, + &n->is_enforced, &n->skip_validation, NULL, yyscanner); n->initially_valid = !n->skip_validation; - $$ = (Node *)n; + $$ = (Node *) n; + } + ; + +/* + * DomainConstraint is separate from TableConstraint because the syntax for + * NOT NULL constraints is different. For table constraints, we need to + * accept a column name, but for domain constraints, we don't. (We could + * accept something like NOT NULL VALUE, but that seems weird.) CREATE DOMAIN + * (which uses ColQualList) has for a long time accepted NOT NULL without a + * column name, so it makes sense that ALTER DOMAIN (which uses + * DomainConstraint) does as well. None of these syntaxes are per SQL + * standard; we are just living with the bits of inconsistency that have built + * up over time. + */ +DomainConstraint: + CONSTRAINT name DomainConstraintElem + { + Constraint *n = castNode(Constraint, $3); + + n->conname = $2; + n->location = @1; + $$ = (Node *) n; + } + | DomainConstraintElem { $$ = $1; } + ; + +DomainConstraintElem: + CHECK '(' a_expr ')' ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_CHECK; + n->location = @1; + n->raw_expr = $3; + n->cooked_expr = NULL; + processCASbits($5, @5, "CHECK", + NULL, NULL, NULL, &n->skip_validation, + &n->is_no_inherit, yyscanner); + n->is_enforced = true; + n->initially_valid = !n->skip_validation; + $$ = (Node *) n; + } + | NOT NULL_P ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_NOTNULL; + n->location = @1; + n->keys = list_make1(makeString("value")); + /* no NOT VALID, NO INHERIT support */ + processCASbits($3, @3, "NOT NULL", + NULL, NULL, NULL, + NULL, NULL, yyscanner); + n->initially_valid = true; + $$ = (Node *) n; } ; @@ -3852,6 +4488,11 @@ opt_no_inherit: NO INHERIT { $$ = true; } | /* EMPTY */ { $$ = false; } ; +opt_without_overlaps: + WITHOUT OVERLAPS { $$ = true; } + | /*EMPTY*/ { $$ = false; } + ; + opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } @@ -3862,6 +4503,16 @@ columnList: | columnList ',' columnElem { $$ = lappend($1, $3); } ; +optionalPeriodName: + ',' PERIOD columnElem { $$ = $3; } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_column_and_period_list: + '(' columnList optionalPeriodName ')' { $$ = list_make2($2, $3); } + | /*EMPTY*/ { $$ = list_make2(NIL, NULL); } + ; + columnElem: ColId { $$ = (Node *) makeString($1); @@ -3911,42 +4562,121 @@ ExclusionConstraintElem: index_elem WITH any_operator } ; -ExclusionWhereClause: +OptWhereClause: WHERE '(' a_expr ')' { $$ = $3; } | /*EMPTY*/ { $$ = NULL; } ; -/* - * We combine the update and delete actions into one value temporarily - * for simplicity of parsing, and then break them down again in the - * calling production. update is in the left 8 bits, delete in the right. - * Note that NOACTION is the default. - */ key_actions: key_update - { $$ = ($1 << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); } + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = $1; + n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction->action = FKCONSTR_ACTION_NOACTION; + n->deleteAction->cols = NIL; + $$ = n; + } | key_delete - { $$ = (FKCONSTR_ACTION_NOACTION << 8) | ($1 & 0xFF); } + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction->action = FKCONSTR_ACTION_NOACTION; + n->updateAction->cols = NIL; + n->deleteAction = $1; + $$ = n; + } | key_update key_delete - { $$ = ($1 << 8) | ($2 & 0xFF); } + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = $1; + n->deleteAction = $2; + $$ = n; + } | key_delete key_update - { $$ = ($2 << 8) | ($1 & 0xFF); } + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = $2; + n->deleteAction = $1; + $$ = n; + } | /*EMPTY*/ - { $$ = (FKCONSTR_ACTION_NOACTION << 8) | (FKCONSTR_ACTION_NOACTION & 0xFF); } + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction->action = FKCONSTR_ACTION_NOACTION; + n->updateAction->cols = NIL; + n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction->action = FKCONSTR_ACTION_NOACTION; + n->deleteAction->cols = NIL; + $$ = n; + } ; -key_update: ON UPDATE key_action { $$ = $3; } +key_update: ON UPDATE key_action + { + if (($3)->cols) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("a column list with %s is only supported for ON DELETE actions", + ($3)->action == FKCONSTR_ACTION_SETNULL ? "SET NULL" : "SET DEFAULT"), + parser_errposition(@1))); + $$ = $3; + } ; -key_delete: ON DELETE_P key_action { $$ = $3; } +key_delete: ON DELETE_P key_action + { + $$ = $3; + } ; key_action: - NO ACTION { $$ = FKCONSTR_ACTION_NOACTION; } - | RESTRICT { $$ = FKCONSTR_ACTION_RESTRICT; } - | CASCADE { $$ = FKCONSTR_ACTION_CASCADE; } - | SET NULL_P { $$ = FKCONSTR_ACTION_SETNULL; } - | SET DEFAULT { $$ = FKCONSTR_ACTION_SETDEFAULT; } + NO ACTION + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_NOACTION; + n->cols = NIL; + $$ = n; + } + | RESTRICT + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_RESTRICT; + n->cols = NIL; + $$ = n; + } + | CASCADE + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_CASCADE; + n->cols = NIL; + $$ = n; + } + | SET NULL_P opt_column_list + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_SETNULL; + n->cols = $3; + $$ = n; + } + | SET DEFAULT opt_column_list + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_SETDEFAULT; + n->cols = $3; + $$ = n; + } ; OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; } @@ -3958,11 +4688,11 @@ OptPartitionSpec: PartitionSpec { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } ; -PartitionSpec: PARTITION BY part_strategy '(' part_params ')' +PartitionSpec: PARTITION BY ColId '(' part_params ')' { PartitionSpec *n = makeNode(PartitionSpec); - n->strategy = $3; + n->strategy = parsePartitionStrategy($3, @3, yyscanner); n->partParams = $5; n->location = @1; @@ -3970,15 +4700,11 @@ PartitionSpec: PARTITION BY part_strategy '(' part_params ')' } ; -part_strategy: IDENT { $$ = $1; } - | unreserved_keyword { $$ = pstrdup($1); } - ; - part_params: part_elem { $$ = list_make1($1); } | part_params ',' part_elem { $$ = lappend($1, $3); } ; -part_elem: ColId opt_collate opt_class +part_elem: ColId opt_collate opt_qualified_name { PartitionElem *n = makeNode(PartitionElem); @@ -3989,7 +4715,7 @@ part_elem: ColId opt_collate opt_class n->location = @1; $$ = n; } - | func_expr_windowless opt_collate opt_class + | func_expr_windowless opt_collate opt_qualified_name { PartitionElem *n = makeNode(PartitionElem); @@ -4000,7 +4726,7 @@ part_elem: ColId opt_collate opt_class n->location = @1; $$ = n; } - | '(' a_expr ')' opt_collate opt_class + | '(' a_expr ')' opt_collate opt_qualified_name { PartitionElem *n = makeNode(PartitionElem); @@ -4012,11 +4738,16 @@ part_elem: ColId opt_collate opt_class $$ = n; } ; -/* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */ -OptWith: - WITH reloptions { $$ = $2; } - | WITH OIDS { $$ = list_make1(makeDefElem("oids", (Node *) makeInteger(true), @1)); } - | WITHOUT OIDS { $$ = list_make1(makeDefElem("oids", (Node *) makeInteger(false), @1)); } + +table_access_method_clause: + USING name { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* WITHOUT OIDS is legacy only */ +OptWith: + WITH reloptions { $$ = $2; } + | WITHOUT OIDS { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; } ; @@ -4034,13 +4765,13 @@ OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; } | /*EMPTY*/ { $$ = NULL; } ; -ExistingIndex: USING INDEX index_name { $$ = $3; } +ExistingIndex: USING INDEX name { $$ = $3; } ; /***************************************************************************** * * QUERY : - * CREATE STATISTICS [IF NOT EXISTS] stats_name [(stat types)] + * CREATE STATISTICS [[IF NOT EXISTS] stats_name] [(stat types)] * ON expression-list FROM from_list * * Note: the expectation here is that the clauses after ON are a subset of @@ -4049,32 +4780,96 @@ ExistingIndex: USING INDEX index_name { $$ = $3; } * but the grammar accepts it and then we'll throw FEATURE_NOT_SUPPORTED * errors as necessary at execution. * + * Statistics name is optional unless IF NOT EXISTS is specified. + * *****************************************************************************/ CreateStatsStmt: - CREATE STATISTICS any_name - opt_name_list ON expr_list FROM from_list + CREATE STATISTICS opt_qualified_name + opt_name_list ON stats_params FROM from_list { CreateStatsStmt *n = makeNode(CreateStatsStmt); + n->defnames = $3; n->stat_types = $4; n->exprs = $6; n->relations = $8; n->stxcomment = NULL; n->if_not_exists = false; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE STATISTICS IF_P NOT EXISTS any_name - opt_name_list ON expr_list FROM from_list + opt_name_list ON stats_params FROM from_list { CreateStatsStmt *n = makeNode(CreateStatsStmt); + n->defnames = $6; n->stat_types = $7; n->exprs = $9; n->relations = $11; n->stxcomment = NULL; n->if_not_exists = true; - $$ = (Node *)n; + $$ = (Node *) n; + } + ; + +/* + * Statistics attributes can be either simple column references, or arbitrary + * expressions in parens. For compatibility with index attributes permitted + * in CREATE INDEX, we allow an expression that's just a function call to be + * written without parens. + */ + +stats_params: stats_param { $$ = list_make1($1); } + | stats_params ',' stats_param { $$ = lappend($1, $3); } + ; + +stats_param: ColId + { + $$ = makeNode(StatsElem); + $$->name = $1; + $$->expr = NULL; + } + | func_expr_windowless + { + $$ = makeNode(StatsElem); + $$->name = NULL; + $$->expr = $1; + } + | '(' a_expr ')' + { + $$ = makeNode(StatsElem); + $$->name = NULL; + $$->expr = $2; + } + ; + +/***************************************************************************** + * + * QUERY : + * ALTER STATISTICS [IF EXISTS] stats_name + * SET STATISTICS + * + *****************************************************************************/ + +AlterStatsStmt: + ALTER STATISTICS any_name SET STATISTICS set_statistics_value + { + 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 set_statistics_value + { + AlterStatsStmt *n = makeNode(AlterStatsStmt); + + n->defnames = $5; + n->missing_ok = true; + n->stxstattarget = $8; + $$ = (Node *) n; } ; @@ -4092,9 +4887,10 @@ CreateAsStmt: CREATE OptTemp TABLE create_as_target AS SelectStmt opt_with_data { CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + ctas->query = $6; ctas->into = $4; - ctas->relkind = OBJECT_TABLE; + ctas->objtype = OBJECT_TABLE; ctas->is_select_into = false; ctas->if_not_exists = false; /* cram additional flags into the IntoClause */ @@ -4105,9 +4901,10 @@ CreateAsStmt: | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS SelectStmt opt_with_data { CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + ctas->query = $9; ctas->into = $7; - ctas->relkind = OBJECT_TABLE; + ctas->objtype = OBJECT_TABLE; ctas->is_select_into = false; ctas->if_not_exists = true; /* cram additional flags into the IntoClause */ @@ -4118,14 +4915,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 */ } @@ -4149,9 +4948,10 @@ CreateMatViewStmt: CREATE OptNoLog MATERIALIZED VIEW create_mv_target AS SelectStmt opt_with_data { CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + ctas->query = $7; ctas->into = $5; - ctas->relkind = OBJECT_MATVIEW; + ctas->objtype = OBJECT_MATVIEW; ctas->is_select_into = false; ctas->if_not_exists = false; /* cram additional flags into the IntoClause */ @@ -4162,9 +4962,10 @@ CreateMatViewStmt: | CREATE OptNoLog MATERIALIZED VIEW IF_P NOT EXISTS create_mv_target AS SelectStmt opt_with_data { CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + ctas->query = $10; ctas->into = $8; - ctas->relkind = OBJECT_MATVIEW; + ctas->objtype = OBJECT_MATVIEW; ctas->is_select_into = false; ctas->if_not_exists = true; /* cram additional flags into the IntoClause */ @@ -4175,14 +4976,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 */ } @@ -4204,6 +5006,7 @@ RefreshMatViewStmt: REFRESH MATERIALIZED VIEW opt_concurrently qualified_name opt_with_data { RefreshMatViewStmt *n = makeNode(RefreshMatViewStmt); + n->concurrent = $4; n->relation = $5; n->skipData = !($6); @@ -4224,22 +5027,24 @@ CreateSeqStmt: CREATE OptTemp SEQUENCE qualified_name OptSeqOptList { CreateSeqStmt *n = makeNode(CreateSeqStmt); + $4->relpersistence = $2; n->sequence = $4; n->options = $5; n->ownerId = InvalidOid; n->if_not_exists = false; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE OptTemp SEQUENCE IF_P NOT EXISTS qualified_name OptSeqOptList { CreateSeqStmt *n = makeNode(CreateSeqStmt); + $7->relpersistence = $2; n->sequence = $7; n->options = $8; n->ownerId = InvalidOid; n->if_not_exists = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -4247,18 +5052,20 @@ AlterSeqStmt: ALTER SEQUENCE qualified_name SeqOptList { AlterSeqStmt *n = makeNode(AlterSeqStmt); + n->sequence = $3; n->options = $4; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SEQUENCE IF_P EXISTS qualified_name SeqOptList { AlterSeqStmt *n = makeNode(AlterSeqStmt); + n->sequence = $5; n->options = $6; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -4277,31 +5084,35 @@ SeqOptList: SeqOptElem { $$ = list_make1($1); } SeqOptElem: AS SimpleTypename { - $$ = makeDefElem("as", (Node *)$2, @1); + $$ = makeDefElem("as", (Node *) $2, @1); } | CACHE NumericOnly { - $$ = makeDefElem("cache", (Node *)$2, @1); + $$ = makeDefElem("cache", (Node *) $2, @1); } | CYCLE { - $$ = makeDefElem("cycle", (Node *)makeInteger(true), @1); + $$ = makeDefElem("cycle", (Node *) makeBoolean(true), @1); } | NO CYCLE { - $$ = makeDefElem("cycle", (Node *)makeInteger(false), @1); + $$ = makeDefElem("cycle", (Node *) makeBoolean(false), @1); } | INCREMENT opt_by NumericOnly { - $$ = makeDefElem("increment", (Node *)$3, @1); + $$ = makeDefElem("increment", (Node *) $3, @1); + } + | LOGGED + { + $$ = makeDefElem("logged", NULL, @1); } | MAXVALUE NumericOnly { - $$ = makeDefElem("maxvalue", (Node *)$2, @1); + $$ = makeDefElem("maxvalue", (Node *) $2, @1); } | MINVALUE NumericOnly { - $$ = makeDefElem("minvalue", (Node *)$2, @1); + $$ = makeDefElem("minvalue", (Node *) $2, @1); } | NO MAXVALUE { @@ -4313,16 +5124,15 @@ SeqOptElem: AS SimpleTypename } | OWNED BY any_name { - $$ = makeDefElem("owned_by", (Node *)$3, @1); + $$ = makeDefElem("owned_by", (Node *) $3, @1); } | SEQUENCE NAME_P any_name { - /* not documented, only used by pg_dump */ - $$ = makeDefElem("sequence_name", (Node *)$3, @1); + $$ = makeDefElem("sequence_name", (Node *) $3, @1); } | START opt_with NumericOnly { - $$ = makeDefElem("start", (Node *)$3, @1); + $$ = makeDefElem("start", (Node *) $3, @1); } | RESTART { @@ -4330,23 +5140,29 @@ SeqOptElem: AS SimpleTypename } | RESTART opt_with NumericOnly { - $$ = makeDefElem("restart", (Node *)$3, @1); + $$ = makeDefElem("restart", (Node *) $3, @1); + } + | UNLOGGED + { + $$ = makeDefElem("unlogged", NULL, @1); } ; -opt_by: BY {} - | /* empty */ {} +opt_by: BY + | /* EMPTY */ ; NumericOnly: - FCONST { $$ = makeFloat($1); } - | '+' FCONST { $$ = makeFloat($2); } + FCONST { $$ = (Node *) makeFloat($1); } + | '+' FCONST { $$ = (Node *) makeFloat($2); } | '-' FCONST { - $$ = makeFloat($2); - doNegateFloat($$); + Float *f = makeFloat($2); + + doNegateFloat(f); + $$ = (Node *) f; } - | SignedIconst { $$ = makeInteger($1); } + | SignedIconst { $$ = (Node *) makeInteger($1); } ; NumericOnly_list: NumericOnly { $$ = list_make1($1); } @@ -4362,29 +5178,34 @@ NumericOnly_list: NumericOnly { $$ = list_make1($1); } *****************************************************************************/ CreatePLangStmt: - CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE NonReservedWord_or_Sconst + CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name { - CreatePLangStmt *n = makeNode(CreatePLangStmt); - n->replace = $2; - n->plname = $6; - /* parameters are all to be supplied by system */ - n->plhandler = NIL; - n->plinline = NIL; - n->plvalidator = NIL; - n->pltrusted = false; - $$ = (Node *)n; + /* + * We now interpret parameterless CREATE LANGUAGE as + * CREATE EXTENSION. "OR REPLACE" is silently translated + * to "IF NOT EXISTS", which isn't quite the same, but + * seems more useful than throwing an error. We just + * ignore TRUSTED, as the previous code would have too. + */ + CreateExtensionStmt *n = makeNode(CreateExtensionStmt); + + n->if_not_exists = $2; + n->extname = $6; + n->options = NIL; + $$ = (Node *) n; } - | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE NonReservedWord_or_Sconst + | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name HANDLER handler_name opt_inline_handler opt_validator { CreatePLangStmt *n = makeNode(CreatePLangStmt); + n->replace = $2; n->plname = $6; n->plhandler = $8; n->plinline = $9; n->plvalidator = $10; n->pltrusted = $3; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -4417,32 +5238,9 @@ opt_validator: | /*EMPTY*/ { $$ = NIL; } ; -DropPLangStmt: - DROP opt_procedural LANGUAGE NonReservedWord_or_Sconst opt_drop_behavior - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_LANGUAGE; - n->objects = list_make1(makeString($4)); - n->behavior = $5; - n->missing_ok = false; - n->concurrent = false; - $$ = (Node *)n; - } - | DROP opt_procedural LANGUAGE IF_P EXISTS NonReservedWord_or_Sconst opt_drop_behavior - { - DropStmt *n = makeNode(DropStmt); - n->removeType = OBJECT_LANGUAGE; - n->objects = list_make1(makeString($6)); - n->behavior = $7; - n->missing_ok = true; - n->concurrent = false; - $$ = (Node *)n; - } - ; - opt_procedural: - PROCEDURAL {} - | /*EMPTY*/ {} + PROCEDURAL + | /*EMPTY*/ ; /***************************************************************************** @@ -4455,6 +5253,7 @@ opt_procedural: CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst opt_reloptions { CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt); + n->tablespacename = $3; n->owner = $4; n->location = $6; @@ -4480,6 +5279,7 @@ OptTableSpaceOwner: OWNER RoleSpec { $$ = $2; } DropTableSpaceStmt: DROP TABLESPACE name { DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); + n->tablespacename = $3; n->missing_ok = false; $$ = (Node *) n; @@ -4487,6 +5287,7 @@ DropTableSpaceStmt: DROP TABLESPACE name | DROP TABLESPACE IF_P EXISTS name { DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); + n->tablespacename = $5; n->missing_ok = true; $$ = (Node *) n; @@ -4497,13 +5298,14 @@ DropTableSpaceStmt: DROP TABLESPACE name * * QUERY: * CREATE EXTENSION extension - * [ WITH ] [ SCHEMA schema ] [ VERSION version ] [ FROM oldversion ] + * [ WITH ] [ SCHEMA schema ] [ VERSION version ] * *****************************************************************************/ CreateExtensionStmt: CREATE EXTENSION name opt_with create_extension_opt_list { CreateExtensionStmt *n = makeNode(CreateExtensionStmt); + n->extname = $3; n->if_not_exists = false; n->options = $5; @@ -4512,6 +5314,7 @@ CreateExtensionStmt: CREATE EXTENSION name opt_with create_extension_opt_list | CREATE EXTENSION IF_P NOT EXISTS name opt_with create_extension_opt_list { CreateExtensionStmt *n = makeNode(CreateExtensionStmt); + n->extname = $6; n->if_not_exists = true; n->options = $8; @@ -4529,19 +5332,22 @@ create_extension_opt_list: create_extension_opt_item: SCHEMA name { - $$ = makeDefElem("schema", (Node *)makeString($2), @1); + $$ = makeDefElem("schema", (Node *) makeString($2), @1); } | VERSION_P NonReservedWord_or_Sconst { - $$ = makeDefElem("new_version", (Node *)makeString($2), @1); + $$ = makeDefElem("new_version", (Node *) makeString($2), @1); } | FROM NonReservedWord_or_Sconst { - $$ = makeDefElem("old_version", (Node *)makeString($2), @1); + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE EXTENSION ... FROM is no longer supported"), + parser_errposition(@1))); } | CASCADE { - $$ = makeDefElem("cascade", (Node *)makeInteger(true), @1); + $$ = makeDefElem("cascade", (Node *) makeBoolean(true), @1); } ; @@ -4554,6 +5360,7 @@ create_extension_opt_item: AlterExtensionStmt: ALTER EXTENSION name UPDATE alter_extension_opt_list { AlterExtensionStmt *n = makeNode(AlterExtensionStmt); + n->extname = $3; n->options = $5; $$ = (Node *) n; @@ -4570,7 +5377,7 @@ alter_extension_opt_list: alter_extension_opt_item: TO NonReservedWord_or_Sconst { - $$ = makeDefElem("new_version", (Node *)makeString($2), @1); + $$ = makeDefElem("new_version", (Node *) makeString($2), @1); } ; @@ -4581,257 +5388,135 @@ alter_extension_opt_item: *****************************************************************************/ AlterExtensionContentsStmt: - ALTER EXTENSION name add_drop ACCESS METHOD name + ALTER EXTENSION name add_drop object_type_name name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; - n->objtype = OBJECT_ACCESS_METHOD; - n->object = (Node *) makeString($7); - $$ = (Node *)n; + n->objtype = $5; + n->object = (Node *) makeString($6); + $$ = (Node *) n; } - | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes + | ALTER EXTENSION name add_drop object_type_any_name any_name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; - n->objtype = OBJECT_AGGREGATE; + n->objtype = $5; n->object = (Node *) $6; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')' - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_CAST; - n->object = (Node *) list_make2($7, $9); $$ = (Node *) n; } - | ALTER EXTENSION name add_drop COLLATION any_name + | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; - n->objtype = OBJECT_COLLATION; + n->objtype = OBJECT_AGGREGATE; n->object = (Node *) $6; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER EXTENSION name add_drop CONVERSION_P any_name + | ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')' { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; - n->objtype = OBJECT_CONVERSION; - n->object = (Node *) $6; - $$ = (Node *)n; + n->objtype = OBJECT_CAST; + n->object = (Node *) list_make2($7, $9); + $$ = (Node *) n; } | ALTER EXTENSION name add_drop DOMAIN_P Typename { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_DOMAIN; n->object = (Node *) $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EXTENSION name add_drop FUNCTION function_with_argtypes { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_FUNCTION; n->object = (Node *) $6; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop opt_procedural LANGUAGE name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_LANGUAGE; - n->object = (Node *) makeString($7); - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EXTENSION name add_drop OPERATOR operator_with_argtypes { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_OPERATOR; n->object = (Node *) $6; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING access_method + | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_OPCLASS; n->object = (Node *) lcons(makeString($9), $7); - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING access_method + | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_OPFAMILY; n->object = (Node *) lcons(makeString($9), $7); - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EXTENSION name add_drop PROCEDURE function_with_argtypes { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_PROCEDURE; n->object = (Node *) $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EXTENSION name add_drop ROUTINE function_with_argtypes { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_ROUTINE; n->object = (Node *) $6; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop SCHEMA name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_SCHEMA; - n->object = (Node *) makeString($6); - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop EVENT TRIGGER name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_EVENT_TRIGGER; - n->object = (Node *) makeString($7); - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop TABLE any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_TABLE; - n->object = (Node *) $6; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop TEXT_P SEARCH PARSER any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_TSPARSER; - n->object = (Node *) $8; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop TEXT_P SEARCH DICTIONARY any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_TSDICTIONARY; - n->object = (Node *) $8; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop TEXT_P SEARCH TEMPLATE any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_TSTEMPLATE; - n->object = (Node *) $8; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop TEXT_P SEARCH CONFIGURATION any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_TSCONFIGURATION; - n->object = (Node *) $8; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop SEQUENCE any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_SEQUENCE; - n->object = (Node *) $6; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop VIEW any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_VIEW; - n->object = (Node *) $6; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop MATERIALIZED VIEW any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_MATVIEW; - n->object = (Node *) $7; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop FOREIGN TABLE any_name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_FOREIGN_TABLE; - n->object = (Node *) $7; - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop FOREIGN DATA_P WRAPPER name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_FDW; - n->object = (Node *) makeString($8); - $$ = (Node *)n; - } - | ALTER EXTENSION name add_drop SERVER name - { - AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); - n->extname = $3; - n->action = $4; - n->objtype = OBJECT_FOREIGN_SERVER; - n->object = (Node *) makeString($6); - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EXTENSION name add_drop TRANSFORM FOR Typename LANGUAGE name { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_TRANSFORM; n->object = (Node *) list_make2($7, makeString($9)); - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EXTENSION name add_drop TYPE_P Typename { AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + n->extname = $3; n->action = $4; n->objtype = OBJECT_TYPE; n->object = (Node *) $6; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -4845,6 +5530,7 @@ AlterExtensionContentsStmt: CreateFdwStmt: CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic_options { CreateFdwStmt *n = makeNode(CreateFdwStmt); + n->fdwname = $5; n->func_options = $6; n->options = $7; @@ -4853,9 +5539,9 @@ CreateFdwStmt: CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic ; fdw_option: - HANDLER handler_name { $$ = makeDefElem("handler", (Node *)$2, @1); } + HANDLER handler_name { $$ = makeDefElem("handler", (Node *) $2, @1); } | NO HANDLER { $$ = makeDefElem("handler", NULL, @1); } - | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *)$2, @1); } + | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *) $2, @1); } | NO VALIDATOR { $$ = makeDefElem("validator", NULL, @1); } ; @@ -4879,6 +5565,7 @@ opt_fdw_options: AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_options { AlterFdwStmt *n = makeNode(AlterFdwStmt); + n->fdwname = $5; n->func_options = $6; n->options = $7; @@ -4887,6 +5574,7 @@ AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_op | ALTER FOREIGN DATA_P WRAPPER name fdw_options { AlterFdwStmt *n = makeNode(AlterFdwStmt); + n->fdwname = $5; n->func_options = $6; n->options = NIL; @@ -4975,6 +5663,7 @@ CreateForeignServerStmt: CREATE SERVER name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options { CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt); + n->servername = $3; n->servertype = $4; n->version = $5; @@ -4987,6 +5676,7 @@ CreateForeignServerStmt: CREATE SERVER name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options { CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt); + n->servername = $6; n->servertype = $7; n->version = $8; @@ -5023,6 +5713,7 @@ opt_foreign_server_version: AlterForeignServerStmt: ALTER SERVER name foreign_server_version alter_generic_options { AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); + n->servername = $3; n->version = $4; n->options = $5; @@ -5032,6 +5723,7 @@ AlterForeignServerStmt: ALTER SERVER name foreign_server_version alter_generic_o | ALTER SERVER name foreign_server_version { AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); + n->servername = $3; n->version = $4; n->has_version = true; @@ -5040,6 +5732,7 @@ AlterForeignServerStmt: ALTER SERVER name foreign_server_version alter_generic_o | ALTER SERVER name alter_generic_options { AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); + n->servername = $3; n->options = $4; $$ = (Node *) n; @@ -5059,6 +5752,7 @@ CreateForeignTableStmt: OptInherit SERVER name create_generic_options { CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + $4->relpersistence = RELPERSISTENCE_PERMANENT; n->base.relation = $4; n->base.tableElts = $6; @@ -5079,6 +5773,7 @@ CreateForeignTableStmt: OptInherit SERVER name create_generic_options { CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + $7->relpersistence = RELPERSISTENCE_PERMANENT; n->base.relation = $7; n->base.tableElts = $9; @@ -5099,6 +5794,7 @@ CreateForeignTableStmt: SERVER name create_generic_options { CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + $4->relpersistence = RELPERSISTENCE_PERMANENT; n->base.relation = $4; n->base.inhRelations = list_make1($7); @@ -5120,6 +5816,7 @@ CreateForeignTableStmt: SERVER name create_generic_options { CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + $7->relpersistence = RELPERSISTENCE_PERMANENT; n->base.relation = $7; n->base.inhRelations = list_make1($10); @@ -5141,45 +5838,18 @@ CreateForeignTableStmt: /***************************************************************************** * * QUERY: - * ALTER FOREIGN TABLE relname [...] + * IMPORT FOREIGN SCHEMA remote_schema + * [ { LIMIT TO | EXCEPT } ( table_list ) ] + * FROM SERVER server_name INTO local_schema [ OPTIONS (...) ] * - *****************************************************************************/ - -AlterForeignTableStmt: - ALTER FOREIGN TABLE relation_expr alter_table_cmds - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = $4; - n->cmds = $5; - n->relkind = OBJECT_FOREIGN_TABLE; - n->missing_ok = false; - $$ = (Node *)n; - } - | ALTER FOREIGN TABLE IF_P EXISTS relation_expr alter_table_cmds - { - AlterTableStmt *n = makeNode(AlterTableStmt); - n->relation = $6; - n->cmds = $7; - n->relkind = OBJECT_FOREIGN_TABLE; - n->missing_ok = true; - $$ = (Node *)n; - } - ; - -/***************************************************************************** - * - * QUERY: - * IMPORT FOREIGN SCHEMA remote_schema - * [ { LIMIT TO | EXCEPT } ( table_list ) ] - * FROM SERVER server_name INTO local_schema [ OPTIONS (...) ] - * - ****************************************************************************/ + ****************************************************************************/ ImportForeignSchemaStmt: IMPORT_P FOREIGN SCHEMA name import_qualification FROM SERVER name INTO name create_generic_options { ImportForeignSchemaStmt *n = makeNode(ImportForeignSchemaStmt); + n->server_name = $8; n->remote_schema = $4; n->local_schema = $10; @@ -5191,14 +5861,15 @@ ImportForeignSchemaStmt: ; import_qualification_type: - LIMIT TO { $$ = FDW_IMPORT_SCHEMA_LIMIT_TO; } - | EXCEPT { $$ = FDW_IMPORT_SCHEMA_EXCEPT; } + LIMIT TO { $$ = FDW_IMPORT_SCHEMA_LIMIT_TO; } + | EXCEPT { $$ = FDW_IMPORT_SCHEMA_EXCEPT; } ; import_qualification: import_qualification_type '(' relation_expr_list ')' { ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + n->type = $1; n->table_names = $3; $$ = n; @@ -5222,6 +5893,7 @@ import_qualification: CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options { CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); + n->user = $5; n->servername = $7; n->options = $8; @@ -5231,6 +5903,7 @@ CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_gen | CREATE USER MAPPING IF_P NOT EXISTS FOR auth_ident SERVER name create_generic_options { CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); + n->user = $8; n->servername = $10; n->options = $11; @@ -5256,6 +5929,7 @@ auth_ident: RoleSpec { $$ = $1; } DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name { DropUserMappingStmt *n = makeNode(DropUserMappingStmt); + n->user = $5; n->servername = $7; n->missing_ok = false; @@ -5264,6 +5938,7 @@ DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name | DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name { DropUserMappingStmt *n = makeNode(DropUserMappingStmt); + n->user = $7; n->servername = $9; n->missing_ok = true; @@ -5281,6 +5956,7 @@ DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options { AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt); + n->user = $5; n->servername = $7; n->options = $8; @@ -5307,6 +5983,7 @@ CreatePolicyStmt: RowSecurityOptionalExpr RowSecurityOptionalWithCheck { CreatePolicyStmt *n = makeNode(CreatePolicyStmt); + n->policy_name = $3; n->table = $5; n->permissive = $6; @@ -5323,6 +6000,7 @@ AlterPolicyStmt: RowSecurityOptionalExpr RowSecurityOptionalWithCheck { AlterPolicyStmt *n = makeNode(AlterPolicyStmt); + n->policy_name = $3; n->table = $5; n->roles = $6; @@ -5362,9 +6040,9 @@ RowSecurityDefaultPermissive: else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized row security option \"%s\"", $2), + errmsg("unrecognized row security option \"%s\"", $2), errhint("Only PERMISSIVE or RESTRICTIVE policies are supported currently."), - parser_errposition(@2))); + parser_errposition(@2))); } | /* EMPTY */ { $$ = true; } @@ -5390,16 +6068,22 @@ 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 : @@ -5408,49 +6092,58 @@ CreateAmStmt: CREATE ACCESS METHOD name TYPE_P INDEX HANDLER handler_name *****************************************************************************/ CreateTrigStmt: - CREATE TRIGGER name TriggerActionTime TriggerEvents ON + CREATE opt_or_replace 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; - n->relation = $7; - n->funcname = $13; - n->args = $15; - n->row = $9; - n->timing = $4; - n->events = intVal(linitial($5)); - n->columns = (List *) lsecond($5); - n->whenClause = $10; - n->transitionRels = $8; - n->isconstraint = false; - n->deferrable = false; - n->initdeferred = false; + + n->replace = $2; + n->isconstraint = false; + n->trigname = $4; + n->relation = $8; + n->funcname = $14; + n->args = $16; + n->row = $10; + n->timing = $5; + n->events = intVal(linitial($6)); + n->columns = (List *) lsecond($6); + n->whenClause = $11; + n->transitionRels = $9; + n->deferrable = false; + n->initdeferred = false; n->constrrel = NULL; - $$ = (Node *)n; + $$ = (Node *) n; } - | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON + | CREATE opt_or_replace 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; - n->relation = $8; - n->funcname = $17; - n->args = $19; + + n->replace = $2; + if (n->replace) /* not supported, see CreateTrigger */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE OR REPLACE CONSTRAINT TRIGGER is not supported"), + parser_errposition(@1))); + n->isconstraint = true; + n->trigname = $5; + n->relation = $9; + n->funcname = $18; + n->args = $20; n->row = true; n->timing = TRIGGER_TYPE_AFTER; - n->events = intVal(linitial($6)); - n->columns = (List *) lsecond($6); - n->whenClause = $14; + n->events = intVal(linitial($7)); + n->columns = (List *) lsecond($7); + n->whenClause = $15; n->transitionRels = NIL; - n->isconstraint = true; - processCASbits($10, @10, "TRIGGER", + processCASbits($11, @11, "TRIGGER", &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - n->constrrel = $9; - $$ = (Node *)n; + NULL, NULL, yyscanner); + n->constrrel = $10; + $$ = (Node *) n; } ; @@ -5465,10 +6158,10 @@ TriggerEvents: { $$ = $1; } | TriggerEvents OR TriggerOneEvent { - int events1 = intVal(linitial($1)); - int events2 = intVal(linitial($3)); - List *columns1 = (List *) lsecond($1); - List *columns2 = (List *) lsecond($3); + int events1 = intVal(linitial($1)); + int events2 = intVal(linitial($3)); + List *columns1 = (List *) lsecond($1); + List *columns2 = (List *) lsecond($3); if (events1 & events2) parser_yyerror("duplicate trigger events specified"); @@ -5511,10 +6204,11 @@ TriggerTransition: TransitionOldOrNew TransitionRowOrTable opt_as TransitionRelName { TriggerTransition *n = makeNode(TriggerTransition); + n->name = $4; n->isNew = $1; n->isTable = $2; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -5556,8 +6250,8 @@ TriggerForSpec: ; TriggerForOptEach: - EACH {} - | /*EMPTY*/ {} + EACH + | /*EMPTY*/ ; TriggerForType: @@ -5570,6 +6264,11 @@ TriggerWhen: | /*EMPTY*/ { $$ = NULL; } ; +FUNCTION_or_PROCEDURE: + FUNCTION + | PROCEDURE + ; + TriggerFuncArgs: TriggerFuncArg { $$ = list_make1($1); } | TriggerFuncArgs ',' TriggerFuncArg { $$ = lappend($1, $3); } @@ -5579,11 +6278,11 @@ TriggerFuncArgs: TriggerFuncArg: Iconst { - $$ = makeString(psprintf("%d", $1)); + $$ = (Node *) makeString(psprintf("%d", $1)); } - | FCONST { $$ = makeString($1); } - | Sconst { $$ = makeString($1); } - | ColLabel { $$ = makeString($1); } + | FCONST { $$ = (Node *) makeString($1); } + | Sconst { $$ = (Node *) makeString($1); } + | ColLabel { $$ = (Node *) makeString($1); } ; OptConstrFromTable: @@ -5611,7 +6310,8 @@ ConstraintAttributeSpec: parser_errposition(@2))); /* generic message for other conflicts */ if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) || - (newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) + (newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED) || + (newspec & (CAS_NOT_ENFORCED | CAS_ENFORCED)) == (CAS_NOT_ENFORCED | CAS_ENFORCED)) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting constraint properties"), @@ -5627,6 +6327,8 @@ ConstraintAttributeElem: | INITIALLY DEFERRED { $$ = CAS_INITIALLY_DEFERRED; } | NOT VALID { $$ = CAS_NOT_VALID; } | NO INHERIT { $$ = CAS_NO_INHERIT; } + | NOT ENFORCED { $$ = CAS_NOT_ENFORCED; } + | ENFORCED { $$ = CAS_ENFORCED; } ; @@ -5640,25 +6342,27 @@ 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; n->eventname = $6; n->whenclause = NULL; n->funcname = $9; - $$ = (Node *)n; + $$ = (Node *) n; } | 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; n->eventname = $6; n->whenclause = $8; n->funcname = $11; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -5685,6 +6389,7 @@ AlterEventTrigStmt: ALTER EVENT TRIGGER name enable_trigger { AlterEventTrigStmt *n = makeNode(AlterEventTrigStmt); + n->trigname = $4; n->tgenabled = $5; $$ = (Node *) n; @@ -5700,43 +6405,20 @@ 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; - } - ; + errmsg("CREATE ASSERTION is not yet implemented"), + parser_errposition(@1))); -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; } ; @@ -5749,57 +6431,64 @@ 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; - $$ = (Node *)n; + 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; - $$ = (Node *)n; + n->definition = $5; + $$ = (Node *) n; } | CREATE OPERATOR any_operator definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_OPERATOR; n->oldstyle = false; n->defnames = $3; n->args = NIL; n->definition = $4; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TYPE_P any_name definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_TYPE; n->oldstyle = false; n->defnames = $3; n->args = NIL; n->definition = $4; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TYPE_P any_name { /* Shell type (identified by lack of definition) */ DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_TYPE; n->oldstyle = false; n->defnames = $3; n->args = NIL; n->definition = NIL; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TYPE_P any_name AS '(' OptTableFuncElementList ')' { @@ -5808,95 +6497,105 @@ DefineStmt: /* can't use qualified_name, sigh */ n->typevar = makeRangeVarFromAnyName($3, @3, yyscanner); n->coldeflist = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TYPE_P any_name AS ENUM_P '(' opt_enum_val_list ')' { CreateEnumStmt *n = makeNode(CreateEnumStmt); + n->typeName = $3; n->vals = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TYPE_P any_name AS RANGE definition { CreateRangeStmt *n = makeNode(CreateRangeStmt); + n->typeName = $3; - n->params = $6; - $$ = (Node *)n; + n->params = $6; + $$ = (Node *) n; } | CREATE TEXT_P SEARCH PARSER any_name definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_TSPARSER; n->args = NIL; n->defnames = $5; n->definition = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TEXT_P SEARCH DICTIONARY any_name definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_TSDICTIONARY; n->args = NIL; n->defnames = $5; n->definition = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TEXT_P SEARCH TEMPLATE any_name definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_TSTEMPLATE; n->args = NIL; n->defnames = $5; n->definition = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE TEXT_P SEARCH CONFIGURATION any_name definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_TSCONFIGURATION; n->args = NIL; n->defnames = $5; n->definition = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE COLLATION any_name definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_COLLATION; n->args = NIL; n->defnames = $3; n->definition = $4; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE COLLATION IF_P NOT EXISTS any_name definition { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_COLLATION; n->args = NIL; n->defnames = $6; n->definition = $7; n->if_not_exists = true; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE COLLATION any_name FROM any_name { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_COLLATION; n->args = NIL; n->defnames = $3; n->definition = list_make1(makeDefElem("from", (Node *) $5, @5)); - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name { DefineStmt *n = makeNode(DefineStmt); + n->kind = OBJECT_COLLATION; n->args = NIL; n->defnames = $6; n->definition = list_make1(makeDefElem("from", (Node *) $8, @8)); n->if_not_exists = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -5918,12 +6617,12 @@ def_elem: ColLabel '=' def_arg ; /* Note: any simple identifier will be returned as a type name! */ -def_arg: func_type { $$ = (Node *)$1; } - | reserved_keyword { $$ = (Node *)makeString(pstrdup($1)); } - | qual_all_Op { $$ = (Node *)$1; } - | NumericOnly { $$ = (Node *)$1; } - | Sconst { $$ = (Node *)makeString($1); } - | NONE { $$ = (Node *)makeString(pstrdup($1)); } +def_arg: func_type { $$ = (Node *) $1; } + | reserved_keyword { $$ = (Node *) makeString(pstrdup($1)); } + | qual_all_Op { $$ = (Node *) $1; } + | NumericOnly { $$ = (Node *) $1; } + | Sconst { $$ = (Node *) makeString($1); } + | NONE { $$ = (Node *) makeString(pstrdup($1)); } ; old_aggr_definition: '(' old_aggr_list ')' { $$ = $2; } @@ -5940,7 +6639,7 @@ old_aggr_list: old_aggr_elem { $$ = list_make1($1); } */ old_aggr_elem: IDENT '=' def_arg { - $$ = makeDefElem($1, (Node *)$3, @1); + $$ = makeDefElem($1, (Node *) $3, @1); } ; @@ -5965,6 +6664,7 @@ AlterEnumStmt: ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); + n->typeName = $3; n->oldVal = NULL; n->newVal = $7; @@ -5976,6 +6676,7 @@ AlterEnumStmt: | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst BEFORE Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); + n->typeName = $3; n->oldVal = NULL; n->newVal = $7; @@ -5987,6 +6688,7 @@ AlterEnumStmt: | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst AFTER Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); + n->typeName = $3; n->oldVal = NULL; n->newVal = $7; @@ -5998,6 +6700,7 @@ AlterEnumStmt: | ALTER TYPE_P any_name RENAME VALUE_P Sconst TO Sconst { AlterEnumStmt *n = makeNode(AlterEnumStmt); + n->typeName = $3; n->oldVal = $6; n->newVal = $8; @@ -6006,10 +6709,37 @@ AlterEnumStmt: n->skipIfNewValExists = false; $$ = (Node *) n; } + | ALTER TYPE_P any_name DROP VALUE_P Sconst + { + /* + * The following problems must be solved before this can be + * implemented: + * + * - There must be no instance of the target value in + * any table. + * + * - The value must not appear in any catalog metadata, + * such as stored view expressions or column defaults. + * + * - The value must not appear in any non-leaf page of a + * btree (and similar issues with other index types). + * This is problematic because a value could persist + * there long after it's gone from user-visible data. + * + * - Concurrent sessions must not be able to insert the + * value while the preceding conditions are being checked. + * + * - Possibly more... + */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("dropping an enum value is not implemented"), + parser_errposition(@4))); + } ; opt_if_not_exists: IF_P NOT EXISTS { $$ = true; } - | /* empty */ { $$ = false; } + | /* EMPTY */ { $$ = false; } ; @@ -6026,9 +6756,10 @@ opt_if_not_exists: IF_P NOT EXISTS { $$ = true; } CreateOpClassStmt: CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename - USING access_method opt_opfamily AS opclass_item_list + USING name opt_opfamily AS opclass_item_list { CreateOpClassStmt *n = makeNode(CreateOpClassStmt); + n->opclassname = $4; n->isDefault = $5; n->datatype = $8; @@ -6045,10 +6776,11 @@ opclass_item_list: ; opclass_item: - OPERATOR Iconst any_operator opclass_purpose opt_recheck + OPERATOR Iconst any_operator opclass_purpose { CreateOpClassItem *n = makeNode(CreateOpClassItem); ObjectWithArgs *owa = makeNode(ObjectWithArgs); + owa->objname = $3; owa->objargs = NIL; n->itemtype = OPCLASS_ITEM_OPERATOR; @@ -6058,9 +6790,9 @@ opclass_item: $$ = (Node *) n; } | OPERATOR Iconst operator_with_argtypes opclass_purpose - opt_recheck { CreateOpClassItem *n = makeNode(CreateOpClassItem); + n->itemtype = OPCLASS_ITEM_OPERATOR; n->name = $3; n->number = $2; @@ -6070,6 +6802,7 @@ opclass_item: | FUNCTION Iconst function_with_argtypes { CreateOpClassItem *n = makeNode(CreateOpClassItem); + n->itemtype = OPCLASS_ITEM_FUNCTION; n->name = $3; n->number = $2; @@ -6078,6 +6811,7 @@ opclass_item: | FUNCTION Iconst '(' type_list ')' function_with_argtypes { CreateOpClassItem *n = makeNode(CreateOpClassItem); + n->itemtype = OPCLASS_ITEM_FUNCTION; n->name = $6; n->number = $2; @@ -6087,6 +6821,7 @@ opclass_item: | STORAGE Typename { CreateOpClassItem *n = makeNode(CreateOpClassItem); + n->itemtype = OPCLASS_ITEM_STORAGETYPE; n->storedtype = $2; $$ = (Node *) n; @@ -6106,28 +6841,12 @@ opclass_purpose: FOR SEARCH { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; } ; -opt_recheck: RECHECK - { - /* - * RECHECK no longer does anything in opclass definitions, - * but we still accept it to ease porting of old database - * dumps. - */ - ereport(NOTICE, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("RECHECK is no longer required"), - errhint("Update your data type."), - parser_errposition(@1))); - $$ = true; - } - | /*EMPTY*/ { $$ = false; } - ; - CreateOpFamilyStmt: - CREATE OPERATOR FAMILY any_name USING access_method + CREATE OPERATOR FAMILY any_name USING name { CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt); + n->opfamilyname = $4; n->amname = $6; $$ = (Node *) n; @@ -6135,18 +6854,20 @@ CreateOpFamilyStmt: ; AlterOpFamilyStmt: - ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list + ALTER OPERATOR FAMILY any_name USING name ADD_P opclass_item_list { AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); + n->opfamilyname = $4; n->amname = $6; n->isDrop = false; n->items = $8; $$ = (Node *) n; } - | ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list + | ALTER OPERATOR FAMILY any_name USING name DROP opclass_drop_list { AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); + n->opfamilyname = $4; n->amname = $6; n->isDrop = true; @@ -6164,6 +6885,7 @@ opclass_drop: OPERATOR Iconst '(' type_list ')' { CreateOpClassItem *n = makeNode(CreateOpClassItem); + n->itemtype = OPCLASS_ITEM_OPERATOR; n->number = $2; n->class_args = $4; @@ -6172,6 +6894,7 @@ opclass_drop: | FUNCTION Iconst '(' type_list ')' { CreateOpClassItem *n = makeNode(CreateOpClassItem); + n->itemtype = OPCLASS_ITEM_FUNCTION; n->number = $2; n->class_args = $4; @@ -6181,9 +6904,10 @@ opclass_drop: DropOpClassStmt: - DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior + DROP OPERATOR CLASS any_name USING name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->objects = list_make1(lcons(makeString($6), $4)); n->removeType = OBJECT_OPCLASS; n->behavior = $7; @@ -6191,9 +6915,10 @@ DropOpClassStmt: n->concurrent = false; $$ = (Node *) n; } - | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior + | DROP OPERATOR CLASS IF_P EXISTS any_name USING name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->objects = list_make1(lcons(makeString($8), $6)); n->removeType = OBJECT_OPCLASS; n->behavior = $9; @@ -6204,9 +6929,10 @@ DropOpClassStmt: ; DropOpFamilyStmt: - DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior + DROP OPERATOR FAMILY any_name USING name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->objects = list_make1(lcons(makeString($6), $4)); n->removeType = OBJECT_OPFAMILY; n->behavior = $7; @@ -6214,9 +6940,10 @@ DropOpFamilyStmt: n->concurrent = false; $$ = (Node *) n; } - | DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior + | DROP OPERATOR FAMILY IF_P EXISTS any_name USING name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->objects = list_make1(lcons(makeString($8), $6)); n->removeType = OBJECT_OPFAMILY; n->behavior = $9; @@ -6239,9 +6966,10 @@ DropOwnedStmt: DROP OWNED BY role_list opt_drop_behavior { DropOwnedStmt *n = makeNode(DropOwnedStmt); + n->roles = $4; n->behavior = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -6249,9 +6977,10 @@ ReassignOwnedStmt: REASSIGN OWNED BY role_list TO RoleSpec { ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt); + n->roles = $4; n->newrole = $6; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -6264,49 +6993,54 @@ ReassignOwnedStmt: * *****************************************************************************/ -DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior +DropStmt: DROP object_type_any_name IF_P EXISTS any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = $2; n->missing_ok = true; n->objects = $5; n->behavior = $6; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | DROP drop_type_any_name any_name_list opt_drop_behavior + | DROP object_type_any_name any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = $2; n->missing_ok = false; n->objects = $3; n->behavior = $4; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP drop_type_name IF_P EXISTS name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = $2; n->missing_ok = true; n->objects = $5; n->behavior = $6; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP drop_type_name name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = $2; n->missing_ok = false; n->objects = $3; n->behavior = $4; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | DROP drop_type_name_on_any_name name ON any_name opt_drop_behavior + | DROP object_type_name_on_any_name name ON any_name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = $2; n->objects = list_make1(lappend($5, makeString($3))); n->behavior = $6; @@ -6314,9 +7048,10 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior n->concurrent = false; $$ = (Node *) n; } - | DROP drop_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior + | DROP object_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = $2; n->objects = list_make1(lappend($7, makeString($5))); n->behavior = $8; @@ -6327,6 +7062,7 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior | DROP TYPE_P type_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_TYPE; n->missing_ok = false; n->objects = $3; @@ -6337,6 +7073,7 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior | DROP TYPE_P IF_P EXISTS type_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_TYPE; n->missing_ok = true; n->objects = $5; @@ -6347,6 +7084,7 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior | DROP DOMAIN_P type_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_DOMAIN; n->missing_ok = false; n->objects = $3; @@ -6357,6 +7095,7 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior | DROP DOMAIN_P IF_P EXISTS type_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_DOMAIN; n->missing_ok = true; n->objects = $5; @@ -6367,27 +7106,29 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior | DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_INDEX; n->missing_ok = false; n->objects = $4; n->behavior = $5; n->concurrent = true; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP INDEX CONCURRENTLY IF_P EXISTS any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_INDEX; n->missing_ok = true; n->objects = $6; n->behavior = $7; n->concurrent = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; -/* object types taking any_name_list */ -drop_type_any_name: +/* object types taking any_name/any_name_list */ +object_type_any_name: TABLE { $$ = OBJECT_TABLE; } | SEQUENCE { $$ = OBJECT_SEQUENCE; } | VIEW { $$ = OBJECT_VIEW; } @@ -6403,19 +7144,33 @@ drop_type_any_name: | TEXT_P SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; } ; -/* object types taking name_list */ +/* + * object types taking name/name_list + * + * DROP handles some of them separately + */ + +object_type_name: + drop_type_name { $$ = $1; } + | DATABASE { $$ = OBJECT_DATABASE; } + | ROLE { $$ = OBJECT_ROLE; } + | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; } + | TABLESPACE { $$ = OBJECT_TABLESPACE; } + ; + drop_type_name: ACCESS METHOD { $$ = OBJECT_ACCESS_METHOD; } | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } | EXTENSION { $$ = OBJECT_EXTENSION; } | FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; } + | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; } | PUBLICATION { $$ = OBJECT_PUBLICATION; } | SCHEMA { $$ = OBJECT_SCHEMA; } | SERVER { $$ = OBJECT_FOREIGN_SERVER; } ; /* object types attached to a table */ -drop_type_name_on_any_name: +object_type_name_on_any_name: POLICY { $$ = OBJECT_POLICY; } | RULE { $$ = OBJECT_RULE; } | TRIGGER { $$ = OBJECT_TRIGGER; } @@ -6439,6 +7194,7 @@ attrs: '.' attr_name type_name_list: Typename { $$ = list_make1($1); } | type_name_list ',' Typename { $$ = lappend($1, $3); } + ; /***************************************************************************** * @@ -6451,10 +7207,11 @@ TruncateStmt: TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior { TruncateStmt *n = makeNode(TruncateStmt); + n->relations = $3; n->restart_seqs = $4; n->behavior = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -6466,46 +7223,33 @@ opt_restart_seqs: /***************************************************************************** * - * The COMMENT ON statement can take different forms based upon the type of - * the object associated with the comment. The form of the statement is: - * - * COMMENT ON [ [ ACCESS METHOD | CONVERSION | COLLATION | - * DATABASE | DOMAIN | - * EXTENSION | EVENT TRIGGER | FOREIGN DATA WRAPPER | - * FOREIGN TABLE | INDEX | [PROCEDURAL] LANGUAGE | - * MATERIALIZED VIEW | POLICY | ROLE | SCHEMA | SEQUENCE | - * SERVER | TABLE | TABLESPACE | - * TEXT SEARCH CONFIGURATION | TEXT SEARCH DICTIONARY | - * TEXT SEARCH PARSER | TEXT SEARCH TEMPLATE | TYPE | - * VIEW] | - * AGGREGATE (arg1, ...) | - * CAST ( AS ) | - * COLUMN . | - * CONSTRAINT ON | - * CONSTRAINT ON DOMAIN | - * FUNCTION (arg1, arg2, ...) | - * LARGE OBJECT | - * OPERATOR (leftoperand_typ, rightoperand_typ) | - * OPERATOR CLASS USING | - * OPERATOR FAMILY USING | - * RULE ON | - * TRIGGER ON ] - * IS { 'text' | NULL } + * COMMENT ON IS * *****************************************************************************/ CommentStmt: - COMMENT ON comment_type_any_name any_name IS comment_text + COMMENT ON object_type_any_name any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = $3; n->object = (Node *) $4; n->comment = $6; $$ = (Node *) n; } - | COMMENT ON comment_type_name name IS comment_text + | COMMENT ON COLUMN any_name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_COLUMN; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON object_type_name name IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = $3; n->object = (Node *) makeString($4); n->comment = $6; @@ -6514,6 +7258,7 @@ CommentStmt: | COMMENT ON TYPE_P Typename IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_TYPE; n->object = (Node *) $4; n->comment = $6; @@ -6522,6 +7267,7 @@ CommentStmt: | COMMENT ON DOMAIN_P Typename IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_DOMAIN; n->object = (Node *) $4; n->comment = $6; @@ -6530,6 +7276,7 @@ CommentStmt: | COMMENT ON AGGREGATE aggregate_with_argtypes IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_AGGREGATE; n->object = (Node *) $4; n->comment = $6; @@ -6538,6 +7285,7 @@ CommentStmt: | COMMENT ON FUNCTION function_with_argtypes IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_FUNCTION; n->object = (Node *) $4; n->comment = $6; @@ -6546,6 +7294,7 @@ CommentStmt: | COMMENT ON OPERATOR operator_with_argtypes IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_OPERATOR; n->object = (Node *) $4; n->comment = $6; @@ -6554,6 +7303,7 @@ CommentStmt: | COMMENT ON CONSTRAINT name ON any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_TABCONSTRAINT; n->object = (Node *) lappend($6, makeString($4)); n->comment = $8; @@ -6562,6 +7312,7 @@ CommentStmt: | COMMENT ON CONSTRAINT name ON DOMAIN_P any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_DOMCONSTRAINT; /* * should use Typename not any_name in the production, but @@ -6572,10 +7323,11 @@ CommentStmt: n->comment = $9; $$ = (Node *) n; } - | COMMENT ON POLICY name ON any_name IS comment_text + | COMMENT ON object_type_name_on_any_name name ON any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_POLICY; + + n->objtype = $3; n->object = (Node *) lappend($6, makeString($4)); n->comment = $8; $$ = (Node *) n; @@ -6583,6 +7335,7 @@ CommentStmt: | COMMENT ON PROCEDURE function_with_argtypes IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_PROCEDURE; n->object = (Node *) $4; n->comment = $6; @@ -6591,46 +7344,34 @@ CommentStmt: | COMMENT ON ROUTINE function_with_argtypes IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_ROUTINE; n->object = (Node *) $4; n->comment = $6; $$ = (Node *) n; } - | COMMENT ON RULE name ON any_name IS comment_text - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_RULE; - n->object = (Node *) lappend($6, makeString($4)); - n->comment = $8; - $$ = (Node *) n; - } | COMMENT ON TRANSFORM FOR Typename LANGUAGE name IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_TRANSFORM; n->object = (Node *) list_make2($5, makeString($7)); n->comment = $9; $$ = (Node *) n; } - | COMMENT ON TRIGGER name ON any_name IS comment_text - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_TRIGGER; - n->object = (Node *) lappend($6, makeString($4)); - n->comment = $8; - $$ = (Node *) n; - } - | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text + | COMMENT ON OPERATOR CLASS any_name USING name IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_OPCLASS; n->object = (Node *) lcons(makeString($7), $5); n->comment = $9; $$ = (Node *) n; } - | COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text + | COMMENT ON OPERATOR FAMILY any_name USING name IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_OPFAMILY; n->object = (Node *) lcons(makeString($7), $5); n->comment = $9; @@ -6639,6 +7380,7 @@ CommentStmt: | COMMENT ON LARGE_P OBJECT_P NumericOnly IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_LARGEOBJECT; n->object = (Node *) $5; n->comment = $7; @@ -6647,6 +7389,7 @@ CommentStmt: | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text { CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_CAST; n->object = (Node *) list_make2($5, $7); n->comment = $10; @@ -6654,40 +7397,6 @@ CommentStmt: } ; -/* object types taking any_name */ -comment_type_any_name: - COLUMN { $$ = OBJECT_COLUMN; } - | INDEX { $$ = OBJECT_INDEX; } - | SEQUENCE { $$ = OBJECT_SEQUENCE; } - | STATISTICS { $$ = OBJECT_STATISTIC_EXT; } - | TABLE { $$ = OBJECT_TABLE; } - | VIEW { $$ = OBJECT_VIEW; } - | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } - | COLLATION { $$ = OBJECT_COLLATION; } - | CONVERSION_P { $$ = OBJECT_CONVERSION; } - | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } - | TEXT_P SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; } - | TEXT_P SEARCH DICTIONARY { $$ = OBJECT_TSDICTIONARY; } - | TEXT_P SEARCH PARSER { $$ = OBJECT_TSPARSER; } - | TEXT_P SEARCH TEMPLATE { $$ = OBJECT_TSTEMPLATE; } - ; - -/* object types taking name */ -comment_type_name: - ACCESS METHOD { $$ = OBJECT_ACCESS_METHOD; } - | DATABASE { $$ = OBJECT_DATABASE; } - | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } - | EXTENSION { $$ = OBJECT_EXTENSION; } - | FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; } - | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; } - | PUBLICATION { $$ = OBJECT_PUBLICATION; } - | ROLE { $$ = OBJECT_ROLE; } - | SCHEMA { $$ = OBJECT_SCHEMA; } - | SERVER { $$ = OBJECT_FOREIGN_SERVER; } - | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; } - | TABLESPACE { $$ = OBJECT_TABLESPACE; } - ; - comment_text: Sconst { $$ = $1; } | NULL_P { $$ = NULL; } @@ -6704,20 +7413,33 @@ comment_text: *****************************************************************************/ SecLabelStmt: - SECURITY LABEL opt_provider ON security_label_type_any_name any_name + SECURITY LABEL opt_provider ON object_type_any_name any_name IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = $5; n->object = (Node *) $6; n->label = $8; $$ = (Node *) n; } - | SECURITY LABEL opt_provider ON security_label_type_name name + | SECURITY LABEL opt_provider ON COLUMN any_name + IS security_label + { + SecLabelStmt *n = makeNode(SecLabelStmt); + + n->provider = $3; + n->objtype = OBJECT_COLUMN; + n->object = (Node *) $6; + n->label = $8; + $$ = (Node *) n; + } + | SECURITY LABEL opt_provider ON object_type_name name IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = $5; n->object = (Node *) makeString($6); @@ -6728,6 +7450,7 @@ SecLabelStmt: IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = OBJECT_TYPE; n->object = (Node *) $6; @@ -6738,6 +7461,7 @@ SecLabelStmt: IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = OBJECT_DOMAIN; n->object = (Node *) $6; @@ -6748,6 +7472,7 @@ SecLabelStmt: IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = OBJECT_AGGREGATE; n->object = (Node *) $6; @@ -6758,6 +7483,7 @@ SecLabelStmt: IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = OBJECT_FUNCTION; n->object = (Node *) $6; @@ -6768,6 +7494,7 @@ SecLabelStmt: IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = OBJECT_LARGEOBJECT; n->object = (Node *) $7; @@ -6778,6 +7505,7 @@ SecLabelStmt: IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = OBJECT_PROCEDURE; n->object = (Node *) $6; @@ -6788,6 +7516,7 @@ SecLabelStmt: IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; n->objtype = OBJECT_ROUTINE; n->object = (Node *) $6; @@ -6797,29 +7526,7 @@ SecLabelStmt: ; opt_provider: FOR NonReservedWord_or_Sconst { $$ = $2; } - | /* empty */ { $$ = NULL; } - ; - -/* object types taking any_name */ -security_label_type_any_name: - COLUMN { $$ = OBJECT_COLUMN; } - | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } - | SEQUENCE { $$ = OBJECT_SEQUENCE; } - | TABLE { $$ = OBJECT_TABLE; } - | VIEW { $$ = OBJECT_VIEW; } - | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } - ; - -/* object types taking name */ -security_label_type_name: - DATABASE { $$ = OBJECT_DATABASE; } - | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } - | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; } - | PUBLICATION { $$ = OBJECT_PUBLICATION; } - | ROLE { $$ = OBJECT_ROLE; } - | SCHEMA { $$ = OBJECT_SCHEMA; } - | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; } - | TABLESPACE { $$ = OBJECT_TABLESPACE; } + | /* EMPTY */ { $$ = NULL; } ; security_label: Sconst { $$ = $1; } @@ -6836,153 +7543,171 @@ security_label: Sconst { $$ = $1; } FetchStmt: FETCH fetch_args { FetchStmt *n = (FetchStmt *) $2; + n->ismove = false; - $$ = (Node *)n; + $$ = (Node *) n; } | MOVE fetch_args { FetchStmt *n = (FetchStmt *) $2; + n->ismove = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; fetch_args: cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $1; n->direction = FETCH_FORWARD; n->howMany = 1; - $$ = (Node *)n; + $$ = (Node *) n; } | from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $2; n->direction = FETCH_FORWARD; n->howMany = 1; - $$ = (Node *)n; + $$ = (Node *) n; } | NEXT opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; - $$ = (Node *)n; + $$ = (Node *) n; } | PRIOR opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; - $$ = (Node *)n; + $$ = (Node *) n; } | FIRST_P opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = 1; - $$ = (Node *)n; + $$ = (Node *) n; } | LAST_P opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_ABSOLUTE; n->howMany = -1; - $$ = (Node *)n; + $$ = (Node *) n; } | ABSOLUTE_P SignedIconst opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $4; n->direction = FETCH_ABSOLUTE; n->howMany = $2; - $$ = (Node *)n; + $$ = (Node *) n; } | RELATIVE_P SignedIconst opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $4; n->direction = FETCH_RELATIVE; n->howMany = $2; - $$ = (Node *)n; + $$ = (Node *) n; } | SignedIconst opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = $1; - $$ = (Node *)n; + $$ = (Node *) n; } | ALL opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; - $$ = (Node *)n; + $$ = (Node *) n; } | FORWARD opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_FORWARD; n->howMany = 1; - $$ = (Node *)n; + $$ = (Node *) n; } | FORWARD SignedIconst opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = $2; - $$ = (Node *)n; + $$ = (Node *) n; } | FORWARD ALL opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $4; n->direction = FETCH_FORWARD; n->howMany = FETCH_ALL; - $$ = (Node *)n; + $$ = (Node *) n; } | BACKWARD opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $3; n->direction = FETCH_BACKWARD; n->howMany = 1; - $$ = (Node *)n; + $$ = (Node *) n; } | BACKWARD SignedIconst opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = $2; - $$ = (Node *)n; + $$ = (Node *) n; } | BACKWARD ALL opt_from_in cursor_name { FetchStmt *n = makeNode(FetchStmt); + n->portalname = $4; n->direction = FETCH_BACKWARD; n->howMany = FETCH_ALL; - $$ = (Node *)n; + $$ = (Node *) n; } ; -from_in: FROM {} - | IN_P {} +from_in: FROM + | IN_P ; -opt_from_in: from_in {} - | /* EMPTY */ {} +opt_from_in: from_in + | /* EMPTY */ ; @@ -6993,9 +7718,10 @@ opt_from_in: from_in {} *****************************************************************************/ GrantStmt: GRANT privileges ON privilege_target TO grantee_list - opt_grant_grant_option + opt_grant_grant_option opt_granted_by { GrantStmt *n = makeNode(GrantStmt); + n->is_grant = true; n->privileges = $2; n->targtype = ($4)->targtype; @@ -7003,15 +7729,17 @@ GrantStmt: GRANT privileges ON privilege_target TO grantee_list n->objects = ($4)->objs; n->grantees = $6; n->grant_option = $7; - $$ = (Node*)n; + n->grantor = $8; + $$ = (Node *) n; } ; RevokeStmt: REVOKE privileges ON privilege_target - FROM grantee_list opt_drop_behavior + FROM grantee_list opt_granted_by opt_drop_behavior { GrantStmt *n = makeNode(GrantStmt); + n->is_grant = false; n->grant_option = false; n->privileges = $2; @@ -7019,13 +7747,15 @@ RevokeStmt: n->objtype = ($4)->objtype; n->objects = ($4)->objs; n->grantees = $6; - n->behavior = $7; - $$ = (Node *)n; + n->grantor = $7; + n->behavior = $8; + $$ = (Node *) n; } | REVOKE GRANT OPTION FOR privileges ON privilege_target - FROM grantee_list opt_drop_behavior + FROM grantee_list opt_granted_by opt_drop_behavior { GrantStmt *n = makeNode(GrantStmt); + n->is_grant = false; n->grant_option = true; n->privileges = $5; @@ -7033,8 +7763,9 @@ RevokeStmt: n->objtype = ($7)->objtype; n->objects = ($7)->objs; n->grantees = $9; - n->behavior = $10; - $$ = (Node *)n; + n->grantor = $10; + n->behavior = $11; + $$ = (Node *) n; } ; @@ -7057,6 +7788,7 @@ privileges: privilege_list | ALL '(' columnList ')' { AccessPriv *n = makeNode(AccessPriv); + n->priv_name = NULL; n->cols = $3; $$ = list_make1(n); @@ -7064,6 +7796,7 @@ privileges: privilege_list | ALL PRIVILEGES '(' columnList ')' { AccessPriv *n = makeNode(AccessPriv); + n->priv_name = NULL; n->cols = $4; $$ = list_make1(n); @@ -7077,6 +7810,7 @@ privilege_list: privilege { $$ = list_make1($1); } privilege: SELECT opt_column_list { AccessPriv *n = makeNode(AccessPriv); + n->priv_name = pstrdup($1); n->cols = $2; $$ = n; @@ -7084,6 +7818,7 @@ privilege: SELECT opt_column_list | REFERENCES opt_column_list { AccessPriv *n = makeNode(AccessPriv); + n->priv_name = pstrdup($1); n->cols = $2; $$ = n; @@ -7091,19 +7826,50 @@ privilege: SELECT opt_column_list | CREATE opt_column_list { AccessPriv *n = makeNode(AccessPriv); + n->priv_name = pstrdup($1); n->cols = $2; $$ = n; } + | ALTER SYSTEM_P + { + AccessPriv *n = makeNode(AccessPriv); + n->priv_name = pstrdup("alter system"); + n->cols = NIL; + $$ = n; + } | ColId opt_column_list { AccessPriv *n = makeNode(AccessPriv); + n->priv_name = $1; n->cols = $2; $$ = n; } ; +parameter_name_list: + parameter_name + { + $$ = list_make1(makeString($1)); + } + | parameter_name_list ',' parameter_name + { + $$ = lappend($1, makeString($3)); + } + ; + +parameter_name: + ColId + { + $$ = $1; + } + | parameter_name '.' ColId + { + $$ = psprintf("%s.%s", $1, $3); + } + ; + /* Don't bother trying to fold the first two rules into one using * opt_table. You're going to get conflicts. @@ -7112,6 +7878,7 @@ privilege_target: qualified_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; n->objs = $1; @@ -7120,6 +7887,7 @@ privilege_target: | TABLE qualified_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLE; n->objs = $2; @@ -7128,6 +7896,7 @@ privilege_target: | SEQUENCE qualified_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SEQUENCE; n->objs = $2; @@ -7136,6 +7905,7 @@ privilege_target: | FOREIGN DATA_P WRAPPER name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FDW; n->objs = $4; @@ -7144,6 +7914,7 @@ privilege_target: | FOREIGN SERVER name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FOREIGN_SERVER; n->objs = $3; @@ -7152,6 +7923,7 @@ privilege_target: | FUNCTION function_with_argtypes_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_FUNCTION; n->objs = $2; @@ -7160,6 +7932,7 @@ privilege_target: | PROCEDURE function_with_argtypes_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_PROCEDURE; n->objs = $2; @@ -7168,6 +7941,7 @@ privilege_target: | ROUTINE function_with_argtypes_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_ROUTINE; n->objs = $2; @@ -7176,6 +7950,7 @@ privilege_target: | DATABASE name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DATABASE; n->objs = $2; @@ -7184,6 +7959,7 @@ privilege_target: | DOMAIN_P any_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_DOMAIN; n->objs = $2; @@ -7192,6 +7968,7 @@ privilege_target: | LANGUAGE name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LANGUAGE; n->objs = $2; @@ -7200,14 +7977,24 @@ privilege_target: | LARGE_P OBJECT_P NumericOnly_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_LARGEOBJECT; n->objs = $3; $$ = n; } + | PARAMETER parameter_name_list + { + PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; + n->objtype = OBJECT_PARAMETER_ACL; + n->objs = $2; + $$ = n; + } | SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_SCHEMA; n->objs = $2; @@ -7216,6 +8003,7 @@ privilege_target: | TABLESPACE name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TABLESPACE; n->objs = $2; @@ -7224,6 +8012,7 @@ privilege_target: | TYPE_P any_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = OBJECT_TYPE; n->objs = $2; @@ -7232,6 +8021,7 @@ privilege_target: | ALL TABLES IN_P SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_TABLE; n->objs = $5; @@ -7240,6 +8030,7 @@ privilege_target: | ALL SEQUENCES IN_P SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_SEQUENCE; n->objs = $5; @@ -7248,6 +8039,7 @@ privilege_target: | ALL FUNCTIONS IN_P SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_FUNCTION; n->objs = $5; @@ -7256,6 +8048,7 @@ privilege_target: | ALL PROCEDURES IN_P SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_PROCEDURE; n->objs = $5; @@ -7264,6 +8057,7 @@ privilege_target: | ALL ROUTINES IN_P SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; n->objtype = OBJECT_ROUTINE; n->objs = $5; @@ -7295,15 +8089,27 @@ opt_grant_grant_option: *****************************************************************************/ GrantRoleStmt: - GRANT privilege_list TO role_list opt_grant_admin_option opt_granted_by + GRANT privilege_list TO role_list opt_granted_by + { + GrantRoleStmt *n = makeNode(GrantRoleStmt); + + n->is_grant = true; + n->granted_roles = $2; + n->grantee_roles = $4; + n->opt = NIL; + n->grantor = $5; + $$ = (Node *) n; + } + | GRANT privilege_list TO role_list WITH grant_role_opt_list opt_granted_by { GrantRoleStmt *n = makeNode(GrantRoleStmt); + n->is_grant = true; n->granted_roles = $2; n->grantee_roles = $4; - n->admin_opt = $5; - n->grantor = $6; - $$ = (Node*)n; + n->opt = $6; + n->grantor = $7; + $$ = (Node *) n; } ; @@ -7311,27 +8117,48 @@ RevokeRoleStmt: REVOKE privilege_list FROM role_list opt_granted_by opt_drop_behavior { GrantRoleStmt *n = makeNode(GrantRoleStmt); + n->is_grant = false; - n->admin_opt = false; + n->opt = NIL; n->granted_roles = $2; n->grantee_roles = $4; + n->grantor = $5; n->behavior = $6; - $$ = (Node*)n; + $$ = (Node *) n; } - | REVOKE ADMIN OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior + | REVOKE ColId OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior { GrantRoleStmt *n = makeNode(GrantRoleStmt); + DefElem *opt; + + opt = makeDefElem(pstrdup($2), + (Node *) makeBoolean(false), @2); n->is_grant = false; - n->admin_opt = true; + n->opt = list_make1(opt); n->granted_roles = $5; n->grantee_roles = $7; + n->grantor = $8; n->behavior = $9; - $$ = (Node*)n; + $$ = (Node *) n; } ; -opt_grant_admin_option: WITH ADMIN OPTION { $$ = true; } - | /*EMPTY*/ { $$ = false; } +grant_role_opt_list: + grant_role_opt_list ',' grant_role_opt { $$ = lappend($1, $3); } + | grant_role_opt { $$ = list_make1($1); } + ; + +grant_role_opt: + ColLabel grant_role_opt_value + { + $$ = makeDefElem(pstrdup($1), $2, @1); + } + ; + +grant_role_opt_value: + OPTION { $$ = (Node *) makeBoolean(true); } + | TRUE_P { $$ = (Node *) makeBoolean(true); } + | FALSE_P { $$ = (Node *) makeBoolean(false); } ; opt_granted_by: GRANTED BY RoleSpec { $$ = $3; } @@ -7348,9 +8175,10 @@ AlterDefaultPrivilegesStmt: ALTER DEFAULT PRIVILEGES DefACLOptionList DefACLAction { AlterDefaultPrivilegesStmt *n = makeNode(AlterDefaultPrivilegesStmt); + n->options = $4; n->action = (GrantStmt *) $5; - $$ = (Node*)n; + $$ = (Node *) n; } ; @@ -7362,15 +8190,15 @@ DefACLOptionList: DefACLOption: IN_P SCHEMA name_list { - $$ = makeDefElem("schemas", (Node *)$3, @1); + $$ = makeDefElem("schemas", (Node *) $3, @1); } | FOR ROLE role_list { - $$ = makeDefElem("roles", (Node *)$3, @1); + $$ = makeDefElem("roles", (Node *) $3, @1); } | FOR USER role_list { - $$ = makeDefElem("roles", (Node *)$3, @1); + $$ = makeDefElem("roles", (Node *) $3, @1); } ; @@ -7383,6 +8211,7 @@ DefACLAction: opt_grant_grant_option { GrantStmt *n = makeNode(GrantStmt); + n->is_grant = true; n->privileges = $2; n->targtype = ACL_TARGET_DEFAULTS; @@ -7390,12 +8219,13 @@ DefACLAction: n->objects = NIL; n->grantees = $6; n->grant_option = $7; - $$ = (Node*)n; + $$ = (Node *) n; } | REVOKE privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior { GrantStmt *n = makeNode(GrantStmt); + n->is_grant = false; n->grant_option = false; n->privileges = $2; @@ -7404,12 +8234,13 @@ DefACLAction: n->objects = NIL; n->grantees = $6; n->behavior = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | REVOKE GRANT OPTION FOR privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior { GrantStmt *n = makeNode(GrantStmt); + n->is_grant = false; n->grant_option = true; n->privileges = $5; @@ -7418,7 +8249,7 @@ DefACLAction: n->objects = NIL; n->grantees = $9; n->behavior = $10; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -7429,6 +8260,7 @@ defacl_privilege_target: | SEQUENCES { $$ = OBJECT_SEQUENCE; } | TYPES_P { $$ = OBJECT_TYPE; } | SCHEMAS { $$ = OBJECT_SCHEMA; } + | LARGE_P OBJECTS_P { $$ = OBJECT_LARGEOBJECT; } ; @@ -7440,61 +8272,69 @@ defacl_privilege_target: * willing to make TABLESPACE a fully reserved word. *****************************************************************************/ -IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name +IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_single_name ON relation_expr access_method_clause '(' index_params ')' - opt_include opt_reloptions OptTableSpace where_clause + opt_include opt_unique_null_treatment opt_reloptions OptTableSpace where_clause { IndexStmt *n = makeNode(IndexStmt); + n->unique = $2; n->concurrent = $4; n->idxname = $5; n->relation = $7; - n->relationId = InvalidOid; n->accessMethod = $8; n->indexParams = $10; n->indexIncludingParams = $12; - n->options = $13; - n->tableSpace = $14; - n->whereClause = $15; + n->nulls_not_distinct = !$13; + n->options = $14; + n->tableSpace = $15; + n->whereClause = $16; n->excludeOpNames = NIL; n->idxcomment = NULL; n->indexOid = InvalidOid; - n->oldNode = InvalidOid; + n->oldNumber = InvalidRelFileNumber; + n->oldCreateSubid = InvalidSubTransactionId; + n->oldFirstRelfilelocatorSubid = InvalidSubTransactionId; n->primary = false; n->isconstraint = false; n->deferrable = false; n->initdeferred = false; n->transformed = false; n->if_not_exists = false; - $$ = (Node *)n; + n->reset_default_tblspc = false; + $$ = (Node *) n; } - | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS index_name + | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS name ON relation_expr access_method_clause '(' index_params ')' - opt_include opt_reloptions OptTableSpace where_clause + opt_include opt_unique_null_treatment opt_reloptions OptTableSpace where_clause { IndexStmt *n = makeNode(IndexStmt); + n->unique = $2; n->concurrent = $4; n->idxname = $8; n->relation = $10; - n->relationId = InvalidOid; n->accessMethod = $11; n->indexParams = $13; n->indexIncludingParams = $15; - n->options = $16; - n->tableSpace = $17; - n->whereClause = $18; + n->nulls_not_distinct = !$16; + n->options = $17; + n->tableSpace = $18; + n->whereClause = $19; n->excludeOpNames = NIL; n->idxcomment = NULL; n->indexOid = InvalidOid; - n->oldNode = InvalidOid; + n->oldNumber = InvalidRelFileNumber; + n->oldCreateSubid = InvalidSubTransactionId; + n->oldFirstRelfilelocatorSubid = InvalidSubTransactionId; n->primary = false; n->isconstraint = false; n->deferrable = false; n->initdeferred = false; n->transformed = false; n->if_not_exists = true; - $$ = (Node *)n; + n->reset_default_tblspc = false; + $$ = (Node *) n; } ; @@ -7503,18 +8343,8 @@ opt_unique: | /*EMPTY*/ { $$ = false; } ; -opt_concurrently: - CONCURRENTLY { $$ = true; } - | /*EMPTY*/ { $$ = false; } - ; - -opt_index_name: - index_name { $$ = $1; } - | /*EMPTY*/ { $$ = NULL; } - ; - access_method_clause: - USING access_method { $$ = $2; } + USING name { $$ = $2; } | /*EMPTY*/ { $$ = DEFAULT_INDEX_TYPE; } ; @@ -7522,43 +8352,53 @@ index_params: index_elem { $$ = list_make1($1); } | index_params ',' index_elem { $$ = lappend($1, $3); } ; + +index_elem_options: + opt_collate opt_qualified_name opt_asc_desc opt_nulls_order + { + $$ = makeNode(IndexElem); + $$->name = NULL; + $$->expr = NULL; + $$->indexcolname = NULL; + $$->collation = $1; + $$->opclass = $2; + $$->opclassopts = NIL; + $$->ordering = $3; + $$->nulls_ordering = $4; + } + | opt_collate any_name reloptions opt_asc_desc opt_nulls_order + { + $$ = makeNode(IndexElem); + $$->name = NULL; + $$->expr = NULL; + $$->indexcolname = NULL; + $$->collation = $1; + $$->opclass = $2; + $$->opclassopts = $3; + $$->ordering = $4; + $$->nulls_ordering = $5; + } + ; + /* * Index attributes can be either simple column references, or arbitrary * expressions in parens. For backwards-compatibility reasons, we allow * an expression that's just a function call to be written without parens. */ -index_elem: ColId opt_collate opt_class opt_asc_desc opt_nulls_order +index_elem: ColId index_elem_options { - $$ = makeNode(IndexElem); + $$ = $2; $$->name = $1; - $$->expr = NULL; - $$->indexcolname = NULL; - $$->collation = $2; - $$->opclass = $3; - $$->ordering = $4; - $$->nulls_ordering = $5; } - | func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order + | func_expr_windowless index_elem_options { - $$ = makeNode(IndexElem); - $$->name = NULL; + $$ = $2; $$->expr = $1; - $$->indexcolname = NULL; - $$->collation = $2; - $$->opclass = $3; - $$->ordering = $4; - $$->nulls_ordering = $5; } - | '(' a_expr ')' opt_collate opt_class opt_asc_desc opt_nulls_order + | '(' a_expr ')' index_elem_options { - $$ = makeNode(IndexElem); - $$->name = NULL; + $$ = $4; $$->expr = $2; - $$->indexcolname = NULL; - $$->collation = $4; - $$->opclass = $5; - $$->ordering = $6; - $$->nulls_ordering = $7; } ; @@ -7574,9 +8414,6 @@ opt_collate: COLLATE any_name { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; -opt_class: any_name { $$ = $1; } - | /*EMPTY*/ { $$ = NIL; } - ; opt_asc_desc: ASC { $$ = SORTBY_ASC; } | DESC { $$ = SORTBY_DESC; } @@ -7602,53 +8439,61 @@ opt_nulls_order: NULLS_LA FIRST_P { $$ = SORTBY_NULLS_FIRST; } CreateFunctionStmt: CREATE opt_or_replace FUNCTION func_name func_args_with_defaults - RETURNS func_return createfunc_opt_list + RETURNS func_return opt_createfunc_opt_list opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); + n->is_procedure = false; n->replace = $2; n->funcname = $4; n->parameters = $5; n->returnType = $7; n->options = $8; - $$ = (Node *)n; + n->sql_body = $9; + $$ = (Node *) n; } | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults - RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list + RETURNS TABLE '(' table_func_column_list ')' opt_createfunc_opt_list opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); + n->is_procedure = false; n->replace = $2; n->funcname = $4; - n->parameters = mergeTableFuncParameters($5, $9); + n->parameters = mergeTableFuncParameters($5, $9, yyscanner); n->returnType = TableFuncTypeName($9); n->returnType->location = @7; n->options = $11; - $$ = (Node *)n; + n->sql_body = $12; + $$ = (Node *) n; } | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults - createfunc_opt_list + opt_createfunc_opt_list opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); + n->is_procedure = false; n->replace = $2; n->funcname = $4; n->parameters = $5; n->returnType = NULL; n->options = $6; - $$ = (Node *)n; + n->sql_body = $7; + $$ = (Node *) n; } | CREATE opt_or_replace PROCEDURE func_name func_args_with_defaults - createfunc_opt_list + opt_createfunc_opt_list opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); + n->is_procedure = true; n->replace = $2; n->funcname = $4; n->parameters = $5; n->returnType = NULL; n->options = $6; - $$ = (Node *)n; + n->sql_body = $7; + $$ = (Node *) n; } ; @@ -7676,8 +8521,10 @@ function_with_argtypes: func_name func_args { ObjectWithArgs *n = makeNode(ObjectWithArgs); + n->objname = $1; n->objargs = extractArgTypes($2); + n->objfuncargs = $2; $$ = n; } /* @@ -7688,6 +8535,7 @@ function_with_argtypes: | type_func_name_keyword { ObjectWithArgs *n = makeNode(ObjectWithArgs); + n->objname = list_make1(makeString(pstrdup($1))); n->args_unspecified = true; $$ = n; @@ -7695,6 +8543,7 @@ function_with_argtypes: | ColId { ObjectWithArgs *n = makeNode(ObjectWithArgs); + n->objname = list_make1(makeString($1)); n->args_unspecified = true; $$ = n; @@ -7702,6 +8551,7 @@ function_with_argtypes: | ColId indirection { ObjectWithArgs *n = makeNode(ObjectWithArgs); + n->objname = check_func_name(lcons(makeString($1), $2), yyscanner); n->args_unspecified = true; @@ -7738,46 +8588,56 @@ func_arg: arg_class param_name func_type { FunctionParameter *n = makeNode(FunctionParameter); + n->name = $2; n->argType = $3; n->mode = $1; n->defexpr = NULL; + n->location = @1; $$ = n; } | param_name arg_class func_type { FunctionParameter *n = makeNode(FunctionParameter); + n->name = $1; n->argType = $3; n->mode = $2; n->defexpr = NULL; + n->location = @1; $$ = n; } | param_name func_type { FunctionParameter *n = makeNode(FunctionParameter); + n->name = $1; n->argType = $2; - n->mode = FUNC_PARAM_IN; + n->mode = FUNC_PARAM_DEFAULT; n->defexpr = NULL; + n->location = @1; $$ = n; } | arg_class func_type { FunctionParameter *n = makeNode(FunctionParameter); + n->name = NULL; n->argType = $2; n->mode = $1; n->defexpr = NULL; + n->location = @1; $$ = n; } | func_type { FunctionParameter *n = makeNode(FunctionParameter); + n->name = NULL; n->argType = $1; - n->mode = FUNC_PARAM_IN; + n->mode = FUNC_PARAM_DEFAULT; n->defexpr = NULL; + n->location = @1; $$ = n; } ; @@ -7848,7 +8708,8 @@ func_arg_with_default: /* Aggregate args can be most things that function args can be */ aggr_arg: func_arg { - if (!($1->mode == FUNC_PARAM_IN || + if (!($1->mode == FUNC_PARAM_DEFAULT || + $1->mode == FUNC_PARAM_IN || $1->mode == FUNC_PARAM_VARIADIC)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -7879,8 +8740,8 @@ aggr_arg: func_arg * * The return value of this production is a two-element list, in which the * first item is a sublist of FunctionParameter nodes (with any duplicate - * VARIADIC item already dropped, as per above) and the second is an integer - * Value node, containing -1 if there was no ORDER BY and otherwise the number + * VARIADIC item already dropped, as per above) and the second is an Integer + * node, containing -1 if there was no ORDER BY and otherwise the number * of argument declarations before the ORDER BY. (If this number is equal * to the first sublist's length, then we dropped a duplicate VARIADIC item.) * This representation is passed as-is to CREATE AGGREGATE; for operations @@ -7915,8 +8776,10 @@ aggregate_with_argtypes: func_name aggr_args { ObjectWithArgs *n = makeNode(ObjectWithArgs); + n->objname = $1; n->objargs = extractAggrArgTypes($2); + n->objfuncargs = (List *) linitial($2); $$ = n; } ; @@ -7927,6 +8790,11 @@ aggregate_with_argtypes_list: { $$ = lappend($1, $3); } ; +opt_createfunc_opt_list: + createfunc_opt_list + | /*EMPTY*/ { $$ = NIL; } + ; + createfunc_opt_list: /* Must be at least one to prevent conflict */ createfunc_opt_item { $$ = list_make1($1); } @@ -7939,87 +8807,91 @@ createfunc_opt_list: common_func_opt_item: CALLED ON NULL_P INPUT_P { - $$ = makeDefElem("strict", (Node *)makeInteger(false), @1); + $$ = makeDefElem("strict", (Node *) makeBoolean(false), @1); } | RETURNS NULL_P ON NULL_P INPUT_P { - $$ = makeDefElem("strict", (Node *)makeInteger(true), @1); + $$ = makeDefElem("strict", (Node *) makeBoolean(true), @1); } | STRICT_P { - $$ = makeDefElem("strict", (Node *)makeInteger(true), @1); + $$ = makeDefElem("strict", (Node *) makeBoolean(true), @1); } | IMMUTABLE { - $$ = makeDefElem("volatility", (Node *)makeString("immutable"), @1); + $$ = makeDefElem("volatility", (Node *) makeString("immutable"), @1); } | STABLE { - $$ = makeDefElem("volatility", (Node *)makeString("stable"), @1); + $$ = makeDefElem("volatility", (Node *) makeString("stable"), @1); } | VOLATILE { - $$ = makeDefElem("volatility", (Node *)makeString("volatile"), @1); + $$ = makeDefElem("volatility", (Node *) makeString("volatile"), @1); } | EXTERNAL SECURITY DEFINER { - $$ = makeDefElem("security", (Node *)makeInteger(true), @1); + $$ = makeDefElem("security", (Node *) makeBoolean(true), @1); } | EXTERNAL SECURITY INVOKER { - $$ = makeDefElem("security", (Node *)makeInteger(false), @1); + $$ = makeDefElem("security", (Node *) makeBoolean(false), @1); } | SECURITY DEFINER { - $$ = makeDefElem("security", (Node *)makeInteger(true), @1); + $$ = makeDefElem("security", (Node *) makeBoolean(true), @1); } | SECURITY INVOKER { - $$ = makeDefElem("security", (Node *)makeInteger(false), @1); + $$ = makeDefElem("security", (Node *) makeBoolean(false), @1); } | LEAKPROOF { - $$ = makeDefElem("leakproof", (Node *)makeInteger(true), @1); + $$ = makeDefElem("leakproof", (Node *) makeBoolean(true), @1); } | NOT LEAKPROOF { - $$ = makeDefElem("leakproof", (Node *)makeInteger(false), @1); + $$ = makeDefElem("leakproof", (Node *) makeBoolean(false), @1); } | COST NumericOnly { - $$ = makeDefElem("cost", (Node *)$2, @1); + $$ = makeDefElem("cost", (Node *) $2, @1); } | ROWS NumericOnly { - $$ = makeDefElem("rows", (Node *)$2, @1); + $$ = makeDefElem("rows", (Node *) $2, @1); + } + | SUPPORT any_name + { + $$ = makeDefElem("support", (Node *) $2, @1); } | FunctionSetResetClause { /* we abuse the normal content of a DefElem here */ - $$ = makeDefElem("set", (Node *)$1, @1); + $$ = makeDefElem("set", (Node *) $1, @1); } | PARALLEL ColId { - $$ = makeDefElem("parallel", (Node *)makeString($2), @1); + $$ = makeDefElem("parallel", (Node *) makeString($2), @1); } ; createfunc_opt_item: AS func_as { - $$ = makeDefElem("as", (Node *)$2, @1); + $$ = makeDefElem("as", (Node *) $2, @1); } | LANGUAGE NonReservedWord_or_Sconst { - $$ = makeDefElem("language", (Node *)makeString($2), @1); + $$ = makeDefElem("language", (Node *) makeString($2), @1); } | TRANSFORM transform_type_list { - $$ = makeDefElem("transform", (Node *)$2, @1); + $$ = makeDefElem("transform", (Node *) $2, @1); } | WINDOW { - $$ = makeDefElem("window", (Node *)makeInteger(true), @1); + $$ = makeDefElem("window", (Node *) makeBoolean(true), @1); } | common_func_opt_item { @@ -8034,6 +8906,56 @@ func_as: Sconst { $$ = list_make1(makeString($1)); } } ; +ReturnStmt: RETURN a_expr + { + ReturnStmt *r = makeNode(ReturnStmt); + + r->returnval = (Node *) $2; + $$ = (Node *) r; + } + ; + +opt_routine_body: + ReturnStmt + { + $$ = $1; + } + | BEGIN_P ATOMIC routine_body_stmt_list END_P + { + /* + * A compound statement is stored as a single-item list + * containing the list of statements as its member. That + * way, the parse analysis code can tell apart an empty + * body from no body at all. + */ + $$ = (Node *) list_make1($3); + } + | /*EMPTY*/ + { + $$ = NULL; + } + ; + +routine_body_stmt_list: + routine_body_stmt_list routine_body_stmt ';' + { + /* As in stmtmulti, discard empty statements */ + if ($2 != NULL) + $$ = lappend($1, $2); + else + $$ = $1; + } + | /*EMPTY*/ + { + $$ = NIL; + } + ; + +routine_body_stmt: + stmt + | ReturnStmt + ; + transform_type_list: FOR TYPE_P Typename { $$ = list_make1($3); } | transform_type_list ',' FOR TYPE_P Typename { $$ = lappend($1, $5); } @@ -8047,10 +8969,12 @@ opt_definition: table_func_column: param_name func_type { FunctionParameter *n = makeNode(FunctionParameter); + n->name = $1; n->argType = $2; n->mode = FUNC_PARAM_TABLE; n->defexpr = NULL; + n->location = @1; $$ = n; } ; @@ -8078,6 +9002,7 @@ AlterFunctionStmt: ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict { AlterFunctionStmt *n = makeNode(AlterFunctionStmt); + n->objtype = OBJECT_FUNCTION; n->func = $3; n->actions = $4; @@ -8086,6 +9011,7 @@ AlterFunctionStmt: | ALTER PROCEDURE function_with_argtypes alterfunc_opt_list opt_restrict { AlterFunctionStmt *n = makeNode(AlterFunctionStmt); + n->objtype = OBJECT_PROCEDURE; n->func = $3; n->actions = $4; @@ -8094,6 +9020,7 @@ AlterFunctionStmt: | ALTER ROUTINE function_with_argtypes alterfunc_opt_list opt_restrict { AlterFunctionStmt *n = makeNode(AlterFunctionStmt); + n->objtype = OBJECT_ROUTINE; n->func = $3; n->actions = $4; @@ -8130,62 +9057,68 @@ RemoveFuncStmt: DROP FUNCTION function_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_FUNCTION; n->objects = $3; n->behavior = $4; n->missing_ok = false; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP FUNCTION IF_P EXISTS function_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_FUNCTION; n->objects = $5; n->behavior = $6; n->missing_ok = true; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP PROCEDURE function_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_PROCEDURE; n->objects = $3; n->behavior = $4; n->missing_ok = false; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP PROCEDURE IF_P EXISTS function_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_PROCEDURE; n->objects = $5; n->behavior = $6; n->missing_ok = true; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP ROUTINE function_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_ROUTINE; n->objects = $3; n->behavior = $4; n->missing_ok = false; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP ROUTINE IF_P EXISTS function_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_ROUTINE; n->objects = $5; n->behavior = $6; n->missing_ok = true; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8193,22 +9126,24 @@ RemoveAggrStmt: DROP AGGREGATE aggregate_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_AGGREGATE; n->objects = $3; n->behavior = $4; n->missing_ok = false; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP AGGREGATE IF_P EXISTS aggregate_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_AGGREGATE; n->objects = $5; n->behavior = $6; n->missing_ok = true; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8216,22 +9151,24 @@ RemoveOperStmt: DROP OPERATOR operator_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_OPERATOR; n->objects = $3; n->behavior = $4; n->missing_ok = false; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } | DROP OPERATOR IF_P EXISTS operator_with_argtypes_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_OPERATOR; n->objects = $5; n->behavior = $6; n->missing_ok = true; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8269,6 +9206,7 @@ operator_with_argtypes: any_operator oper_argtypes { ObjectWithArgs *n = makeNode(ObjectWithArgs); + n->objname = $1; n->objargs = $2; $$ = n; @@ -8287,8 +9225,9 @@ operator_with_argtypes: DoStmt: DO dostmt_opt_list { DoStmt *n = makeNode(DoStmt); + n->args = $2; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8300,11 +9239,11 @@ dostmt_opt_list: dostmt_opt_item: Sconst { - $$ = makeDefElem("as", (Node *)makeString($1), @1); + $$ = makeDefElem("as", (Node *) makeString($1), @1); } | LANGUAGE NonReservedWord_or_Sconst { - $$ = makeDefElem("language", (Node *)makeString($2), @1); + $$ = makeDefElem("language", (Node *) makeString($2), @1); } ; @@ -8318,34 +9257,37 @@ CreateCastStmt: CREATE CAST '(' Typename AS Typename ')' WITH FUNCTION function_with_argtypes cast_context { CreateCastStmt *n = makeNode(CreateCastStmt); + n->sourcetype = $4; n->targettype = $6; n->func = $10; n->context = (CoercionContext) $11; n->inout = false; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE CAST '(' Typename AS Typename ')' WITHOUT FUNCTION cast_context { CreateCastStmt *n = makeNode(CreateCastStmt); + n->sourcetype = $4; n->targettype = $6; n->func = NULL; n->context = (CoercionContext) $10; n->inout = false; - $$ = (Node *)n; + $$ = (Node *) n; } | CREATE CAST '(' Typename AS Typename ')' WITH INOUT cast_context { CreateCastStmt *n = makeNode(CreateCastStmt); + n->sourcetype = $4; n->targettype = $6; n->func = NULL; n->context = (CoercionContext) $10; n->inout = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8358,12 +9300,13 @@ cast_context: AS IMPLICIT_P { $$ = COERCION_IMPLICIT; } DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_CAST; n->objects = list_make1(list_make2($5, $7)); n->behavior = $9; n->missing_ok = $3; n->concurrent = false; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8381,12 +9324,13 @@ opt_if_exists: IF_P EXISTS { $$ = true; } CreateTransformStmt: CREATE opt_or_replace TRANSFORM FOR Typename LANGUAGE name '(' transform_element_list ')' { CreateTransformStmt *n = makeNode(CreateTransformStmt); + n->replace = $2; n->type_name = $5; n->lang = $7; n->fromsql = linitial($9); n->tosql = lsecond($9); - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8412,11 +9356,12 @@ transform_element_list: FROM SQL_P WITH FUNCTION function_with_argtypes ',' TO S DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_TRANSFORM; n->objects = list_make1(list_make2($5, makeString($7))); n->behavior = $8; n->missing_ok = $3; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8425,62 +9370,62 @@ DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_d * * QUERY: * - * REINDEX [ (options) ] type + * REINDEX [ (options) ] {INDEX | TABLE | SCHEMA} [CONCURRENTLY] + * REINDEX [ (options) ] {DATABASE | SYSTEM} [CONCURRENTLY] [] *****************************************************************************/ ReindexStmt: - REINDEX reindex_target_type qualified_name + REINDEX opt_reindex_option_list reindex_target_relation opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); - n->kind = $2; - n->relation = $3; + + n->kind = $3; + n->relation = $5; n->name = NULL; - n->options = 0; - $$ = (Node *)n; + n->params = $2; + if ($4) + n->params = lappend(n->params, + makeDefElem("concurrently", NULL, @4)); + $$ = (Node *) n; } - | REINDEX reindex_target_multitable name + | REINDEX opt_reindex_option_list SCHEMA opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); - n->kind = $2; - n->name = $3; + + n->kind = REINDEX_OBJECT_SCHEMA; n->relation = NULL; - n->options = 0; - $$ = (Node *)n; + n->name = $5; + n->params = $2; + if ($4) + n->params = lappend(n->params, + makeDefElem("concurrently", NULL, @4)); + $$ = (Node *) n; } - | REINDEX '(' reindex_option_list ')' reindex_target_type qualified_name + | REINDEX opt_reindex_option_list reindex_target_all opt_concurrently opt_single_name { ReindexStmt *n = makeNode(ReindexStmt); - n->kind = $5; - n->relation = $6; - n->name = NULL; - n->options = $3; - $$ = (Node *)n; - } - | REINDEX '(' reindex_option_list ')' reindex_target_multitable name - { - ReindexStmt *n = makeNode(ReindexStmt); - n->kind = $5; - n->name = $6; + + n->kind = $3; n->relation = NULL; - n->options = $3; - $$ = (Node *)n; + n->name = $5; + n->params = $2; + if ($4) + n->params = lappend(n->params, + makeDefElem("concurrently", NULL, @4)); + $$ = (Node *) n; } ; -reindex_target_type: +reindex_target_relation: INDEX { $$ = REINDEX_OBJECT_INDEX; } | TABLE { $$ = REINDEX_OBJECT_TABLE; } ; -reindex_target_multitable: - SCHEMA { $$ = REINDEX_OBJECT_SCHEMA; } - | SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } +reindex_target_all: + SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } ; -reindex_option_list: - reindex_option_elem { $$ = $1; } - | reindex_option_list ',' reindex_option_elem { $$ = $1 | $3; } - ; -reindex_option_elem: - VERBOSE { $$ = REINDEXOPT_VERBOSE; } +opt_reindex_option_list: + '(' utility_option_list ')' { $$ = $2; } + | /* EMPTY */ { $$ = NULL; } ; /***************************************************************************** @@ -8494,19 +9439,21 @@ AlterTblSpcStmt: { AlterTableSpaceOptionsStmt *n = makeNode(AlterTableSpaceOptionsStmt); + n->tablespacename = $3; n->options = $5; n->isReset = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLESPACE name RESET reloptions { AlterTableSpaceOptionsStmt *n = makeNode(AlterTableSpaceOptionsStmt); + n->tablespacename = $3; n->options = $5; n->isReset = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -8519,503 +9466,580 @@ AlterTblSpcStmt: RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_AGGREGATE; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER COLLATION any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_COLLATION; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER CONVERSION_P any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_CONVERSION; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER DATABASE database_name RENAME TO database_name + | ALTER DATABASE name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_DATABASE; n->subname = $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER DOMAIN_P any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_DOMAIN; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_DOMCONSTRAINT; n->object = (Node *) $3; n->subname = $6; n->newname = $8; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN DATA_P WRAPPER name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_FDW; n->object = (Node *) makeString($5); n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FUNCTION function_with_argtypes RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_FUNCTION; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER GROUP_P RoleId RENAME TO RoleId { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_ROLE; n->subname = $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER opt_procedural LANGUAGE name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_LANGUAGE; n->object = (Node *) makeString($4); n->newname = $7; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER OPERATOR CLASS any_name USING access_method RENAME TO name + | ALTER OPERATOR CLASS any_name USING name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_OPCLASS; n->object = (Node *) lcons(makeString($6), $4); n->newname = $9; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER OPERATOR FAMILY any_name USING access_method RENAME TO name + | ALTER OPERATOR FAMILY any_name USING name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_OPFAMILY; n->object = (Node *) lcons(makeString($6), $4); n->newname = $9; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER POLICY name ON qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_POLICY; n->relation = $5; n->subname = $3; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER POLICY IF_P EXISTS name ON qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_POLICY; n->relation = $7; n->subname = $5; n->newname = $10; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER PROCEDURE function_with_argtypes RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_PROCEDURE; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER PUBLICATION name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_PUBLICATION; n->object = (Node *) makeString($3); n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER ROUTINE function_with_argtypes RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_ROUTINE; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SCHEMA name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_SCHEMA; n->subname = $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SERVER name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_FOREIGN_SERVER; n->object = (Node *) makeString($3); n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SUBSCRIPTION name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_SUBSCRIPTION; n->object = (Node *) makeString($3); n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE relation_expr RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TABLE; n->relation = $3; n->subname = NULL; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE IF_P EXISTS relation_expr RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TABLE; n->relation = $5; n->subname = NULL; n->newname = $8; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SEQUENCE qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_SEQUENCE; n->relation = $3; n->subname = NULL; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SEQUENCE IF_P EXISTS qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_SEQUENCE; n->relation = $5; n->subname = NULL; n->newname = $8; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER VIEW qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_VIEW; n->relation = $3; n->subname = NULL; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER VIEW IF_P EXISTS qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_VIEW; n->relation = $5; n->subname = NULL; n->newname = $8; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_MATVIEW; n->relation = $4; n->subname = NULL; n->newname = $7; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_MATVIEW; n->relation = $6; n->subname = NULL; n->newname = $9; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER INDEX qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_INDEX; n->relation = $3; n->subname = NULL; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER INDEX IF_P EXISTS qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_INDEX; n->relation = $5; n->subname = NULL; n->newname = $8; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN TABLE relation_expr RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_FOREIGN_TABLE; n->relation = $4; n->subname = NULL; n->newname = $7; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_FOREIGN_TABLE; n->relation = $6; n->subname = NULL; n->newname = $9; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE relation_expr RENAME opt_column name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_COLUMN; n->relationType = OBJECT_TABLE; n->relation = $3; n->subname = $6; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_COLUMN; n->relationType = OBJECT_TABLE; n->relation = $5; n->subname = $8; n->newname = $10; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; + } + | ALTER VIEW qualified_name RENAME opt_column name TO name + { + RenameStmt *n = makeNode(RenameStmt); + + n->renameType = OBJECT_COLUMN; + n->relationType = OBJECT_VIEW; + n->relation = $3; + n->subname = $6; + n->newname = $8; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name + { + RenameStmt *n = makeNode(RenameStmt); + + n->renameType = OBJECT_COLUMN; + n->relationType = OBJECT_VIEW; + n->relation = $5; + n->subname = $8; + n->newname = $10; + n->missing_ok = true; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW qualified_name RENAME opt_column name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_COLUMN; n->relationType = OBJECT_MATVIEW; n->relation = $4; n->subname = $7; n->newname = $9; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_COLUMN; n->relationType = OBJECT_MATVIEW; n->relation = $6; n->subname = $9; n->newname = $11; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE relation_expr RENAME CONSTRAINT name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TABCONSTRAINT; n->relation = $3; n->subname = $6; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE IF_P EXISTS relation_expr RENAME CONSTRAINT name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TABCONSTRAINT; n->relation = $5; n->subname = $8; n->newname = $10; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN TABLE relation_expr RENAME opt_column name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_COLUMN; n->relationType = OBJECT_FOREIGN_TABLE; n->relation = $4; n->subname = $7; n->newname = $9; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_COLUMN; n->relationType = OBJECT_FOREIGN_TABLE; n->relation = $6; n->subname = $9; n->newname = $11; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER RULE name ON qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_RULE; n->relation = $5; n->subname = $3; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TRIGGER name ON qualified_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TRIGGER; n->relation = $5; n->subname = $3; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EVENT TRIGGER name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_EVENT_TRIGGER; n->object = (Node *) makeString($4); n->newname = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER ROLE RoleId RENAME TO RoleId { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_ROLE; n->subname = $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER USER RoleId RENAME TO RoleId { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_ROLE; n->subname = $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLESPACE name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TABLESPACE; n->subname = $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER STATISTICS any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_STATISTIC_EXT; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TSPARSER; n->object = (Node *) $5; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TSDICTIONARY; n->object = (Node *) $5; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TSTEMPLATE; n->object = (Node *) $5; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TSCONFIGURATION; n->object = (Node *) $5; n->newname = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TYPE_P any_name RENAME TO name { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_TYPE; n->object = (Node *) $3; n->newname = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TYPE_P any_name RENAME ATTRIBUTE name TO name opt_drop_behavior { RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_ATTRIBUTE; n->relationType = OBJECT_TYPE; n->relation = makeRangeVarFromAnyName($3, @3, yyscanner); @@ -9023,12 +10047,12 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name n->newname = $8; n->behavior = $9; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } ; -opt_column: COLUMN { $$ = COLUMN; } - | /*EMPTY*/ { $$ = 0; } +opt_column: COLUMN + | /*EMPTY*/ ; opt_set_data: SET DATA_P { $$ = 1; } @@ -9042,57 +10066,73 @@ opt_set_data: SET DATA_P { $$ = 1; } *****************************************************************************/ AlterObjectDependsStmt: - ALTER FUNCTION function_with_argtypes DEPENDS ON EXTENSION name + ALTER FUNCTION function_with_argtypes opt_no DEPENDS ON EXTENSION name { AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); + n->objectType = OBJECT_FUNCTION; n->object = (Node *) $3; - n->extname = makeString($7); - $$ = (Node *)n; + n->extname = makeString($8); + n->remove = $4; + $$ = (Node *) n; } - | ALTER PROCEDURE function_with_argtypes DEPENDS ON EXTENSION name + | ALTER PROCEDURE function_with_argtypes opt_no DEPENDS ON EXTENSION name { AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); + n->objectType = OBJECT_PROCEDURE; n->object = (Node *) $3; - n->extname = makeString($7); - $$ = (Node *)n; + n->extname = makeString($8); + n->remove = $4; + $$ = (Node *) n; } - | ALTER ROUTINE function_with_argtypes DEPENDS ON EXTENSION name + | ALTER ROUTINE function_with_argtypes opt_no DEPENDS ON EXTENSION name { AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); + n->objectType = OBJECT_ROUTINE; n->object = (Node *) $3; - n->extname = makeString($7); - $$ = (Node *)n; + n->extname = makeString($8); + n->remove = $4; + $$ = (Node *) n; } - | ALTER TRIGGER name ON qualified_name DEPENDS ON EXTENSION name + | ALTER TRIGGER name ON qualified_name opt_no DEPENDS ON EXTENSION name { AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); + n->objectType = OBJECT_TRIGGER; n->relation = $5; n->object = (Node *) list_make1(makeString($3)); - n->extname = makeString($9); - $$ = (Node *)n; + n->extname = makeString($10); + n->remove = $6; + $$ = (Node *) n; } - | ALTER MATERIALIZED VIEW qualified_name DEPENDS ON EXTENSION name + | ALTER MATERIALIZED VIEW qualified_name opt_no DEPENDS ON EXTENSION name { AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); + n->objectType = OBJECT_MATVIEW; n->relation = $4; - n->extname = makeString($8); - $$ = (Node *)n; + n->extname = makeString($9); + n->remove = $5; + $$ = (Node *) n; } - | ALTER INDEX qualified_name DEPENDS ON EXTENSION name + | ALTER INDEX qualified_name opt_no DEPENDS ON EXTENSION name { AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt); + n->objectType = OBJECT_INDEX; n->relation = $3; - n->extname = makeString($7); - $$ = (Node *)n; + n->extname = makeString($8); + n->remove = $4; + $$ = (Node *) n; } ; +opt_no: NO { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + /***************************************************************************** * * ALTER THING name SET SCHEMA name @@ -9103,245 +10143,272 @@ AlterObjectSchemaStmt: ALTER AGGREGATE aggregate_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_AGGREGATE; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER COLLATION any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_COLLATION; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER CONVERSION_P any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_CONVERSION; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER DOMAIN_P any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_DOMAIN; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EXTENSION name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_EXTENSION; n->object = (Node *) makeString($3); n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FUNCTION function_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_FUNCTION; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER OPERATOR operator_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_OPERATOR; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER OPERATOR CLASS any_name USING access_method SET SCHEMA name + | ALTER OPERATOR CLASS any_name USING name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_OPCLASS; n->object = (Node *) lcons(makeString($6), $4); n->newschema = $9; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER OPERATOR FAMILY any_name USING access_method SET SCHEMA name + | ALTER OPERATOR FAMILY any_name USING name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_OPFAMILY; n->object = (Node *) lcons(makeString($6), $4); n->newschema = $9; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER PROCEDURE function_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_PROCEDURE; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER ROUTINE function_with_argtypes SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_ROUTINE; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE relation_expr SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_TABLE; n->relation = $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLE IF_P EXISTS relation_expr SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_TABLE; n->relation = $5; n->newschema = $8; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER STATISTICS any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_STATISTIC_EXT; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH PARSER any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_TSPARSER; n->object = (Node *) $5; n->newschema = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH DICTIONARY any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_TSDICTIONARY; n->object = (Node *) $5; n->newschema = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH TEMPLATE any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_TSTEMPLATE; n->object = (Node *) $5; n->newschema = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_TSCONFIGURATION; n->object = (Node *) $5; n->newschema = $8; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SEQUENCE qualified_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_SEQUENCE; n->relation = $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SEQUENCE IF_P EXISTS qualified_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_SEQUENCE; n->relation = $5; n->newschema = $8; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER VIEW qualified_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_VIEW; n->relation = $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER VIEW IF_P EXISTS qualified_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_VIEW; n->relation = $5; n->newschema = $8; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW qualified_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_MATVIEW; n->relation = $4; n->newschema = $7; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_MATVIEW; n->relation = $6; n->newschema = $9; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN TABLE relation_expr SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_FOREIGN_TABLE; n->relation = $4; n->newschema = $7; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN TABLE IF_P EXISTS relation_expr SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_FOREIGN_TABLE; n->relation = $6; n->newschema = $9; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TYPE_P any_name SET SCHEMA name { AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt); + n->objectType = OBJECT_TYPE; n->object = (Node *) $3; n->newschema = $6; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -9355,9 +10422,10 @@ AlterOperatorStmt: ALTER OPERATOR operator_with_argtypes SET '(' operator_def_list ')' { AlterOperatorStmt *n = makeNode(AlterOperatorStmt); + n->opername = $3; n->options = $6; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -9369,15 +10437,36 @@ operator_def_elem: ColLabel '=' NONE { $$ = makeDefElem($1, NULL, @1); } | ColLabel '=' operator_def_arg { $$ = makeDefElem($1, (Node *) $3, @1); } + | ColLabel + { $$ = makeDefElem($1, NULL, @1); } ; /* must be similar enough to def_arg to avoid reduce/reduce conflicts */ operator_def_arg: - func_type { $$ = (Node *)$1; } - | reserved_keyword { $$ = (Node *)makeString(pstrdup($1)); } - | qual_all_Op { $$ = (Node *)$1; } - | NumericOnly { $$ = (Node *)$1; } - | Sconst { $$ = (Node *)makeString($1); } + func_type { $$ = (Node *) $1; } + | reserved_keyword { $$ = (Node *) makeString(pstrdup($1)); } + | qual_all_Op { $$ = (Node *) $1; } + | NumericOnly { $$ = (Node *) $1; } + | Sconst { $$ = (Node *) makeString($1); } + ; + +/***************************************************************************** + * + * ALTER TYPE name SET define + * + * We repurpose ALTER OPERATOR's version of "definition" here + * + *****************************************************************************/ + +AlterTypeStmt: + ALTER TYPE_P any_name SET '(' operator_def_list ')' + { + AlterTypeStmt *n = makeNode(AlterTypeStmt); + + n->typeName = $3; + n->options = $6; + $$ = (Node *) n; + } ; /***************************************************************************** @@ -9389,249 +10478,378 @@ operator_def_arg: AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_AGGREGATE; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER COLLATION any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_COLLATION; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER CONVERSION_P any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_CONVERSION; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER DATABASE database_name OWNER TO RoleSpec + | ALTER DATABASE name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_DATABASE; n->object = (Node *) makeString($3); n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER DOMAIN_P any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_DOMAIN; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FUNCTION function_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_FUNCTION; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER opt_procedural LANGUAGE name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_LANGUAGE; n->object = (Node *) makeString($4); n->newowner = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_LARGEOBJECT; n->object = (Node *) $4; n->newowner = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER OPERATOR operator_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_OPERATOR; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleSpec + | ALTER OPERATOR CLASS any_name USING name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_OPCLASS; n->object = (Node *) lcons(makeString($6), $4); n->newowner = $9; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleSpec + | ALTER OPERATOR FAMILY any_name USING name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_OPFAMILY; n->object = (Node *) lcons(makeString($6), $4); n->newowner = $9; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER PROCEDURE function_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_PROCEDURE; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER ROUTINE function_with_argtypes OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_ROUTINE; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SCHEMA name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_SCHEMA; n->object = (Node *) makeString($3); n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TYPE_P any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_TYPE; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TABLESPACE name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_TABLESPACE; n->object = (Node *) makeString($3); n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER STATISTICS any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_STATISTIC_EXT; n->object = (Node *) $3; n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_TSDICTIONARY; n->object = (Node *) $5; n->newowner = $8; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_TSCONFIGURATION; n->object = (Node *) $5; n->newowner = $8; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER FOREIGN DATA_P WRAPPER name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_FDW; n->object = (Node *) makeString($5); n->newowner = $8; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SERVER name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_FOREIGN_SERVER; n->object = (Node *) makeString($3); n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER EVENT TRIGGER name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_EVENT_TRIGGER; n->object = (Node *) makeString($4); n->newowner = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER PUBLICATION name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_PUBLICATION; n->object = (Node *) makeString($3); n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SUBSCRIPTION name OWNER TO RoleSpec { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); + n->objectType = OBJECT_SUBSCRIPTION; n->object = (Node *) makeString($3); n->newowner = $6; - $$ = (Node *)n; + $$ = (Node *) n; } ; /***************************************************************************** * - * CREATE PUBLICATION name [ FOR TABLE ] [ WITH options ] + * CREATE PUBLICATION name [WITH options] + * + * CREATE PUBLICATION FOR ALL TABLES [WITH options] + * + * CREATE PUBLICATION FOR pub_obj [, ...] [WITH options] + * + * pub_obj is one of: + * + * TABLE table [, ...] + * TABLES IN SCHEMA schema [, ...] * *****************************************************************************/ CreatePublicationStmt: - CREATE PUBLICATION name opt_publication_for_tables opt_definition + CREATE PUBLICATION name opt_definition { CreatePublicationStmt *n = makeNode(CreatePublicationStmt); + n->pubname = $3; - n->options = $5; - if ($4 != NULL) - { - /* FOR TABLE */ - if (IsA($4, List)) - n->tables = (List *)$4; - /* FOR ALL TABLES */ - else - n->for_all_tables = true; - } - $$ = (Node *)n; + n->options = $4; + $$ = (Node *) n; } - ; + | CREATE PUBLICATION name FOR ALL TABLES opt_definition + { + CreatePublicationStmt *n = makeNode(CreatePublicationStmt); -opt_publication_for_tables: - publication_for_tables { $$ = $1; } - | /* EMPTY */ { $$ = NULL; } + n->pubname = $3; + n->options = $7; + n->for_all_tables = true; + $$ = (Node *) n; + } + | CREATE PUBLICATION name FOR pub_obj_list opt_definition + { + CreatePublicationStmt *n = makeNode(CreatePublicationStmt); + + n->pubname = $3; + n->options = $6; + n->pubobjects = (List *) $5; + preprocess_pubobj_list(n->pubobjects, yyscanner); + $$ = (Node *) n; + } ; -publication_for_tables: - FOR TABLE relation_expr_list +/* + * FOR TABLE and FOR TABLES IN SCHEMA specifications + * + * This rule parses publication objects with and without keyword prefixes. + * + * The actual type of the object without keyword prefix depends on the previous + * one with keyword prefix. It will be preprocessed in preprocess_pubobj_list(). + * + * For the object without keyword prefix, we cannot just use relation_expr here, + * because some extended expressions in relation_expr cannot be used as a + * schemaname and we cannot differentiate it. So, we extract the rules from + * relation_expr here. + */ +PublicationObjSpec: + TABLE relation_expr opt_column_list OptWhereClause { - $$ = (Node *) $3; + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_TABLE; + $$->pubtable = makeNode(PublicationTable); + $$->pubtable->relation = $2; + $$->pubtable->columns = $3; + $$->pubtable->whereClause = $4; } - | FOR ALL TABLES + | TABLES IN_P SCHEMA ColId { - $$ = (Node *) makeInteger(true); + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_TABLES_IN_SCHEMA; + $$->name = $4; + $$->location = @4; } - ; + | TABLES IN_P SCHEMA CURRENT_SCHEMA + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA; + $$->location = @4; + } + | ColId opt_column_list OptWhereClause + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION; + /* + * If either a row filter or column list is specified, create + * a PublicationTable object. + */ + if ($2 || $3) + { + /* + * The OptWhereClause must be stored here but it is + * valid only for tables. For non-table objects, an + * error will be thrown later via + * preprocess_pubobj_list(). + */ + $$->pubtable = makeNode(PublicationTable); + $$->pubtable->relation = makeRangeVar(NULL, $1, @1); + $$->pubtable->columns = $2; + $$->pubtable->whereClause = $3; + } + else + { + $$->name = $1; + } + $$->location = @1; + } + | ColId indirection opt_column_list OptWhereClause + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION; + $$->pubtable = makeNode(PublicationTable); + $$->pubtable->relation = makeRangeVarFromQualifiedName($1, $2, @1, yyscanner); + $$->pubtable->columns = $3; + $$->pubtable->whereClause = $4; + $$->location = @1; + } + /* grammar like tablename * , ONLY tablename, ONLY ( tablename ) */ + | extended_relation_expr opt_column_list OptWhereClause + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION; + $$->pubtable = makeNode(PublicationTable); + $$->pubtable->relation = $1; + $$->pubtable->columns = $2; + $$->pubtable->whereClause = $3; + } + | CURRENT_SCHEMA + { + $$ = makeNode(PublicationObjSpec); + $$->pubobjtype = PUBLICATIONOBJ_CONTINUATION; + $$->location = @1; + } + ; +pub_obj_list: PublicationObjSpec + { $$ = list_make1($1); } + | pub_obj_list ',' PublicationObjSpec + { $$ = lappend($1, $3); } + ; /***************************************************************************** * * ALTER PUBLICATION name SET ( options ) * - * ALTER PUBLICATION name ADD TABLE table [, table2] + * ALTER PUBLICATION name ADD pub_obj [, ...] + * + * ALTER PUBLICATION name DROP pub_obj [, ...] * - * ALTER PUBLICATION name DROP TABLE table [, table2] + * ALTER PUBLICATION name SET pub_obj [, ...] * - * ALTER PUBLICATION name SET TABLE table [, table2] + * pub_obj is one of: + * + * TABLE table_name [, ...] + * TABLES IN SCHEMA schema_name [, ...] * *****************************************************************************/ @@ -9639,33 +10857,40 @@ AlterPublicationStmt: ALTER PUBLICATION name SET definition { AlterPublicationStmt *n = makeNode(AlterPublicationStmt); + n->pubname = $3; n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER PUBLICATION name ADD_P TABLE relation_expr_list + | ALTER PUBLICATION name ADD_P pub_obj_list { AlterPublicationStmt *n = makeNode(AlterPublicationStmt); + n->pubname = $3; - n->tables = $6; - n->tableAction = DEFELEM_ADD; - $$ = (Node *)n; + n->pubobjects = $5; + preprocess_pubobj_list(n->pubobjects, yyscanner); + n->action = AP_AddObjects; + $$ = (Node *) n; } - | ALTER PUBLICATION name SET TABLE relation_expr_list + | ALTER PUBLICATION name SET pub_obj_list { AlterPublicationStmt *n = makeNode(AlterPublicationStmt); + n->pubname = $3; - n->tables = $6; - n->tableAction = DEFELEM_SET; - $$ = (Node *)n; + n->pubobjects = $5; + preprocess_pubobj_list(n->pubobjects, yyscanner); + n->action = AP_SetObjects; + $$ = (Node *) n; } - | ALTER PUBLICATION name DROP TABLE relation_expr_list + | ALTER PUBLICATION name DROP pub_obj_list { AlterPublicationStmt *n = makeNode(AlterPublicationStmt); + n->pubname = $3; - n->tables = $6; - n->tableAction = DEFELEM_DROP; - $$ = (Node *)n; + n->pubobjects = $5; + preprocess_pubobj_list(n->pubobjects, yyscanner); + n->action = AP_DropObjects; + $$ = (Node *) n; } ; @@ -9676,7 +10901,7 @@ AlterPublicationStmt: *****************************************************************************/ CreateSubscriptionStmt: - CREATE SUBSCRIPTION name CONNECTION Sconst PUBLICATION publication_name_list opt_definition + CREATE SUBSCRIPTION name CONNECTION Sconst PUBLICATION name_list opt_definition { CreateSubscriptionStmt *n = makeNode(CreateSubscriptionStmt); @@ -9684,24 +10909,10 @@ CreateSubscriptionStmt: n->conninfo = $5; n->publication = $7; n->options = $8; - $$ = (Node *)n; - } - ; - -publication_name_list: - publication_name_item - { - $$ = list_make1($1); - } - | publication_name_list ',' publication_name_item - { - $$ = lappend($1, $3); + $$ = (Node *) n; } ; -publication_name_item: - ColLabel { $$ = makeString($1); }; - /***************************************************************************** * * ALTER SUBSCRIPTION name ... @@ -9713,58 +10924,96 @@ AlterSubscriptionStmt: { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); + n->kind = ALTER_SUBSCRIPTION_OPTIONS; n->subname = $3; n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SUBSCRIPTION name CONNECTION Sconst { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); + n->kind = ALTER_SUBSCRIPTION_CONNECTION; n->subname = $3; n->conninfo = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); + n->kind = ALTER_SUBSCRIPTION_REFRESH; n->subname = $3; n->options = $6; - $$ = (Node *)n; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name ADD_P PUBLICATION name_list opt_definition + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_ADD_PUBLICATION; + n->subname = $3; + n->publication = $6; + n->options = $7; + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name DROP PUBLICATION name_list opt_definition + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_DROP_PUBLICATION; + n->subname = $3; + n->publication = $6; + n->options = $7; + $$ = (Node *) n; } - | ALTER SUBSCRIPTION name SET PUBLICATION publication_name_list opt_definition + | ALTER SUBSCRIPTION name SET PUBLICATION name_list opt_definition { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_PUBLICATION; + + n->kind = ALTER_SUBSCRIPTION_SET_PUBLICATION; n->subname = $3; n->publication = $6; n->options = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SUBSCRIPTION name ENABLE_P { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); + n->kind = ALTER_SUBSCRIPTION_ENABLED; n->subname = $3; n->options = list_make1(makeDefElem("enabled", - (Node *)makeInteger(true), @1)); - $$ = (Node *)n; + (Node *) makeBoolean(true), @1)); + $$ = (Node *) n; } | ALTER SUBSCRIPTION name DISABLE_P { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); + n->kind = ALTER_SUBSCRIPTION_ENABLED; n->subname = $3; n->options = list_make1(makeDefElem("enabled", - (Node *)makeInteger(false), @1)); - $$ = (Node *)n; + (Node *) makeBoolean(false), @1)); + $$ = (Node *) n; + } + | ALTER SUBSCRIPTION name SKIP definition + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + + n->kind = ALTER_SUBSCRIPTION_SKIP; + n->subname = $3; + n->options = $5; + $$ = (Node *) n; } ; @@ -9777,6 +11026,7 @@ AlterSubscriptionStmt: DropSubscriptionStmt: DROP SUBSCRIPTION name opt_drop_behavior { DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt); + n->subname = $3; n->missing_ok = false; n->behavior = $4; @@ -9785,6 +11035,7 @@ DropSubscriptionStmt: DROP SUBSCRIPTION name opt_drop_behavior | DROP SUBSCRIPTION IF_P EXISTS name opt_drop_behavior { DropSubscriptionStmt *n = makeNode(DropSubscriptionStmt); + n->subname = $5; n->missing_ok = true; n->behavior = $6; @@ -9802,7 +11053,8 @@ RuleStmt: CREATE opt_or_replace RULE name AS ON event TO qualified_name where_clause DO opt_instead RuleActionList { - RuleStmt *n = makeNode(RuleStmt); + RuleStmt *n = makeNode(RuleStmt); + n->replace = $2; n->relation = $9; n->rulename = $4; @@ -9810,7 +11062,7 @@ RuleStmt: CREATE opt_or_replace RULE name AS n->event = $7; n->instead = $12; n->actions = $13; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -9873,9 +11125,10 @@ opt_instead: NotifyStmt: NOTIFY ColId notify_payload { NotifyStmt *n = makeNode(NotifyStmt); + n->conditionname = $2; n->payload = $3; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -9887,8 +11140,9 @@ notify_payload: ListenStmt: LISTEN ColId { ListenStmt *n = makeNode(ListenStmt); + n->conditionname = $2; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -9896,14 +11150,16 @@ UnlistenStmt: UNLISTEN ColId { UnlistenStmt *n = makeNode(UnlistenStmt); + n->conditionname = $2; - $$ = (Node *)n; + $$ = (Node *) n; } | UNLISTEN '*' { UnlistenStmt *n = makeNode(UnlistenStmt); + n->conditionname = NULL; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -9918,109 +11174,144 @@ 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; - $$ = (Node *)n; - } - | BEGIN_P opt_transaction transaction_mode_list_or_empty - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_BEGIN; - n->options = $3; - $$ = (Node *)n; + n->chain = $3; + n->location = -1; + $$ = (Node *) n; } | START TRANSACTION transaction_mode_list_or_empty { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_START; n->options = $3; - $$ = (Node *)n; - } - | COMMIT opt_transaction - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_COMMIT; - n->options = NIL; - $$ = (Node *)n; + n->location = -1; + $$ = (Node *) n; } - | END_P opt_transaction + | COMMIT opt_transaction opt_transaction_chain { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_COMMIT; n->options = NIL; - $$ = (Node *)n; + n->chain = $3; + n->location = -1; + $$ = (Node *) n; } - | ROLLBACK opt_transaction + | ROLLBACK opt_transaction opt_transaction_chain { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_ROLLBACK; n->options = NIL; - $$ = (Node *)n; + n->chain = $3; + n->location = -1; + $$ = (Node *) n; } | SAVEPOINT ColId { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_SAVEPOINT; n->savepoint_name = $2; - $$ = (Node *)n; + n->location = @2; + $$ = (Node *) n; } | RELEASE SAVEPOINT ColId { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_RELEASE; n->savepoint_name = $3; - $$ = (Node *)n; + n->location = @3; + $$ = (Node *) n; } | RELEASE ColId { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_RELEASE; n->savepoint_name = $2; - $$ = (Node *)n; + n->location = @2; + $$ = (Node *) n; } | ROLLBACK opt_transaction TO SAVEPOINT ColId { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_ROLLBACK_TO; n->savepoint_name = $5; - $$ = (Node *)n; + n->location = @5; + $$ = (Node *) n; } | ROLLBACK opt_transaction TO ColId { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_ROLLBACK_TO; n->savepoint_name = $4; - $$ = (Node *)n; + n->location = @4; + $$ = (Node *) n; } | PREPARE TRANSACTION Sconst { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_PREPARE; n->gid = $3; - $$ = (Node *)n; + n->location = @3; + $$ = (Node *) n; } | COMMIT PREPARED Sconst { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_COMMIT_PREPARED; n->gid = $3; - $$ = (Node *)n; + n->location = @3; + $$ = (Node *) n; } | ROLLBACK PREPARED Sconst { TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_ROLLBACK_PREPARED; n->gid = $3; - $$ = (Node *)n; + n->location = @3; + $$ = (Node *) n; + } + ; + +TransactionStmtLegacy: + BEGIN_P opt_transaction transaction_mode_list_or_empty + { + TransactionStmt *n = makeNode(TransactionStmt); + + n->kind = TRANS_STMT_BEGIN; + n->options = $3; + n->location = -1; + $$ = (Node *) n; + } + | END_P opt_transaction opt_transaction_chain + { + TransactionStmt *n = makeNode(TransactionStmt); + + n->kind = TRANS_STMT_COMMIT; + n->options = NIL; + n->chain = $3; + n->location = -1; + $$ = (Node *) n; } ; -opt_transaction: WORK {} - | TRANSACTION {} - | /*EMPTY*/ {} +opt_transaction: WORK + | TRANSACTION + | /*EMPTY*/ ; transaction_mode_item: @@ -10057,6 +11348,12 @@ transaction_mode_list_or_empty: { $$ = NIL; } ; +opt_transaction_chain: + AND CHAIN { $$ = true; } + | AND NO CHAIN { $$ = false; } + | /* EMPTY */ { $$ = false; } + ; + /***************************************************************************** * @@ -10069,7 +11366,8 @@ transaction_mode_list_or_empty: ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list opt_reloptions AS SelectStmt opt_check_option { - ViewStmt *n = makeNode(ViewStmt); + ViewStmt *n = makeNode(ViewStmt); + n->view = $4; n->view->relpersistence = $2; n->aliases = $5; @@ -10082,7 +11380,8 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list opt_reloptions | CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list opt_reloptions AS SelectStmt opt_check_option { - ViewStmt *n = makeNode(ViewStmt); + ViewStmt *n = makeNode(ViewStmt); + n->view = $6; n->view->relpersistence = $4; n->aliases = $7; @@ -10095,7 +11394,8 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list opt_reloptions | CREATE OptTemp RECURSIVE VIEW qualified_name '(' columnList ')' opt_reloptions AS SelectStmt opt_check_option { - ViewStmt *n = makeNode(ViewStmt); + ViewStmt *n = makeNode(ViewStmt); + n->view = $5; n->view->relpersistence = $2; n->aliases = $7; @@ -10113,7 +11413,8 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list opt_reloptions | CREATE OR REPLACE OptTemp RECURSIVE VIEW qualified_name '(' columnList ')' opt_reloptions AS SelectStmt opt_check_option { - ViewStmt *n = makeNode(ViewStmt); + ViewStmt *n = makeNode(ViewStmt); + n->view = $7; n->view->relpersistence = $4; n->aliases = $9; @@ -10146,9 +11447,10 @@ opt_check_option: LoadStmt: LOAD file_name { - LoadStmt *n = makeNode(LoadStmt); + LoadStmt *n = makeNode(LoadStmt); + n->filename = $2; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -10160,12 +11462,13 @@ LoadStmt: LOAD file_name *****************************************************************************/ CreatedbStmt: - CREATE DATABASE database_name opt_with createdb_opt_list + CREATE DATABASE name opt_with createdb_opt_list { CreatedbStmt *n = makeNode(CreatedbStmt); + n->dbname = $3; n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -10180,13 +11483,13 @@ createdb_opt_items: ; createdb_opt_item: - createdb_opt_name opt_equal SignedIconst + createdb_opt_name opt_equal NumericOnly { - $$ = makeDefElem($1, (Node *)makeInteger($3), @1); + $$ = makeDefElem($1, $3, @1); } | createdb_opt_name opt_equal opt_boolean_or_string { - $$ = makeDefElem($1, (Node *)makeString($3), @1); + $$ = makeDefElem($1, (Node *) makeString($3), @1); } | createdb_opt_name opt_equal DEFAULT { @@ -10219,8 +11522,8 @@ createdb_opt_name: * Though the equals sign doesn't match other WITH options, pg_dump uses * equals for backward compatibility, and it doesn't seem worth removing it. */ -opt_equal: '=' {} - | /*EMPTY*/ {} +opt_equal: '=' + | /*EMPTY*/ ; @@ -10231,76 +11534,131 @@ opt_equal: '=' {} *****************************************************************************/ AlterDatabaseStmt: - ALTER DATABASE database_name WITH createdb_opt_list + ALTER DATABASE name WITH createdb_opt_list { AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt); + n->dbname = $3; n->options = $5; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER DATABASE database_name createdb_opt_list + | ALTER DATABASE name createdb_opt_list { AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt); + n->dbname = $3; n->options = $4; - $$ = (Node *)n; + $$ = (Node *) n; } - | ALTER DATABASE database_name SET TABLESPACE name + | ALTER DATABASE name SET TABLESPACE name { AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt); + n->dbname = $3; n->options = list_make1(makeDefElem("tablespace", - (Node *)makeString($6), @6)); - $$ = (Node *)n; + (Node *) makeString($6), @6)); + $$ = (Node *) n; + } + | ALTER DATABASE name REFRESH COLLATION VERSION_P + { + AlterDatabaseRefreshCollStmt *n = makeNode(AlterDatabaseRefreshCollStmt); + + n->dbname = $3; + $$ = (Node *) n; } ; AlterDatabaseSetStmt: - ALTER DATABASE database_name SetResetClause + ALTER DATABASE name SetResetClause { AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt); + n->dbname = $3; n->setstmt = $4; - $$ = (Node *)n; + $$ = (Node *) n; } ; /***************************************************************************** * - * DROP DATABASE [ IF EXISTS ] + * DROP DATABASE [ IF EXISTS ] dbname [ [ WITH ] ( options ) ] * * This is implicitly CASCADE, no need for drop behavior *****************************************************************************/ -DropdbStmt: DROP DATABASE database_name +DropdbStmt: DROP DATABASE name { DropdbStmt *n = makeNode(DropdbStmt); + n->dbname = $3; n->missing_ok = false; - $$ = (Node *)n; + n->options = NULL; + $$ = (Node *) n; } - | DROP DATABASE IF_P EXISTS database_name + | DROP DATABASE IF_P EXISTS name { DropdbStmt *n = makeNode(DropdbStmt); + n->dbname = $5; n->missing_ok = true; - $$ = (Node *)n; + n->options = NULL; + $$ = (Node *) n; } - ; + | DROP DATABASE name opt_with '(' drop_option_list ')' + { + DropdbStmt *n = makeNode(DropdbStmt); + n->dbname = $3; + n->missing_ok = false; + n->options = $6; + $$ = (Node *) n; + } + | DROP DATABASE IF_P EXISTS name opt_with '(' drop_option_list ')' + { + DropdbStmt *n = makeNode(DropdbStmt); -/***************************************************************************** - * - * ALTER COLLATION + n->dbname = $5; + n->missing_ok = true; + n->options = $8; + $$ = (Node *) n; + } + ; + +drop_option_list: + drop_option + { + $$ = list_make1((Node *) $1); + } + | drop_option_list ',' drop_option + { + $$ = lappend($1, (Node *) $3); + } + ; + +/* + * Currently only the FORCE option is supported, but the syntax is designed + * to be extensible so that we can add more options in the future if required. + */ +drop_option: + FORCE + { + $$ = makeDefElem("force", NULL, @1); + } + ; + +/***************************************************************************** + * + * ALTER COLLATION * *****************************************************************************/ AlterCollationStmt: ALTER COLLATION any_name REFRESH VERSION_P { AlterCollationStmt *n = makeNode(AlterCollationStmt); + n->collname = $3; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -10316,14 +11674,16 @@ AlterSystemStmt: ALTER SYSTEM_P SET generic_set { AlterSystemStmt *n = makeNode(AlterSystemStmt); + n->setstmt = $4; - $$ = (Node *)n; + $$ = (Node *) n; } | ALTER SYSTEM_P RESET generic_reset { AlterSystemStmt *n = makeNode(AlterSystemStmt); + n->setstmt = $4; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -10338,11 +11698,12 @@ CreateDomainStmt: CREATE DOMAIN_P any_name opt_as Typename ColQualList { CreateDomainStmt *n = makeNode(CreateDomainStmt); + n->domainname = $3; n->typeName = $5; SplitColQualList($6, &n->constraints, &n->collClause, yyscanner); - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -10351,71 +11712,78 @@ AlterDomainStmt: ALTER DOMAIN_P any_name alter_column_default { AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'T'; n->typeName = $3; n->def = $4; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER DOMAIN DROP NOT NULL */ | ALTER DOMAIN_P any_name DROP NOT NULL_P { AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'N'; n->typeName = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER DOMAIN SET NOT NULL */ | ALTER DOMAIN_P any_name SET NOT NULL_P { AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'O'; n->typeName = $3; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER DOMAIN ADD CONSTRAINT ... */ - | ALTER DOMAIN_P any_name ADD_P TableConstraint + | ALTER DOMAIN_P any_name ADD_P DomainConstraint { AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'C'; n->typeName = $3; n->def = $5; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER DOMAIN DROP CONSTRAINT [RESTRICT|CASCADE] */ | ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior { AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'X'; n->typeName = $3; n->name = $6; n->behavior = $7; n->missing_ok = false; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER DOMAIN DROP CONSTRAINT IF EXISTS [RESTRICT|CASCADE] */ | ALTER DOMAIN_P any_name DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior { AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'X'; n->typeName = $3; n->name = $8; n->behavior = $9; n->missing_ok = true; - $$ = (Node *)n; + $$ = (Node *) n; } /* ALTER DOMAIN VALIDATE CONSTRAINT */ | ALTER DOMAIN_P any_name VALIDATE CONSTRAINT name { AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'V'; n->typeName = $3; n->name = $6; - $$ = (Node *)n; + $$ = (Node *) n; } ; -opt_as: AS {} - | /* EMPTY */ {} +opt_as: AS + | /* EMPTY */ ; @@ -10429,9 +11797,10 @@ AlterTSDictionaryStmt: ALTER TEXT_P SEARCH DICTIONARY any_name definition { AlterTSDictionaryStmt *n = makeNode(AlterTSDictionaryStmt); + n->dictname = $5; n->options = $6; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -10439,70 +11808,76 @@ AlterTSConfigurationStmt: ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list any_with any_name_list { AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); + n->kind = ALTER_TSCONFIG_ADD_MAPPING; n->cfgname = $5; n->tokentype = $9; n->dicts = $11; n->override = false; n->replace = false; - $$ = (Node*)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list any_with any_name_list { AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); + n->kind = ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN; n->cfgname = $5; n->tokentype = $9; n->dicts = $11; n->override = true; n->replace = false; - $$ = (Node*)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name any_with any_name { AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); + n->kind = ALTER_TSCONFIG_REPLACE_DICT; n->cfgname = $5; n->tokentype = NIL; n->dicts = list_make2($9,$11); n->override = false; n->replace = true; - $$ = (Node*)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name any_with any_name { AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); + n->kind = ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN; n->cfgname = $5; n->tokentype = $9; n->dicts = list_make2($11,$13); n->override = false; n->replace = true; - $$ = (Node*)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list { AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); + n->kind = ALTER_TSCONFIG_DROP_MAPPING; n->cfgname = $5; n->tokentype = $9; n->missing_ok = false; - $$ = (Node*)n; + $$ = (Node *) n; } | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list { AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt); + n->kind = ALTER_TSCONFIG_DROP_MAPPING; n->cfgname = $5; n->tokentype = $11; n->missing_ok = true; - $$ = (Node*)n; + $$ = (Node *) n; } ; /* Use this if TIME or ORDINALITY after WITH should be taken as an identifier */ -any_with: WITH {} - | WITH_LA {} +any_with: WITH + | WITH_LA ; @@ -10520,54 +11895,84 @@ CreateConversionStmt: TO Sconst FROM any_name { CreateConversionStmt *n = makeNode(CreateConversionStmt); + n->conversion_name = $4; n->for_encoding_name = $6; n->to_encoding_name = $8; n->func_name = $10; n->def = $2; - $$ = (Node *)n; + $$ = (Node *) n; } ; /***************************************************************************** * * QUERY: - * CLUSTER [VERBOSE] [ USING ] - * CLUSTER [VERBOSE] + * CLUSTER (options) [ [ USING ] ] + * CLUSTER [VERBOSE] [ [ USING ] ] * CLUSTER [VERBOSE] ON (for pre-8.3) * *****************************************************************************/ ClusterStmt: - CLUSTER opt_verbose qualified_name cluster_index_specification + CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification + { + ClusterStmt *n = makeNode(ClusterStmt); + + n->relation = $5; + n->indexname = $6; + n->params = $3; + $$ = (Node *) n; + } + | CLUSTER '(' utility_option_list ')' + { + ClusterStmt *n = makeNode(ClusterStmt); + + n->relation = NULL; + n->indexname = NULL; + n->params = $3; + $$ = (Node *) n; + } + /* unparenthesized VERBOSE kept for pre-14 compatibility */ + | CLUSTER opt_verbose qualified_name cluster_index_specification { ClusterStmt *n = makeNode(ClusterStmt); + n->relation = $3; n->indexname = $4; - n->verbose = $2; - $$ = (Node*)n; + n->params = NIL; + if ($2) + n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + $$ = (Node *) n; } + /* unparenthesized VERBOSE kept for pre-17 compatibility */ | CLUSTER opt_verbose { ClusterStmt *n = makeNode(ClusterStmt); + n->relation = NULL; n->indexname = NULL; - n->verbose = $2; - $$ = (Node*)n; + n->params = NIL; + if ($2) + n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + $$ = (Node *) n; } /* kept for pre-8.3 compatibility */ - | CLUSTER opt_verbose index_name ON qualified_name + | CLUSTER opt_verbose name ON qualified_name { ClusterStmt *n = makeNode(ClusterStmt); + n->relation = $5; n->indexname = $3; - n->verbose = $2; - $$ = (Node*)n; + n->params = NIL; + if ($2) + n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + $$ = (Node *) n; } ; cluster_index_specification: - USING index_name { $$ = $2; } + USING name { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; @@ -10583,79 +11988,91 @@ 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; - $$ = (Node *)n; + n->is_vacuumcmd = true; + $$ = (Node *) n; } - | VACUUM '(' vacuum_option_list ')' opt_vacuum_relation_list + | VACUUM '(' utility_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; - $$ = (Node *)n; + n->is_vacuumcmd = false; + $$ = (Node *) n; } - | analyze_keyword '(' analyze_option_list ')' opt_vacuum_relation_list + | analyze_keyword '(' utility_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; } +utility_option_list: + utility_option_elem + { + $$ = list_make1($1); + } + | utility_option_list ',' utility_option_elem + { + $$ = lappend($1, $3); + } + ; + +analyze_keyword: + ANALYZE + | ANALYSE /* British */ + ; + +utility_option_elem: + utility_option_name utility_option_arg + { + $$ = makeDefElem($1, $2, @1); + } ; -analyze_option_elem: - VERBOSE { $$ = VACOPT_VERBOSE; } +utility_option_name: + NonReservedWord { $$ = $1; } + | analyze_keyword { $$ = "analyze"; } + | FORMAT_LA { $$ = "format"; } ; -analyze_keyword: - ANALYZE {} - | ANALYSE /* British */ {} +utility_option_arg: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + | NumericOnly { $$ = (Node *) $1; } + | /* EMPTY */ { $$ = NULL; } ; opt_analyze: @@ -10682,7 +12099,7 @@ opt_name_list: ; vacuum_relation: - qualified_name opt_name_list + relation_expr opt_name_list { $$ = (Node *) makeVacuumRelation($1, InvalidOid, $2); } @@ -10713,6 +12130,7 @@ ExplainStmt: EXPLAIN ExplainableStmt { ExplainStmt *n = makeNode(ExplainStmt); + n->query = $2; n->options = NIL; $$ = (Node *) n; @@ -10720,6 +12138,7 @@ ExplainStmt: | EXPLAIN analyze_keyword opt_verbose ExplainableStmt { ExplainStmt *n = makeNode(ExplainStmt); + n->query = $4; n->options = list_make1(makeDefElem("analyze", NULL, @2)); if ($3) @@ -10730,13 +12149,15 @@ ExplainStmt: | EXPLAIN VERBOSE ExplainableStmt { ExplainStmt *n = makeNode(ExplainStmt); + n->query = $3; n->options = list_make1(makeDefElem("verbose", NULL, @2)); $$ = (Node *) n; } - | EXPLAIN '(' explain_option_list ')' ExplainableStmt + | EXPLAIN '(' utility_option_list ')' ExplainableStmt { ExplainStmt *n = makeNode(ExplainStmt); + n->query = $5; n->options = $3; $$ = (Node *) n; @@ -10748,6 +12169,7 @@ ExplainableStmt: | InsertStmt | UpdateStmt | DeleteStmt + | MergeStmt | DeclareCursorStmt | CreateAsStmt | CreateMatViewStmt @@ -10755,35 +12177,6 @@ ExplainableStmt: | ExecuteStmt /* by default all are $$=$1 */ ; -explain_option_list: - explain_option_elem - { - $$ = list_make1($1); - } - | explain_option_list ',' explain_option_elem - { - $$ = lappend($1, $3); - } - ; - -explain_option_elem: - explain_option_name explain_option_arg - { - $$ = makeDefElem($1, $2, @1); - } - ; - -explain_option_name: - NonReservedWord { $$ = $1; } - | analyze_keyword { $$ = "analyze"; } - ; - -explain_option_arg: - opt_boolean_or_string { $$ = (Node *) makeString($1); } - | NumericOnly { $$ = (Node *) $1; } - | /* EMPTY */ { $$ = NULL; } - ; - /***************************************************************************** * * QUERY: @@ -10794,6 +12187,7 @@ explain_option_arg: PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt { PrepareStmt *n = makeNode(PrepareStmt); + n->name = $2; n->argtypes = $3; n->query = $5; @@ -10809,7 +12203,8 @@ PreparableStmt: SelectStmt | InsertStmt | UpdateStmt - | DeleteStmt /* by default all are $$=$1 */ + | DeleteStmt + | MergeStmt /* by default all are $$=$1 */ ; /***************************************************************************** @@ -10822,6 +12217,7 @@ PreparableStmt: ExecuteStmt: EXECUTE name execute_param_clause { ExecuteStmt *n = makeNode(ExecuteStmt); + n->name = $2; n->params = $3; $$ = (Node *) n; @@ -10831,17 +12227,37 @@ ExecuteStmt: EXECUTE name execute_param_clause { CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); ExecuteStmt *n = makeNode(ExecuteStmt); + n->name = $7; n->params = $8; ctas->query = (Node *) n; ctas->into = $4; - ctas->relkind = OBJECT_TABLE; + ctas->objtype = 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->objtype = 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; } @@ -10858,25 +12274,37 @@ execute_param_clause: '(' expr_list ')' { $$ = $2; } DeallocateStmt: DEALLOCATE name { DeallocateStmt *n = makeNode(DeallocateStmt); + n->name = $2; + n->isall = false; + n->location = @2; $$ = (Node *) n; } | DEALLOCATE PREPARE name { DeallocateStmt *n = makeNode(DeallocateStmt); + n->name = $3; + n->isall = false; + n->location = @3; $$ = (Node *) n; } | DEALLOCATE ALL { DeallocateStmt *n = makeNode(DeallocateStmt); + n->name = NULL; + n->isall = true; + n->location = -1; $$ = (Node *) n; } | DEALLOCATE PREPARE ALL { DeallocateStmt *n = makeNode(DeallocateStmt); + n->name = NULL; + n->isall = true; + n->location = -1; $$ = (Node *) n; } ; @@ -10894,7 +12322,7 @@ InsertStmt: { $5->relation = $4; $5->onConflictClause = $6; - $5->returningList = $7; + $5->returningClause = $7; $5->withClause = $1; $$ = (Node *) $5; } @@ -11027,8 +12455,45 @@ opt_conf_expr: ; returning_clause: - RETURNING target_list { $$ = $2; } - | /* EMPTY */ { $$ = NIL; } + RETURNING returning_with_clause target_list + { + ReturningClause *n = makeNode(ReturningClause); + + n->options = $2; + n->exprs = $3; + $$ = n; + } + | /* EMPTY */ + { + $$ = NULL; + } + ; + +returning_with_clause: + WITH '(' returning_options ')' { $$ = $3; } + | /* EMPTY */ { $$ = NIL; } + ; + +returning_options: + returning_option { $$ = list_make1($1); } + | returning_options ',' returning_option { $$ = lappend($1, $3); } + ; + +returning_option: + returning_option_kind AS ColId + { + ReturningOption *n = makeNode(ReturningOption); + + n->option = $1; + n->value = $3; + n->location = @1; + $$ = (Node *) n; + } + ; + +returning_option_kind: + OLD { $$ = RETURNING_OPTION_OLD; } + | NEW { $$ = RETURNING_OPTION_NEW; } ; @@ -11043,12 +12508,13 @@ DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause { DeleteStmt *n = makeNode(DeleteStmt); + n->relation = $4; n->usingClause = $5; n->whereClause = $6; - n->returningList = $7; + n->returningClause = $7; n->withClause = $1; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -11067,12 +12533,12 @@ using_clause: LockStmt: LOCK_P opt_table relation_expr_list opt_lock opt_nowait { - LockStmt *n = makeNode(LockStmt); + LockStmt *n = makeNode(LockStmt); n->relations = $3; n->mode = $4; n->nowait = $5; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -11115,16 +12581,16 @@ UpdateStmt: opt_with_clause UPDATE relation_expr_opt_alias returning_clause { UpdateStmt *n = makeNode(UpdateStmt); + n->relation = $3; n->targetList = $5; n->fromClause = $6; n->whereClause = $7; - n->returningList = $8; + n->returningClause = $8; n->withClause = $1; - $$ = (Node *)n; + $$ = (Node *) n; } ; - set_clause_list: set_clause { $$ = $1; } | set_clause_list ',' set_clause { $$ = list_concat($1,$3); } @@ -11138,14 +12604,14 @@ set_clause: } | '(' set_target_list ')' '=' a_expr { - int ncolumns = list_length($2); - int i = 1; - ListCell *col_cell; + int ncolumns = list_length($2); + int i = 1; + ListCell *col_cell; /* Create a MultiAssignRef source for each target */ foreach(col_cell, $2) { - ResTarget *res_col = (ResTarget *) lfirst(col_cell); + ResTarget *res_col = (ResTarget *) lfirst(col_cell); MultiAssignRef *r = makeNode(MultiAssignRef); r->source = (Node *) $5; @@ -11179,50 +12645,230 @@ set_target_list: /***************************************************************************** * * QUERY: - * CURSOR STATEMENTS + * MERGE * *****************************************************************************/ -DeclareCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR SelectStmt + +MergeStmt: + opt_with_clause MERGE INTO relation_expr_opt_alias + USING table_ref + ON a_expr + merge_when_list + returning_clause { - DeclareCursorStmt *n = makeNode(DeclareCursorStmt); - n->portalname = $2; - /* currently we always set FAST_PLAN option */ - n->options = $3 | $5 | CURSOR_OPT_FAST_PLAN; - n->query = $7; - $$ = (Node *)n; + MergeStmt *m = makeNode(MergeStmt); + + m->withClause = $1; + m->relation = $4; + m->sourceRelation = $6; + m->joinCondition = $8; + m->mergeWhenClauses = $9; + m->returningClause = $10; + + $$ = (Node *) m; } ; -cursor_name: name { $$ = $1; } +merge_when_list: + merge_when_clause { $$ = list_make1($1); } + | merge_when_list merge_when_clause { $$ = lappend($1,$2); } ; -cursor_options: /*EMPTY*/ { $$ = 0; } - | cursor_options NO SCROLL { $$ = $1 | CURSOR_OPT_NO_SCROLL; } - | cursor_options SCROLL { $$ = $1 | CURSOR_OPT_SCROLL; } - | cursor_options BINARY { $$ = $1 | CURSOR_OPT_BINARY; } - | cursor_options INSENSITIVE { $$ = $1 | CURSOR_OPT_INSENSITIVE; } +/* + * A WHEN clause may be WHEN MATCHED, WHEN NOT MATCHED BY SOURCE, or WHEN NOT + * MATCHED [BY TARGET]. The first two cases match target tuples, and support + * UPDATE/DELETE/DO NOTHING actions. The third case does not match target + * tuples, and only supports INSERT/DO NOTHING actions. + */ +merge_when_clause: + merge_when_tgt_matched opt_merge_when_condition THEN merge_update + { + $4->matchKind = $1; + $4->condition = $2; + + $$ = (Node *) $4; + } + | merge_when_tgt_matched opt_merge_when_condition THEN merge_delete + { + $4->matchKind = $1; + $4->condition = $2; + + $$ = (Node *) $4; + } + | merge_when_tgt_not_matched opt_merge_when_condition THEN merge_insert + { + $4->matchKind = $1; + $4->condition = $2; + + $$ = (Node *) $4; + } + | merge_when_tgt_matched opt_merge_when_condition THEN DO NOTHING + { + MergeWhenClause *m = makeNode(MergeWhenClause); + + m->matchKind = $1; + m->commandType = CMD_NOTHING; + m->condition = $2; + + $$ = (Node *) m; + } + | merge_when_tgt_not_matched opt_merge_when_condition THEN DO NOTHING + { + MergeWhenClause *m = makeNode(MergeWhenClause); + + m->matchKind = $1; + m->commandType = CMD_NOTHING; + m->condition = $2; + + $$ = (Node *) m; + } ; -opt_hold: /* EMPTY */ { $$ = 0; } - | WITH HOLD { $$ = CURSOR_OPT_HOLD; } - | WITHOUT HOLD { $$ = 0; } +merge_when_tgt_matched: + WHEN MATCHED { $$ = MERGE_WHEN_MATCHED; } + | WHEN NOT MATCHED BY SOURCE { $$ = MERGE_WHEN_NOT_MATCHED_BY_SOURCE; } ; -/***************************************************************************** - * - * QUERY: - * SELECT STATEMENTS - * - *****************************************************************************/ +merge_when_tgt_not_matched: + WHEN NOT MATCHED { $$ = MERGE_WHEN_NOT_MATCHED_BY_TARGET; } + | WHEN NOT MATCHED BY TARGET { $$ = MERGE_WHEN_NOT_MATCHED_BY_TARGET; } + ; -/* A complete SELECT statement looks like this. - * - * The rule returns either a single SelectStmt node or a tree of them, - * representing a set-operation tree. - * - * There is an ambiguity when a sub-SELECT is within an a_expr and there - * are excess parentheses: do the parentheses belong to the sub-SELECT or - * to the surrounding a_expr? We don't really care, but bison wants to know. +opt_merge_when_condition: + AND a_expr { $$ = $2; } + | { $$ = NULL; } + ; + +merge_update: + UPDATE SET set_clause_list + { + MergeWhenClause *n = makeNode(MergeWhenClause); + n->commandType = CMD_UPDATE; + n->override = OVERRIDING_NOT_SET; + n->targetList = $3; + n->values = NIL; + + $$ = n; + } + ; + +merge_delete: + DELETE_P + { + MergeWhenClause *n = makeNode(MergeWhenClause); + n->commandType = CMD_DELETE; + n->override = OVERRIDING_NOT_SET; + n->targetList = NIL; + n->values = NIL; + + $$ = n; + } + ; + +merge_insert: + INSERT merge_values_clause + { + MergeWhenClause *n = makeNode(MergeWhenClause); + n->commandType = CMD_INSERT; + n->override = OVERRIDING_NOT_SET; + n->targetList = NIL; + n->values = $2; + $$ = n; + } + | INSERT OVERRIDING override_kind VALUE_P merge_values_clause + { + MergeWhenClause *n = makeNode(MergeWhenClause); + n->commandType = CMD_INSERT; + n->override = $3; + n->targetList = NIL; + n->values = $5; + $$ = n; + } + | INSERT '(' insert_column_list ')' merge_values_clause + { + MergeWhenClause *n = makeNode(MergeWhenClause); + n->commandType = CMD_INSERT; + n->override = OVERRIDING_NOT_SET; + n->targetList = $3; + n->values = $5; + $$ = n; + } + | INSERT '(' insert_column_list ')' OVERRIDING override_kind VALUE_P merge_values_clause + { + MergeWhenClause *n = makeNode(MergeWhenClause); + n->commandType = CMD_INSERT; + n->override = $6; + n->targetList = $3; + n->values = $8; + $$ = n; + } + | INSERT DEFAULT VALUES + { + MergeWhenClause *n = makeNode(MergeWhenClause); + n->commandType = CMD_INSERT; + n->override = OVERRIDING_NOT_SET; + n->targetList = NIL; + n->values = NIL; + $$ = n; + } + ; + +merge_values_clause: + VALUES '(' expr_list ')' + { + $$ = $3; + } + ; + +/***************************************************************************** + * + * QUERY: + * CURSOR STATEMENTS + * + *****************************************************************************/ +DeclareCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR SelectStmt + { + DeclareCursorStmt *n = makeNode(DeclareCursorStmt); + + n->portalname = $2; + /* currently we always set FAST_PLAN option */ + n->options = $3 | $5 | CURSOR_OPT_FAST_PLAN; + n->query = $7; + $$ = (Node *) n; + } + ; + +cursor_name: name { $$ = $1; } + ; + +cursor_options: /*EMPTY*/ { $$ = 0; } + | cursor_options NO SCROLL { $$ = $1 | CURSOR_OPT_NO_SCROLL; } + | cursor_options SCROLL { $$ = $1 | CURSOR_OPT_SCROLL; } + | cursor_options BINARY { $$ = $1 | CURSOR_OPT_BINARY; } + | cursor_options ASENSITIVE { $$ = $1 | CURSOR_OPT_ASENSITIVE; } + | cursor_options INSENSITIVE { $$ = $1 | CURSOR_OPT_INSENSITIVE; } + ; + +opt_hold: /* EMPTY */ { $$ = 0; } + | WITH HOLD { $$ = CURSOR_OPT_HOLD; } + | WITHOUT HOLD { $$ = 0; } + ; + +/***************************************************************************** + * + * QUERY: + * SELECT STATEMENTS + * + *****************************************************************************/ + +/* A complete SELECT statement looks like this. + * + * The rule returns either a single SelectStmt node or a tree of them, + * representing a set-operation tree. + * + * There is an ambiguity when a sub-SELECT is within an a_expr and there + * are excess parentheses: do the parentheses belong to the sub-SELECT or + * to the surrounding a_expr? We don't really care, but bison wants to know. * To resolve the ambiguity, we are careful to define the grammar so that * the decision is staved off as long as possible: as long as we can keep * absorbing parentheses into the sub-SELECT, we will do so, and only when @@ -11278,14 +12924,14 @@ select_no_parens: | select_clause sort_clause { insertSelectOptions((SelectStmt *) $1, $2, NIL, - NULL, NULL, NULL, + NULL, NULL, yyscanner); $$ = $1; } | select_clause opt_sort_clause for_locking_clause opt_select_limit { insertSelectOptions((SelectStmt *) $1, $2, $3, - list_nth($4, 0), list_nth($4, 1), + $4, NULL, yyscanner); $$ = $1; @@ -11293,7 +12939,7 @@ select_no_parens: | select_clause opt_sort_clause select_limit opt_for_locking_clause { insertSelectOptions((SelectStmt *) $1, $2, $4, - list_nth($3, 0), list_nth($3, 1), + $3, NULL, yyscanner); $$ = $1; @@ -11301,7 +12947,7 @@ select_no_parens: | with_clause select_clause { insertSelectOptions((SelectStmt *) $2, NULL, NIL, - NULL, NULL, + NULL, $1, yyscanner); $$ = $2; @@ -11309,7 +12955,7 @@ select_no_parens: | with_clause select_clause sort_clause { insertSelectOptions((SelectStmt *) $2, $3, NIL, - NULL, NULL, + NULL, $1, yyscanner); $$ = $2; @@ -11317,7 +12963,7 @@ select_no_parens: | with_clause select_clause opt_sort_clause for_locking_clause opt_select_limit { insertSelectOptions((SelectStmt *) $2, $3, $4, - list_nth($5, 0), list_nth($5, 1), + $5, $1, yyscanner); $$ = $2; @@ -11325,7 +12971,7 @@ select_no_parens: | with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause { insertSelectOptions((SelectStmt *) $2, $3, $5, - list_nth($4, 0), list_nth($4, 1), + $4, $1, yyscanner); $$ = $2; @@ -11346,6 +12992,11 @@ select_clause: * As with select_no_parens, simple_select cannot have outer parentheses, * but can have parenthesized subclauses. * + * It might appear that we could fold the first two alternatives into one + * by using opt_distinct_clause. However, that causes a shift/reduce conflict + * against INSERT ... SELECT ... ON CONFLICT. We avoid the ambiguity by + * requiring SELECT DISTINCT [ON] to be followed by a non-empty target_list. + * * Note that sort clauses cannot be included at this level --- SQL requires * SELECT foo UNION SELECT bar ORDER BY baz * to be parsed as @@ -11366,36 +13017,40 @@ simple_select: group_clause having_clause window_clause { SelectStmt *n = makeNode(SelectStmt); + n->targetList = $3; n->intoClause = $4; n->fromClause = $5; n->whereClause = $6; - n->groupClause = $7; + n->groupClause = ($7)->list; + n->groupDistinct = ($7)->distinct; n->havingClause = $8; n->windowClause = $9; - $$ = (Node *)n; + $$ = (Node *) n; } | SELECT distinct_clause target_list into_clause from_clause where_clause group_clause having_clause window_clause { SelectStmt *n = makeNode(SelectStmt); + n->distinctClause = $2; n->targetList = $3; n->intoClause = $4; n->fromClause = $5; n->whereClause = $6; - n->groupClause = $7; + n->groupClause = ($7)->list; + n->groupDistinct = ($7)->distinct; n->havingClause = $8; n->windowClause = $9; - $$ = (Node *)n; + $$ = (Node *) n; } | values_clause { $$ = $1; } | TABLE relation_expr { /* same as SELECT * FROM relation_expr */ - ColumnRef *cr = makeNode(ColumnRef); - ResTarget *rt = makeNode(ResTarget); + ColumnRef *cr = makeNode(ColumnRef); + ResTarget *rt = makeNode(ResTarget); SelectStmt *n = makeNode(SelectStmt); cr->fields = list_make1(makeNode(A_Star)); @@ -11403,24 +13058,24 @@ simple_select: rt->name = NULL; rt->indirection = NIL; - rt->val = (Node *)cr; + rt->val = (Node *) cr; rt->location = -1; n->targetList = list_make1(rt); n->fromClause = list_make1($2); - $$ = (Node *)n; + $$ = (Node *) n; } - | select_clause UNION all_or_distinct select_clause + | select_clause UNION set_quantifier select_clause { - $$ = makeSetOp(SETOP_UNION, $3, $1, $4); + $$ = makeSetOp(SETOP_UNION, $3 == SET_QUANTIFIER_ALL, $1, $4); } - | select_clause INTERSECT all_or_distinct select_clause + | select_clause INTERSECT set_quantifier select_clause { - $$ = makeSetOp(SETOP_INTERSECT, $3, $1, $4); + $$ = makeSetOp(SETOP_INTERSECT, $3 == SET_QUANTIFIER_ALL, $1, $4); } - | select_clause EXCEPT all_or_distinct select_clause + | select_clause EXCEPT set_quantifier select_clause { - $$ = makeSetOp(SETOP_EXCEPT, $3, $1, $4); + $$ = makeSetOp(SETOP_EXCEPT, $3 == SET_QUANTIFIER_ALL, $1, $4); } ; @@ -11430,8 +13085,6 @@ simple_select: * WITH [ RECURSIVE ] [ (,...) ] * AS (query) [ SEARCH or CYCLE clause ] * - * We don't currently support the SEARCH or CYCLE clause. - * * Recognizing WITH_LA here allows a CTE to be named TIME or ORDINALITY. */ with_clause: @@ -11463,15 +13116,83 @@ 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 ')' opt_search_clause opt_cycle_clause { CommonTableExpr *n = makeNode(CommonTableExpr); + n->ctename = $1; n->aliascolnames = $2; - n->ctequery = $5; + n->ctematerialized = $4; + n->ctequery = $6; + n->search_clause = castNode(CTESearchClause, $8); + n->cycle_clause = castNode(CTECycleClause, $9); + n->location = @1; + $$ = (Node *) n; + } + ; + +opt_materialized: + MATERIALIZED { $$ = CTEMaterializeAlways; } + | NOT MATERIALIZED { $$ = CTEMaterializeNever; } + | /*EMPTY*/ { $$ = CTEMaterializeDefault; } + ; + +opt_search_clause: + SEARCH DEPTH FIRST_P BY columnList SET ColId + { + CTESearchClause *n = makeNode(CTESearchClause); + + n->search_col_list = $5; + n->search_breadth_first = false; + n->search_seq_column = $7; + n->location = @1; + $$ = (Node *) n; + } + | SEARCH BREADTH FIRST_P BY columnList SET ColId + { + CTESearchClause *n = makeNode(CTESearchClause); + + n->search_col_list = $5; + n->search_breadth_first = true; + n->search_seq_column = $7; + n->location = @1; + $$ = (Node *) n; + } + | /*EMPTY*/ + { + $$ = NULL; + } + ; + +opt_cycle_clause: + CYCLE columnList SET ColId TO AexprConst DEFAULT AexprConst USING ColId + { + CTECycleClause *n = makeNode(CTECycleClause); + + n->cycle_col_list = $2; + n->cycle_mark_column = $4; + n->cycle_mark_value = $6; + n->cycle_mark_default = $8; + n->cycle_path_column = $10; + n->location = @1; + $$ = (Node *) n; + } + | CYCLE columnList SET ColId USING ColId + { + CTECycleClause *n = makeNode(CTECycleClause); + + n->cycle_col_list = $2; + n->cycle_mark_column = $4; + n->cycle_mark_value = makeBoolAConst(true, -1); + n->cycle_mark_default = makeBoolAConst(false, -1); + n->cycle_path_column = $6; n->location = @1; $$ = (Node *) n; } + | /*EMPTY*/ + { + $$ = NULL; + } ; opt_with_clause: @@ -11553,14 +13274,14 @@ OptTempTableName: } ; -opt_table: TABLE {} - | /*EMPTY*/ {} +opt_table: TABLE + | /*EMPTY*/ ; -all_or_distinct: - ALL { $$ = true; } - | DISTINCT { $$ = false; } - | /*EMPTY*/ { $$ = false; } +set_quantifier: + ALL { $$ = SET_QUANTIFIER_ALL; } + | DISTINCT { $$ = SET_QUANTIFIER_DISTINCT; } + | /*EMPTY*/ { $$ = SET_QUANTIFIER_DEFAULT; } ; /* We use (NIL) as a placeholder to indicate that all target expressions @@ -11572,12 +13293,17 @@ distinct_clause: ; opt_all_clause: - ALL { $$ = NIL;} - | /*EMPTY*/ { $$ = NIL; } + ALL + | /*EMPTY*/ + ; + +opt_distinct_clause: + distinct_clause { $$ = $1; } + | opt_all_clause { $$ = NIL; } ; opt_sort_clause: - sort_clause { $$ = $1;} + sort_clause { $$ = $1; } | /*EMPTY*/ { $$ = NIL; } ; @@ -11612,20 +13338,54 @@ sortby: a_expr USING qual_all_Op opt_nulls_order select_limit: - limit_clause offset_clause { $$ = list_make2($2, $1); } - | offset_clause limit_clause { $$ = list_make2($1, $2); } - | limit_clause { $$ = list_make2(NULL, $1); } - | offset_clause { $$ = list_make2($1, NULL); } + limit_clause offset_clause + { + $$ = $1; + ($$)->limitOffset = $2; + ($$)->offsetLoc = @2; + } + | offset_clause limit_clause + { + $$ = $2; + ($$)->limitOffset = $1; + ($$)->offsetLoc = @1; + } + | limit_clause + { + $$ = $1; + } + | offset_clause + { + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + + n->limitOffset = $1; + n->limitCount = NULL; + n->limitOption = LIMIT_OPTION_COUNT; + n->offsetLoc = @1; + n->countLoc = -1; + n->optionLoc = -1; + $$ = n; + } ; opt_select_limit: select_limit { $$ = $1; } - | /* EMPTY */ { $$ = list_make2(NULL,NULL); } + | /* EMPTY */ { $$ = NULL; } ; limit_clause: LIMIT select_limit_value - { $$ = $2; } + { + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + + n->limitOffset = NULL; + n->limitCount = $2; + n->limitOption = LIMIT_OPTION_COUNT; + n->offsetLoc = -1; + n->countLoc = @1; + n->optionLoc = -1; + $$ = n; + } | LIMIT select_limit_value ',' select_offset_value { /* Disabled because it was too confusing, bjm 2002-02-18 */ @@ -11643,9 +13403,53 @@ limit_clause: * we can see the ONLY token in the lookahead slot. */ | FETCH first_or_next select_fetch_first_value row_or_rows ONLY - { $$ = $3; } + { + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + + n->limitOffset = NULL; + n->limitCount = $3; + n->limitOption = LIMIT_OPTION_COUNT; + n->offsetLoc = -1; + n->countLoc = @1; + n->optionLoc = -1; + $$ = n; + } + | FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES + { + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + + n->limitOffset = NULL; + n->limitCount = $3; + n->limitOption = LIMIT_OPTION_WITH_TIES; + n->offsetLoc = -1; + n->countLoc = @1; + n->optionLoc = @5; + $$ = n; + } | FETCH first_or_next row_or_rows ONLY - { $$ = makeIntConst(1, -1); } + { + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + + n->limitOffset = NULL; + n->limitCount = makeIntConst(1, -1); + n->limitOption = LIMIT_OPTION_COUNT; + n->offsetLoc = -1; + n->countLoc = @1; + n->optionLoc = -1; + $$ = n; + } + | FETCH first_or_next row_or_rows WITH TIES + { + SelectLimit *n = (SelectLimit *) palloc(sizeof(SelectLimit)); + + n->limitOffset = NULL; + n->limitCount = makeIntConst(1, -1); + n->limitOption = LIMIT_OPTION_WITH_TIES; + n->offsetLoc = -1; + n->countLoc = @1; + n->optionLoc = @4; + $$ = n; + } ; offset_clause: @@ -11729,8 +13533,22 @@ first_or_next: FIRST_P { $$ = 0; } * GroupingSet node of some type. */ group_clause: - GROUP_P BY group_by_list { $$ = $3; } - | /*EMPTY*/ { $$ = NIL; } + GROUP_P BY set_quantifier group_by_list + { + GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + + n->distinct = $3 == SET_QUANTIFIER_DISTINCT; + n->list = $4; + $$ = n; + } + | /*EMPTY*/ + { + GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + + n->distinct = false; + n->list = NIL; + $$ = n; + } ; group_by_list: @@ -11804,6 +13622,7 @@ for_locking_item: for_locking_strength locked_rels_list opt_nowait_or_skip { LockingClause *n = makeNode(LockingClause); + n->lockedRels = $2; n->strength = $1; n->waitPolicy = $3; @@ -11812,10 +13631,10 @@ for_locking_item: ; for_locking_strength: - FOR UPDATE { $$ = LCS_FORUPDATE; } - | FOR NO KEY UPDATE { $$ = LCS_FORNOKEYUPDATE; } - | FOR SHARE { $$ = LCS_FORSHARE; } - | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; } + FOR UPDATE { $$ = LCS_FORUPDATE; } + | FOR NO KEY UPDATE { $$ = LCS_FORNOKEYUPDATE; } + | FOR SHARE { $$ = LCS_FORSHARE; } + | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; } ; locked_rels_list: @@ -11833,12 +13652,14 @@ values_clause: VALUES '(' expr_list ')' { SelectStmt *n = makeNode(SelectStmt); + n->valuesLists = list_make1($3); $$ = (Node *) n; } | values_clause ',' '(' expr_list ')' { SelectStmt *n = (SelectStmt *) $1; + n->valuesLists = lappend(n->valuesLists, $4); $$ = (Node *) n; } @@ -11874,6 +13695,7 @@ table_ref: relation_expr opt_alias_clause | relation_expr opt_alias_clause tablesample_clause { RangeTableSample *n = (RangeTableSample *) $3; + $1->alias = $2; /* relation_expr goes inside the RangeTableSample node */ n->relation = (Node *) $1; @@ -11882,6 +13704,7 @@ table_ref: relation_expr opt_alias_clause | func_table func_alias_clause { RangeFunction *n = (RangeFunction *) $1; + n->alias = linitial($2); n->coldeflist = lsecond($2); $$ = (Node *) n; @@ -11889,6 +13712,7 @@ table_ref: relation_expr opt_alias_clause | LATERAL_P func_table func_alias_clause { RangeFunction *n = (RangeFunction *) $2; + n->lateral = true; n->alias = linitial($3); n->coldeflist = lsecond($3); @@ -11897,12 +13721,14 @@ table_ref: relation_expr opt_alias_clause | xmltable opt_alias_clause { RangeTableFunc *n = (RangeTableFunc *) $1; + n->alias = $2; $$ = (Node *) n; } | LATERAL_P xmltable opt_alias_clause { RangeTableFunc *n = (RangeTableFunc *) $2; + n->lateral = true; n->alias = $3; $$ = (Node *) n; @@ -11910,61 +13736,19 @@ table_ref: relation_expr opt_alias_clause | select_with_parens opt_alias_clause { RangeSubselect *n = makeNode(RangeSubselect); + n->lateral = false; n->subquery = $1; n->alias = $2; - /* - * The SQL spec does not permit a subselect - * () without an alias clause, - * so we don't either. This avoids the problem - * of needing to invent a unique refname for it. - * That could be surmounted if there's sufficient - * popular demand, but for now let's just implement - * the spec and see if anyone complains. - * However, it does seem like a good idea to emit - * an error message that's better than "syntax error". - */ - if ($2 == NULL) - { - if (IsA($1, SelectStmt) && - ((SelectStmt *) $1)->valuesLists) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("VALUES in FROM must have an alias"), - errhint("For example, FROM (VALUES ...) [AS] foo."), - parser_errposition(@1))); - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("subquery in FROM must have an alias"), - errhint("For example, FROM (SELECT ...) [AS] foo."), - parser_errposition(@1))); - } $$ = (Node *) n; } | LATERAL_P select_with_parens opt_alias_clause { RangeSubselect *n = makeNode(RangeSubselect); + n->lateral = true; n->subquery = $2; n->alias = $3; - /* same comment as above */ - if ($3 == NULL) - { - if (IsA($2, SelectStmt) && - ((SelectStmt *) $2)->valuesLists) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("VALUES in FROM must have an alias"), - errhint("For example, FROM (VALUES ...) [AS] foo."), - parser_errposition(@2))); - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("subquery in FROM must have an alias"), - errhint("For example, FROM (SELECT ...) [AS] foo."), - parser_errposition(@2))); - } $$ = (Node *) n; } | joined_table @@ -11976,6 +13760,21 @@ table_ref: relation_expr opt_alias_clause $2->alias = $4; $$ = (Node *) $2; } + | json_table opt_alias_clause + { + JsonTable *jt = castNode(JsonTable, $1); + + jt->alias = $2; + $$ = (Node *) jt; + } + | LATERAL_P json_table opt_alias_clause + { + JsonTable *jt = castNode(JsonTable, $2); + + jt->alias = $3; + jt->lateral = true; + $$ = (Node *) jt; + } ; @@ -12004,62 +13803,84 @@ joined_table: | table_ref CROSS JOIN table_ref { /* CROSS JOIN is same as unqualified inner join */ - JoinExpr *n = makeNode(JoinExpr); + JoinExpr *n = makeNode(JoinExpr); + n->jointype = JOIN_INNER; n->isNatural = false; n->larg = $1; n->rarg = $4; n->usingClause = NIL; + n->join_using_alias = NULL; n->quals = NULL; $$ = n; } | table_ref join_type JOIN table_ref join_qual { - JoinExpr *n = makeNode(JoinExpr); + JoinExpr *n = makeNode(JoinExpr); + n->jointype = $2; n->isNatural = false; n->larg = $1; n->rarg = $4; if ($5 != NULL && IsA($5, List)) - n->usingClause = (List *) $5; /* USING clause */ + { + /* USING clause */ + n->usingClause = linitial_node(List, castNode(List, $5)); + n->join_using_alias = lsecond_node(Alias, castNode(List, $5)); + } else - n->quals = $5; /* ON clause */ + { + /* ON clause */ + n->quals = $5; + } $$ = n; } | table_ref JOIN table_ref join_qual { /* letting join_type reduce to empty doesn't work */ - JoinExpr *n = makeNode(JoinExpr); + JoinExpr *n = makeNode(JoinExpr); + n->jointype = JOIN_INNER; n->isNatural = false; n->larg = $1; n->rarg = $3; if ($4 != NULL && IsA($4, List)) - n->usingClause = (List *) $4; /* USING clause */ + { + /* USING clause */ + n->usingClause = linitial_node(List, castNode(List, $4)); + n->join_using_alias = lsecond_node(Alias, castNode(List, $4)); + } else - n->quals = $4; /* ON clause */ + { + /* ON clause */ + n->quals = $4; + } $$ = n; } | table_ref NATURAL join_type JOIN table_ref { - JoinExpr *n = makeNode(JoinExpr); + JoinExpr *n = makeNode(JoinExpr); + n->jointype = $3; n->isNatural = true; n->larg = $1; n->rarg = $5; n->usingClause = NIL; /* figure out which columns later... */ + n->join_using_alias = NULL; n->quals = NULL; /* fill later */ $$ = n; } | table_ref NATURAL JOIN table_ref { /* letting join_type reduce to empty doesn't work */ - JoinExpr *n = makeNode(JoinExpr); + JoinExpr *n = makeNode(JoinExpr); + n->jointype = JOIN_INNER; n->isNatural = true; n->larg = $1; n->rarg = $4; n->usingClause = NIL; /* figure out which columns later... */ + n->join_using_alias = NULL; n->quals = NULL; /* fill later */ $$ = n; } @@ -12094,6 +13915,22 @@ opt_alias_clause: alias_clause { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } ; +/* + * The alias clause after JOIN ... USING only accepts the AS ColId spelling, + * per SQL standard. (The grammar could parse the other variants, but they + * don't seem to be useful, and it might lead to parser problems in the + * future.) + */ +opt_alias_clause_for_join_using: + AS ColId + { + $$ = makeNode(Alias); + $$->aliasname = $2; + /* the column name list will be inserted later */ + } + | /*EMPTY*/ { $$ = NULL; } + ; + /* * func_alias_clause can include both an Alias and a coldeflist, so we make it * return a 2-element list that gets disassembled by calling production. @@ -12109,13 +13946,15 @@ func_alias_clause: } | AS ColId '(' TableFuncElementList ')' { - Alias *a = makeNode(Alias); + Alias *a = makeNode(Alias); + a->aliasname = $2; $$ = list_make2(a, $4); } | ColId '(' TableFuncElementList ')' { - Alias *a = makeNode(Alias); + Alias *a = makeNode(Alias); + a->aliasname = $1; $$ = list_make2(a, $3); } @@ -12125,28 +13964,37 @@ func_alias_clause: } ; -join_type: FULL join_outer { $$ = JOIN_FULL; } - | LEFT join_outer { $$ = JOIN_LEFT; } - | RIGHT join_outer { $$ = JOIN_RIGHT; } +join_type: FULL opt_outer { $$ = JOIN_FULL; } + | LEFT opt_outer { $$ = JOIN_LEFT; } + | RIGHT opt_outer { $$ = JOIN_RIGHT; } | INNER_P { $$ = JOIN_INNER; } ; /* OUTER is just noise... */ -join_outer: OUTER_P { $$ = NULL; } - | /*EMPTY*/ { $$ = NULL; } +opt_outer: OUTER_P + | /*EMPTY*/ ; /* JOIN qualification clauses * Possibilities are: - * USING ( column list ) allows only unqualified column names, + * USING ( column list ) [ AS alias ] + * allows only unqualified column names, * which must match between tables. * ON expr allows more general qualifications. * - * We return USING as a List node, while an ON-expr will not be a List. + * We return USING as a two-element List (the first item being a sub-List + * of the common column names, and the second either an Alias item or NULL). + * An ON-expr will not be a List, so it can be told apart that way. */ -join_qual: USING '(' name_list ')' { $$ = (Node *) $3; } - | ON a_expr { $$ = $2; } +join_qual: USING '(' name_list ')' opt_alias_clause_for_join_using + { + $$ = (Node *) list_make2($3, $5); + } + | ON a_expr + { + $$ = $2; + } ; @@ -12158,7 +14006,14 @@ relation_expr: $$->inh = true; $$->alias = NULL; } - | qualified_name '*' + | extended_relation_expr + { + $$ = $1; + } + ; + +extended_relation_expr: + qualified_name '*' { /* inheritance query, explicitly */ $$ = $1; @@ -12203,14 +14058,16 @@ relation_expr_opt_alias: relation_expr %prec UMINUS } | relation_expr ColId { - Alias *alias = makeNode(Alias); + Alias *alias = makeNode(Alias); + alias->aliasname = $2; $1->alias = alias; $$ = $1; } | relation_expr AS ColId { - Alias *alias = makeNode(Alias); + Alias *alias = makeNode(Alias); + alias->aliasname = $3; $1->alias = alias; $$ = $1; @@ -12224,6 +14081,7 @@ tablesample_clause: TABLESAMPLE func_name '(' expr_list ')' opt_repeatable_clause { RangeTableSample *n = makeNode(RangeTableSample); + /* n->relation will be filled in later */ n->method = $2; n->args = $4; @@ -12253,6 +14111,7 @@ opt_repeatable_clause: func_table: func_expr_windowless opt_ordinality { RangeFunction *n = makeNode(RangeFunction); + n->lateral = false; n->ordinality = $2; n->is_rowsfrom = false; @@ -12263,6 +14122,7 @@ func_table: func_expr_windowless opt_ordinality | ROWS FROM '(' rowsfrom_list ')' opt_ordinality { RangeFunction *n = makeNode(RangeFunction); + n->lateral = false; n->ordinality = $6; n->is_rowsfrom = true; @@ -12301,6 +14161,7 @@ where_or_current_clause: | WHERE CURRENT_P OF cursor_name { CurrentOfExpr *n = makeNode(CurrentOfExpr); + /* cvarno is filled in by parse analysis */ n->cursor_name = $4; n->cursor_param = 0; @@ -12329,13 +14190,13 @@ TableFuncElementList: TableFuncElement: ColId Typename opt_collate_clause { ColumnDef *n = makeNode(ColumnDef); + n->colname = $1; n->typeName = $2; n->inhcount = 0; 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; @@ -12343,7 +14204,7 @@ TableFuncElement: ColId Typename opt_collate_clause n->collOid = InvalidOid; n->constraints = NIL; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -12354,23 +14215,25 @@ xmltable: XMLTABLE '(' c_expr xmlexists_argument COLUMNS xmltable_column_list ')' { RangeTableFunc *n = makeNode(RangeTableFunc); + n->rowexpr = $3; n->docexpr = $4; n->columns = $6; n->namespaces = NIL; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | XMLTABLE '(' XMLNAMESPACES '(' xml_namespace_list ')' ',' c_expr xmlexists_argument COLUMNS xmltable_column_list ')' { RangeTableFunc *n = makeNode(RangeTableFunc); + n->rowexpr = $8; n->docexpr = $9; n->columns = $11; n->namespaces = $5; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -12381,7 +14244,7 @@ xmltable_column_list: xmltable_column_el { $$ = list_make1($1); } xmltable_column_el: ColId Typename { - RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); + RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); fc->colname = $1; fc->for_ordinality = false; @@ -12395,9 +14258,9 @@ xmltable_column_el: } | ColId Typename xmltable_column_option_list { - RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); - ListCell *option; - bool nullability_seen = false; + RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); + ListCell *option; + bool nullability_seen = false; fc->colname = $1; fc->typeName = $2; @@ -12429,14 +14292,14 @@ xmltable_column_el: parser_errposition(defel->location))); fc->colexpr = defel->arg; } - else if (strcmp(defel->defname, "is_not_null") == 0) + else if (strcmp(defel->defname, "__pg__is_not_null") == 0) { if (nullability_seen) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant NULL / NOT NULL declarations for column \"%s\"", fc->colname), parser_errposition(defel->location))); - fc->is_not_null = intVal(defel->arg); + fc->is_not_null = boolVal(defel->arg); nullability_seen = true; } else @@ -12452,7 +14315,7 @@ xmltable_column_el: } | ColId FOR ORDINALITY { - RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); + RangeTableFuncCol *fc = makeNode(RangeTableFuncCol); fc->colname = $1; fc->for_ordinality = true; @@ -12472,13 +14335,22 @@ xmltable_column_option_list: xmltable_column_option_el: IDENT b_expr - { $$ = makeDefElem($1, $2, @1); } + { + if (strcmp($1, "__pg__is_not_null") == 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("option name \"%s\" cannot be used in XMLTABLE", $1), + parser_errposition(@1))); + $$ = makeDefElem($1, $2, @1); + } | DEFAULT b_expr { $$ = makeDefElem("default", $2, @1); } | NOT NULL_P - { $$ = makeDefElem("is_not_null", (Node *) makeInteger(true), @1); } + { $$ = makeDefElem("__pg__is_not_null", (Node *) makeBoolean(true), @1); } | NULL_P - { $$ = makeDefElem("is_not_null", (Node *) makeInteger(false), @1); } + { $$ = makeDefElem("__pg__is_not_null", (Node *) makeBoolean(false), @1); } + | PATH b_expr + { $$ = makeDefElem("path", $2, @1); } ; xml_namespace_list: @@ -12507,6 +14379,152 @@ xml_namespace_el: } ; +json_table: + JSON_TABLE '(' + json_value_expr ',' a_expr json_table_path_name_opt + json_passing_clause_opt + COLUMNS '(' json_table_column_definition_list ')' + json_on_error_clause_opt + ')' + { + JsonTable *n = makeNode(JsonTable); + char *pathstring; + + n->context_item = (JsonValueExpr *) $3; + if (!IsA($5, A_Const) || + castNode(A_Const, $5)->val.node.type != T_String) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only string constants are supported in JSON_TABLE path specification"), + parser_errposition(@5))); + pathstring = castNode(A_Const, $5)->val.sval.sval; + n->pathspec = makeJsonTablePathSpec(pathstring, $6, @5, @6); + n->passing = $7; + n->columns = $10; + n->on_error = (JsonBehavior *) $12; + n->location = @1; + $$ = (Node *) n; + } + ; + +json_table_path_name_opt: + AS name { $$ = $2; } + | /* empty */ { $$ = NULL; } + ; + +json_table_column_definition_list: + json_table_column_definition + { $$ = list_make1($1); } + | json_table_column_definition_list ',' json_table_column_definition + { $$ = lappend($1, $3); } + ; + +json_table_column_definition: + ColId FOR ORDINALITY + { + JsonTableColumn *n = makeNode(JsonTableColumn); + + n->coltype = JTC_FOR_ORDINALITY; + n->name = $1; + n->location = @1; + $$ = (Node *) n; + } + | ColId Typename + json_table_column_path_clause_opt + json_wrapper_behavior + json_quotes_clause_opt + json_behavior_clause_opt + { + JsonTableColumn *n = makeNode(JsonTableColumn); + + n->coltype = JTC_REGULAR; + n->name = $1; + n->typeName = $2; + n->format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); + n->pathspec = (JsonTablePathSpec *) $3; + n->wrapper = $4; + n->quotes = $5; + n->on_empty = (JsonBehavior *) linitial($6); + n->on_error = (JsonBehavior *) lsecond($6); + n->location = @1; + $$ = (Node *) n; + } + | ColId Typename json_format_clause + json_table_column_path_clause_opt + json_wrapper_behavior + json_quotes_clause_opt + json_behavior_clause_opt + { + JsonTableColumn *n = makeNode(JsonTableColumn); + + n->coltype = JTC_FORMATTED; + n->name = $1; + n->typeName = $2; + n->format = (JsonFormat *) $3; + n->pathspec = (JsonTablePathSpec *) $4; + n->wrapper = $5; + n->quotes = $6; + n->on_empty = (JsonBehavior *) linitial($7); + n->on_error = (JsonBehavior *) lsecond($7); + n->location = @1; + $$ = (Node *) n; + } + | ColId Typename + EXISTS json_table_column_path_clause_opt + json_on_error_clause_opt + { + JsonTableColumn *n = makeNode(JsonTableColumn); + + n->coltype = JTC_EXISTS; + n->name = $1; + n->typeName = $2; + n->format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); + n->wrapper = JSW_NONE; + n->quotes = JS_QUOTES_UNSPEC; + n->pathspec = (JsonTablePathSpec *) $4; + n->on_empty = NULL; + n->on_error = (JsonBehavior *) $5; + n->location = @1; + $$ = (Node *) n; + } + | NESTED path_opt Sconst + COLUMNS '(' json_table_column_definition_list ')' + { + JsonTableColumn *n = makeNode(JsonTableColumn); + + n->coltype = JTC_NESTED; + n->pathspec = (JsonTablePathSpec *) + makeJsonTablePathSpec($3, NULL, @3, -1); + n->columns = $6; + n->location = @1; + $$ = (Node *) n; + } + | NESTED path_opt Sconst AS name + COLUMNS '(' json_table_column_definition_list ')' + { + JsonTableColumn *n = makeNode(JsonTableColumn); + + n->coltype = JTC_NESTED; + n->pathspec = (JsonTablePathSpec *) + makeJsonTablePathSpec($3, $5, @3, @5); + n->columns = $8; + n->location = @1; + $$ = (Node *) n; + } + ; + +path_opt: + PATH + | /* EMPTY */ + ; + +json_table_column_path_clause_opt: + PATH Sconst + { $$ = (Node *) makeJsonTablePathSpec($2, NULL, @2, -1); } + | /* EMPTY */ + { $$ = NULL; } + ; + /***************************************************************************** * * Type syntax @@ -12579,6 +14597,7 @@ SimpleTypename: $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), makeIntConst($3, @3)); } + | JsonType { $$ = $1; } ; /* We have a separate ConstTypename to allow defaulting fixed-length @@ -12589,7 +14608,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: @@ -12597,6 +14616,7 @@ ConstTypename: | ConstBit { $$ = $1; } | ConstCharacter { $$ = $1; } | ConstDatetime { $$ = $1; } + | JsonType { $$ = $1; } ; /* @@ -12890,7 +14910,7 @@ ConstInterval: opt_timezone: WITH_LA TIME ZONE { $$ = true; } - | WITHOUT TIME ZONE { $$ = false; } + | WITHOUT_LA TIME ZONE { $$ = false; } | /*EMPTY*/ { $$ = false; } ; @@ -12965,6 +14985,13 @@ interval_second: } ; +JsonType: + JSON + { + $$ = SystemTypeName("json"); + $$->location = @1; + } + ; /***************************************************************************** * @@ -13000,6 +15027,7 @@ a_expr: c_expr { $$ = $1; } | a_expr COLLATE any_name { CollateClause *n = makeNode(CollateClause); + n->arg = $1; n->collname = $3; n->location = @2; @@ -13009,8 +15037,16 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeFuncCall(SystemFuncName("timezone"), list_make2($5, $1), + COERCE_SQL_SYNTAX, @2); } + | a_expr AT LOCAL %prec AT + { + $$ = (Node *) makeFuncCall(SystemFuncName("timezone"), + list_make1($1), + COERCE_SQL_SYNTAX, + -1); + } /* * These operators must be called out explicitly in order to make use * of bison's automatic operator-precedence handling. All other @@ -13053,8 +15089,6 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op a_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); } - | a_expr qual_Op %prec POSTFIXOP - { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); } | a_expr AND a_expr { $$ = makeAndExpr($1, $3, @2); } @@ -13072,9 +15106,10 @@ a_expr: c_expr { $$ = $1; } } | a_expr LIKE a_expr ESCAPE a_expr %prec LIKE { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2($3, $5), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), + list_make2($3, $5), + COERCE_EXPLICIT_CALL, + @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~", $1, (Node *) n, @2); } @@ -13085,9 +15120,10 @@ a_expr: c_expr { $$ = $1; } } | a_expr NOT_LA LIKE a_expr ESCAPE a_expr %prec NOT_LA { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2($4, $6), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), + list_make2($4, $6), + COERCE_EXPLICIT_CALL, + @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~", $1, (Node *) n, @2); } @@ -13098,9 +15134,10 @@ a_expr: c_expr { $$ = $1; } } | a_expr ILIKE a_expr ESCAPE a_expr %prec ILIKE { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2($3, $5), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), + list_make2($3, $5), + COERCE_EXPLICIT_CALL, + @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*", $1, (Node *) n, @2); } @@ -13111,42 +15148,47 @@ a_expr: c_expr { $$ = $1; } } | a_expr NOT_LA ILIKE a_expr ESCAPE a_expr %prec NOT_LA { - FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), - list_make2($4, $6), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), + list_make2($4, $6), + COERCE_EXPLICIT_CALL, + @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*", $1, (Node *) n, @2); } | a_expr SIMILAR TO a_expr %prec SIMILAR { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2($4, makeNullAConst(-1)), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), + list_make1($4), + COERCE_EXPLICIT_CALL, + @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"), - list_make2($4, $6), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), + list_make2($4, $6), + COERCE_EXPLICIT_CALL, + @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", $1, (Node *) n, @2); } | a_expr NOT_LA SIMILAR TO a_expr %prec NOT_LA { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2($5, makeNullAConst(-1)), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), + list_make1($5), + COERCE_EXPLICIT_CALL, + @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"), - list_make2($5, $7), - @2); + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), + list_make2($5, $7), + COERCE_EXPLICIT_CALL, + @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", $1, (Node *) n, @2); } @@ -13162,35 +15204,39 @@ a_expr: c_expr { $$ = $1; } */ | a_expr IS NULL_P %prec IS { - NullTest *n = makeNode(NullTest); + NullTest *n = makeNode(NullTest); + n->arg = (Expr *) $1; n->nulltesttype = IS_NULL; n->location = @2; - $$ = (Node *)n; + $$ = (Node *) n; } | a_expr ISNULL { - NullTest *n = makeNode(NullTest); + NullTest *n = makeNode(NullTest); + n->arg = (Expr *) $1; n->nulltesttype = IS_NULL; n->location = @2; - $$ = (Node *)n; + $$ = (Node *) n; } | a_expr IS NOT NULL_P %prec IS { - NullTest *n = makeNode(NullTest); + NullTest *n = makeNode(NullTest); + n->arg = (Expr *) $1; n->nulltesttype = IS_NOT_NULL; n->location = @2; - $$ = (Node *)n; + $$ = (Node *) n; } | a_expr NOTNULL { - NullTest *n = makeNode(NullTest); + NullTest *n = makeNode(NullTest); + n->arg = (Expr *) $1; n->nulltesttype = IS_NOT_NULL; n->location = @2; - $$ = (Node *)n; + $$ = (Node *) n; } | row OVERLAPS row { @@ -13206,55 +15252,62 @@ a_expr: c_expr { $$ = $1; } parser_errposition(@3))); $$ = (Node *) makeFuncCall(SystemFuncName("overlaps"), list_concat($1, $3), + COERCE_SQL_SYNTAX, @2); } | a_expr IS TRUE_P %prec IS { BooleanTest *b = makeNode(BooleanTest); + b->arg = (Expr *) $1; b->booltesttype = IS_TRUE; b->location = @2; - $$ = (Node *)b; + $$ = (Node *) b; } | a_expr IS NOT TRUE_P %prec IS { BooleanTest *b = makeNode(BooleanTest); + b->arg = (Expr *) $1; b->booltesttype = IS_NOT_TRUE; b->location = @2; - $$ = (Node *)b; + $$ = (Node *) b; } | a_expr IS FALSE_P %prec IS { BooleanTest *b = makeNode(BooleanTest); + b->arg = (Expr *) $1; b->booltesttype = IS_FALSE; b->location = @2; - $$ = (Node *)b; + $$ = (Node *) b; } | a_expr IS NOT FALSE_P %prec IS { BooleanTest *b = makeNode(BooleanTest); + b->arg = (Expr *) $1; b->booltesttype = IS_NOT_FALSE; b->location = @2; - $$ = (Node *)b; + $$ = (Node *) b; } | a_expr IS UNKNOWN %prec IS { BooleanTest *b = makeNode(BooleanTest); + b->arg = (Expr *) $1; b->booltesttype = IS_UNKNOWN; b->location = @2; - $$ = (Node *)b; + $$ = (Node *) b; } | a_expr IS NOT UNKNOWN %prec IS { BooleanTest *b = makeNode(BooleanTest); + b->arg = (Expr *) $1; b->booltesttype = IS_NOT_UNKNOWN; b->location = @2; - $$ = (Node *)b; + $$ = (Node *) b; } | a_expr IS DISTINCT FROM a_expr %prec IS { @@ -13264,14 +15317,6 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2); } - | a_expr IS OF '(' type_list ')' %prec IS - { - $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2); - } - | a_expr IS NOT OF '(' type_list ')' %prec IS - { - $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2); - } | a_expr BETWEEN opt_asymmetric b_expr AND a_expr %prec BETWEEN { $$ = (Node *) makeSimpleA_Expr(AEXPR_BETWEEN, @@ -13304,58 +15349,62 @@ a_expr: c_expr { $$ = $1; } (Node *) list_make2($5, $7), @2); } - | a_expr IN_P in_expr + | a_expr IN_P select_with_parens { - /* in_expr returns a SubLink or a list of a_exprs */ - if (IsA($3, SubLink)) - { - /* generate foo = ANY (subquery) */ - SubLink *n = (SubLink *) $3; - n->subLinkType = ANY_SUBLINK; - n->subLinkId = 0; - n->testexpr = $1; - n->operName = NIL; /* show it's IN not = ANY */ - n->location = @2; - $$ = (Node *)n; - } - else - { - /* generate scalar IN expression */ - $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", $1, $3, @2); - } + /* generate foo = ANY (subquery) */ + SubLink *n = makeNode(SubLink); + + n->subselect = $3; + n->subLinkType = ANY_SUBLINK; + n->subLinkId = 0; + n->testexpr = $1; + n->operName = NIL; /* show it's IN not = ANY */ + n->location = @2; + $$ = (Node *) n; } - | a_expr NOT_LA IN_P in_expr %prec NOT_LA + | a_expr IN_P '(' expr_list ')' { - /* in_expr returns a SubLink or a list of a_exprs */ - if (IsA($4, SubLink)) - { - /* generate NOT (foo = ANY (subquery)) */ - /* Make an = ANY node */ - SubLink *n = (SubLink *) $4; - n->subLinkType = ANY_SUBLINK; - n->subLinkId = 0; - n->testexpr = $1; - n->operName = NIL; /* show it's IN not = ANY */ - n->location = @2; - /* Stick a NOT on top; must have same parse location */ - $$ = makeNotExpr((Node *) n, @2); - } - else - { - /* generate scalar NOT IN expression */ - $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $4, @2); - } + /* generate scalar IN expression */ + A_Expr *n = makeSimpleA_Expr(AEXPR_IN, "=", $1, (Node *) $4, @2); + + n->rexpr_list_start = @3; + n->rexpr_list_end = @5; + $$ = (Node *) n; + } + | a_expr NOT_LA IN_P select_with_parens %prec NOT_LA + { + /* generate NOT (foo = ANY (subquery)) */ + SubLink *n = makeNode(SubLink); + + n->subselect = $4; + n->subLinkType = ANY_SUBLINK; + n->subLinkId = 0; + n->testexpr = $1; + n->operName = NIL; /* show it's IN not = ANY */ + n->location = @2; + /* Stick a NOT on top; must have same parse location */ + $$ = makeNotExpr((Node *) n, @2); + } + | a_expr NOT_LA IN_P '(' expr_list ')' + { + /* generate scalar NOT IN expression */ + A_Expr *n = makeSimpleA_Expr(AEXPR_IN, "<>", $1, (Node *) $5, @2); + + n->rexpr_list_start = @4; + n->rexpr_list_end = @6; + $$ = (Node *) n; } | a_expr subquery_Op sub_type select_with_parens %prec Op { - SubLink *n = makeNode(SubLink); + SubLink *n = makeNode(SubLink); + n->subLinkType = $3; n->subLinkId = 0; n->testexpr = $1; n->operName = $2; n->subselect = $4; n->location = @2; - $$ = (Node *)n; + $$ = (Node *) n; } | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op { @@ -13364,7 +15413,7 @@ a_expr: c_expr { $$ = $1; } else $$ = (Node *) makeA_Expr(AEXPR_OP_ALL, $2, $1, $5, @2); } - | UNIQUE select_with_parens + | UNIQUE opt_unique_null_treatment select_with_parens { /* Not sure how to get rid of the parentheses * but there are lots of shift/reduce errors without them. @@ -13391,6 +15440,72 @@ a_expr: c_expr { $$ = $1; } list_make1($1), @2), @2); } + | a_expr IS NORMALIZED %prec IS + { + $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make1($1), + COERCE_SQL_SYNTAX, + @2); + } + | a_expr IS unicode_normal_form NORMALIZED %prec IS + { + $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make2($1, makeStringConst($3, @3)), + COERCE_SQL_SYNTAX, + @2); + } + | a_expr IS NOT NORMALIZED %prec IS + { + $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make1($1), + COERCE_SQL_SYNTAX, + @2), + @2); + } + | a_expr IS NOT unicode_normal_form NORMALIZED %prec IS + { + $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make2($1, makeStringConst($4, @4)), + COERCE_SQL_SYNTAX, + @2), + @2); + } + | a_expr IS json_predicate_type_constraint + json_key_uniqueness_constraint_opt %prec IS + { + JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); + + $$ = makeJsonIsPredicate($1, format, $3, $4, @1); + } + /* + * Required by SQL/JSON, but there are conflicts + | a_expr + json_format_clause + IS json_predicate_type_constraint + json_key_uniqueness_constraint_opt %prec IS + { + $$ = makeJsonIsPredicate($1, $2, $4, $5, @1); + } + */ + | a_expr IS NOT + json_predicate_type_constraint + json_key_uniqueness_constraint_opt %prec IS + { + JsonFormat *format = makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); + + $$ = makeNotExpr(makeJsonIsPredicate($1, format, $4, $5, @1), @1); + } + /* + * Required by SQL/JSON, but there are conflicts + | a_expr + json_format_clause + IS NOT + json_predicate_type_constraint + json_key_uniqueness_constraint_opt %prec IS + { + $$ = makeNotExpr(makeJsonIsPredicate($1, $2, $5, $6, @1), @1); + } + */ | DEFAULT { /* @@ -13401,9 +15516,10 @@ a_expr: c_expr { $$ = $1; } * lets us say something smarter than "syntax error". */ SetToDefault *n = makeNode(SetToDefault); + /* parse analysis will fill in the rest */ n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -13452,8 +15568,6 @@ b_expr: c_expr { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op b_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); } - | b_expr qual_Op %prec POSTFIXOP - { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); } | b_expr IS DISTINCT FROM b_expr %prec IS { $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2); @@ -13462,14 +15576,6 @@ b_expr: c_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2); } - | b_expr IS OF '(' type_list ')' %prec IS - { - $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2); - } - | b_expr IS NOT OF '(' type_list ')' %prec IS - { - $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2); - } | b_expr IS DOCUMENT_P %prec IS { $$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL, @@ -13495,12 +15601,14 @@ c_expr: columnref { $$ = $1; } | AexprConst { $$ = $1; } | PARAM opt_indirection { - ParamRef *p = makeNode(ParamRef); + ParamRef *p = makeNode(ParamRef); + p->number = $1; p->location = @1; if ($2) { A_Indirection *n = makeNode(A_Indirection); + n->arg = (Node *) p; n->indirection = check_indirection($2, yyscanner); $$ = (Node *) n; @@ -13513,31 +15621,10 @@ c_expr: columnref { $$ = $1; } if ($4) { A_Indirection *n = makeNode(A_Indirection); + n->arg = $2; n->indirection = check_indirection($4, yyscanner); - $$ = (Node *)n; - } - else if (operator_precedence_warning) - { - /* - * If precedence warnings are enabled, insert - * AEXPR_PAREN nodes wrapping all explicitly - * parenthesized subexpressions; this prevents bogus - * warnings from being issued when the ordering has - * been forced by parentheses. Take care that an - * AEXPR_PAREN node has the same exprLocation as its - * child, so as not to cause surprising changes in - * error cursor positioning. - * - * In principle we should not be relying on a GUC to - * decide whether to insert AEXPR_PAREN nodes. - * However, since they have no effect except to - * suppress warnings, it's probably safe enough; and - * we'd just as soon not waste cycles on dummy parse - * nodes if we don't have to. - */ - $$ = (Node *) makeA_Expr(AEXPR_PAREN, NIL, $2, NULL, - exprLocation($2)); + $$ = (Node *) n; } else $$ = $2; @@ -13548,14 +15635,15 @@ c_expr: columnref { $$ = $1; } { $$ = $1; } | select_with_parens %prec UMINUS { - SubLink *n = makeNode(SubLink); + SubLink *n = makeNode(SubLink); + n->subLinkType = EXPR_SUBLINK; n->subLinkId = 0; n->testexpr = NULL; n->operName = NIL; n->subselect = $1; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | select_with_parens indirection { @@ -13569,116 +15657,140 @@ c_expr: columnref { $$ = $1; } * subscripting or field selection to a sub-SELECT result, * we need this redundant-looking production. */ - SubLink *n = makeNode(SubLink); + SubLink *n = makeNode(SubLink); A_Indirection *a = makeNode(A_Indirection); + n->subLinkType = EXPR_SUBLINK; n->subLinkId = 0; n->testexpr = NULL; n->operName = NIL; n->subselect = $1; n->location = @1; - a->arg = (Node *)n; + a->arg = (Node *) n; a->indirection = check_indirection($2, yyscanner); - $$ = (Node *)a; + $$ = (Node *) a; } | EXISTS select_with_parens { - SubLink *n = makeNode(SubLink); + SubLink *n = makeNode(SubLink); + n->subLinkType = EXISTS_SUBLINK; n->subLinkId = 0; n->testexpr = NULL; n->operName = NIL; n->subselect = $2; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | ARRAY select_with_parens { - SubLink *n = makeNode(SubLink); + SubLink *n = makeNode(SubLink); + n->subLinkType = ARRAY_SUBLINK; n->subLinkId = 0; n->testexpr = NULL; n->operName = NIL; n->subselect = $2; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | ARRAY array_expr { A_ArrayExpr *n = castNode(A_ArrayExpr, $2); + /* point outermost A_ArrayExpr to the ARRAY keyword */ n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } | explicit_row { - RowExpr *r = makeNode(RowExpr); + RowExpr *r = makeNode(RowExpr); + r->args = $1; r->row_typeid = InvalidOid; /* not analyzed yet */ r->colnames = NIL; /* to be filled in during analysis */ r->row_format = COERCE_EXPLICIT_CALL; /* abuse */ r->location = @1; - $$ = (Node *)r; + $$ = (Node *) r; } | implicit_row { - RowExpr *r = makeNode(RowExpr); + RowExpr *r = makeNode(RowExpr); + r->args = $1; r->row_typeid = InvalidOid; /* not analyzed yet */ r->colnames = NIL; /* to be filled in during analysis */ r->row_format = COERCE_IMPLICIT_CAST; /* abuse */ r->location = @1; - $$ = (Node *)r; + $$ = (Node *) r; } | GROUPING '(' expr_list ')' { GroupingFunc *g = makeNode(GroupingFunc); + g->args = $3; g->location = @1; - $$ = (Node *)g; + $$ = (Node *) g; } ; func_application: func_name '(' ')' { - $$ = (Node *) makeFuncCall($1, NIL, @1); + $$ = (Node *) makeFuncCall($1, NIL, + COERCE_EXPLICIT_CALL, + @1); } | func_name '(' func_arg_list opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, $3, @1); + FuncCall *n = makeFuncCall($1, $3, + COERCE_EXPLICIT_CALL, + @1); + n->agg_order = $4; - $$ = (Node *)n; + $$ = (Node *) n; } | func_name '(' VARIADIC func_arg_expr opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, list_make1($4), @1); + FuncCall *n = makeFuncCall($1, list_make1($4), + COERCE_EXPLICIT_CALL, + @1); + n->func_variadic = true; n->agg_order = $5; - $$ = (Node *)n; + $$ = (Node *) n; } | func_name '(' func_arg_list ',' VARIADIC func_arg_expr opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, lappend($3, $6), @1); + FuncCall *n = makeFuncCall($1, lappend($3, $6), + COERCE_EXPLICIT_CALL, + @1); + n->func_variadic = true; n->agg_order = $7; - $$ = (Node *)n; + $$ = (Node *) n; } | func_name '(' ALL func_arg_list opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, $4, @1); + FuncCall *n = makeFuncCall($1, $4, + COERCE_EXPLICIT_CALL, + @1); + n->agg_order = $5; /* Ideally we'd mark the FuncCall node to indicate * "must be an aggregate", but there's no provision * for that in FuncCall at the moment. */ - $$ = (Node *)n; + $$ = (Node *) n; } | func_name '(' DISTINCT func_arg_list opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, $4, @1); + FuncCall *n = makeFuncCall($1, $4, + COERCE_EXPLICIT_CALL, + @1); + n->agg_order = $5; n->agg_distinct = true; - $$ = (Node *)n; + $$ = (Node *) n; } | func_name '(' '*' ')' { @@ -13692,9 +15804,12 @@ func_application: func_name '(' ')' * so that later processing can detect what the argument * really was. */ - FuncCall *n = makeFuncCall($1, NIL, @1); + FuncCall *n = makeFuncCall($1, NIL, + COERCE_EXPLICIT_CALL, + @1); + n->agg_star = true; - $$ = (Node *)n; + $$ = (Node *) n; } ; @@ -13710,7 +15825,8 @@ func_application: func_name '(' ')' */ func_expr: func_application within_group_clause filter_clause over_clause { - FuncCall *n = (FuncCall *) $1; + FuncCall *n = (FuncCall *) $1; + /* * The order clause for WITHIN GROUP and the one for * plain-aggregate ORDER BY share a field, so we have to @@ -13743,12 +15859,22 @@ func_expr: func_application within_group_clause filter_clause over_clause n->over = $4; $$ = (Node *) n; } + | json_aggregate_func filter_clause over_clause + { + JsonAggConstructor *n = IsA($1, JsonObjectAgg) ? + ((JsonObjectAgg *) $1)->constructor : + ((JsonArrayAgg *) $1)->constructor; + + n->agg_filter = $2; + n->over = $3; + $$ = (Node *) $1; + } | func_expr_common_subexpr { $$ = $1; } ; /* - * As func_expr but does not accept WINDOW functions directly + * Like func_expr but does not accept WINDOW functions directly * (but they can still be contained in arguments for functions etc). * Use this when window expressions are not allowed, where needed to * disambiguate the grammar (e.g. in CREATE INDEX). @@ -13756,6 +15882,7 @@ func_expr: func_application within_group_clause filter_clause over_clause func_expr_windowless: func_application { $$ = $1; } | func_expr_common_subexpr { $$ = $1; } + | json_aggregate_func { $$ = $1; } ; /* @@ -13766,6 +15893,7 @@ func_expr_common_subexpr: { $$ = (Node *) makeFuncCall(SystemFuncName("pg_collation_for"), list_make1($4), + COERCE_SQL_SYNTAX, @1); } | CURRENT_DATE @@ -13816,6 +15944,13 @@ func_expr_common_subexpr: { $$ = makeSQLValueFunction(SVFOP_SESSION_USER, -1, @1); } + | SYSTEM_USER + { + $$ = (Node *) makeFuncCall(SystemFuncName("system_user"), + NIL, + COERCE_SQL_SYNTAX, + @1); + } | USER { $$ = makeSQLValueFunction(SVFOP_USER, -1, @1); @@ -13832,28 +15967,77 @@ func_expr_common_subexpr: { $$ = makeTypeCast($3, $5, @1); } | EXTRACT '(' extract_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("date_part"), $3, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("extract"), + $3, + COERCE_SQL_SYNTAX, + @1); + } + | NORMALIZE '(' a_expr ')' + { + $$ = (Node *) makeFuncCall(SystemFuncName("normalize"), + list_make1($3), + COERCE_SQL_SYNTAX, + @1); + } + | NORMALIZE '(' a_expr ',' unicode_normal_form ')' + { + $$ = (Node *) makeFuncCall(SystemFuncName("normalize"), + list_make2($3, makeStringConst($5, @5)), + COERCE_SQL_SYNTAX, + @1); } | OVERLAY '(' overlay_list ')' { - /* overlay(A PLACING B FROM C FOR D) is converted to - * overlay(A, B, C, D) - * overlay(A PLACING B FROM C) is converted to - * overlay(A, B, C) + $$ = (Node *) makeFuncCall(SystemFuncName("overlay"), + $3, + COERCE_SQL_SYNTAX, + @1); + } + | OVERLAY '(' func_arg_list_opt ')' + { + /* + * allow functions named overlay() to be called without + * special syntax */ - $$ = (Node *) makeFuncCall(SystemFuncName("overlay"), $3, @1); + $$ = (Node *) makeFuncCall(list_make1(makeString("overlay")), + $3, + COERCE_EXPLICIT_CALL, + @1); } | POSITION '(' position_list ')' { - /* position(A in B) is converted to position(B, A) */ - $$ = (Node *) makeFuncCall(SystemFuncName("position"), $3, @1); + /* + * position(A in B) is converted to position(B, A) + * + * We deliberately don't offer a "plain syntax" option + * for position(), because the reversal of the arguments + * creates too much risk of confusion. + */ + $$ = (Node *) makeFuncCall(SystemFuncName("position"), + $3, + COERCE_SQL_SYNTAX, + @1); } | SUBSTRING '(' substr_list ')' { /* substring(A from B for C) is converted to * substring(A, B, C) - thomas 2000-11-28 */ - $$ = (Node *) makeFuncCall(SystemFuncName("substring"), $3, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("substring"), + $3, + COERCE_SQL_SYNTAX, + @1); + } + | SUBSTRING '(' func_arg_list_opt ')' + { + /* + * allow functions named substring() to be called without + * special syntax + */ + $$ = (Node *) makeFuncCall(list_make1(makeString("substring")), + $3, + COERCE_EXPLICIT_CALL, + @1); } | TREAT '(' a_expr AS Typename ')' { @@ -13866,28 +16050,41 @@ func_expr_common_subexpr: * Convert SystemTypeName() to SystemFuncName() even though * at the moment they result in the same thing. */ - $$ = (Node *) makeFuncCall(SystemFuncName(((Value *)llast($5->names))->val.str), - list_make1($3), - @1); + $$ = (Node *) makeFuncCall(SystemFuncName(strVal(llast($5->names))), + list_make1($3), + COERCE_EXPLICIT_CALL, + @1); } | TRIM '(' BOTH trim_list ')' { /* various trim expressions are defined in SQL * - thomas 1997-07-19 */ - $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), $4, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), + $4, + COERCE_SQL_SYNTAX, + @1); } | TRIM '(' LEADING trim_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("ltrim"), $4, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("ltrim"), + $4, + COERCE_SQL_SYNTAX, + @1); } | TRIM '(' TRAILING trim_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("rtrim"), $4, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("rtrim"), + $4, + COERCE_SQL_SYNTAX, + @1); } | TRIM '(' trim_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), $3, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), + $3, + COERCE_SQL_SYNTAX, + @1); } | NULLIF '(' a_expr ',' a_expr ')' { @@ -13896,25 +16093,28 @@ func_expr_common_subexpr: | COALESCE '(' expr_list ')' { CoalesceExpr *c = makeNode(CoalesceExpr); + c->args = $3; c->location = @1; - $$ = (Node *)c; + $$ = (Node *) c; } | GREATEST '(' expr_list ')' { MinMaxExpr *v = makeNode(MinMaxExpr); + v->args = $3; v->op = IS_GREATEST; v->location = @1; - $$ = (Node *)v; + $$ = (Node *) v; } | LEAST '(' expr_list ')' { MinMaxExpr *v = makeNode(MinMaxExpr); + v->args = $3; v->op = IS_LEAST; v->location = @1; - $$ = (Node *)v; + $$ = (Node *) v; } | XMLCONCAT '(' expr_list ')' { @@ -13940,7 +16140,10 @@ func_expr_common_subexpr: { /* xmlexists(A PASSING [BY REF] B [BY REF]) is * converted to xmlexists(A, B)*/ - $$ = (Node *) makeFuncCall(SystemFuncName("xmlexists"), list_make2($3, $4), @1); + $$ = (Node *) makeFuncCall(SystemFuncName("xmlexists"), + list_make2($3, $4), + COERCE_SQL_SYNTAX, + @1); } | XMLFOREST '(' xml_attribute_list ')' { @@ -13952,8 +16155,9 @@ func_expr_common_subexpr: makeXmlExpr(IS_XMLPARSE, NULL, NIL, list_make2($4, makeBoolAConst($5, -1)), @1); + x->xmloption = $3; - $$ = (Node *)x; + $$ = (Node *) x; } | XMLPI '(' NAME_P ColLabel ')' { @@ -13968,18 +16172,186 @@ func_expr_common_subexpr: $$ = makeXmlExpr(IS_XMLROOT, NULL, NIL, list_make3($3, $5, $6), @1); } - | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename ')' + | XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename xml_indent_option ')' { XmlSerialize *n = makeNode(XmlSerialize); + n->xmloption = $3; n->expr = $4; n->typeName = $6; + n->indent = $7; n->location = @1; - $$ = (Node *)n; + $$ = (Node *) n; } - ; - -/* + | JSON_OBJECT '(' func_arg_list ')' + { + /* Support for legacy (non-standard) json_object() */ + $$ = (Node *) makeFuncCall(SystemFuncName("json_object"), + $3, COERCE_EXPLICIT_CALL, @1); + } + | JSON_OBJECT '(' json_name_and_value_list + json_object_constructor_null_clause_opt + json_key_uniqueness_constraint_opt + json_returning_clause_opt ')' + { + JsonObjectConstructor *n = makeNode(JsonObjectConstructor); + + n->exprs = $3; + n->absent_on_null = $4; + n->unique = $5; + n->output = (JsonOutput *) $6; + n->location = @1; + $$ = (Node *) n; + } + | JSON_OBJECT '(' json_returning_clause_opt ')' + { + JsonObjectConstructor *n = makeNode(JsonObjectConstructor); + + n->exprs = NULL; + n->absent_on_null = false; + n->unique = false; + n->output = (JsonOutput *) $3; + n->location = @1; + $$ = (Node *) n; + } + | JSON_ARRAY '(' + json_value_expr_list + json_array_constructor_null_clause_opt + json_returning_clause_opt + ')' + { + JsonArrayConstructor *n = makeNode(JsonArrayConstructor); + + n->exprs = $3; + n->absent_on_null = $4; + n->output = (JsonOutput *) $5; + n->location = @1; + $$ = (Node *) n; + } + | JSON_ARRAY '(' + select_no_parens + json_format_clause_opt + /* json_array_constructor_null_clause_opt */ + json_returning_clause_opt + ')' + { + JsonArrayQueryConstructor *n = makeNode(JsonArrayQueryConstructor); + + n->query = $3; + n->format = (JsonFormat *) $4; + n->absent_on_null = true; /* XXX */ + n->output = (JsonOutput *) $5; + n->location = @1; + $$ = (Node *) n; + } + | JSON_ARRAY '(' + json_returning_clause_opt + ')' + { + JsonArrayConstructor *n = makeNode(JsonArrayConstructor); + + n->exprs = NIL; + n->absent_on_null = true; + n->output = (JsonOutput *) $3; + n->location = @1; + $$ = (Node *) n; + } + | JSON '(' json_value_expr json_key_uniqueness_constraint_opt ')' + { + JsonParseExpr *n = makeNode(JsonParseExpr); + + n->expr = (JsonValueExpr *) $3; + n->unique_keys = $4; + n->output = NULL; + n->location = @1; + $$ = (Node *) n; + } + | JSON_SCALAR '(' a_expr ')' + { + JsonScalarExpr *n = makeNode(JsonScalarExpr); + + n->expr = (Expr *) $3; + n->output = NULL; + n->location = @1; + $$ = (Node *) n; + } + | JSON_SERIALIZE '(' json_value_expr json_returning_clause_opt ')' + { + JsonSerializeExpr *n = makeNode(JsonSerializeExpr); + + n->expr = (JsonValueExpr *) $3; + n->output = (JsonOutput *) $4; + n->location = @1; + $$ = (Node *) n; + } + | MERGE_ACTION '(' ')' + { + MergeSupportFunc *m = makeNode(MergeSupportFunc); + + m->msftype = TEXTOID; + m->location = @1; + $$ = (Node *) m; + } + | JSON_QUERY '(' + json_value_expr ',' a_expr json_passing_clause_opt + json_returning_clause_opt + json_wrapper_behavior + json_quotes_clause_opt + json_behavior_clause_opt + ')' + { + JsonFuncExpr *n = makeNode(JsonFuncExpr); + + n->op = JSON_QUERY_OP; + n->context_item = (JsonValueExpr *) $3; + n->pathspec = $5; + n->passing = $6; + n->output = (JsonOutput *) $7; + n->wrapper = $8; + n->quotes = $9; + n->on_empty = (JsonBehavior *) linitial($10); + n->on_error = (JsonBehavior *) lsecond($10); + n->location = @1; + $$ = (Node *) n; + } + | JSON_EXISTS '(' + json_value_expr ',' a_expr json_passing_clause_opt + json_on_error_clause_opt + ')' + { + JsonFuncExpr *n = makeNode(JsonFuncExpr); + + n->op = JSON_EXISTS_OP; + n->context_item = (JsonValueExpr *) $3; + n->pathspec = $5; + n->passing = $6; + n->output = NULL; + n->on_error = (JsonBehavior *) $7; + n->location = @1; + $$ = (Node *) n; + } + | JSON_VALUE '(' + json_value_expr ',' a_expr json_passing_clause_opt + json_returning_clause_opt + json_behavior_clause_opt + ')' + { + JsonFuncExpr *n = makeNode(JsonFuncExpr); + + n->op = JSON_VALUE_OP; + n->context_item = (JsonValueExpr *) $3; + n->pathspec = $5; + n->passing = $6; + n->output = (JsonOutput *) $7; + n->on_empty = (JsonBehavior *) linitial($8); + n->on_error = (JsonBehavior *) lsecond($8); + n->location = @1; + $$ = (Node *) n; + } + ; + + +/* * SQL/XML support */ xml_root_version: VERSION_P a_expr @@ -14027,6 +16399,11 @@ document_or_content: DOCUMENT_P { $$ = XMLOPTION_DOCUMENT; } | CONTENT_P { $$ = XMLOPTION_CONTENT; } ; +xml_indent_option: INDENT { $$ = true; } + | NO INDENT { $$ = false; } + | /*EMPTY*/ { $$ = false; } + ; + xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = true; } | STRIP_P WHITESPACE_P { $$ = false; } | /*EMPTY*/ { $$ = false; } @@ -14038,20 +16415,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_P + | BY VALUE_P + ; + /* * Aggregate decoration clauses @@ -14084,7 +16466,8 @@ window_definition_list: window_definition: ColId AS window_specification { - WindowDef *n = $3; + WindowDef *n = $3; + n->name = $1; $$ = n; } @@ -14094,7 +16477,8 @@ over_clause: OVER window_specification { $$ = $2; } | OVER ColId { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->name = $2; n->refname = NULL; n->partitionClause = NIL; @@ -14112,7 +16496,8 @@ over_clause: OVER window_specification window_specification: '(' opt_existing_window_name opt_partition_clause opt_sort_clause opt_frame_clause ')' { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->name = NULL; n->refname = $2; n->partitionClause = $3; @@ -14151,28 +16536,32 @@ opt_partition_clause: PARTITION BY expr_list { $$ = $3; } opt_frame_clause: RANGE frame_extent opt_window_exclusion_clause { - WindowDef *n = $2; + WindowDef *n = $2; + n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE; n->frameOptions |= $3; $$ = n; } | ROWS frame_extent opt_window_exclusion_clause { - WindowDef *n = $2; + WindowDef *n = $2; + n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS; n->frameOptions |= $3; $$ = n; } | GROUPS frame_extent opt_window_exclusion_clause { - WindowDef *n = $2; + WindowDef *n = $2; + n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_GROUPS; n->frameOptions |= $3; $$ = n; } | /*EMPTY*/ { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->frameOptions = FRAMEOPTION_DEFAULTS; n->startOffset = NULL; n->endOffset = NULL; @@ -14182,7 +16571,8 @@ opt_frame_clause: frame_extent: frame_bound { - WindowDef *n = $1; + WindowDef *n = $1; + /* reject invalid cases */ if (n->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) ereport(ERROR, @@ -14199,8 +16589,9 @@ frame_extent: frame_bound } | BETWEEN frame_bound AND frame_bound { - WindowDef *n1 = $2; - WindowDef *n2 = $4; + WindowDef *n1 = $2; + WindowDef *n2 = $4; + /* form merged options */ int frameOptions = n1->frameOptions; /* shift converts START_ options to END_ options */ @@ -14244,7 +16635,8 @@ frame_extent: frame_bound frame_bound: UNBOUNDED PRECEDING { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING; n->startOffset = NULL; n->endOffset = NULL; @@ -14252,7 +16644,8 @@ frame_bound: } | UNBOUNDED FOLLOWING { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING; n->startOffset = NULL; n->endOffset = NULL; @@ -14260,7 +16653,8 @@ frame_bound: } | CURRENT_P ROW { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->frameOptions = FRAMEOPTION_START_CURRENT_ROW; n->startOffset = NULL; n->endOffset = NULL; @@ -14268,7 +16662,8 @@ frame_bound: } | a_expr PRECEDING { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->frameOptions = FRAMEOPTION_START_OFFSET_PRECEDING; n->startOffset = $1; n->endOffset = NULL; @@ -14276,7 +16671,8 @@ frame_bound: } | a_expr FOLLOWING { - WindowDef *n = makeNode(WindowDef); + WindowDef *n = makeNode(WindowDef); + n->frameOptions = FRAMEOPTION_START_OFFSET_FOLLOWING; n->startOffset = $1; n->endOffset = NULL; @@ -14365,9 +16761,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. @@ -14402,6 +16798,7 @@ func_arg_expr: a_expr | param_name COLON_EQUALS a_expr { NamedArgExpr *na = makeNode(NamedArgExpr); + na->name = $1; na->arg = (Expr *) $3; na->argnumber = -1; /* until determined */ @@ -14411,6 +16808,7 @@ func_arg_expr: a_expr | param_name EQUALS_GREATER a_expr { NamedArgExpr *na = makeNode(NamedArgExpr); + na->name = $1; na->arg = (Expr *) $3; na->argnumber = -1; /* until determined */ @@ -14419,21 +16817,25 @@ func_arg_expr: a_expr } ; +func_arg_list_opt: func_arg_list { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + type_list: Typename { $$ = list_make1($1); } | type_list ',' Typename { $$ = lappend($1, $3); } ; array_expr: '[' expr_list ']' { - $$ = makeAArrayExpr($2, @1); + $$ = makeAArrayExpr($2, @1, @3); } | '[' array_expr_list ']' { - $$ = makeAArrayExpr($2, @1); + $$ = makeAArrayExpr($2, @1, @3); } | '[' ']' { - $$ = makeAArrayExpr(NIL, @1); + $$ = makeAArrayExpr(NIL, @1, @2); } ; @@ -14447,7 +16849,6 @@ extract_list: { $$ = list_make2(makeStringConst($1, @1), $3); } - | /*EMPTY*/ { $$ = NIL; } ; /* Allow delimited string Sconst in extract_arg as an SQL extension. @@ -14464,63 +16865,74 @@ extract_arg: | Sconst { $$ = $1; } ; -/* OVERLAY() arguments - * SQL99 defines the OVERLAY() function: - * o overlay(text placing text from int for int) - * o overlay(text placing text from int) - * and similarly for binary strings - */ +unicode_normal_form: + NFC { $$ = "NFC"; } + | NFD { $$ = "NFD"; } + | NFKC { $$ = "NFKC"; } + | NFKD { $$ = "NFKD"; } + ; + +/* OVERLAY() arguments */ overlay_list: - a_expr overlay_placing substr_from substr_for + a_expr PLACING a_expr FROM a_expr FOR a_expr { - $$ = list_make4($1, $2, $3, $4); + /* overlay(A PLACING B FROM C FOR D) is converted to overlay(A, B, C, D) */ + $$ = list_make4($1, $3, $5, $7); } - | a_expr overlay_placing substr_from + | a_expr PLACING a_expr FROM a_expr { - $$ = list_make3($1, $2, $3); + /* overlay(A PLACING B FROM C) is converted to overlay(A, B, C) */ + $$ = list_make3($1, $3, $5); } ; -overlay_placing: - PLACING a_expr - { $$ = $2; } - ; - /* position_list uses b_expr not a_expr to avoid conflict with general IN */ - position_list: b_expr IN_P b_expr { $$ = list_make2($3, $1); } - | /*EMPTY*/ { $$ = NIL; } ; -/* SUBSTRING() arguments - * SQL9x defines a specific syntax for arguments to SUBSTRING(): - * o substring(text from int for int) - * o substring(text from int) get entire string from starting point "int" - * o substring(text for int) get first "int" characters of string - * o substring(text from pattern) get entire string matching pattern - * o substring(text from pattern for escape) same with specified escape char - * We also want to support generic substring functions which accept - * the usual generic list of arguments. So we will accept both styles - * here, and convert the SQL9x style to the generic list for further - * processing. - thomas 2000-11-28 +/* + * SUBSTRING() arguments + * + * Note that SQL:1999 has both + * text FROM int FOR int + * and + * text FROM pattern FOR escape + * + * In the parser we map them both to a call to the substring() function and + * rely on type resolution to pick the right one. + * + * In SQL:2003, the second variant was changed to + * text SIMILAR pattern ESCAPE escape + * We could in theory map that to a different function internally, but + * since we still support the SQL:1999 version, we don't. However, + * ruleutils.c will reverse-list the call in the newer style. */ substr_list: - a_expr substr_from substr_for + a_expr FROM a_expr FOR a_expr { - $$ = list_make3($1, $2, $3); + $$ = list_make3($1, $3, $5); } - | a_expr substr_for substr_from + | a_expr FOR a_expr FROM a_expr { - /* not legal per SQL99, but might as well allow it */ - $$ = list_make3($1, $3, $2); + /* not legal per SQL, but might as well allow it */ + $$ = list_make3($1, $5, $3); } - | a_expr substr_from + | a_expr FROM a_expr { - $$ = list_make2($1, $2); + /* + * Because we aren't restricting data types here, this + * syntax can end up resolving to textregexsubstr(). + * We've historically allowed that to happen, so continue + * to accept it. However, ruleutils.c will reverse-list + * such a call in regular function call syntax. + */ + $$ = list_make2($1, $3); } - | a_expr substr_for + | a_expr FOR a_expr { + /* not legal per SQL */ + /* * Since there are no cases where this syntax allows * a textual FOR value, we forcibly cast the argument @@ -14531,22 +16943,13 @@ substr_list: * is unknown or doesn't have an implicit cast to int4. */ $$ = list_make3($1, makeIntConst(1, -1), - makeTypeCast($2, + makeTypeCast($3, SystemTypeName("int4"), -1)); } - | expr_list + | a_expr SIMILAR a_expr ESCAPE a_expr { - $$ = $1; + $$ = list_make3($1, $3, $5); } - | /*EMPTY*/ - { $$ = NIL; } - ; - -substr_from: - FROM a_expr { $$ = $2; } - ; - -substr_for: FOR a_expr { $$ = $2; } ; trim_list: a_expr FROM expr_list { $$ = lappend($3, $1); } @@ -14554,16 +16957,6 @@ trim_list: a_expr FROM expr_list { $$ = lappend($3, $1); } | expr_list { $$ = $1; } ; -in_expr: select_with_parens - { - SubLink *n = makeNode(SubLink); - n->subselect = $1; - /* other fields will be filled later */ - $$ = (Node *)n; - } - | '(' expr_list ')' { $$ = (Node *)$2; } - ; - /* * Define SQL-style CASE clause. * - Full specification @@ -14573,13 +16966,14 @@ in_expr: select_with_parens */ case_expr: CASE case_arg when_clause_list case_default END_P { - CaseExpr *c = makeNode(CaseExpr); + CaseExpr *c = makeNode(CaseExpr); + c->casetype = InvalidOid; /* not analyzed yet */ c->arg = (Expr *) $2; c->args = $3; c->defresult = (Expr *) $4; c->location = @1; - $$ = (Node *)c; + $$ = (Node *) c; } ; @@ -14592,11 +16986,12 @@ when_clause_list: when_clause: WHEN a_expr THEN a_expr { - CaseWhen *w = makeNode(CaseWhen); + CaseWhen *w = makeNode(CaseWhen); + w->expr = (Expr *) $2; w->result = (Expr *) $4; w->location = @1; - $$ = (Node *)w; + $$ = (Node *) w; } ; @@ -14631,6 +17026,7 @@ indirection_el: | '[' a_expr ']' { A_Indices *ai = makeNode(A_Indices); + ai->is_slice = false; ai->lidx = NULL; ai->uidx = $2; @@ -14639,6 +17035,7 @@ indirection_el: | '[' opt_slice_bound ':' opt_slice_bound ']' { A_Indices *ai = makeNode(A_Indices); + ai->is_slice = true; ai->lidx = $2; ai->uidx = $4; @@ -14665,6 +17062,255 @@ opt_asymmetric: ASYMMETRIC | /*EMPTY*/ ; +/* SQL/JSON support */ +json_passing_clause_opt: + PASSING json_arguments { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +json_arguments: + json_argument { $$ = list_make1($1); } + | json_arguments ',' json_argument { $$ = lappend($1, $3); } + ; + +json_argument: + json_value_expr AS ColLabel + { + JsonArgument *n = makeNode(JsonArgument); + + n->val = (JsonValueExpr *) $1; + n->name = $3; + $$ = (Node *) n; + } + ; + +/* ARRAY is a noise word */ +json_wrapper_behavior: + WITHOUT WRAPPER { $$ = JSW_NONE; } + | WITHOUT ARRAY WRAPPER { $$ = JSW_NONE; } + | WITH WRAPPER { $$ = JSW_UNCONDITIONAL; } + | WITH ARRAY WRAPPER { $$ = JSW_UNCONDITIONAL; } + | WITH CONDITIONAL ARRAY WRAPPER { $$ = JSW_CONDITIONAL; } + | WITH UNCONDITIONAL ARRAY WRAPPER { $$ = JSW_UNCONDITIONAL; } + | WITH CONDITIONAL WRAPPER { $$ = JSW_CONDITIONAL; } + | WITH UNCONDITIONAL WRAPPER { $$ = JSW_UNCONDITIONAL; } + | /* empty */ { $$ = JSW_UNSPEC; } + ; + +json_behavior: + DEFAULT a_expr + { $$ = (Node *) makeJsonBehavior(JSON_BEHAVIOR_DEFAULT, $2, @1); } + | json_behavior_type + { $$ = (Node *) makeJsonBehavior($1, NULL, @1); } + ; + +json_behavior_type: + ERROR_P { $$ = JSON_BEHAVIOR_ERROR; } + | NULL_P { $$ = JSON_BEHAVIOR_NULL; } + | TRUE_P { $$ = JSON_BEHAVIOR_TRUE; } + | FALSE_P { $$ = JSON_BEHAVIOR_FALSE; } + | UNKNOWN { $$ = JSON_BEHAVIOR_UNKNOWN; } + | EMPTY_P ARRAY { $$ = JSON_BEHAVIOR_EMPTY_ARRAY; } + | EMPTY_P OBJECT_P { $$ = JSON_BEHAVIOR_EMPTY_OBJECT; } + /* non-standard, for Oracle compatibility only */ + | EMPTY_P { $$ = JSON_BEHAVIOR_EMPTY_ARRAY; } + ; + +json_behavior_clause_opt: + json_behavior ON EMPTY_P + { $$ = list_make2($1, NULL); } + | json_behavior ON ERROR_P + { $$ = list_make2(NULL, $1); } + | json_behavior ON EMPTY_P json_behavior ON ERROR_P + { $$ = list_make2($1, $4); } + | /* EMPTY */ + { $$ = list_make2(NULL, NULL); } + ; + +json_on_error_clause_opt: + json_behavior ON ERROR_P + { $$ = $1; } + | /* EMPTY */ + { $$ = NULL; } + ; + +json_value_expr: + a_expr json_format_clause_opt + { + /* formatted_expr will be set during parse-analysis. */ + $$ = (Node *) makeJsonValueExpr((Expr *) $1, NULL, + castNode(JsonFormat, $2)); + } + ; + +json_format_clause: + FORMAT_LA JSON ENCODING name + { + int encoding; + + if (!pg_strcasecmp($4, "utf8")) + encoding = JS_ENC_UTF8; + else if (!pg_strcasecmp($4, "utf16")) + encoding = JS_ENC_UTF16; + else if (!pg_strcasecmp($4, "utf32")) + encoding = JS_ENC_UTF32; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("unrecognized JSON encoding: %s", $4), + parser_errposition(@4))); + + $$ = (Node *) makeJsonFormat(JS_FORMAT_JSON, encoding, @1); + } + | FORMAT_LA JSON + { + $$ = (Node *) makeJsonFormat(JS_FORMAT_JSON, JS_ENC_DEFAULT, @1); + } + ; + +json_format_clause_opt: + json_format_clause + { + $$ = $1; + } + | /* EMPTY */ + { + $$ = (Node *) makeJsonFormat(JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1); + } + ; + +json_quotes_clause_opt: + KEEP QUOTES ON SCALAR STRING_P { $$ = JS_QUOTES_KEEP; } + | KEEP QUOTES { $$ = JS_QUOTES_KEEP; } + | OMIT QUOTES ON SCALAR STRING_P { $$ = JS_QUOTES_OMIT; } + | OMIT QUOTES { $$ = JS_QUOTES_OMIT; } + | /* EMPTY */ { $$ = JS_QUOTES_UNSPEC; } + ; + +json_returning_clause_opt: + RETURNING Typename json_format_clause_opt + { + JsonOutput *n = makeNode(JsonOutput); + + n->typeName = $2; + n->returning = makeNode(JsonReturning); + n->returning->format = (JsonFormat *) $3; + $$ = (Node *) n; + } + | /* EMPTY */ { $$ = NULL; } + ; + +/* + * We must assign the only-JSON production a precedence less than IDENT in + * order to favor shifting over reduction when JSON is followed by VALUE_P, + * OBJECT_P, or SCALAR. (ARRAY doesn't need that treatment, because it's a + * fully reserved word.) Because json_predicate_type_constraint is always + * followed by json_key_uniqueness_constraint_opt, we also need the only-JSON + * production to have precedence less than WITH and WITHOUT. UNBOUNDED isn't + * really related to this syntax, but it's a convenient choice because it + * already has a precedence less than IDENT for other reasons. + */ +json_predicate_type_constraint: + JSON %prec UNBOUNDED { $$ = JS_TYPE_ANY; } + | JSON VALUE_P { $$ = JS_TYPE_ANY; } + | JSON ARRAY { $$ = JS_TYPE_ARRAY; } + | JSON OBJECT_P { $$ = JS_TYPE_OBJECT; } + | JSON SCALAR { $$ = JS_TYPE_SCALAR; } + ; + +/* + * KEYS is a noise word here. To avoid shift/reduce conflicts, assign the + * KEYS-less productions a precedence less than IDENT (i.e., less than KEYS). + * This prevents reducing them when the next token is KEYS. + */ +json_key_uniqueness_constraint_opt: + WITH UNIQUE KEYS { $$ = true; } + | WITH UNIQUE %prec UNBOUNDED { $$ = true; } + | WITHOUT UNIQUE KEYS { $$ = false; } + | WITHOUT UNIQUE %prec UNBOUNDED { $$ = false; } + | /* EMPTY */ %prec UNBOUNDED { $$ = false; } + ; + +json_name_and_value_list: + json_name_and_value + { $$ = list_make1($1); } + | json_name_and_value_list ',' json_name_and_value + { $$ = lappend($1, $3); } + ; + +json_name_and_value: +/* Supporting this syntax seems to require major surgery + KEY c_expr VALUE_P json_value_expr + { $$ = makeJsonKeyValue($2, $4); } + | +*/ + c_expr VALUE_P json_value_expr + { $$ = makeJsonKeyValue($1, $3); } + | + a_expr ':' json_value_expr + { $$ = makeJsonKeyValue($1, $3); } + ; + +/* empty means false for objects, true for arrays */ +json_object_constructor_null_clause_opt: + NULL_P ON NULL_P { $$ = false; } + | ABSENT ON NULL_P { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + +json_array_constructor_null_clause_opt: + NULL_P ON NULL_P { $$ = false; } + | ABSENT ON NULL_P { $$ = true; } + | /* EMPTY */ { $$ = true; } + ; + +json_value_expr_list: + json_value_expr { $$ = list_make1($1); } + | json_value_expr_list ',' json_value_expr { $$ = lappend($1, $3);} + ; + +json_aggregate_func: + JSON_OBJECTAGG '(' + json_name_and_value + json_object_constructor_null_clause_opt + json_key_uniqueness_constraint_opt + json_returning_clause_opt + ')' + { + JsonObjectAgg *n = makeNode(JsonObjectAgg); + + n->arg = (JsonKeyValue *) $3; + n->absent_on_null = $4; + n->unique = $5; + n->constructor = makeNode(JsonAggConstructor); + n->constructor->output = (JsonOutput *) $6; + n->constructor->agg_order = NULL; + n->constructor->location = @1; + $$ = (Node *) n; + } + | JSON_ARRAYAGG '(' + json_value_expr + json_array_aggregate_order_by_clause_opt + json_array_constructor_null_clause_opt + json_returning_clause_opt + ')' + { + JsonArrayAgg *n = makeNode(JsonArrayAgg); + + n->arg = (JsonValueExpr *) $3; + n->absent_on_null = $5; + n->constructor = makeNode(JsonAggConstructor); + n->constructor->agg_order = $4; + n->constructor->output = (JsonOutput *) $6; + n->constructor->location = @1; + $$ = (Node *) n; + } + ; + +json_array_aggregate_order_by_clause_opt: + ORDER BY sortby_list { $$ = $3; } + | /* EMPTY */ { $$ = NIL; } + ; /***************************************************************************** * @@ -14686,23 +17332,15 @@ target_el: a_expr AS ColLabel $$ = makeNode(ResTarget); $$->name = $3; $$->indirection = NIL; - $$->val = (Node *)$1; + $$->val = (Node *) $1; $$->location = @1; } - /* - * We support omitting AS only for column labels that aren't - * any known keyword. There is an ambiguity against postfix - * operators: is "a ! b" an infix expression, or a postfix - * expression and a column label? We prefer to resolve this - * as an infix expression, which we accomplish by assigning - * IDENT a precedence higher than POSTFIXOP. - */ - | a_expr IDENT + | a_expr BareColLabel { $$ = makeNode(ResTarget); $$->name = $2; $$->indirection = NIL; - $$->val = (Node *)$1; + $$->val = (Node *) $1; $$->location = @1; } | a_expr @@ -14710,19 +17348,20 @@ target_el: a_expr AS ColLabel $$ = makeNode(ResTarget); $$->name = NULL; $$->indirection = NIL; - $$->val = (Node *)$1; + $$->val = (Node *) $1; $$->location = @1; } | '*' { - ColumnRef *n = makeNode(ColumnRef); + ColumnRef *n = makeNode(ColumnRef); + n->fields = list_make1(makeNode(A_Star)); n->location = @1; $$ = makeNode(ResTarget); $$->name = NULL; $$->indirection = NIL; - $$->val = (Node *)n; + $$->val = (Node *) n; $$->location = @1; } ; @@ -14753,28 +17392,7 @@ qualified_name: } | ColId indirection { - check_qualified_name($2, yyscanner); - $$ = makeRangeVar(NULL, NULL, @1); - switch (list_length($2)) - { - case 1: - $$->catalogname = NULL; - $$->schemaname = $1; - $$->relname = strVal(linitial($2)); - break; - case 2: - $$->catalogname = $1; - $$->schemaname = strVal(linitial($2)); - $$->relname = strVal(lsecond($2)); - break; - default: - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("improper qualified name (too many dotted names): %s", - NameListToString(lcons(makeString($1), $2))), - parser_errposition(@1))); - break; - } + $$ = makeRangeVarFromQualifiedName($1, $2, @1, yyscanner); } ; @@ -14787,16 +17405,8 @@ name_list: name name: ColId { $$ = $1; }; -database_name: - ColId { $$ = $1; }; - -access_method: - ColId { $$ = $1; }; - attr_name: ColLabel { $$ = $1; }; -index_name: ColId { $$ = $1; }; - file_name: Sconst { $$ = $1; }; /* @@ -14848,15 +17458,16 @@ AexprConst: Iconst | func_name Sconst { /* generic type 'literal' syntax */ - TypeName *t = makeTypeNameFromNameList($1); + TypeName *t = makeTypeNameFromNameList($1); + t->location = @1; $$ = makeStringConstCast($2, @2, t); } | func_name '(' func_arg_list opt_sort_clause ')' Sconst { /* generic syntax with a type modifier */ - TypeName *t = makeTypeNameFromNameList($1); - ListCell *lc; + TypeName *t = makeTypeNameFromNameList($1); + ListCell *lc; /* * We must use func_arg_list and opt_sort_clause in the @@ -14890,13 +17501,15 @@ AexprConst: Iconst } | ConstInterval Sconst opt_interval { - TypeName *t = $1; + TypeName *t = $1; + t->typmods = $3; $$ = makeStringConstCast($2, @2, t); } | ConstInterval '(' Iconst ')' Sconst { - TypeName *t = $1; + TypeName *t = $1; + t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), makeIntConst($3, @3)); $$ = makeStringConstCast($5, @5, t); @@ -14926,7 +17539,8 @@ SignedIconst: Iconst { $$ = $1; } /* Role specifications */ RoleId: RoleSpec { - RoleSpec *spc = (RoleSpec *) $1; + RoleSpec *spc = (RoleSpec *) $1; + switch (spc->roletype) { case ROLESPEC_CSTRING: @@ -14953,53 +17567,134 @@ RoleId: RoleSpec "CURRENT_USER"), parser_errposition(@1))); break; + case ROLESPEC_CURRENT_ROLE: + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("%s cannot be used as a role name here", + "CURRENT_ROLE"), + parser_errposition(@1))); + break; } } ; RoleSpec: NonReservedWord + { + /* + * "public" and "none" are not keywords, but they must + * be treated specially here. + */ + RoleSpec *n; + + if (strcmp($1, "public") == 0) { - /* - * "public" and "none" are not keywords, but they must - * be treated specially here. - */ - RoleSpec *n; - if (strcmp($1, "public") == 0) - { - n = (RoleSpec *) makeRoleSpec(ROLESPEC_PUBLIC, @1); - n->roletype = ROLESPEC_PUBLIC; - } - else if (strcmp($1, "none") == 0) - { - ereport(ERROR, - (errcode(ERRCODE_RESERVED_NAME), - errmsg("role name \"%s\" is reserved", - "none"), - parser_errposition(@1))); - } - else - { - n = makeRoleSpec(ROLESPEC_CSTRING, @1); - n->rolename = pstrdup($1); - } - $$ = n; + n = (RoleSpec *) makeRoleSpec(ROLESPEC_PUBLIC, @1); + n->roletype = ROLESPEC_PUBLIC; } - | CURRENT_USER + else if (strcmp($1, "none") == 0) { - $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("role name \"%s\" is reserved", + "none"), + parser_errposition(@1))); } - | SESSION_USER + else { - $$ = makeRoleSpec(ROLESPEC_SESSION_USER, @1); + n = makeRoleSpec(ROLESPEC_CSTRING, @1); + n->rolename = pstrdup($1); } - ; - + $$ = n; + } + | CURRENT_ROLE + { + $$ = makeRoleSpec(ROLESPEC_CURRENT_ROLE, @1); + } + | CURRENT_USER + { + $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); + } + | SESSION_USER + { + $$ = makeRoleSpec(ROLESPEC_SESSION_USER, @1); + } + ; + role_list: RoleSpec - { $$ = list_make1($1); } + { $$ = list_make1($1); } | role_list ',' RoleSpec - { $$ = lappend($1, $3); } + { $$ = lappend($1, $3); } + ; + + +/***************************************************************************** + * + * PL/pgSQL extensions + * + * You'd think a PL/pgSQL "expression" should be just an a_expr, but + * historically it can include just about anything that can follow SELECT. + * Therefore the returned struct is a SelectStmt. + *****************************************************************************/ + +PLpgSQL_Expr: opt_distinct_clause opt_target_list + from_clause where_clause + group_clause having_clause window_clause + opt_sort_clause opt_select_limit opt_for_locking_clause + { + SelectStmt *n = makeNode(SelectStmt); + + n->distinctClause = $1; + n->targetList = $2; + n->fromClause = $3; + n->whereClause = $4; + n->groupClause = ($5)->list; + n->groupDistinct = ($5)->distinct; + n->havingClause = $6; + n->windowClause = $7; + n->sortClause = $8; + if ($9) + { + n->limitOffset = $9->limitOffset; + n->limitCount = $9->limitCount; + if (!n->sortClause && + $9->limitOption == LIMIT_OPTION_WITH_TIES) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("WITH TIES cannot be specified without ORDER BY clause"), + parser_errposition($9->optionLoc))); + n->limitOption = $9->limitOption; + } + n->lockingClause = $10; + $$ = (Node *) n; + } ; +/* + * PL/pgSQL Assignment statement: name opt_indirection := PLpgSQL_Expr + */ + +PLAssignStmt: plassign_target opt_indirection plassign_equals PLpgSQL_Expr + { + PLAssignStmt *n = makeNode(PLAssignStmt); + + n->name = $1; + n->indirection = check_indirection($2, yyscanner); + /* nnames will be filled by calling production */ + n->val = (SelectStmt *) $4; + n->location = @1; + $$ = (Node *) n; + } + ; + +plassign_target: ColId { $$ = $1; } + | PARAM { $$ = psprintf("$%d", $1); } + ; + +plassign_equals: COLON_EQUALS + | '=' + ; + + /* * Name classification hierarchy. * @@ -15043,6 +17738,13 @@ ColLabel: IDENT { $$ = $1; } | reserved_keyword { $$ = pstrdup($1); } ; +/* Bare column label --- names that can be column labels without writing "AS". + * This classification is orthogonal to the other keyword categories. + */ +BareColLabel: IDENT { $$ = $1; } + | bare_label_keyword { $$ = pstrdup($1); } + ; + /* * Keyword category lists. Generally, every keyword present in @@ -15054,13 +17756,14 @@ ColLabel: IDENT { $$ = $1; } * * Make sure that each keyword's category in kwlist.h matches where * it is listed here. (Someday we may be able to generate these lists and - * kwlist.h's table from a common master list.) + * kwlist.h's table from one source of truth.) */ /* "Unreserved" keywords --- available for use as any kind of name. */ unreserved_keyword: ABORT_P + | ABSENT | ABSOLUTE_P | ACCESS | ACTION @@ -15071,14 +17774,17 @@ unreserved_keyword: | ALSO | ALTER | ALWAYS + | ASENSITIVE | ASSERTION | ASSIGNMENT | AT + | ATOMIC | ATTACH | ATTRIBUTE | BACKWARD | BEFORE | BEGIN_P + | BREADTH | BY | CACHE | CALL @@ -15097,6 +17803,8 @@ unreserved_keyword: | COMMENTS | COMMIT | COMMITTED + | COMPRESSION + | CONDITIONAL | CONFIGURATION | CONFLICT | CONNECTION @@ -15123,6 +17831,7 @@ unreserved_keyword: | DELIMITER | DELIMITERS | DEPENDS + | DEPTH | DETACH | DICTIONARY | DISABLE_P @@ -15132,10 +17841,13 @@ unreserved_keyword: | DOUBLE_P | DROP | EACH + | EMPTY_P | ENABLE_P | ENCODING | ENCRYPTED + | ENFORCED | ENUM_P + | ERROR_P | ESCAPE | EVENT | EXCLUDE @@ -15143,13 +17855,16 @@ unreserved_keyword: | EXCLUSIVE | EXECUTE | EXPLAIN + | EXPRESSION | EXTENSION | EXTERNAL | FAMILY | FILTER + | FINALIZE | FIRST_P | FOLLOWING | FORCE + | FORMAT | FORWARD | FUNCTION | FUNCTIONS @@ -15170,6 +17885,7 @@ unreserved_keyword: | INCLUDE | INCLUDING | INCREMENT + | INDENT | INDEX | INDEXES | INHERIT @@ -15181,7 +17897,9 @@ unreserved_keyword: | INSTEAD | INVOKER | ISOLATION + | KEEP | KEY + | KEYS | LABEL | LANGUAGE | LARGE_P @@ -15197,8 +17915,10 @@ unreserved_keyword: | LOGGED | MAPPING | MATCH + | MATCHED | MATERIALIZED | MAXVALUE + | MERGE | METHOD | MINUTE_P | MINVALUE @@ -15207,18 +17927,26 @@ unreserved_keyword: | MOVE | NAME_P | NAMES + | NESTED | NEW | NEXT + | NFC + | NFD + | NFKC + | NFKD | NO + | NORMALIZED | NOTHING | NOTIFY | NOWAIT | NULLS_P | OBJECT_P + | OBJECTS_P | OF | OFF | OIDS | OLD + | OMIT | OPERATOR | OPTION | OPTIONS @@ -15229,11 +17957,15 @@ unreserved_keyword: | OWNED | OWNER | PARALLEL + | PARAMETER | PARSER | PARTIAL | PARTITION | PASSING | PASSWORD + | PATH + | PERIOD + | PLAN | PLANS | POLICY | PRECEDING @@ -15248,12 +17980,12 @@ unreserved_keyword: | PROGRAM | PUBLICATION | QUOTE + | QUOTES | RANGE | READ | REASSIGN - | RECHECK | RECURSIVE - | REF + | REF_P | REFERENCING | REFRESH | REINDEX @@ -15266,6 +17998,7 @@ unreserved_keyword: | RESET | RESTART | RESTRICT + | RETURN | RETURNS | REVOKE | ROLE @@ -15276,6 +18009,7 @@ unreserved_keyword: | ROWS | RULE | SAVEPOINT + | SCALAR | SCHEMA | SCHEMAS | SCROLL @@ -15294,6 +18028,7 @@ unreserved_keyword: | SIMPLE | SKIP | SNAPSHOT + | SOURCE | SQL_P | STABLE | STANDALONE_P @@ -15303,13 +18038,17 @@ unreserved_keyword: | STDIN | STDOUT | STORAGE + | STORED | STRICT_P + | STRING_P | STRIP_P | SUBSCRIPTION + | SUPPORT | SYSID | SYSTEM_P | TABLES | TABLESPACE + | TARGET | TEMP | TEMPLATE | TEMPORARY @@ -15322,8 +18061,10 @@ unreserved_keyword: | TRUSTED | TYPE_P | TYPES_P + | UESCAPE | UNBOUNDED | UNCOMMITTED + | UNCONDITIONAL | UNENCRYPTED | UNKNOWN | UNLISTEN @@ -15339,6 +18080,7 @@ unreserved_keyword: | VERSION_P | VIEW | VIEWS + | VIRTUAL | VOLATILE | WHITESPACE_P | WITHIN @@ -15381,10 +18123,23 @@ col_name_keyword: | INT_P | INTEGER | INTERVAL + | JSON + | JSON_ARRAY + | JSON_ARRAYAGG + | JSON_EXISTS + | JSON_OBJECT + | JSON_OBJECTAGG + | JSON_QUERY + | JSON_SCALAR + | JSON_SERIALIZE + | JSON_TABLE + | JSON_VALUE | LEAST + | MERGE_ACTION | NATIONAL | NCHAR | NONE + | NORMALIZE | NULLIF | NUMERIC | OUT_P @@ -15521,20 +18276,488 @@ reserved_keyword: | SESSION_USER | SOME | SYMMETRIC + | SYSTEM_USER + | TABLE + | THEN + | TO + | TRAILING + | TRUE_P + | UNION + | UNIQUE + | USER + | USING + | VARIADIC + | WHEN + | WHERE + | WINDOW + | WITH + ; + +/* + * While all keywords can be used as column labels when preceded by AS, + * not all of them can be used as a "bare" column label without AS. + * Those that can be used as a bare label must be listed here, + * in addition to appearing in one of the category lists above. + * + * Always add a new keyword to this list if possible. Mark it BARE_LABEL + * in kwlist.h if it is included here, or AS_LABEL if it is not. + */ +bare_label_keyword: + ABORT_P + | ABSENT + | ABSOLUTE_P + | ACCESS + | ACTION + | ADD_P + | ADMIN + | AFTER + | AGGREGATE + | ALL + | ALSO + | ALTER + | ALWAYS + | ANALYSE + | ANALYZE + | AND + | ANY + | ASC + | ASENSITIVE + | ASSERTION + | ASSIGNMENT + | ASYMMETRIC + | AT + | ATOMIC + | ATTACH + | ATTRIBUTE + | AUTHORIZATION + | BACKWARD + | BEFORE + | BEGIN_P + | BETWEEN + | BIGINT + | BINARY + | BIT + | BOOLEAN_P + | BOTH + | BREADTH + | BY + | CACHE + | CALL + | CALLED + | CASCADE + | CASCADED + | CASE + | CAST + | CATALOG_P + | CHAIN + | CHARACTERISTICS + | CHECK + | CHECKPOINT + | CLASS + | CLOSE + | CLUSTER + | COALESCE + | COLLATE + | COLLATION + | COLUMN + | COLUMNS + | COMMENT + | COMMENTS + | COMMIT + | COMMITTED + | COMPRESSION + | CONCURRENTLY + | CONDITIONAL + | CONFIGURATION + | CONFLICT + | CONNECTION + | CONSTRAINT + | CONSTRAINTS + | CONTENT_P + | CONTINUE_P + | CONVERSION_P + | COPY + | COST + | CROSS + | CSV + | CUBE + | CURRENT_P + | CURRENT_CATALOG + | CURRENT_DATE + | CURRENT_ROLE + | CURRENT_SCHEMA + | CURRENT_TIME + | CURRENT_TIMESTAMP + | CURRENT_USER + | CURSOR + | CYCLE + | DATA_P + | DATABASE + | DEALLOCATE + | DEC + | DECIMAL_P + | DECLARE + | DEFAULT + | DEFAULTS + | DEFERRABLE + | DEFERRED + | DEFINER + | DELETE_P + | DELIMITER + | DELIMITERS + | DEPENDS + | DEPTH + | DESC + | DETACH + | DICTIONARY + | DISABLE_P + | DISCARD + | DISTINCT + | DO + | DOCUMENT_P + | DOMAIN_P + | DOUBLE_P + | DROP + | EACH + | ELSE + | EMPTY_P + | ENABLE_P + | ENCODING + | ENCRYPTED + | END_P + | ENFORCED + | ENUM_P + | ERROR_P + | ESCAPE + | EVENT + | EXCLUDE + | EXCLUDING + | EXCLUSIVE + | EXECUTE + | EXISTS + | EXPLAIN + | EXPRESSION + | EXTENSION + | EXTERNAL + | EXTRACT + | FALSE_P + | FAMILY + | FINALIZE + | FIRST_P + | FLOAT_P + | FOLLOWING + | FORCE + | FOREIGN + | FORMAT + | FORWARD + | FREEZE + | FULL + | FUNCTION + | FUNCTIONS + | GENERATED + | GLOBAL + | GRANTED + | GREATEST + | GROUPING + | GROUPS + | HANDLER + | HEADER_P + | HOLD + | IDENTITY_P + | IF_P + | ILIKE + | IMMEDIATE + | IMMUTABLE + | IMPLICIT_P + | IMPORT_P + | IN_P + | INCLUDE + | INCLUDING + | INCREMENT + | INDENT + | INDEX + | INDEXES + | INHERIT + | INHERITS + | INITIALLY + | INLINE_P + | INNER_P + | INOUT + | INPUT_P + | INSENSITIVE + | INSERT + | INSTEAD + | INT_P + | INTEGER + | INTERVAL + | INVOKER + | IS + | ISOLATION + | JOIN + | JSON + | JSON_ARRAY + | JSON_ARRAYAGG + | JSON_EXISTS + | JSON_OBJECT + | JSON_OBJECTAGG + | JSON_QUERY + | JSON_SCALAR + | JSON_SERIALIZE + | JSON_TABLE + | JSON_VALUE + | KEEP + | KEY + | KEYS + | LABEL + | LANGUAGE + | LARGE_P + | LAST_P + | LATERAL_P + | LEADING + | LEAKPROOF + | LEAST + | LEFT + | LEVEL + | LIKE + | LISTEN + | LOAD + | LOCAL + | LOCALTIME + | LOCALTIMESTAMP + | LOCATION + | LOCK_P + | LOCKED + | LOGGED + | MAPPING + | MATCH + | MATCHED + | MATERIALIZED + | MAXVALUE + | MERGE + | MERGE_ACTION + | METHOD + | MINVALUE + | MODE + | MOVE + | NAME_P + | NAMES + | NATIONAL + | NATURAL + | NCHAR + | NESTED + | NEW + | NEXT + | NFC + | NFD + | NFKC + | NFKD + | NO + | NONE + | NORMALIZE + | NORMALIZED + | NOT + | NOTHING + | NOTIFY + | NOWAIT + | NULL_P + | NULLIF + | NULLS_P + | NUMERIC + | OBJECT_P + | OBJECTS_P + | OF + | OFF + | OIDS + | OLD + | OMIT + | ONLY + | OPERATOR + | OPTION + | OPTIONS + | OR + | ORDINALITY + | OTHERS + | OUT_P + | OUTER_P + | OVERLAY + | OVERRIDING + | OWNED + | OWNER + | PARALLEL + | PARAMETER + | PARSER + | PARTIAL + | PARTITION + | PASSING + | PASSWORD + | PATH + | PERIOD + | PLACING + | PLAN + | PLANS + | POLICY + | POSITION + | PRECEDING + | PREPARE + | PREPARED + | PRESERVE + | PRIMARY + | PRIOR + | PRIVILEGES + | PROCEDURAL + | PROCEDURE + | PROCEDURES + | PROGRAM + | PUBLICATION + | QUOTE + | QUOTES + | RANGE + | READ + | REAL + | REASSIGN + | RECURSIVE + | REF_P + | REFERENCES + | REFERENCING + | REFRESH + | REINDEX + | RELATIVE_P + | RELEASE + | RENAME + | REPEATABLE + | REPLACE + | REPLICA + | RESET + | RESTART + | RESTRICT + | RETURN + | RETURNS + | REVOKE + | RIGHT + | ROLE + | ROLLBACK + | ROLLUP + | ROUTINE + | ROUTINES + | ROW + | ROWS + | RULE + | SAVEPOINT + | SCALAR + | SCHEMA + | SCHEMAS + | SCROLL + | SEARCH + | SECURITY + | SELECT + | SEQUENCE + | SEQUENCES + | SERIALIZABLE + | SERVER + | SESSION + | SESSION_USER + | SET + | SETOF + | SETS + | SHARE + | SHOW + | SIMILAR + | SIMPLE + | SKIP + | SMALLINT + | SNAPSHOT + | SOME + | SOURCE + | SQL_P + | STABLE + | STANDALONE_P + | START + | STATEMENT + | STATISTICS + | STDIN + | STDOUT + | STORAGE + | STORED + | STRICT_P + | STRING_P + | STRIP_P + | SUBSCRIPTION + | SUBSTRING + | SUPPORT + | SYMMETRIC + | SYSID + | SYSTEM_P + | SYSTEM_USER | TABLE + | TABLES + | TABLESAMPLE + | TABLESPACE + | TARGET + | TEMP + | TEMPLATE + | TEMPORARY + | TEXT_P | THEN - | TO + | TIES + | TIME + | TIMESTAMP | TRAILING + | TRANSACTION + | TRANSFORM + | TREAT + | TRIGGER + | TRIM | TRUE_P - | UNION + | TRUNCATE + | TRUSTED + | TYPE_P + | TYPES_P + | UESCAPE + | UNBOUNDED + | UNCOMMITTED + | UNCONDITIONAL + | UNENCRYPTED | UNIQUE + | UNKNOWN + | UNLISTEN + | UNLOGGED + | UNTIL + | UPDATE | USER | USING + | VACUUM + | VALID + | VALIDATE + | VALIDATOR + | VALUE_P + | VALUES + | VARCHAR | VARIADIC + | VERBOSE + | VERSION_P + | VIEW + | VIEWS + | VIRTUAL + | VOLATILE | WHEN - | WHERE - | WINDOW - | WITH + | WHITESPACE_P + | WORK + | WRAPPER + | WRITE + | XML_P + | XMLATTRIBUTES + | XMLCONCAT + | XMLELEMENT + | XMLEXISTS + | XMLFOREST + | XMLNAMESPACES + | XMLPARSE + | XMLPI + | XMLROOT + | XMLSERIALIZE + | XMLTABLE + | YES_P + | ZONE ; %% @@ -15582,14 +18805,14 @@ makeColumnRef(char *colname, List *indirection, int location, core_yyscan_t yyscanner) { /* - * Generate a ColumnRef node, with an A_Indirection node added if there - * is any subscripting in the specified indirection list. However, - * any field selection at the start of the indirection list must be - * transposed into the "fields" part of the ColumnRef node. + * Generate a ColumnRef node, with an A_Indirection node added if there is + * any subscripting in the specified indirection list. However, any field + * selection at the start of the indirection list must be transposed into + * the "fields" part of the ColumnRef node. */ ColumnRef *c = makeNode(ColumnRef); - int nfields = 0; - ListCell *l; + int nfields = 0; + ListCell *l; c->location = location; foreach(l, indirection) @@ -15619,7 +18842,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++; @@ -15632,29 +18855,18 @@ makeColumnRef(char *colname, List *indirection, Node * makeTypeCast(Node *arg, TypeName *typename, int location) { - TypeCast *n = makeNode(TypeCast); + TypeCast *n = makeNode(TypeCast); + n->arg = arg; n->typeName = typename; n->location = location; return (Node *) n; } -static Node * -makeStringConst(char *str, int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_String; - n->val.val.str = str; - n->location = location; - - return (Node *)n; -} - Node * makeStringConstCast(char *str, int location, TypeName *typename) { - Node *s = makeStringConst(str, location); + Node *s = makeStringConst(str, location); return makeTypeCast(s, typename, -1); } @@ -15662,96 +18874,93 @@ makeStringConstCast(char *str, int location, TypeName *typename) Node * makeIntConst(int val, int location) { - A_Const *n = makeNode(A_Const); + A_Const *n = makeNode(A_Const); - n->val.type = T_Integer; - n->val.val.ival = val; + n->val.ival.type = T_Integer; + n->val.ival.ival = val; n->location = location; - return (Node *)n; + return (Node *) n; } static Node * makeFloatConst(char *str, int location) { - A_Const *n = makeNode(A_Const); + A_Const *n = makeNode(A_Const); - n->val.type = T_Float; - n->val.val.str = str; + n->val.fval.type = T_Float; + n->val.fval.fval = str; n->location = location; - return (Node *)n; + return (Node *) n; +} + +static Node * +makeBoolAConst(bool state, int location) +{ + A_Const *n = makeNode(A_Const); + + n->val.boolval.type = T_Boolean; + n->val.boolval.boolval = state; + n->location = location; + + return (Node *) n; } static Node * makeBitStringConst(char *str, int location) { - A_Const *n = makeNode(A_Const); + A_Const *n = makeNode(A_Const); - n->val.type = T_BitString; - n->val.val.str = str; + n->val.bsval.type = T_BitString; + n->val.bsval.bsval = str; n->location = location; - return (Node *)n; + return (Node *) n; } static Node * makeNullAConst(int location) { - A_Const *n = makeNode(A_Const); + A_Const *n = makeNode(A_Const); - n->val.type = T_Null; - n->location = location; + n->isnull = true; + n->location = location; - return (Node *)n; + return (Node *) n; } static Node * -makeAConst(Value *v, int location) +makeAConst(Node *v, int location) { - Node *n; + Node *n; switch (v->type) { case T_Float: - n = makeFloatConst(v->val.str, location); + n = makeFloatConst(castNode(Float, v)->fval, location); break; case T_Integer: - n = makeIntConst(v->val.ival, location); + n = makeIntConst(castNode(Integer, v)->ival, location); break; - case T_String: default: - n = makeStringConst(v->val.str, location); - break; + /* currently not used */ + Assert(false); + n = NULL; } return n; } -/* makeBoolAConst() - * Create an A_Const string node and put it inside a boolean cast. - */ -static Node * -makeBoolAConst(bool state, int location) -{ - A_Const *n = makeNode(A_Const); - - n->val.type = T_String; - n->val.val.str = (state ? "t" : "f"); - n->location = location; - - return makeTypeCast((Node *)n, SystemTypeName("bool"), -1); -} - /* makeRoleSpec * Create a RoleSpec with the given type */ static RoleSpec * makeRoleSpec(RoleSpecType type, int location) { - RoleSpec *spec = makeNode(RoleSpec); + RoleSpec *spec = makeNode(RoleSpec); spec->roletype = type; spec->location = location; @@ -15802,13 +19011,13 @@ check_func_name(List *names, core_yyscan_t yyscanner) static List * check_indirection(List *indirection, core_yyscan_t yyscanner) { - ListCell *l; + ListCell *l; foreach(l, indirection) { if (IsA(lfirst(l), A_Star)) { - if (lnext(l) != NULL) + if (lnext(indirection, l) != NULL) parser_yyerror("improper use of \"*\""); } } @@ -15857,7 +19066,7 @@ makeOrderedSetArgs(List *directargs, List *orderedargs, core_yyscan_t yyscanner) { FunctionParameter *lastd = (FunctionParameter *) llast(directargs); - int ndirectargs; + Integer *ndirectargs; /* No restriction unless last direct arg is VARIADIC */ if (lastd->mode == FUNC_PARAM_VARIADIC) @@ -15865,25 +19074,25 @@ makeOrderedSetArgs(List *directargs, List *orderedargs, FunctionParameter *firsto = (FunctionParameter *) linitial(orderedargs); /* - * We ignore the names, though the aggr_arg production allows them; - * it doesn't allow default values, so those need not be checked. + * We ignore the names, though the aggr_arg production allows them; it + * doesn't allow default values, so those need not be checked. */ if (list_length(orderedargs) != 1 || firsto->mode != FUNC_PARAM_VARIADIC) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type"), - parser_errposition(exprLocation((Node *) firsto)))); + parser_errposition(firsto->location))); /* OK, drop the duplicate VARIADIC argument from the internal form */ orderedargs = NIL; } /* don't merge into the next line, as list_concat changes directargs */ - ndirectargs = list_length(directargs); + ndirectargs = makeInteger(list_length(directargs)); return list_make2(list_concat(directargs, orderedargs), - makeInteger(ndirectargs)); + ndirectargs); } /* insertSelectOptions() @@ -15894,7 +19103,7 @@ makeOrderedSetArgs(List *directargs, List *orderedargs, static void insertSelectOptions(SelectStmt *stmt, List *sortClause, List *lockingClause, - Node *limitOffset, Node *limitCount, + SelectLimit *limitClause, WithClause *withClause, core_yyscan_t yyscanner) { @@ -15915,23 +19124,50 @@ insertSelectOptions(SelectStmt *stmt, } /* We can handle multiple locking clauses, though */ stmt->lockingClause = list_concat(stmt->lockingClause, lockingClause); - if (limitOffset) + if (limitClause && limitClause->limitOffset) { if (stmt->limitOffset) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("multiple OFFSET clauses not allowed"), - parser_errposition(exprLocation(limitOffset)))); - stmt->limitOffset = limitOffset; + parser_errposition(limitClause->offsetLoc))); + stmt->limitOffset = limitClause->limitOffset; } - if (limitCount) + if (limitClause && limitClause->limitCount) { if (stmt->limitCount) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("multiple LIMIT clauses not allowed"), - parser_errposition(exprLocation(limitCount)))); - stmt->limitCount = limitCount; + parser_errposition(limitClause->countLoc))); + stmt->limitCount = limitClause->limitCount; + } + if (limitClause) + { + /* If there was a conflict, we must have detected it above */ + Assert(!stmt->limitOption); + if (!stmt->sortClause && limitClause->limitOption == LIMIT_OPTION_WITH_TIES) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("WITH TIES cannot be specified without ORDER BY clause"), + parser_errposition(limitClause->optionLoc))); + if (limitClause->limitOption == LIMIT_OPTION_WITH_TIES && stmt->lockingClause) + { + ListCell *lc; + + foreach(lc, stmt->lockingClause) + { + LockingClause *lock = lfirst_node(LockingClause, lc); + + if (lock->waitPolicy == LockWaitSkip) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("%s and %s options cannot be used together", + "SKIP LOCKED", "WITH TIES"), + parser_errposition(limitClause->optionLoc))); + } + } + stmt->limitOption = limitClause->limitOption; } if (withClause) { @@ -15977,7 +19213,6 @@ SystemTypeName(char *name) return makeTypeNameFromNameList(list_make2(makeString("pg_catalog"), makeString(name))); } - /* doNegate() * Handle negation of a numeric constant. * @@ -15996,19 +19231,19 @@ doNegate(Node *n, int location) { if (IsA(n, A_Const)) { - A_Const *con = (A_Const *)n; + A_Const *con = (A_Const *) n; /* report the constant's location as that of the '-' sign */ con->location = location; - if (con->val.type == T_Integer) + if (IsA(&con->val, Integer)) { - con->val.val.ival = -con->val.val.ival; + con->val.ival.ival = -con->val.ival.ival; return n; } - if (con->val.type == T_Float) + if (IsA(&con->val, Float)) { - doNegateFloat(&con->val); + doNegateFloat(&con->val.fval); return n; } } @@ -16017,32 +19252,25 @@ doNegate(Node *n, int location) } static void -doNegateFloat(Value *v) +doNegateFloat(Float *v) { - char *oldval = v->val.str; + char *oldval = v->fval; - Assert(IsA(v, Float)); if (*oldval == '+') oldval++; if (*oldval == '-') - v->val.str = oldval+1; /* just strip the '-' */ + v->fval = oldval + 1; /* just strip the '-' */ else - v->val.str = psprintf("-%s", oldval); + v->fval = psprintf("-%s", oldval); } static Node * makeAndExpr(Node *lexpr, Node *rexpr, int location) { - Node *lexp = lexpr; - - /* Look through AEXPR_PAREN nodes so they don't affect flattening */ - while (IsA(lexp, A_Expr) && - ((A_Expr *) lexp)->kind == AEXPR_PAREN) - lexp = ((A_Expr *) lexp)->lexpr; /* Flatten "a AND b AND c ..." to a single BoolExpr on sight */ - if (IsA(lexp, BoolExpr)) + if (IsA(lexpr, BoolExpr)) { - BoolExpr *blexpr = (BoolExpr *) lexp; + BoolExpr *blexpr = (BoolExpr *) lexpr; if (blexpr->boolop == AND_EXPR) { @@ -16056,16 +19284,10 @@ makeAndExpr(Node *lexpr, Node *rexpr, int location) static Node * makeOrExpr(Node *lexpr, Node *rexpr, int location) { - Node *lexp = lexpr; - - /* Look through AEXPR_PAREN nodes so they don't affect flattening */ - while (IsA(lexp, A_Expr) && - ((A_Expr *) lexp)->kind == AEXPR_PAREN) - lexp = ((A_Expr *) lexp)->lexpr; /* Flatten "a OR b OR c ..." to a single BoolExpr on sight */ - if (IsA(lexp, BoolExpr)) + if (IsA(lexpr, BoolExpr)) { - BoolExpr *blexpr = (BoolExpr *) lexp; + BoolExpr *blexpr = (BoolExpr *) lexpr; if (blexpr->boolop == OR_EXPR) { @@ -16083,12 +19305,14 @@ makeNotExpr(Node *expr, int location) } static Node * -makeAArrayExpr(List *elements, int location) +makeAArrayExpr(List *elements, int location, int location_end) { A_ArrayExpr *n = makeNode(A_ArrayExpr); n->elements = elements; n->location = location; + n->list_start = location; + n->list_end = location_end; return (Node *) n; } @@ -16108,10 +19332,11 @@ static Node * makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, int location) { - XmlExpr *x = makeNode(XmlExpr); + XmlExpr *x = makeNode(XmlExpr); x->op = op; x->name = name; + /* * named_args is a list of ResTarget; it'll be split apart into separate * expression and name lists in transformXmlExpr(). @@ -16121,7 +19346,7 @@ makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, x->args = args; /* xmloption, if relevant, must be filled in by caller */ /* type and typmod will be filled in during parse analysis */ - x->type = InvalidOid; /* marks the node as not analyzed */ + x->type = InvalidOid; /* marks the node as not analyzed */ x->location = location; return (Node *) x; } @@ -16130,7 +19355,7 @@ makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, * Merge the input and output parameters of a table function. */ static List * -mergeTableFuncParameters(List *func_args, List *columns) +mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner) { ListCell *lc; @@ -16139,10 +19364,13 @@ mergeTableFuncParameters(List *func_args, List *columns) { FunctionParameter *p = (FunctionParameter *) lfirst(lc); - if (p->mode != FUNC_PARAM_IN && p->mode != FUNC_PARAM_VARIADIC) + if (p->mode != FUNC_PARAM_DEFAULT && + p->mode != FUNC_PARAM_IN && + p->mode != FUNC_PARAM_VARIADIC) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("OUT and INOUT arguments aren't allowed in TABLE functions"))); + errmsg("OUT and INOUT arguments aren't allowed in TABLE functions"), + parser_errposition(p->location))); } return list_concat(func_args, columns); @@ -16155,7 +19383,7 @@ mergeTableFuncParameters(List *func_args, List *columns) static TypeName * TableFuncTypeName(List *columns) { - TypeName *result; + TypeName *result; if (list_length(columns) == 1) { @@ -16179,7 +19407,7 @@ TableFuncTypeName(List *columns) static RangeVar * makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner) { - RangeVar *r = makeNode(RangeVar); + RangeVar *r = makeNode(RangeVar); switch (list_length(names)) { @@ -16213,6 +19441,43 @@ makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner) return r; } +/* + * Convert a relation_name with name and namelist to a RangeVar using + * makeRangeVar. + */ +static RangeVar * +makeRangeVarFromQualifiedName(char *name, List *namelist, int location, + core_yyscan_t yyscanner) +{ + RangeVar *r; + + check_qualified_name(namelist, yyscanner); + r = makeRangeVar(NULL, NULL, location); + + switch (list_length(namelist)) + { + case 1: + r->catalogname = NULL; + r->schemaname = name; + r->relname = strVal(linitial(namelist)); + break; + case 2: + r->catalogname = name; + r->schemaname = strVal(linitial(namelist)); + r->relname = strVal(lsecond(namelist)); + break; + default: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("improper qualified name (too many dotted names): %s", + NameListToString(lcons(makeString(name), namelist))), + parser_errposition(location))); + break; + } + + return r; +} + /* Separate Constraint nodes from COLLATE clauses in a ColQualList */ static void SplitColQualList(List *qualList, @@ -16220,20 +19485,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); + Node *n = (Node *) lfirst(cell); - next = lnext(cell); if (IsA(n, Constraint)) { /* keep it in list */ - prev = cell; continue; } if (IsA(n, CollateClause)) @@ -16250,7 +19510,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; } @@ -16262,8 +19522,8 @@ SplitColQualList(List *qualList, */ static void processCASbits(int cas_bits, int location, const char *constrType, - bool *deferrable, bool *initdeferred, bool *not_valid, - bool *no_inherit, core_yyscan_t yyscanner) + bool *deferrable, bool *initdeferred, bool *is_enforced, + bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner) { /* defaults */ if (deferrable) @@ -16272,6 +19532,8 @@ processCASbits(int cas_bits, int location, const char *constrType, *initdeferred = false; if (not_valid) *not_valid = false; + if (is_enforced) + *is_enforced = true; if (cas_bits & (CAS_DEFERRABLE | CAS_INITIALLY_DEFERRED)) { @@ -16280,7 +19542,7 @@ processCASbits(int cas_bits, int location, const char *constrType, else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ + /* translator: %s is CHECK, UNIQUE, or similar */ errmsg("%s constraints cannot be marked DEFERRABLE", constrType), parser_errposition(location))); @@ -16293,7 +19555,7 @@ processCASbits(int cas_bits, int location, const char *constrType, else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ + /* translator: %s is CHECK, UNIQUE, or similar */ errmsg("%s constraints cannot be marked DEFERRABLE", constrType), parser_errposition(location))); @@ -16306,7 +19568,7 @@ processCASbits(int cas_bits, int location, const char *constrType, else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ + /* translator: %s is CHECK, UNIQUE, or similar */ errmsg("%s constraints cannot be marked NOT VALID", constrType), parser_errposition(location))); @@ -16319,11 +19581,153 @@ processCASbits(int cas_bits, int location, const char *constrType, else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - /* translator: %s is CHECK, UNIQUE, or similar */ + /* translator: %s is CHECK, UNIQUE, or similar */ errmsg("%s constraints cannot be marked NO INHERIT", constrType), parser_errposition(location))); } + + if (cas_bits & CAS_NOT_ENFORCED) + { + if (is_enforced) + *is_enforced = false; + else + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + /* translator: %s is CHECK, UNIQUE, or similar */ + errmsg("%s constraints cannot be marked NOT ENFORCED", + constrType), + parser_errposition(location))); + + /* + * NB: The validated status is irrelevant when the constraint is set to + * NOT ENFORCED, but for consistency, it should be set accordingly. + * This ensures that if the constraint is later changed to ENFORCED, it + * will automatically be in the correct NOT VALIDATED state. + */ + if (not_valid) + *not_valid = true; + } + + if (cas_bits & CAS_ENFORCED) + { + if (is_enforced) + *is_enforced = true; + else + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + /* translator: %s is CHECK, UNIQUE, or similar */ + errmsg("%s constraints cannot be marked ENFORCED", + constrType), + parser_errposition(location))); + } +} + +/* + * Parse a user-supplied partition strategy string into parse node + * PartitionStrategy representation, or die trying. + */ +static PartitionStrategy +parsePartitionStrategy(char *strategy, int location, core_yyscan_t yyscanner) +{ + if (pg_strcasecmp(strategy, "list") == 0) + return PARTITION_STRATEGY_LIST; + else if (pg_strcasecmp(strategy, "range") == 0) + return PARTITION_STRATEGY_RANGE; + else if (pg_strcasecmp(strategy, "hash") == 0) + return PARTITION_STRATEGY_HASH; + + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("unrecognized partitioning strategy \"%s\"", strategy), + parser_errposition(location))); + return PARTITION_STRATEGY_LIST; /* keep compiler quiet */ + +} + +/* + * Process pubobjspec_list to check for errors in any of the objects and + * convert PUBLICATIONOBJ_CONTINUATION into appropriate PublicationObjSpecType. + */ +static void +preprocess_pubobj_list(List *pubobjspec_list, core_yyscan_t yyscanner) +{ + ListCell *cell; + PublicationObjSpec *pubobj; + PublicationObjSpecType prevobjtype = PUBLICATIONOBJ_CONTINUATION; + + if (!pubobjspec_list) + return; + + pubobj = (PublicationObjSpec *) linitial(pubobjspec_list); + if (pubobj->pubobjtype == PUBLICATIONOBJ_CONTINUATION) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid publication object list"), + errdetail("One of TABLE or TABLES IN SCHEMA must be specified before a standalone table or schema name."), + parser_errposition(pubobj->location))); + + foreach(cell, pubobjspec_list) + { + pubobj = (PublicationObjSpec *) lfirst(cell); + + if (pubobj->pubobjtype == PUBLICATIONOBJ_CONTINUATION) + pubobj->pubobjtype = prevobjtype; + + if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLE) + { + /* relation name or pubtable must be set for this type of object */ + if (!pubobj->name && !pubobj->pubtable) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid table name"), + parser_errposition(pubobj->location))); + + if (pubobj->name) + { + /* convert it to PublicationTable */ + PublicationTable *pubtable = makeNode(PublicationTable); + + pubtable->relation = + makeRangeVar(NULL, pubobj->name, pubobj->location); + pubobj->pubtable = pubtable; + pubobj->name = NULL; + } + } + else if (pubobj->pubobjtype == PUBLICATIONOBJ_TABLES_IN_SCHEMA || + pubobj->pubobjtype == PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA) + { + /* WHERE clause is not allowed on a schema object */ + if (pubobj->pubtable && pubobj->pubtable->whereClause) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("WHERE clause not allowed for schema"), + parser_errposition(pubobj->location))); + + /* Column list is not allowed on a schema object */ + if (pubobj->pubtable && pubobj->pubtable->columns) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("column specification not allowed for schema"), + parser_errposition(pubobj->location))); + + /* + * We can distinguish between the different type of schema objects + * based on whether name and pubtable is set. + */ + if (pubobj->name) + pubobj->pubobjtype = PUBLICATIONOBJ_TABLES_IN_SCHEMA; + else if (!pubobj->name && !pubobj->pubtable) + pubobj->pubobjtype = PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA; + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid schema name"), + parser_errposition(pubobj->location))); + } + + prevobjtype = pubobj->pubobjtype; + } } /*---------- @@ -16355,6 +19759,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; @@ -16363,11 +19768,13 @@ makeRecursiveViewSelect(char *relname, List *aliases, Node *query) w->ctes = list_make1(cte); w->location = -1; - /* create target list for the new SELECT from the alias list of the - * recursive view specification */ - foreach (lc, aliases) + /* + * create target list for the new SELECT from the alias list of the + * recursive view specification + */ + foreach(lc, aliases) { - ResTarget *rt = makeNode(ResTarget); + ResTarget *rt = makeNode(ResTarget); rt->name = NULL; rt->indirection = NIL; @@ -16377,8 +19784,10 @@ makeRecursiveViewSelect(char *relname, List *aliases, Node *query) tl = lappend(tl, rt); } - /* create new SELECT combining WITH clause, target list, and fake FROM - * clause */ + /* + * create new SELECT combining WITH clause, target list, and fake FROM + * clause + */ s->withClause = w; s->targetList = tl; s->fromClause = list_make1(makeRangeVar(NULL, relname, -1)); diff --git a/src/parser/gram_minimal.y b/src/parser/gram_minimal.y new file mode 100644 index 000000000..dc540e1c9 --- /dev/null +++ b/src/parser/gram_minimal.y @@ -0,0 +1,19786 @@ +%{ + +/*#define YYDEBUG 1*/ +/*------------------------------------------------------------------------- + * + * gram.y + * POSTGRESQL BISON rules/actions + * + * Portions Copyright (c) 2003-2025, PgPool Global Development Group + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/parser/gram.y + * + * HISTORY + * AUTHOR DATE MAJOR EVENT + * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion + * Andrew Yu Oct, 1994 lispy code conversion + * + * NOTES + * CAPITALS are used to represent terminal symbols. + * non-capitals are used to represent non-terminals. + * + * In general, nothing in this file should initiate database accesses + * nor depend on changeable state (such as SET variables). If you do + * database accesses, your code will fail when we have aborted the + * current transaction and are just parsing commands to find the next + * ROLLBACK or COMMIT. If you make use of SET variables, then you + * will do the wrong thing in multi-query strings like this: + * SET constraint_exclusion TO off; SELECT * FROM foo; + * because the entire string is parsed by gram.y before the SET gets + * executed. Anything that depends on the database or changeable state + * should be handled during parse analysis so that it happens at the + * right time not the wrong time. + * + * WARNINGS + * If you use a list, make sure the datum is a node so that the printing + * routines work. + * + * Sometimes we assign constants to makeStrings. Make sure we don't free + * those. + * + *------------------------------------------------------------------------- + */ + +#include "pool_parser.h" +#include "utils/elog.h" +#include "utils/palloc.h" +#include "utils/pgstrcasecmp.h" +#include +#include +#include +#include +#include + +#include "nodes.h" +#include "keywords.h" +#include "gramparse.h" +#include "makefuncs.h" +#include "parser.h" +#include "pg_class.h" +#include "pg_trigger.h" + +/* + * Definition taken from + * postgreSQL source code file: src/include/commands/trigger.h + */ +#define TRIGGER_FIRES_ON_ORIGIN 'O' +#define TRIGGER_FIRES_ALWAYS 'A' +#define TRIGGER_FIRES_ON_REPLICA 'R' +#define TRIGGER_DISABLED 'D' + +/* + * Definition taken from + * postgreSQL source code file: src/include/catalog/pg_class.h + */ + +#define REPLICA_IDENTITY_DEFAULT 'd' +#define REPLICA_IDENTITY_NOTHING 'n' +#define REPLICA_IDENTITY_FULL 'f' +#define REPLICA_IDENTITY_INDEX 'i' + +/* + * Definition taken from + * postgreSQL source code file: src/include/catalog/pg_attribute.h + */ +#define ATTRIBUTE_IDENTITY_ALWAYS 'a' +#define ATTRIBUTE_IDENTITY_BY_DEFAULT 'd' + +#define ATTRIBUTE_GENERATED_STORED 's' +#define ATTRIBUTE_GENERATED_VIRTUAL 'v' +/* + * Definition taken from + * postgreSQL source code file: src/include/utils/xml.h + */ +typedef enum +{ + XML_STANDALONE_YES, + XML_STANDALONE_NO, + XML_STANDALONE_NO_VALUE, + XML_STANDALONE_OMITTED +} XmlStandaloneType; + +/* + * Location tracking support. Unlike bison's default, we only want + * to track the start position not the end position of each nonterminal. + * Nonterminals that reduce to empty receive position "-1". Since a + * production's leading RHS nonterminal(s) may have reduced to empty, + * we have to scan to find the first one that's not -1. + */ +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do { \ + (Current) = (-1); \ + for (int _i = 1; _i <= (N); _i++) \ + { \ + if ((Rhs)[_i] >= 0) \ + { \ + (Current) = (Rhs)[_i]; \ + break; \ + } \ + } \ + } while (0) + +/* + * 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. + */ +#define YYMALLOC palloc +#define YYFREE pfree + +/* Private struct for the result of privilege_target production */ +typedef struct PrivTarget +{ + GrantTargetType targtype; + ObjectType objtype; + List *objs; +} PrivTarget; + +/* Private struct for the result of import_qualification production */ +typedef struct ImportQual +{ + ImportForeignSchemaType type; + List *table_names; +} ImportQual; + +/* Private struct for the result of select_limit & limit_clause productions */ +typedef struct SelectLimit +{ + Node *limitOffset; + Node *limitCount; + LimitOption limitOption; /* indicates presence of WITH TIES */ + ParseLoc offsetLoc; /* location of OFFSET token, if present */ + ParseLoc countLoc; /* location of LIMIT/FETCH token, if present */ + ParseLoc optionLoc; /* location of WITH TIES, if present */ +} SelectLimit; + +/* Private struct for the result of group_clause production */ +typedef struct GroupClause +{ + bool distinct; + List *list; +} GroupClause; + +/* Private structs for the result of key_actions and key_action productions */ +typedef struct KeyAction +{ + char action; + List *cols; +} KeyAction; + +typedef struct KeyActions +{ + KeyAction *updateAction; + KeyAction *deleteAction; +} KeyActions; + +/* ConstraintAttributeSpec yields an integer bitmask of these flags: */ +#define CAS_NOT_DEFERRABLE 0x01 +#define CAS_DEFERRABLE 0x02 +#define CAS_INITIALLY_IMMEDIATE 0x04 +#define CAS_INITIALLY_DEFERRED 0x08 +#define CAS_NOT_VALID 0x10 +#define CAS_NO_INHERIT 0x20 +#define CAS_NOT_ENFORCED 0x40 +#define CAS_ENFORCED 0x80 + + +#define parser_yyerror(msg) scanner_yyerror(msg, yyscanner) +#define parser_errposition(pos) scanner_errposition(pos, yyscanner) + +static void minimal_base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, + const char *msg); +static RawStmt *makeRawStmt(Node *stmt, int stmt_location); +static void updateRawStmtEnd(RawStmt *rs, int end_location); +static Node *makeColumnRef(char *colname, List *indirection, + int location, core_yyscan_t yyscanner); +static Node *makeFloatConst(char *str, int location); +static Node *makeBoolAConst(bool state, int location); +static Node *makeBitStringConst(char *str, int location); +static Node *makeNullAConst(int location); +static Node *makeAConst(Node *v, int location); +static RoleSpec *makeRoleSpec(RoleSpecType type, int location); +static void check_qualified_name(List *names, core_yyscan_t yyscanner); +static List *check_func_name(List *names, core_yyscan_t yyscanner); +static List *check_indirection(List *indirection, core_yyscan_t yyscanner); +static List *extractArgTypes(List *parameters); +static List *extractAggrArgTypes(List *aggrargs); +static List *makeOrderedSetArgs(List *directargs, List *orderedargs, + core_yyscan_t yyscanner); +static void insertSelectOptions(SelectStmt *stmt, + List *sortClause, List *lockingClause, + SelectLimit *limitClause, + WithClause *withClause, + core_yyscan_t yyscanner); +static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg); +static Node *doNegate(Node *n, int location); +static void doNegateFloat(Float *v); +static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location); +static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location); +static Node *makeNotExpr(Node *expr, int location); +static Node *makeAArrayExpr(List *elements, int location, int end_location); +static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, + int location); +static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, + List *args, int location); +static List *mergeTableFuncParameters(List *func_args, List *columns, core_yyscan_t yyscanner); +static TypeName *TableFuncTypeName(List *columns); +static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner); +static RangeVar *makeRangeVarFromQualifiedName(char *name, List *namelist, int location, + core_yyscan_t yyscanner); +static void SplitColQualList(List *qualList, + List **constraintList, CollateClause **collClause, + core_yyscan_t yyscanner); +static void processCASbits(int cas_bits, int location, const char *constrType, + bool *deferrable, bool *initdeferred, bool *is_enforced, + bool *not_valid, bool *no_inherit, core_yyscan_t yyscanner); +static PartitionStrategy parsePartitionStrategy(char *strategy, int location, + core_yyscan_t yyscanner); +static void preprocess_pubobj_list(List *pubobjspec_list, + core_yyscan_t yyscanner); +static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); + +%} + +%pure-parser +%expect 0 +%name-prefix="minimal_base_yy" +%locations + +%parse-param {core_yyscan_t yyscanner} +%lex-param {core_yyscan_t yyscanner} + +%union +{ + core_YYSTYPE core_yystype; + /* these fields must match core_YYSTYPE: */ + int ival; + char *str; + const char *keyword; + + char chr; + bool boolean; + JoinType jtype; + DropBehavior dbehavior; + OnCommitAction oncommit; + List *list; + Node *node; + ObjectType objtype; + TypeName *typnam; + FunctionParameter *fun_param; + FunctionParameterMode fun_param_mode; + ObjectWithArgs *objwithargs; + DefElem *defelt; + SortBy *sortby; + WindowDef *windef; + JoinExpr *jexpr; + IndexElem *ielem; + StatsElem *selem; + Alias *alias; + RangeVar *range; + IntoClause *into; + WithClause *with; + InferClause *infer; + OnConflictClause *onconflict; + A_Indices *aind; + ResTarget *target; + struct PrivTarget *privtarget; + AccessPriv *accesspriv; + struct ImportQual *importqual; + InsertStmt *istmt; + VariableSetStmt *vsetstmt; + PartitionElem *partelem; + PartitionSpec *partspec; + PartitionBoundSpec *partboundspec; + RoleSpec *rolespec; + PublicationObjSpec *publicationobjectspec; + struct SelectLimit *selectlimit; + SetQuantifier setquantifier; + struct GroupClause *groupclause; + MergeMatchKind mergematch; + MergeWhenClause *mergewhen; + struct KeyActions *keyactions; + struct KeyAction *keyaction; + ReturningClause *retclause; + ReturningOptionKind retoptionkind; +} + +%type stmt toplevel_stmt schema_stmt routine_body_stmt + AlterEventTrigStmt AlterCollationStmt + AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt + AlterFdwStmt AlterForeignServerStmt AlterGroupStmt + AlterObjectDependsStmt AlterObjectSchemaStmt AlterOwnerStmt + AlterOperatorStmt AlterTypeStmt AlterSeqStmt AlterSystemStmt AlterTableStmt + AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt + AlterCompositeTypeStmt AlterUserMappingStmt + AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt + AlterDefaultPrivilegesStmt DefACLAction + AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt + ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt + CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt + CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt + CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt + CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt + CreateAssertionStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt + CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt + CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt + DropOpClassStmt DropOpFamilyStmt DropStmt + DropCastStmt DropRoleStmt + DropdbStmt DropTableSpaceStmt + DropTransformStmt + DropUserMappingStmt ExplainStmt FetchStmt + GrantStmt GrantRoleStmt ImportForeignSchemaStmt IndexStmt InsertStmt +InsertStmtShort + ListenStmt LoadStmt LockStmt MergeStmt NotifyStmt ExplainableStmt PreparableStmt + CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt + RemoveFuncStmt RemoveOperStmt RenameStmt ReturnStmt RevokeStmt RevokeRoleStmt + RuleActionStmt RuleActionStmtOrEmpty RuleStmt + SecLabelStmt SelectStmt TransactionStmt TransactionStmtLegacy TruncateStmt + UnlistenStmt UpdateStmt +UpdateStmtShort + VacuumStmt + VariableResetStmt VariableSetStmt VariableShowStmt + ViewStmt CheckPointStmt CreateConversionStmt + DeallocateStmt PrepareStmt ExecuteStmt + DropOwnedStmt ReassignOwnedStmt + AlterTSConfigurationStmt AlterTSDictionaryStmt + CreateMatViewStmt RefreshMatViewStmt CreateAmStmt + CreatePublicationStmt AlterPublicationStmt + CreateSubscriptionStmt AlterSubscriptionStmt DropSubscriptionStmt + +%type select_no_parens select_with_parens select_clause + simple_select values_clause + PLpgSQL_Expr PLAssignStmt + +%type opt_single_name +%type opt_qualified_name +%type opt_concurrently +%type opt_drop_behavior + +%type alter_column_default opclass_item opclass_drop alter_using +%type add_drop opt_asc_desc opt_nulls_order + +%type alter_table_cmd alter_type_cmd opt_collate_clause + replica_identity partition_cmd index_partition_cmd +%type alter_table_cmds alter_type_cmds +%type alter_identity_column_option_list +%type alter_identity_column_option +%type set_statistics_value +%type set_access_method_name + +%type createdb_opt_list createdb_opt_items copy_opt_list + transaction_mode_list + create_extension_opt_list alter_extension_opt_list +%type createdb_opt_item copy_opt_item + transaction_mode_item + create_extension_opt_item alter_extension_opt_item + +%type opt_lock lock_type cast_context +%type utility_option_name +%type utility_option_elem +%type utility_option_list +%type utility_option_arg +%type drop_option +%type opt_or_replace opt_no + opt_grant_grant_option + opt_nowait opt_if_exists opt_with_data + opt_transaction_chain +%type grant_role_opt_list +%type grant_role_opt +%type grant_role_opt_value +%type opt_nowait_or_skip + +%type OptRoleList AlterOptRoleList +%type CreateOptRoleElem AlterOptRoleElem + +%type opt_type +%type foreign_server_version opt_foreign_server_version +%type opt_in_database + +%type parameter_name +%type OptSchemaEltList parameter_name_list + +%type am_type + +%type TriggerForSpec TriggerForType +%type TriggerActionTime +%type TriggerEvents TriggerOneEvent +%type TriggerFuncArg +%type TriggerWhen +%type TransitionRelName +%type TransitionRowOrTable TransitionOldOrNew +%type TriggerTransition + +%type event_trigger_when_list event_trigger_value_list +%type event_trigger_when_item +%type enable_trigger + +%type copy_file_name + access_method_clause attr_name + table_access_method_clause name cursor_name file_name + cluster_index_specification + +%type func_name handler_name qual_Op qual_all_Op subquery_Op + opt_inline_handler opt_validator validator_clause + opt_collate + +%type qualified_name insert_target OptConstrFromTable + +%type all_Op MathOp + +%type row_security_cmd RowSecurityDefaultForCmd +%type RowSecurityDefaultPermissive +%type RowSecurityOptionalWithCheck RowSecurityOptionalExpr +%type RowSecurityDefaultToRole RowSecurityOptionalToRole + +%type iso_level opt_encoding +%type grantee +%type grantee_list +%type privilege +%type privileges privilege_list +%type privilege_target +%type function_with_argtypes aggregate_with_argtypes operator_with_argtypes +%type function_with_argtypes_list aggregate_with_argtypes_list operator_with_argtypes_list +%type defacl_privilege_target +%type DefACLOption +%type DefACLOptionList +%type import_qualification_type +%type import_qualification +%type vacuum_relation +%type opt_select_limit select_limit limit_clause + +%type parse_toplevel stmtmulti routine_body_stmt_list + OptTableElementList TableElementList OptInherit definition + OptTypedTableElementList TypedTableElementList + reloptions opt_reloptions + OptWith opt_definition func_args func_args_list + func_args_with_defaults func_args_with_defaults_list + aggr_args aggr_args_list + func_as createfunc_opt_list opt_createfunc_opt_list alterfunc_opt_list + old_aggr_definition old_aggr_list + oper_argtypes RuleActionList RuleActionMulti + opt_column_list columnList opt_name_list + sort_clause opt_sort_clause sortby_list index_params + stats_params + opt_include opt_c_include index_including_params + name_list role_list from_clause from_list opt_array_bounds + qualified_name_list any_name any_name_list type_name_list + any_operator expr_list attrs + distinct_clause opt_distinct_clause + target_list opt_target_list insert_column_list set_target_list + merge_values_clause + set_clause_list set_clause + def_list operator_def_list indirection opt_indirection + reloption_list TriggerFuncArgs opclass_item_list opclass_drop_list + opclass_purpose opt_opfamily transaction_mode_list_or_empty + OptTableFuncElementList TableFuncElementList opt_type_modifiers + prep_type_clause + execute_param_clause using_clause + returning_with_clause returning_options + opt_enum_val_list enum_val_list table_func_column_list + create_generic_options alter_generic_options + relation_expr_list dostmt_opt_list + transform_element_list transform_type_list + TriggerTransitions TriggerReferencing + vacuum_relation_list opt_vacuum_relation_list + drop_option_list pub_obj_list + +%type returning_clause +%type returning_option +%type returning_option_kind +%type opt_routine_body +%type group_clause +%type group_by_list +%type group_by_item empty_grouping_set rollup_clause cube_clause +%type grouping_sets_clause + +%type opt_fdw_options fdw_options +%type fdw_option + +%type OptTempTableName +%type into_clause create_as_target create_mv_target + +%type createfunc_opt_item common_func_opt_item dostmt_opt_item +%type func_arg func_arg_with_default table_func_column aggr_arg +%type arg_class +%type func_return func_type + +%type opt_trusted opt_restart_seqs +%type OptTemp +%type OptNoLog +%type OnCommitOption + +%type for_locking_strength +%type for_locking_item +%type for_locking_clause opt_for_locking_clause for_locking_items +%type locked_rels_list +%type set_quantifier + +%type join_qual +%type join_type + +%type extract_list overlay_list position_list +%type substr_list trim_list +%type opt_interval interval_second +%type unicode_normal_form + +%type opt_instead +%type opt_unique opt_verbose opt_full +%type opt_freeze opt_analyze opt_default +%type opt_binary copy_delimiter + +%type copy_from opt_program + +%type event cursor_options opt_hold opt_set_data +%type object_type_any_name object_type_name object_type_name_on_any_name + drop_type_name + +%type fetch_args select_limit_value + offset_clause select_offset_value + select_fetch_first_value I_or_F_const +%type row_or_rows first_or_next + +%type OptSeqOptList SeqOptList OptParenthesizedSeqOptList +%type SeqOptElem + +%type insert_rest +%type opt_conf_expr +%type opt_on_conflict +%type merge_insert merge_update merge_delete + +%type merge_when_tgt_matched merge_when_tgt_not_matched +%type merge_when_clause opt_merge_when_condition +%type merge_when_list + +%type generic_set set_rest set_rest_more generic_reset reset_rest + SetResetClause FunctionSetResetClause + +%type TableElement TypedTableElement ConstraintElem DomainConstraintElem TableFuncElement +%type columnDef columnOptions optionalPeriodName +%type def_elem reloption_elem old_aggr_elem operator_def_elem +%type def_arg columnElem where_clause where_or_current_clause + a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound + columnref having_clause func_table xmltable array_expr + OptWhereClause operator_def_arg +%type opt_column_and_period_list +%type rowsfrom_item rowsfrom_list opt_col_def_list +%type opt_ordinality opt_without_overlaps +%type ExclusionConstraintList ExclusionConstraintElem +%type func_arg_list func_arg_list_opt +%type func_arg_expr +%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 opt_search_clause opt_cycle_clause +%type sub_type opt_materialized +%type NumericOnly +%type NumericOnly_list +%type alias_clause opt_alias_clause opt_alias_clause_for_join_using +%type func_alias_clause +%type sortby +%type index_elem index_elem_options +%type stats_param +%type table_ref +%type joined_table +%type relation_expr +%type extended_relation_expr +%type relation_expr_opt_alias +%type tablesample_clause opt_repeatable_clause +%type target_el set_target insert_column_item + +%type generic_option_name +%type generic_option_arg +%type generic_option_elem alter_generic_option_elem +%type generic_option_list alter_generic_option_list + +%type reindex_target_relation reindex_target_all +%type opt_reindex_option_list + +%type copy_generic_opt_arg copy_generic_opt_arg_list_item +%type copy_generic_opt_elem +%type copy_generic_opt_list copy_generic_opt_arg_list +%type copy_options + +%type Typename SimpleTypename ConstTypename + GenericType Numeric opt_float JsonType + Character ConstCharacter + CharacterWithLength CharacterWithoutLength + ConstDatetime ConstInterval + Bit ConstBit BitWithLength BitWithoutLength +%type character +%type extract_arg +%type opt_varying opt_timezone opt_no_inherit + +%type Iconst SignedIconst +%type Sconst comment_text notify_payload +%type RoleId opt_boolean_or_string +%type var_list +%type ColId ColLabel BareColLabel +%type NonReservedWord NonReservedWord_or_Sconst +%type var_name type_function_name param_name +%type createdb_opt_name plassign_target +%type var_value zone_value +%type auth_ident RoleSpec opt_granted_by +%type PublicationObjSpec + +%type unreserved_keyword type_func_name_keyword +%type col_name_keyword reserved_keyword +%type bare_label_keyword + +%type DomainConstraint TableConstraint TableLikeClause +%type TableLikeOptionList TableLikeOption +%type column_compression opt_column_compression column_storage opt_column_storage +%type ColQualList +%type ColConstraint ColConstraintElem ConstraintAttr +%type key_match +%type key_delete key_update key_action +%type key_actions +%type ConstraintAttributeSpec ConstraintAttributeElem +%type ExistingIndex + +%type constraints_set_list +%type constraints_set_mode +%type OptTableSpace OptConsTableSpace +%type OptTableSpaceOwner +%type opt_check_option + +%type opt_provider security_label + +%type xml_attribute_el +%type xml_attribute_list xml_attributes +%type xml_root_version opt_xml_root_standalone +%type xmlexists_argument +%type document_or_content +%type xml_indent_option xml_whitespace_option +%type xmltable_column_list xmltable_column_option_list +%type xmltable_column_el +%type xmltable_column_option_el +%type xml_namespace_list +%type xml_namespace_el + +%type func_application func_expr_common_subexpr +%type func_expr func_expr_windowless +%type common_table_expr +%type with_clause opt_with_clause +%type cte_list + +%type within_group_clause +%type filter_clause +%type window_clause window_definition_list opt_partition_clause +%type window_definition over_clause window_specification + opt_frame_clause frame_extent frame_bound +%type opt_window_exclusion_clause +%type opt_existing_window_name +%type opt_if_not_exists +%type opt_unique_null_treatment +%type generated_when override_kind opt_virtual_or_stored +%type PartitionSpec OptPartitionSpec +%type part_elem +%type part_params +%type PartitionBoundSpec +%type hash_partbound +%type hash_partbound_elem + +%type json_format_clause + json_format_clause_opt + json_value_expr + json_returning_clause_opt + json_name_and_value + json_aggregate_func + json_argument + json_behavior + json_on_error_clause_opt + json_table + json_table_column_definition + json_table_column_path_clause_opt +%type json_name_and_value_list + json_value_expr_list + json_array_aggregate_order_by_clause_opt + json_arguments + json_behavior_clause_opt + json_passing_clause_opt + json_table_column_definition_list +%type json_table_path_name_opt +%type json_behavior_type + json_predicate_type_constraint + json_quotes_clause_opt + json_wrapper_behavior +%type json_key_uniqueness_constraint_opt + json_object_constructor_null_clause_opt + json_array_constructor_null_clause_opt + + +/* + * 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 + * the set of keywords. PL/pgSQL depends on this so that it can share the + * same lexer. If you add/change tokens here, fix PL/pgSQL to match! + * + * UIDENT and USCONST are reduced to IDENT and SCONST in parser.c, so that + * they need no productions here; but we must assign token codes to them. + * + * DOT_DOT is unused in the core SQL grammar, and so will always provoke + * parse errors. It is needed by PL/pgSQL. + */ +%token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op +%token ICONST PARAM +%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER +%token LESS_EQUALS GREATER_EQUALS NOT_EQUALS + +/* + * If you want to make any keyword changes, update the keyword table in + * src/include/parser/kwlist.h and add new keywords to the appropriate one + * of the reserved-or-not-so-reserved keyword lists, below; search + * this file for "Keyword category lists". + */ + +/* ordinary key words in alphabetical order */ +%token ABORT_P ABSENT ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER + AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC + ASENSITIVE ASSERTION ASSIGNMENT ASYMMETRIC ATOMIC AT ATTACH ATTRIBUTE AUTHORIZATION + + BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT + BOOLEAN_P BOTH BREADTH BY + + CACHE CALL CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P + CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE + CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMNS COMMENT COMMENTS COMMIT + COMMITTED COMPRESSION CONCURRENTLY CONDITIONAL CONFIGURATION CONFLICT + CONNECTION CONSTRAINT CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY + COST CREATE CROSS CSV CUBE CURRENT_P + CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA + CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE + + DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS + DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC + DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P + DOUBLE_P DROP + + EACH ELSE EMPTY_P ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P ERROR_P + ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN + EXPRESSION EXTENSION EXTERNAL EXTRACT + + FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR + FORCE FOREIGN FORMAT FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS + + GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS + + HANDLER HAVING HEADER_P HOLD HOUR_P + + IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE + INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P + INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER + INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION + + JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_EXISTS JSON_OBJECT JSON_OBJECTAGG + JSON_QUERY JSON_SCALAR JSON_SERIALIZE JSON_TABLE JSON_VALUE + + KEEP KEY KEYS + + LABEL LANGUAGE LARGE_P LAST_P LATERAL_P + LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL + LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED + + MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE MERGE_ACTION METHOD + MINUTE_P MINVALUE MODE MONTH_P MOVE + + NAME_P NAMES NATIONAL NATURAL NCHAR NESTED NEW NEXT NFC NFD NFKC NFKD NO + NONE NORMALIZE NORMALIZED + NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF + NULLS_P NUMERIC + + OBJECT_P OBJECTS_P OF OFF OFFSET OIDS OLD OMIT ON ONLY OPERATOR OPTION OPTIONS OR + ORDER ORDINALITY OTHERS OUT_P OUTER_P + OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER + + PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH PGPOOL + PERIOD PLACING PLAN PLANS POLICY + POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY + PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION + + QUOTE QUOTES + + RANGE READ REAL REASSIGN RECURSIVE REF_P REFERENCES REFERENCING + REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA + RESET RESTART RESTRICT RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + ROUTINE ROUTINES ROW ROWS RULE + + SAVEPOINT SCALAR 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 SOURCE SQL_P STABLE STANDALONE_P + START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P + SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER + + TABLE TABLES TABLESAMPLE TABLESPACE TARGET TEMP TEMPLATE TEMPORARY TEXT_P THEN + TIES TIME TIMESTAMP TO TRAILING TRANSACTION TRANSFORM + TREAT TRIGGER TRIM TRUE_P + TRUNCATE TRUSTED TYPE_P TYPES_P + + UESCAPE UNBOUNDED UNCONDITIONAL UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN + UNLISTEN UNLOGGED UNTIL UPDATE USER USING + + VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING + VERBOSE VERSION_P VIEW VIEWS VIRTUAL VOLATILE + + WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE + + XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES + XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE + + YEAR_P YES_P + + ZONE + +/* + * The grammar thinks these are keywords, but they are not in the kwlist.h + * list and so can never be entered directly. The filter in parser.c + * creates these tokens when required (based on looking one token ahead). + * + * NOT_LA exists so that productions such as NOT LIKE can be given the same + * precedence as LIKE; otherwise they'd effectively have the same precedence + * as NOT, at least with respect to their left-hand subexpression. + * FORMAT_LA, NULLS_LA, WITH_LA, and WITHOUT_LA are needed to make the grammar + * LALR(1). + */ +%token FORMAT_LA NOT_LA NULLS_LA WITH_LA WITHOUT_LA + +/* + * The grammar likewise thinks these tokens are keywords, but they are never + * generated by the scanner. Rather, they can be injected by parser.c as + * the initial token of the string (using the lookahead-token mechanism + * implemented there). This provides a way to tell the grammar to parse + * something other than the usual list of SQL commands. + */ +%token MODE_TYPE_NAME +%token MODE_PLPGSQL_EXPR +%token MODE_PLPGSQL_ASSIGN1 +%token MODE_PLPGSQL_ASSIGN2 +%token MODE_PLPGSQL_ASSIGN3 + + +/* Precedence: lowest to highest */ +%left UNION EXCEPT +%left INTERSECT +%left OR +%left AND +%right NOT +%nonassoc IS ISNULL NOTNULL /* IS sets precedence for IS NULL, etc */ +%nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS +%nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA +%nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */ + +/* + * Sometimes it is necessary to assign precedence to keywords that are not + * really part of the operator hierarchy, in order to resolve grammar + * ambiguities. It's best to avoid doing so whenever possible, because such + * assignments have global effect and may hide ambiguities besides the one + * you intended to solve. (Attaching a precedence to a single rule with + * %prec is far safer and should be preferred.) If you must give precedence + * to a new keyword, try very hard to give it the same precedence as IDENT. + * If the keyword has IDENT's precedence then it clearly acts the same as + * non-keywords and other similar keywords, thus reducing the risk of + * unexpected precedence effects. + * + * We used to need to assign IDENT an explicit precedence just less than Op, + * to support target_el without AS. While that's not really necessary since + * we removed postfix operators, we continue to do so because it provides a + * reference point for a precedence level that we can assign to other + * keywords that lack a natural precedence level. + * + * We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support + * opt_existing_window_name (see comment there). + * + * The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING + * are even messier: since UNBOUNDED is an unreserved keyword (per spec!), + * there is no principled way to distinguish these from the productions + * a_expr PRECEDING/FOLLOWING. We hack this up by giving UNBOUNDED slightly + * lower precedence than PRECEDING and FOLLOWING. At present this doesn't + * appear to cause UNBOUNDED to be treated differently from other unreserved + * keywords anywhere else in the grammar, but it's definitely risky. We can + * blame any funny behavior of UNBOUNDED on the SQL standard, though. + * + * To support CUBE and ROLLUP in GROUP BY without reserving them, we give them + * an explicit priority lower than '(', so that a rule with CUBE '(' will shift + * rather than reducing a conflicting rule that takes CUBE as a function name. + * Using the same precedence as IDENT seems right for the reasons given above. + * + * SET is likewise assigned the same precedence as IDENT, to support the + * relation_expr_opt_alias production (see comment there). + * + * KEYS, OBJECT_P, SCALAR, VALUE_P, WITH, and WITHOUT are similarly assigned + * the same precedence as IDENT. This allows resolving conflicts in the + * json_predicate_type_constraint and json_key_uniqueness_constraint_opt + * productions (see comments there). + * + * Like the UNBOUNDED PRECEDING/FOLLOWING case, NESTED is assigned a lower + * precedence than PATH to fix ambiguity in the json_table production. + */ +%nonassoc UNBOUNDED NESTED /* ideally would have same precedence as IDENT */ +%nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP + SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT PATH +%left Op OPERATOR /* multi-character ops and user-defined operators */ +%left '+' '-' +%left '*' '/' '%' +%left '^' +/* Unary Operators */ +%left AT /* sets precedence for AT TIME ZONE, AT LOCAL */ +%left COLLATE +%right UMINUS +%left '[' ']' +%left '(' ')' +%left TYPECAST +%left '.' +/* + * These might seem to be low-precedence, but actually they are not part + * of the arithmetic hierarchy at all in their use as JOIN operators. + * We make them high-precedence to support their use as function names. + * They wouldn't be given a precedence at all, were it not that we need + * left-associativity among the JOIN rules themselves. + */ +%left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL + +%% + +/* + * The target production for the whole parse. + * + * Ordinarily we parse a list of statements, but if we see one of the + * special MODE_XXX symbols as first token, we parse something else. + * The options here correspond to enum RawParseMode, which see for details. + */ +parse_toplevel: + stmtmulti + { + pg_yyget_extra(yyscanner)->parsetree = $1; + (void) yynerrs; /* suppress compiler warning */ + } + | MODE_TYPE_NAME Typename + { + pg_yyget_extra(yyscanner)->parsetree = list_make1($2); + } + | MODE_PLPGSQL_EXPR PLpgSQL_Expr + { + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt($2, @2)); + } + | MODE_PLPGSQL_ASSIGN1 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + + n->nnames = 1; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, @2)); + } + | MODE_PLPGSQL_ASSIGN2 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + + n->nnames = 2; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, @2)); + } + | MODE_PLPGSQL_ASSIGN3 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + + n->nnames = 3; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, @2)); + } + ; + +/* + * At top level, we wrap each stmt with a RawStmt node carrying start location + * and length of the stmt's text. + * We also take care to discard empty statements entirely (which among other + * things dodges the problem of assigning them a location). + */ +stmtmulti: stmtmulti ';' toplevel_stmt + { + if ($1 != NIL) + { + /* update length of previous stmt */ + updateRawStmtEnd(llast_node(RawStmt, $1), @2); + } + if ($3 != NULL) + $$ = lappend($1, makeRawStmt($3, @3)); + else + $$ = $1; + } + | toplevel_stmt + { + if ($1 != NULL) + $$ = list_make1(makeRawStmt($1, @1)); + else + $$ = NIL; + } + ; + +/* + * toplevel_stmt includes BEGIN and END. stmt does not include them, because + * those words have different meanings in function bodies. + */ +toplevel_stmt: + stmt + | TransactionStmtLegacy + ; + +stmt: + AlterEventTrigStmt + | AlterCollationStmt + | AlterDatabaseStmt + | AlterDatabaseSetStmt + | AlterDefaultPrivilegesStmt + | AlterDomainStmt + | AlterEnumStmt + | AlterExtensionStmt + | AlterExtensionContentsStmt + | AlterFdwStmt + | AlterForeignServerStmt + | AlterFunctionStmt + | AlterGroupStmt + | AlterObjectDependsStmt + | AlterObjectSchemaStmt + | AlterOwnerStmt + | AlterOperatorStmt + | AlterTypeStmt + | AlterPolicyStmt + | AlterSeqStmt + | AlterSystemStmt + | AlterTableStmt + | AlterTblSpcStmt + | AlterCompositeTypeStmt + | AlterPublicationStmt + | AlterRoleSetStmt + | AlterRoleStmt + | AlterSubscriptionStmt + | AlterStatsStmt + | AlterTSConfigurationStmt + | AlterTSDictionaryStmt + | AlterUserMappingStmt + | AnalyzeStmt + | CallStmt + | CheckPointStmt + | ClosePortalStmt + | ClusterStmt + | CommentStmt + | ConstraintsSetStmt + | CopyStmt + | CreateAmStmt + | CreateAsStmt + | CreateAssertionStmt + | CreateCastStmt + | CreateConversionStmt + | CreateDomainStmt + | CreateExtensionStmt + | CreateFdwStmt + | CreateForeignServerStmt + | CreateForeignTableStmt + | CreateFunctionStmt + | CreateGroupStmt + | CreateMatViewStmt + | CreateOpClassStmt + | CreateOpFamilyStmt + | CreatePublicationStmt + | AlterOpFamilyStmt + | CreatePolicyStmt + | CreatePLangStmt + | CreateSchemaStmt + | CreateSeqStmt + | CreateStmt + | CreateSubscriptionStmt + | CreateStatsStmt + | CreateTableSpaceStmt + | CreateTransformStmt + | CreateTrigStmt + | CreateEventTrigStmt + | CreateRoleStmt + | CreateUserStmt + | CreateUserMappingStmt + | CreatedbStmt + | DeallocateStmt + | DeclareCursorStmt + | DefineStmt + | DeleteStmt + | DiscardStmt + | DoStmt + | DropCastStmt + | DropOpClassStmt + | DropOpFamilyStmt + | DropOwnedStmt + | DropStmt + | DropSubscriptionStmt + | DropTableSpaceStmt + | DropTransformStmt + | DropRoleStmt + | DropUserMappingStmt + | DropdbStmt + | ExecuteStmt + | ExplainStmt + | FetchStmt + | GrantStmt + | GrantRoleStmt + | ImportForeignSchemaStmt + | IndexStmt + | InsertStmtShort + | ListenStmt + | RefreshMatViewStmt + | LoadStmt + | LockStmt + | MergeStmt + | NotifyStmt + | PrepareStmt + | ReassignOwnedStmt + | ReindexStmt + | RemoveAggrStmt + | RemoveFuncStmt + | RemoveOperStmt + | RenameStmt + | RevokeStmt + | RevokeRoleStmt + | RuleStmt + | SecLabelStmt + | SelectStmt + | TransactionStmt + | TruncateStmt + | UnlistenStmt + | UpdateStmtShort + | VacuumStmt + | VariableResetStmt + | VariableSetStmt + | VariableShowStmt + | ViewStmt + | /*EMPTY*/ + { $$ = NULL; } + ; + +/* + * Generic supporting productions for DDL + */ +opt_single_name: + ColId { $$ = $1; } + | /* EMPTY */ { $$ = NULL; } + ; + +opt_qualified_name: + any_name { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +opt_concurrently: + CONCURRENTLY { $$ = true; } + | /*EMPTY*/ { $$ = false; } + ; + +opt_drop_behavior: + CASCADE { $$ = DROP_CASCADE; } + | RESTRICT { $$ = DROP_RESTRICT; } + | /* EMPTY */ { $$ = DROP_RESTRICT; /* default */ } + ; + +/***************************************************************************** + * + * CALL statement + * + *****************************************************************************/ + +CallStmt: CALL func_application + { + CallStmt *n = makeNode(CallStmt); + + n->funccall = castNode(FuncCall, $2); + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * Create a new Postgres DBMS role + * + *****************************************************************************/ + +CreateRoleStmt: + CREATE ROLE RoleId opt_with OptRoleList + { + CreateRoleStmt *n = makeNode(CreateRoleStmt); + + n->stmt_type = ROLESTMT_ROLE; + n->role = $3; + n->options = $5; + $$ = (Node *) n; + } + ; + + +opt_with: WITH + | WITH_LA + | /*EMPTY*/ + ; + +/* + * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER + * for backwards compatibility). Note: the only option required by SQL99 + * is "WITH ADMIN name". + */ +OptRoleList: + OptRoleList CreateOptRoleElem { $$ = lappend($1, $2); } + | /* EMPTY */ { $$ = NIL; } + ; + +AlterOptRoleList: + AlterOptRoleList AlterOptRoleElem { $$ = lappend($1, $2); } + | /* EMPTY */ { $$ = NIL; } + ; + +AlterOptRoleElem: + PASSWORD Sconst + { + $$ = makeDefElem("password", + (Node *) makeString($2), @1); + } + | PASSWORD NULL_P + { + $$ = makeDefElem("password", NULL, @1); + } + | ENCRYPTED PASSWORD Sconst + { + /* + * These days, passwords are always stored in encrypted + * form, so there is no difference between PASSWORD and + * ENCRYPTED PASSWORD. + */ + $$ = makeDefElem("password", + (Node *) makeString($3), @1); + } + | UNENCRYPTED PASSWORD Sconst + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("UNENCRYPTED PASSWORD is no longer supported"), + errhint("Remove UNENCRYPTED to store the password in encrypted form instead."), + parser_errposition(@1))); + } + | INHERIT + { + $$ = makeDefElem("inherit", (Node *) makeBoolean(true), @1); + } + | CONNECTION LIMIT SignedIconst + { + $$ = makeDefElem("connectionlimit", (Node *) makeInteger($3), @1); + } + | VALID UNTIL Sconst + { + $$ = makeDefElem("validUntil", (Node *) makeString($3), @1); + } + /* Supported but not documented for roles, for use by ALTER GROUP. */ + | USER role_list + { + $$ = makeDefElem("rolemembers", (Node *) $2, @1); + } + | IDENT + { + /* + * We handle identifiers that aren't parser keywords with + * the following special-case codes, to avoid bloating the + * size of the main parser. + */ + if (strcmp($1, "superuser") == 0) + $$ = makeDefElem("superuser", (Node *) makeBoolean(true), @1); + else if (strcmp($1, "nosuperuser") == 0) + $$ = makeDefElem("superuser", (Node *) makeBoolean(false), @1); + else if (strcmp($1, "createrole") == 0) + $$ = makeDefElem("createrole", (Node *) makeBoolean(true), @1); + else if (strcmp($1, "nocreaterole") == 0) + $$ = makeDefElem("createrole", (Node *) makeBoolean(false), @1); + else if (strcmp($1, "replication") == 0) + $$ = makeDefElem("isreplication", (Node *) makeBoolean(true), @1); + else if (strcmp($1, "noreplication") == 0) + $$ = makeDefElem("isreplication", (Node *) makeBoolean(false), @1); + else if (strcmp($1, "createdb") == 0) + $$ = makeDefElem("createdb", (Node *) makeBoolean(true), @1); + else if (strcmp($1, "nocreatedb") == 0) + $$ = makeDefElem("createdb", (Node *) makeBoolean(false), @1); + else if (strcmp($1, "login") == 0) + $$ = makeDefElem("canlogin", (Node *) makeBoolean(true), @1); + else if (strcmp($1, "nologin") == 0) + $$ = makeDefElem("canlogin", (Node *) makeBoolean(false), @1); + else if (strcmp($1, "bypassrls") == 0) + $$ = makeDefElem("bypassrls", (Node *) makeBoolean(true), @1); + else if (strcmp($1, "nobypassrls") == 0) + $$ = makeDefElem("bypassrls", (Node *) makeBoolean(false), @1); + else if (strcmp($1, "noinherit") == 0) + { + /* + * Note that INHERIT is a keyword, so it's handled by main parser, but + * NOINHERIT is handled here. + */ + $$ = makeDefElem("inherit", (Node *) makeBoolean(false), @1); + } + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized role option \"%s\"", $1), + parser_errposition(@1))); + } + ; + +CreateOptRoleElem: + AlterOptRoleElem { $$ = $1; } + /* The following are not supported by ALTER ROLE/USER/GROUP */ + | SYSID Iconst + { + $$ = makeDefElem("sysid", (Node *) makeInteger($2), @1); + } + | ADMIN role_list + { + $$ = makeDefElem("adminmembers", (Node *) $2, @1); + } + | ROLE role_list + { + $$ = makeDefElem("rolemembers", (Node *) $2, @1); + } + | IN_P ROLE role_list + { + $$ = makeDefElem("addroleto", (Node *) $3, @1); + } + | IN_P GROUP_P role_list + { + $$ = makeDefElem("addroleto", (Node *) $3, @1); + } + ; + + +/***************************************************************************** + * + * Create a new Postgres DBMS user (role with implied login ability) + * + *****************************************************************************/ + +CreateUserStmt: + CREATE USER RoleId opt_with OptRoleList + { + CreateRoleStmt *n = makeNode(CreateRoleStmt); + + n->stmt_type = ROLESTMT_USER; + n->role = $3; + n->options = $5; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * Alter a postgresql DBMS role + * + *****************************************************************************/ + +AlterRoleStmt: + ALTER ROLE RoleSpec opt_with AlterOptRoleList + { + AlterRoleStmt *n = makeNode(AlterRoleStmt); + + n->role = $3; + n->action = +1; /* add, if there are members */ + n->options = $5; + $$ = (Node *) n; + } + | ALTER USER RoleSpec opt_with AlterOptRoleList + { + AlterRoleStmt *n = makeNode(AlterRoleStmt); + + n->role = $3; + n->action = +1; /* add, if there are members */ + n->options = $5; + $$ = (Node *) n; + } + ; + +opt_in_database: + /* EMPTY */ { $$ = NULL; } + | IN_P DATABASE name { $$ = $3; } + ; + +AlterRoleSetStmt: + ALTER ROLE RoleSpec opt_in_database SetResetClause + { + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + + n->role = $3; + n->database = $4; + n->setstmt = $5; + $$ = (Node *) n; + } + | ALTER ROLE ALL opt_in_database SetResetClause + { + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + + n->role = NULL; + n->database = $4; + n->setstmt = $5; + $$ = (Node *) n; + } + | ALTER USER RoleSpec opt_in_database SetResetClause + { + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + + n->role = $3; + n->database = $4; + n->setstmt = $5; + $$ = (Node *) n; + } + | ALTER USER ALL opt_in_database SetResetClause + { + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + + n->role = NULL; + n->database = $4; + n->setstmt = $5; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * Drop a postgresql DBMS role + * + * XXX Ideally this would have CASCADE/RESTRICT options, but a role + * might own objects in multiple databases, and there is presently no way to + * implement cascading to other databases. So we always behave as RESTRICT. + *****************************************************************************/ + +DropRoleStmt: + DROP ROLE role_list + { + DropRoleStmt *n = makeNode(DropRoleStmt); + + n->missing_ok = false; + n->roles = $3; + $$ = (Node *) n; + } + | DROP ROLE IF_P EXISTS role_list + { + DropRoleStmt *n = makeNode(DropRoleStmt); + + n->missing_ok = true; + n->roles = $5; + $$ = (Node *) n; + } + | DROP USER role_list + { + DropRoleStmt *n = makeNode(DropRoleStmt); + + n->missing_ok = false; + n->roles = $3; + $$ = (Node *) n; + } + | DROP USER IF_P EXISTS role_list + { + DropRoleStmt *n = makeNode(DropRoleStmt); + + n->roles = $5; + n->missing_ok = true; + $$ = (Node *) n; + } + | DROP GROUP_P role_list + { + DropRoleStmt *n = makeNode(DropRoleStmt); + + n->missing_ok = false; + n->roles = $3; + $$ = (Node *) n; + } + | DROP GROUP_P IF_P EXISTS role_list + { + DropRoleStmt *n = makeNode(DropRoleStmt); + + n->missing_ok = true; + n->roles = $5; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * Create a postgresql group (role without login ability) + * + *****************************************************************************/ + +CreateGroupStmt: + CREATE GROUP_P RoleId opt_with OptRoleList + { + CreateRoleStmt *n = makeNode(CreateRoleStmt); + + n->stmt_type = ROLESTMT_GROUP; + n->role = $3; + n->options = $5; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * Alter a postgresql group + * + *****************************************************************************/ + +AlterGroupStmt: + ALTER GROUP_P RoleSpec add_drop USER role_list + { + AlterRoleStmt *n = makeNode(AlterRoleStmt); + + n->role = $3; + n->action = $4; + n->options = list_make1(makeDefElem("rolemembers", + (Node *) $6, @6)); + $$ = (Node *) n; + } + ; + +add_drop: ADD_P { $$ = +1; } + | DROP { $$ = -1; } + ; + + +/***************************************************************************** + * + * Manipulate a schema + * + *****************************************************************************/ + +CreateSchemaStmt: + CREATE SCHEMA opt_single_name AUTHORIZATION RoleSpec OptSchemaEltList + { + CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + + /* One can omit the schema name or the authorization id. */ + n->schemaname = $3; + n->authrole = $5; + n->schemaElts = $6; + n->if_not_exists = false; + $$ = (Node *) n; + } + | CREATE SCHEMA ColId OptSchemaEltList + { + CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + + /* ...but not both */ + n->schemaname = $3; + n->authrole = NULL; + n->schemaElts = $4; + n->if_not_exists = false; + $$ = (Node *) n; + } + | CREATE SCHEMA IF_P NOT EXISTS opt_single_name AUTHORIZATION RoleSpec OptSchemaEltList + { + CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + + /* schema name can be omitted here, too */ + n->schemaname = $6; + n->authrole = $8; + if ($9 != NIL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"), + parser_errposition(@9))); + n->schemaElts = $9; + n->if_not_exists = true; + $$ = (Node *) n; + } + | CREATE SCHEMA IF_P NOT EXISTS ColId OptSchemaEltList + { + CreateSchemaStmt *n = makeNode(CreateSchemaStmt); + + /* ...but not here */ + n->schemaname = $6; + n->authrole = NULL; + if ($7 != NIL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE SCHEMA IF NOT EXISTS cannot include schema elements"), + parser_errposition(@7))); + n->schemaElts = $7; + n->if_not_exists = true; + $$ = (Node *) n; + } + ; + +OptSchemaEltList: + OptSchemaEltList schema_stmt + { + $$ = lappend($1, $2); + } + | /* EMPTY */ + { $$ = NIL; } + ; + +/* + * schema_stmt are the ones that can show up inside a CREATE SCHEMA + * statement (in addition to by themselves). + */ +schema_stmt: + CreateStmt + | IndexStmt + | CreateSeqStmt + | CreateTrigStmt + | GrantStmt + | ViewStmt + ; + + +/***************************************************************************** + * + * Set PG internal variable + * SET name TO 'var_value' + * Include SQL syntax (thomas 1997-10-22): + * SET TIME ZONE 'var_value' + * + *****************************************************************************/ + +VariableSetStmt: + PGPOOL SET generic_set + { + VariableSetStmt *n = $3; + n->type = T_PgpoolVariableSetStmt; /* Hack to keep changes minimum */ + n->is_local = false; + $$ = (Node *) n; + } + | PGPOOL set_rest_more + { + VariableSetStmt *n = $2; + n->type = T_PgpoolQueryCacheStmt; /* Hack to keep changes minimum */ + n->is_local = false; + $$ = (Node *) n; + } + | SET set_rest + { + VariableSetStmt *n = $2; + + n->is_local = false; + $$ = (Node *) n; + } + | SET LOCAL set_rest + { + VariableSetStmt *n = $3; + + n->is_local = true; + $$ = (Node *) n; + } + | SET SESSION set_rest + { + VariableSetStmt *n = $3; + + n->is_local = false; + $$ = (Node *) n; + } + ; + +set_rest: + TRANSACTION transaction_mode_list + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_MULTI; + n->name = "TRANSACTION"; + n->args = $2; + n->jumble_args = true; + n->location = -1; + $$ = n; + } + | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_MULTI; + n->name = "SESSION CHARACTERISTICS"; + n->args = $5; + n->jumble_args = true; + n->location = -1; + $$ = n; + } + | set_rest_more + ; + +generic_set: + var_name TO var_list + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = $3; + n->location = @3; + $$ = n; + } + | var_name '=' var_list + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = $1; + n->args = $3; + n->location = @3; + $$ = n; + } + | var_name TO DEFAULT + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_DEFAULT; + n->name = $1; + n->location = -1; + $$ = n; + } + | var_name '=' DEFAULT + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_DEFAULT; + n->name = $1; + n->location = -1; + $$ = n; + } + ; + +set_rest_more: /* Generic SET syntaxes: */ + generic_set {$$ = $1;} + | var_name FROM CURRENT_P + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_CURRENT; + n->name = $1; + n->location = -1; + $$ = n; + } + /* Special syntaxes mandated by SQL standard: */ + | TIME ZONE zone_value + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = "timezone"; + n->location = -1; + n->jumble_args = true; + if ($3 != NULL) + n->args = list_make1($3); + else + n->kind = VAR_SET_DEFAULT; + $$ = n; + } + | CATALOG_P Sconst + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("current database cannot be changed"), + parser_errposition(@2))); + $$ = NULL; /*not reached*/ + } + | SCHEMA Sconst + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = "search_path"; + n->args = list_make1(makeStringConst($2, @2)); + n->location = @2; + $$ = n; + } + | NAMES opt_encoding + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = "client_encoding"; + n->location = @2; + if ($2 != NULL) + n->args = list_make1(makeStringConst($2, @2)); + else + n->kind = VAR_SET_DEFAULT; + $$ = n; + } + | ROLE NonReservedWord_or_Sconst + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = "role"; + n->args = list_make1(makeStringConst($2, @2)); + n->location = @2; + $$ = n; + } + | SESSION AUTHORIZATION NonReservedWord_or_Sconst + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = "session_authorization"; + n->args = list_make1(makeStringConst($3, @3)); + n->location = @3; + $$ = n; + } + | SESSION AUTHORIZATION DEFAULT + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_DEFAULT; + n->name = "session_authorization"; + n->location = -1; + $$ = n; + } + | XML_P OPTION document_or_content + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_VALUE; + n->name = "xmloption"; + n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3)); + n->jumble_args = true; + n->location = -1; + $$ = n; + } + /* Special syntaxes invented by PostgreSQL: */ + | TRANSACTION SNAPSHOT Sconst + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_SET_MULTI; + n->name = "TRANSACTION SNAPSHOT"; + n->args = list_make1(makeStringConst($3, @3)); + n->location = @3; + $$ = n; + } + /* PGPOOL CACHE DELETE */ + | SET CACHE DELETE_P Sconst + { + VariableSetStmt *n = makeNode(VariableSetStmt); + n->name = $4; /* query to delete query cache */ + $$ = n; + } + ; + +var_name: ColId { $$ = $1; } + | var_name '.' ColId + { $$ = psprintf("%s.%s", $1, $3); } + ; + +var_list: var_value { $$ = list_make1($1); } + | var_list ',' var_value { $$ = lappend($1, $3); } + ; + +var_value: opt_boolean_or_string + { $$ = makeStringConst($1, @1); } + | NumericOnly + { $$ = makeAConst($1, @1); } + ; + +iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; } + | READ COMMITTED { $$ = "read committed"; } + | REPEATABLE READ { $$ = "repeatable read"; } + | SERIALIZABLE { $$ = "serializable"; } + ; + +opt_boolean_or_string: + TRUE_P { $$ = "true"; } + | FALSE_P { $$ = "false"; } + | ON { $$ = "on"; } + /* + * OFF is also accepted as a boolean value, but is handled by + * the NonReservedWord rule. The action for booleans and strings + * is the same, so we don't need to distinguish them here. + */ + | NonReservedWord_or_Sconst { $$ = $1; } + ; + +/* Timezone values can be: + * - a string such as 'pst8pdt' + * - an identifier such as "pst8pdt" + * - an integer or floating point number + * - a time interval per SQL99 + * ColId gives reduce/reduce errors against ConstInterval and LOCAL, + * so use IDENT (meaning we reject anything that is a key word). + */ +zone_value: + Sconst + { + $$ = makeStringConst($1, @1); + } + | IDENT + { + $$ = makeStringConst($1, @1); + } + | ConstInterval Sconst opt_interval + { + TypeName *t = $1; + + if ($3 != NIL) + { + A_Const *n = (A_Const *) linitial($3); + + if ((n->val.ival.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("time zone interval must be HOUR or HOUR TO MINUTE"), + parser_errposition(@3))); + } + t->typmods = $3; + $$ = makeStringConstCast($2, @2, t); + } + | ConstInterval '(' Iconst ')' Sconst + { + TypeName *t = $1; + + t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), + makeIntConst($3, @3)); + $$ = makeStringConstCast($5, @5, t); + } + | NumericOnly { $$ = makeAConst($1, @1); } + | DEFAULT { $$ = NULL; } + | LOCAL { $$ = NULL; } + ; + +opt_encoding: + Sconst { $$ = $1; } + | DEFAULT { $$ = NULL; } + | /*EMPTY*/ { $$ = NULL; } + ; + +NonReservedWord_or_Sconst: + NonReservedWord { $$ = $1; } + | Sconst { $$ = $1; } + ; + +VariableResetStmt: + RESET reset_rest { $$ = (Node *) $2; } + | PGPOOL RESET generic_reset + { + VariableSetStmt *n = $3; + n->type = T_PgpoolVariableSetStmt; /* Hack to keep the changes minimum */ + $$ = (Node *) n; + } + ; + +reset_rest: + generic_reset { $$ = $1; } + | TIME ZONE + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_RESET; + n->name = "timezone"; + n->location = -1; + $$ = n; + } + | TRANSACTION ISOLATION LEVEL + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_RESET; + n->name = "transaction_isolation"; + n->location = -1; + $$ = n; + } + | SESSION AUTHORIZATION + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_RESET; + n->name = "session_authorization"; + n->location = -1; + $$ = n; + } + ; + +generic_reset: + var_name + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_RESET; + n->name = $1; + n->location = -1; + $$ = n; + } + | ALL + { + VariableSetStmt *n = makeNode(VariableSetStmt); + + n->kind = VAR_RESET_ALL; + n->location = -1; + $$ = n; + } + ; + +/* SetResetClause allows SET or RESET without LOCAL */ +SetResetClause: + SET set_rest { $$ = $2; } + | VariableResetStmt { $$ = (VariableSetStmt *) $1; } + ; + +/* SetResetClause allows SET or RESET without LOCAL */ +FunctionSetResetClause: + SET set_rest_more { $$ = $2; } + | VariableResetStmt { $$ = (VariableSetStmt *) $1; } + ; + + +VariableShowStmt: + /* pgpool extension */ + PGPOOL SHOW var_name + { + VariableShowStmt *n = (VariableShowStmt *)newNode(sizeof(VariableShowStmt),T_PgpoolVariableShowStmt); + n->name = $3; + $$ = (Node *) n; + } + | PGPOOL SHOW ALL + { + VariableShowStmt *n = (VariableShowStmt *)newNode(sizeof(VariableShowStmt),T_PgpoolVariableShowStmt); + n->name = "all"; + $$ = (Node *) n; + } + | SHOW var_name + { + VariableShowStmt *n = makeNode(VariableShowStmt); + + n->name = $2; + $$ = (Node *) n; + } + | SHOW TIME ZONE + { + VariableShowStmt *n = makeNode(VariableShowStmt); + + n->name = "timezone"; + $$ = (Node *) n; + } + | SHOW TRANSACTION ISOLATION LEVEL + { + VariableShowStmt *n = makeNode(VariableShowStmt); + + n->name = "transaction_isolation"; + $$ = (Node *) n; + } + | SHOW SESSION AUTHORIZATION + { + VariableShowStmt *n = makeNode(VariableShowStmt); + + n->name = "session_authorization"; + $$ = (Node *) n; + } + | SHOW ALL + { + VariableShowStmt *n = makeNode(VariableShowStmt); + + n->name = "all"; + $$ = (Node *) n; + } + ; + + +ConstraintsSetStmt: + SET CONSTRAINTS constraints_set_list constraints_set_mode + { + ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt); + + n->constraints = $3; + n->deferred = $4; + $$ = (Node *) n; + } + ; + +constraints_set_list: + ALL { $$ = NIL; } + | qualified_name_list { $$ = $1; } + ; + +constraints_set_mode: + DEFERRED { $$ = true; } + | IMMEDIATE { $$ = false; } + ; + + +/* + * Checkpoint statement + */ +CheckPointStmt: + CHECKPOINT + { + CheckPointStmt *n = makeNode(CheckPointStmt); + + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * DISCARD { ALL | TEMP | PLANS | SEQUENCES } + * + *****************************************************************************/ + +DiscardStmt: + DISCARD ALL + { + DiscardStmt *n = makeNode(DiscardStmt); + + n->target = DISCARD_ALL; + $$ = (Node *) n; + } + | DISCARD TEMP + { + DiscardStmt *n = makeNode(DiscardStmt); + + n->target = DISCARD_TEMP; + $$ = (Node *) n; + } + | DISCARD TEMPORARY + { + DiscardStmt *n = makeNode(DiscardStmt); + + n->target = DISCARD_TEMP; + $$ = (Node *) n; + } + | DISCARD PLANS + { + DiscardStmt *n = makeNode(DiscardStmt); + + n->target = DISCARD_PLANS; + $$ = (Node *) n; + } + | DISCARD SEQUENCES + { + DiscardStmt *n = makeNode(DiscardStmt); + + n->target = DISCARD_SEQUENCES; + $$ = (Node *) n; + } + + ; + + +/***************************************************************************** + * + * ALTER [ TABLE | INDEX | SEQUENCE | VIEW | MATERIALIZED VIEW | FOREIGN TABLE ] variations + * + * Note: we accept all subcommands for each of the variants, and sort + * out what's really legal at execution time. + *****************************************************************************/ + +AlterTableStmt: + ALTER TABLE relation_expr alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $3; + n->cmds = $4; + n->objtype = OBJECT_TABLE; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER TABLE IF_P EXISTS relation_expr alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $5; + n->cmds = $6; + n->objtype = OBJECT_TABLE; + n->missing_ok = true; + $$ = (Node *) n; + } + | ALTER TABLE relation_expr partition_cmd + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $3; + n->cmds = list_make1($4); + n->objtype = OBJECT_TABLE; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER TABLE IF_P EXISTS relation_expr partition_cmd + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $5; + n->cmds = list_make1($6); + n->objtype = OBJECT_TABLE; + n->missing_ok = true; + $$ = (Node *) n; + } + | ALTER TABLE ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait + { + AlterTableMoveAllStmt *n = + makeNode(AlterTableMoveAllStmt); + + n->orig_tablespacename = $6; + n->objtype = OBJECT_TABLE; + n->roles = NIL; + n->new_tablespacename = $9; + n->nowait = $10; + $$ = (Node *) n; + } + | ALTER TABLE ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait + { + AlterTableMoveAllStmt *n = + makeNode(AlterTableMoveAllStmt); + + n->orig_tablespacename = $6; + n->objtype = OBJECT_TABLE; + n->roles = $9; + n->new_tablespacename = $12; + n->nowait = $13; + $$ = (Node *) n; + } + | ALTER INDEX qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $3; + n->cmds = $4; + n->objtype = OBJECT_INDEX; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER INDEX IF_P EXISTS qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $5; + n->cmds = $6; + n->objtype = OBJECT_INDEX; + n->missing_ok = true; + $$ = (Node *) n; + } + | ALTER INDEX qualified_name index_partition_cmd + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $3; + n->cmds = list_make1($4); + n->objtype = OBJECT_INDEX; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER INDEX ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait + { + AlterTableMoveAllStmt *n = + makeNode(AlterTableMoveAllStmt); + + n->orig_tablespacename = $6; + n->objtype = OBJECT_INDEX; + n->roles = NIL; + n->new_tablespacename = $9; + n->nowait = $10; + $$ = (Node *) n; + } + | ALTER INDEX ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait + { + AlterTableMoveAllStmt *n = + makeNode(AlterTableMoveAllStmt); + + n->orig_tablespacename = $6; + n->objtype = OBJECT_INDEX; + n->roles = $9; + n->new_tablespacename = $12; + n->nowait = $13; + $$ = (Node *) n; + } + | ALTER SEQUENCE qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $3; + n->cmds = $4; + n->objtype = OBJECT_SEQUENCE; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER SEQUENCE IF_P EXISTS qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $5; + n->cmds = $6; + n->objtype = OBJECT_SEQUENCE; + n->missing_ok = true; + $$ = (Node *) n; + } + | ALTER VIEW qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $3; + n->cmds = $4; + n->objtype = OBJECT_VIEW; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER VIEW IF_P EXISTS qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $5; + n->cmds = $6; + n->objtype = OBJECT_VIEW; + n->missing_ok = true; + $$ = (Node *) n; + } + | ALTER MATERIALIZED VIEW qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $4; + n->cmds = $5; + n->objtype = OBJECT_MATVIEW; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $6; + n->cmds = $7; + n->objtype = OBJECT_MATVIEW; + n->missing_ok = true; + $$ = (Node *) n; + } + | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name SET TABLESPACE name opt_nowait + { + AlterTableMoveAllStmt *n = + makeNode(AlterTableMoveAllStmt); + + n->orig_tablespacename = $7; + n->objtype = OBJECT_MATVIEW; + n->roles = NIL; + n->new_tablespacename = $10; + n->nowait = $11; + $$ = (Node *) n; + } + | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name OWNED BY role_list SET TABLESPACE name opt_nowait + { + AlterTableMoveAllStmt *n = + makeNode(AlterTableMoveAllStmt); + + n->orig_tablespacename = $7; + n->objtype = OBJECT_MATVIEW; + n->roles = $10; + n->new_tablespacename = $13; + n->nowait = $14; + $$ = (Node *) n; + } + | ALTER FOREIGN TABLE relation_expr alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $4; + n->cmds = $5; + n->objtype = OBJECT_FOREIGN_TABLE; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER FOREIGN TABLE IF_P EXISTS relation_expr alter_table_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + n->relation = $6; + n->cmds = $7; + n->objtype = OBJECT_FOREIGN_TABLE; + n->missing_ok = true; + $$ = (Node *) n; + } + ; + +alter_table_cmds: + alter_table_cmd { $$ = list_make1($1); } + | alter_table_cmds ',' alter_table_cmd { $$ = lappend($1, $3); } + ; + +partition_cmd: + /* ALTER TABLE ATTACH PARTITION FOR VALUES */ + ATTACH PARTITION qualified_name PartitionBoundSpec + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_AttachPartition; + cmd->name = $3; + cmd->bound = $4; + cmd->concurrent = false; + n->def = (Node *) cmd; + + $$ = (Node *) n; + } + /* ALTER TABLE DETACH PARTITION [CONCURRENTLY] */ + | DETACH PARTITION qualified_name opt_concurrently + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_DetachPartition; + cmd->name = $3; + cmd->bound = NULL; + cmd->concurrent = $4; + n->def = (Node *) cmd; + + $$ = (Node *) n; + } + | DETACH PARTITION qualified_name FINALIZE + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_DetachPartitionFinalize; + cmd->name = $3; + cmd->bound = NULL; + cmd->concurrent = false; + n->def = (Node *) cmd; + $$ = (Node *) n; + } + ; + +index_partition_cmd: + /* ALTER INDEX ATTACH PARTITION */ + ATTACH PARTITION qualified_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_AttachPartition; + cmd->name = $3; + cmd->bound = NULL; + cmd->concurrent = false; + n->def = (Node *) cmd; + + $$ = (Node *) n; + } + ; + +alter_table_cmd: + /* ALTER TABLE ADD */ + ADD_P columnDef + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_AddColumn; + n->def = $2; + n->missing_ok = false; + $$ = (Node *) n; + } + /* ALTER TABLE ADD IF NOT EXISTS */ + | ADD_P IF_P NOT EXISTS columnDef + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_AddColumn; + n->def = $5; + n->missing_ok = true; + $$ = (Node *) n; + } + /* ALTER TABLE ADD COLUMN */ + | ADD_P COLUMN columnDef + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_AddColumn; + n->def = $3; + n->missing_ok = false; + $$ = (Node *) n; + } + /* ALTER TABLE ADD COLUMN IF NOT EXISTS */ + | ADD_P COLUMN IF_P NOT EXISTS columnDef + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_AddColumn; + n->def = $6; + n->missing_ok = true; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] {SET DEFAULT |DROP DEFAULT} */ + | ALTER opt_column ColId alter_column_default + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ColumnDefault; + n->name = $3; + n->def = $4; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] DROP NOT NULL */ + | ALTER opt_column ColId DROP NOT NULL_P + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropNotNull; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET NOT NULL */ + | ALTER opt_column ColId SET NOT NULL_P + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetNotNull; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET EXPRESSION AS */ + | ALTER opt_column ColId SET EXPRESSION AS '(' a_expr ')' + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetExpression; + n->name = $3; + n->def = $8; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] DROP EXPRESSION */ + | ALTER opt_column ColId DROP EXPRESSION + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropExpression; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] DROP EXPRESSION IF EXISTS */ + | ALTER opt_column ColId DROP EXPRESSION IF_P EXISTS + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropExpression; + n->name = $3; + n->missing_ok = true; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ + | ALTER opt_column ColId SET STATISTICS set_statistics_value + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetStatistics; + n->name = $3; + n->def = $6; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ + | ALTER opt_column Iconst SET STATISTICS set_statistics_value + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + if ($3 <= 0 || $3 > PG_INT16_MAX) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("column number must be in range from 1 to %d", PG_INT16_MAX), + parser_errposition(@3))); + + n->subtype = AT_SetStatistics; + n->num = (int16) $3; + n->def = $6; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET ( column_parameter = value [, ... ] ) */ + | ALTER opt_column ColId SET reloptions + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetOptions; + n->name = $3; + n->def = (Node *) $5; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] RESET ( column_parameter [, ... ] ) */ + | ALTER opt_column ColId RESET reloptions + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ResetOptions; + n->name = $3; + n->def = (Node *) $5; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET STORAGE */ + | ALTER opt_column ColId SET column_storage + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetStorage; + n->name = $3; + n->def = (Node *) makeString($5); + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET COMPRESSION */ + | ALTER opt_column ColId SET column_compression + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetCompression; + n->name = $3; + n->def = (Node *) makeString($5); + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] ADD GENERATED ... AS IDENTITY ... */ + | ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList + { + AlterTableCmd *n = makeNode(AlterTableCmd); + Constraint *c = makeNode(Constraint); + + c->contype = CONSTR_IDENTITY; + c->generated_when = $6; + c->options = $9; + c->location = @5; + + n->subtype = AT_AddIdentity; + n->name = $3; + n->def = (Node *) c; + + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] SET /RESET */ + | ALTER opt_column ColId alter_identity_column_option_list + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetIdentity; + n->name = $3; + n->def = (Node *) $4; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] DROP IDENTITY */ + | ALTER opt_column ColId DROP IDENTITY_P + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropIdentity; + n->name = $3; + n->missing_ok = false; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER [COLUMN] DROP IDENTITY IF EXISTS */ + | ALTER opt_column ColId DROP IDENTITY_P IF_P EXISTS + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropIdentity; + n->name = $3; + n->missing_ok = true; + $$ = (Node *) n; + } + /* ALTER TABLE DROP [COLUMN] IF EXISTS [RESTRICT|CASCADE] */ + | DROP opt_column IF_P EXISTS ColId opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropColumn; + n->name = $5; + n->behavior = $6; + n->missing_ok = true; + $$ = (Node *) n; + } + /* ALTER TABLE DROP [COLUMN] [RESTRICT|CASCADE] */ + | DROP opt_column ColId opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropColumn; + n->name = $3; + n->behavior = $4; + n->missing_ok = false; + $$ = (Node *) n; + } + /* + * ALTER TABLE ALTER [COLUMN] [SET DATA] TYPE + * [ USING ] + */ + | ALTER opt_column ColId opt_set_data TYPE_P Typename opt_collate_clause alter_using + { + AlterTableCmd *n = makeNode(AlterTableCmd); + ColumnDef *def = makeNode(ColumnDef); + + n->subtype = AT_AlterColumnType; + n->name = $3; + n->def = (Node *) def; + /* We only use these fields of the ColumnDef node */ + def->typeName = $6; + def->collClause = (CollateClause *) $7; + def->raw_default = $8; + def->location = @3; + $$ = (Node *) n; + } + /* ALTER FOREIGN TABLE ALTER [COLUMN] OPTIONS */ + | ALTER opt_column ColId alter_generic_options + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AlterColumnGenericOptions; + n->name = $3; + n->def = (Node *) $4; + $$ = (Node *) n; + } + /* ALTER TABLE ADD CONSTRAINT ... */ + | ADD_P TableConstraint + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddConstraint; + n->def = $2; + n->missing_ok = false; + $$ = (Node *) n; + } + /* ALTER TABLE ALTER CONSTRAINT ... */ + | ALTER CONSTRAINT name ConstraintAttributeSpec + { + AlterTableCmd *n = makeNode(AlterTableCmd); + ATAlterConstraint *c = makeNode(ATAlterConstraint); + + n->subtype = AT_AlterConstraint; + n->def = (Node *) c; + c->conname = $3; + if ($4 & (CAS_NOT_ENFORCED | CAS_ENFORCED)) + c->alterEnforceability = true; + if ($4 & (CAS_DEFERRABLE | CAS_NOT_DEFERRABLE | + CAS_INITIALLY_DEFERRED | CAS_INITIALLY_IMMEDIATE)) + c->alterDeferrability = true; + if ($4 & CAS_NO_INHERIT) + c->alterInheritability = true; + /* handle unsupported case with specific error message */ + if ($4 & CAS_NOT_VALID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constraints cannot be altered to be NOT VALID"), + parser_errposition(@4))); + processCASbits($4, @4, "FOREIGN KEY", + &c->deferrable, + &c->initdeferred, + &c->is_enforced, + NULL, + &c->noinherit, + yyscanner); + $$ = (Node *) n; + } + /* ALTER TABLE ALTER CONSTRAINT INHERIT */ + | ALTER CONSTRAINT name INHERIT + { + AlterTableCmd *n = makeNode(AlterTableCmd); + ATAlterConstraint *c = makeNode(ATAlterConstraint); + + n->subtype = AT_AlterConstraint; + n->def = (Node *) c; + c->conname = $3; + c->alterInheritability = true; + c->noinherit = false; + + $$ = (Node *) n; + } + /* ALTER TABLE VALIDATE CONSTRAINT ... */ + | VALIDATE CONSTRAINT name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ValidateConstraint; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE DROP CONSTRAINT IF EXISTS [RESTRICT|CASCADE] */ + | DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropConstraint; + n->name = $5; + n->behavior = $6; + n->missing_ok = true; + $$ = (Node *) n; + } + /* ALTER TABLE DROP CONSTRAINT [RESTRICT|CASCADE] */ + | DROP CONSTRAINT name opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropConstraint; + n->name = $3; + n->behavior = $4; + n->missing_ok = false; + $$ = (Node *) n; + } + /* ALTER TABLE SET WITHOUT OIDS, for backward compat */ + | SET WITHOUT OIDS + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropOids; + $$ = (Node *) n; + } + /* ALTER TABLE CLUSTER ON */ + | CLUSTER ON name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ClusterOn; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE SET WITHOUT CLUSTER */ + | SET WITHOUT CLUSTER + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropCluster; + n->name = NULL; + $$ = (Node *) n; + } + /* ALTER TABLE SET LOGGED */ + | SET LOGGED + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetLogged; + $$ = (Node *) n; + } + /* ALTER TABLE SET UNLOGGED */ + | SET UNLOGGED + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetUnLogged; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE TRIGGER */ + | ENABLE_P TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableTrig; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE ALWAYS TRIGGER */ + | ENABLE_P ALWAYS TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableAlwaysTrig; + n->name = $4; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE REPLICA TRIGGER */ + | ENABLE_P REPLICA TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableReplicaTrig; + n->name = $4; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE TRIGGER ALL */ + | ENABLE_P TRIGGER ALL + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableTrigAll; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE TRIGGER USER */ + | ENABLE_P TRIGGER USER + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableTrigUser; + $$ = (Node *) n; + } + /* ALTER TABLE DISABLE TRIGGER */ + | DISABLE_P TRIGGER name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DisableTrig; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE DISABLE TRIGGER ALL */ + | DISABLE_P TRIGGER ALL + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DisableTrigAll; + $$ = (Node *) n; + } + /* ALTER TABLE DISABLE TRIGGER USER */ + | DISABLE_P TRIGGER USER + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DisableTrigUser; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE RULE */ + | ENABLE_P RULE name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableRule; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE ALWAYS RULE */ + | ENABLE_P ALWAYS RULE name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableAlwaysRule; + n->name = $4; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE REPLICA RULE */ + | ENABLE_P REPLICA RULE name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableReplicaRule; + n->name = $4; + $$ = (Node *) n; + } + /* ALTER TABLE DISABLE RULE */ + | DISABLE_P RULE name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DisableRule; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE INHERIT */ + | INHERIT qualified_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_AddInherit; + n->def = (Node *) $2; + $$ = (Node *) n; + } + /* ALTER TABLE NO INHERIT */ + | NO INHERIT qualified_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropInherit; + n->def = (Node *) $3; + $$ = (Node *) n; + } + /* ALTER TABLE OF */ + | OF any_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + TypeName *def = makeTypeNameFromNameList($2); + + def->location = @2; + n->subtype = AT_AddOf; + n->def = (Node *) def; + $$ = (Node *) n; + } + /* ALTER TABLE NOT OF */ + | NOT OF + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropOf; + $$ = (Node *) n; + } + /* ALTER TABLE OWNER TO RoleSpec */ + | OWNER TO RoleSpec + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ChangeOwner; + n->newowner = $3; + $$ = (Node *) n; + } + /* ALTER TABLE SET ACCESS METHOD { | DEFAULT } */ + | SET ACCESS METHOD set_access_method_name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetAccessMethod; + n->name = $4; + $$ = (Node *) n; + } + /* ALTER TABLE SET TABLESPACE */ + | SET TABLESPACE name + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetTableSpace; + n->name = $3; + $$ = (Node *) n; + } + /* ALTER TABLE SET (...) */ + | SET reloptions + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_SetRelOptions; + n->def = (Node *) $2; + $$ = (Node *) n; + } + /* ALTER TABLE RESET (...) */ + | RESET reloptions + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ResetRelOptions; + n->def = (Node *) $2; + $$ = (Node *) n; + } + /* ALTER TABLE REPLICA IDENTITY */ + | REPLICA IDENTITY_P replica_identity + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ReplicaIdentity; + n->def = $3; + $$ = (Node *) n; + } + /* ALTER TABLE ENABLE ROW LEVEL SECURITY */ + | ENABLE_P ROW LEVEL SECURITY + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_EnableRowSecurity; + $$ = (Node *) n; + } + /* ALTER TABLE DISABLE ROW LEVEL SECURITY */ + | DISABLE_P ROW LEVEL SECURITY + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DisableRowSecurity; + $$ = (Node *) n; + } + /* ALTER TABLE FORCE ROW LEVEL SECURITY */ + | FORCE ROW LEVEL SECURITY + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_ForceRowSecurity; + $$ = (Node *) n; + } + /* ALTER TABLE NO FORCE ROW LEVEL SECURITY */ + | NO FORCE ROW LEVEL SECURITY + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_NoForceRowSecurity; + $$ = (Node *) n; + } + | alter_generic_options + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_GenericOptions; + n->def = (Node *) $1; + $$ = (Node *) n; + } + ; + +alter_column_default: + SET DEFAULT a_expr { $$ = $3; } + | DROP DEFAULT { $$ = NULL; } + ; + +opt_collate_clause: + COLLATE any_name + { + CollateClause *n = makeNode(CollateClause); + + n->arg = NULL; + n->collname = $2; + n->location = @1; + $$ = (Node *) n; + } + | /* EMPTY */ { $$ = NULL; } + ; + +alter_using: + USING a_expr { $$ = $2; } + | /* EMPTY */ { $$ = NULL; } + ; + +replica_identity: + NOTHING + { + ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + + n->identity_type = REPLICA_IDENTITY_NOTHING; + n->name = NULL; + $$ = (Node *) n; + } + | FULL + { + ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + + n->identity_type = REPLICA_IDENTITY_FULL; + n->name = NULL; + $$ = (Node *) n; + } + | DEFAULT + { + ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + + n->identity_type = REPLICA_IDENTITY_DEFAULT; + n->name = NULL; + $$ = (Node *) n; + } + | USING INDEX name + { + ReplicaIdentityStmt *n = makeNode(ReplicaIdentityStmt); + + n->identity_type = REPLICA_IDENTITY_INDEX; + n->name = $3; + $$ = (Node *) n; + } +; + +reloptions: + '(' reloption_list ')' { $$ = $2; } + ; + +opt_reloptions: WITH reloptions { $$ = $2; } + | /* EMPTY */ { $$ = NIL; } + ; + +reloption_list: + reloption_elem { $$ = list_make1($1); } + | reloption_list ',' reloption_elem { $$ = lappend($1, $3); } + ; + +/* This should match def_elem and also allow qualified names */ +reloption_elem: + ColLabel '=' def_arg + { + $$ = makeDefElem($1, (Node *) $3, @1); + } + | ColLabel + { + $$ = makeDefElem($1, NULL, @1); + } + | ColLabel '.' ColLabel '=' def_arg + { + $$ = makeDefElemExtended($1, $3, (Node *) $5, + DEFELEM_UNSPEC, @1); + } + | ColLabel '.' ColLabel + { + $$ = makeDefElemExtended($1, $3, NULL, DEFELEM_UNSPEC, @1); + } + ; + +alter_identity_column_option_list: + alter_identity_column_option + { $$ = list_make1($1); } + | alter_identity_column_option_list alter_identity_column_option + { $$ = lappend($1, $2); } + ; + +alter_identity_column_option: + RESTART + { + $$ = makeDefElem("restart", NULL, @1); + } + | RESTART opt_with NumericOnly + { + $$ = makeDefElem("restart", (Node *) $3, @1); + } + | SET SeqOptElem + { + if (strcmp($2->defname, "as") == 0 || + strcmp($2->defname, "restart") == 0 || + strcmp($2->defname, "owned_by") == 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("sequence option \"%s\" not supported here", $2->defname), + parser_errposition(@2))); + $$ = $2; + } + | SET GENERATED generated_when + { + $$ = makeDefElem("generated", (Node *) makeInteger($3), @1); + } + ; + +set_statistics_value: + SignedIconst { $$ = (Node *) makeInteger($1); } + | DEFAULT { $$ = NULL; } + ; + +set_access_method_name: + ColId { $$ = $1; } + | DEFAULT { $$ = NULL; } + ; + +PartitionBoundSpec: + /* a HASH partition */ + FOR VALUES WITH '(' hash_partbound ')' + { + ListCell *lc; + PartitionBoundSpec *n = makeNode(PartitionBoundSpec); + + n->strategy = PARTITION_STRATEGY_HASH; + n->modulus = n->remainder = -1; + + foreach (lc, $5) + { + DefElem *opt = lfirst_node(DefElem, lc); + + if (strcmp(opt->defname, "modulus") == 0) + { + if (n->modulus != -1) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("modulus for hash partition provided more than once"), + parser_errposition(opt->location))); + n->modulus = defGetInt32(opt); + } + else if (strcmp(opt->defname, "remainder") == 0) + { + if (n->remainder != -1) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("remainder for hash partition provided more than once"), + parser_errposition(opt->location))); + n->remainder = defGetInt32(opt); + } + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized hash partition bound specification \"%s\"", + opt->defname), + parser_errposition(opt->location))); + } + + if (n->modulus == -1) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("modulus for hash partition must be specified"), + parser_errposition(@3))); + if (n->remainder == -1) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("remainder for hash partition must be specified"), + parser_errposition(@3))); + + n->location = @3; + + $$ = n; + } + + /* a LIST partition */ + | FOR VALUES IN_P '(' expr_list ')' + { + PartitionBoundSpec *n = makeNode(PartitionBoundSpec); + + n->strategy = PARTITION_STRATEGY_LIST; + n->is_default = false; + n->listdatums = $5; + n->location = @3; + + $$ = n; + } + + /* a RANGE partition */ + | FOR VALUES FROM '(' expr_list ')' TO '(' expr_list ')' + { + PartitionBoundSpec *n = makeNode(PartitionBoundSpec); + + n->strategy = PARTITION_STRATEGY_RANGE; + n->is_default = false; + n->lowerdatums = $5; + n->upperdatums = $9; + n->location = @3; + + $$ = n; + } + + /* a DEFAULT partition */ + | DEFAULT + { + PartitionBoundSpec *n = makeNode(PartitionBoundSpec); + + n->is_default = true; + n->location = @1; + + $$ = n; + } + ; + +hash_partbound_elem: + NonReservedWord Iconst + { + $$ = makeDefElem($1, (Node *) makeInteger($2), @1); + } + ; + +hash_partbound: + hash_partbound_elem + { + $$ = list_make1($1); + } + | hash_partbound ',' hash_partbound_elem + { + $$ = lappend($1, $3); + } + ; + +/***************************************************************************** + * + * ALTER TYPE + * + * really variants of the ALTER TABLE subcommands with different spellings + *****************************************************************************/ + +AlterCompositeTypeStmt: + ALTER TYPE_P any_name alter_type_cmds + { + AlterTableStmt *n = makeNode(AlterTableStmt); + + /* can't use qualified_name, sigh */ + n->relation = makeRangeVarFromAnyName($3, @3, yyscanner); + n->cmds = $4; + n->objtype = OBJECT_TYPE; + $$ = (Node *) n; + } + ; + +alter_type_cmds: + alter_type_cmd { $$ = list_make1($1); } + | alter_type_cmds ',' alter_type_cmd { $$ = lappend($1, $3); } + ; + +alter_type_cmd: + /* ALTER TYPE ADD ATTRIBUTE [RESTRICT|CASCADE] */ + ADD_P ATTRIBUTE TableFuncElement opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_AddColumn; + n->def = $3; + n->behavior = $4; + $$ = (Node *) n; + } + /* ALTER TYPE DROP ATTRIBUTE IF EXISTS [RESTRICT|CASCADE] */ + | DROP ATTRIBUTE IF_P EXISTS ColId opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropColumn; + n->name = $5; + n->behavior = $6; + n->missing_ok = true; + $$ = (Node *) n; + } + /* ALTER TYPE DROP ATTRIBUTE [RESTRICT|CASCADE] */ + | DROP ATTRIBUTE ColId opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + + n->subtype = AT_DropColumn; + n->name = $3; + n->behavior = $4; + n->missing_ok = false; + $$ = (Node *) n; + } + /* ALTER TYPE ALTER ATTRIBUTE [SET DATA] TYPE [RESTRICT|CASCADE] */ + | ALTER ATTRIBUTE ColId opt_set_data TYPE_P Typename opt_collate_clause opt_drop_behavior + { + AlterTableCmd *n = makeNode(AlterTableCmd); + ColumnDef *def = makeNode(ColumnDef); + + n->subtype = AT_AlterColumnType; + n->name = $3; + n->def = (Node *) def; + n->behavior = $8; + /* We only use these fields of the ColumnDef node */ + def->typeName = $6; + def->collClause = (CollateClause *) $7; + def->raw_default = NULL; + def->location = @3; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * QUERY : + * close + * + *****************************************************************************/ + +ClosePortalStmt: + CLOSE cursor_name + { + ClosePortalStmt *n = makeNode(ClosePortalStmt); + + n->portalname = $2; + $$ = (Node *) n; + } + | CLOSE ALL + { + ClosePortalStmt *n = makeNode(ClosePortalStmt); + + n->portalname = NULL; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * QUERY : + * COPY relname [(columnList)] FROM/TO file [WITH] [(options)] + * COPY ( query ) TO file [WITH] [(options)] + * + * where 'query' can be one of: + * { SELECT | UPDATE | INSERT | DELETE } + * + * and 'file' can be one of: + * { PROGRAM 'command' | STDIN | STDOUT | 'filename' } + * + * In the preferred syntax the options are comma-separated + * and use generic identifiers instead of keywords. The pre-9.0 + * syntax had a hard-wired, space-separated set of options. + * + * Really old syntax, from versions 7.2 and prior: + * 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 + 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 = $5; + n->is_program = $6; + n->filename = $7; + n->whereClause = $11; + + if (n->is_program && n->filename == NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + 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 ($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 + { + CopyStmt *n = makeNode(CopyStmt); + + n->relation = NULL; + n->query = $3; + n->attlist = NIL; + n->is_from = false; + n->is_program = $6; + n->filename = $7; + n->options = $9; + + if (n->is_program && n->filename == NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("STDIN/STDOUT not allowed with PROGRAM"), + parser_errposition(@5))); + + $$ = (Node *) n; + } + ; + +copy_from: + FROM { $$ = true; } + | TO { $$ = false; } + ; + +opt_program: + PROGRAM { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + +/* + * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is + * used depends on the direction. (It really doesn't make sense to copy from + * stdout. We silently correct the "typo".) - AY 9/94 + */ +copy_file_name: + Sconst { $$ = $1; } + | STDIN { $$ = NULL; } + | STDOUT { $$ = NULL; } + ; + +copy_options: copy_opt_list { $$ = $1; } + | '(' copy_generic_opt_list ')' { $$ = $2; } + ; + +/* old COPY option syntax */ +copy_opt_list: + copy_opt_list copy_opt_item { $$ = lappend($1, $2); } + | /* EMPTY */ { $$ = NIL; } + ; + +copy_opt_item: + BINARY + { + $$ = makeDefElem("format", (Node *) makeString("binary"), @1); + } + | FREEZE + { + $$ = makeDefElem("freeze", (Node *) makeBoolean(true), @1); + } + | DELIMITER opt_as Sconst + { + $$ = makeDefElem("delimiter", (Node *) makeString($3), @1); + } + | NULL_P opt_as Sconst + { + $$ = makeDefElem("null", (Node *) makeString($3), @1); + } + | CSV + { + $$ = makeDefElem("format", (Node *) makeString("csv"), @1); + } + | HEADER_P + { + $$ = makeDefElem("header", (Node *) makeBoolean(true), @1); + } + | QUOTE opt_as Sconst + { + $$ = makeDefElem("quote", (Node *) makeString($3), @1); + } + | ESCAPE opt_as Sconst + { + $$ = makeDefElem("escape", (Node *) makeString($3), @1); + } + | FORCE QUOTE columnList + { + $$ = makeDefElem("force_quote", (Node *) $3, @1); + } + | FORCE QUOTE '*' + { + $$ = makeDefElem("force_quote", (Node *) makeNode(A_Star), @1); + } + | FORCE NOT NULL_P columnList + { + $$ = makeDefElem("force_not_null", (Node *) $4, @1); + } + | FORCE NOT NULL_P '*' + { + $$ = makeDefElem("force_not_null", (Node *) makeNode(A_Star), @1); + } + | FORCE NULL_P columnList + { + $$ = makeDefElem("force_null", (Node *) $3, @1); + } + | FORCE NULL_P '*' + { + $$ = makeDefElem("force_null", (Node *) makeNode(A_Star), @1); + } + | ENCODING Sconst + { + $$ = makeDefElem("encoding", (Node *) makeString($2), @1); + } + ; + +/* The following exist for backward compatibility with very old versions */ + +opt_binary: + BINARY + { + $$ = makeDefElem("format", (Node *) makeString("binary"), @1); + } + | /*EMPTY*/ { $$ = NULL; } + ; + +copy_delimiter: + opt_using DELIMITERS Sconst + { + $$ = makeDefElem("delimiter", (Node *) makeString($3), @2); + } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_using: + USING + | /*EMPTY*/ + ; + +/* new COPY option syntax */ +copy_generic_opt_list: + copy_generic_opt_elem + { + $$ = list_make1($1); + } + | copy_generic_opt_list ',' copy_generic_opt_elem + { + $$ = lappend($1, $3); + } + ; + +copy_generic_opt_elem: + ColLabel copy_generic_opt_arg + { + $$ = makeDefElem($1, $2, @1); + } + ; + +copy_generic_opt_arg: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + | NumericOnly { $$ = (Node *) $1; } + | '*' { $$ = (Node *) makeNode(A_Star); } + | DEFAULT { $$ = (Node *) makeString("default"); } + | '(' copy_generic_opt_arg_list ')' { $$ = (Node *) $2; } + | /* EMPTY */ { $$ = NULL; } + ; + +copy_generic_opt_arg_list: + copy_generic_opt_arg_list_item + { + $$ = list_make1($1); + } + | copy_generic_opt_arg_list ',' copy_generic_opt_arg_list_item + { + $$ = lappend($1, $3); + } + ; + +/* beware of emitting non-string list elements here; see commands/define.c */ +copy_generic_opt_arg_list_item: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + ; + + +/***************************************************************************** + * + * QUERY : + * CREATE TABLE relname + * + *****************************************************************************/ + +CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' + OptInherit OptPartitionSpec table_access_method_clause OptWith + OnCommitOption OptTableSpace + { + CreateStmt *n = makeNode(CreateStmt); + + $4->relpersistence = $2; + n->relation = $4; + n->tableElts = $6; + n->inhRelations = $8; + n->partspec = $9; + n->ofTypename = NULL; + n->constraints = NIL; + 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 table_access_method_clause + OptWith OnCommitOption OptTableSpace + { + CreateStmt *n = makeNode(CreateStmt); + + $7->relpersistence = $2; + n->relation = $7; + n->tableElts = $9; + n->inhRelations = $11; + n->partspec = $12; + n->ofTypename = NULL; + n->constraints = NIL; + 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 table_access_method_clause + OptWith OnCommitOption OptTableSpace + { + CreateStmt *n = makeNode(CreateStmt); + + $4->relpersistence = $2; + n->relation = $4; + n->tableElts = $7; + n->inhRelations = NIL; + n->partspec = $8; + n->ofTypename = makeTypeNameFromNameList($6); + n->ofTypename->location = @6; + n->constraints = NIL; + 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 table_access_method_clause + OptWith OnCommitOption OptTableSpace + { + CreateStmt *n = makeNode(CreateStmt); + + $7->relpersistence = $2; + n->relation = $7; + n->tableElts = $10; + n->inhRelations = NIL; + n->partspec = $11; + n->ofTypename = makeTypeNameFromNameList($9); + n->ofTypename->location = @9; + n->constraints = NIL; + 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 + table_access_method_clause OptWith OnCommitOption OptTableSpace + { + CreateStmt *n = makeNode(CreateStmt); + + $4->relpersistence = $2; + n->relation = $4; + n->tableElts = $8; + n->inhRelations = list_make1($7); + n->partbound = $9; + n->partspec = $10; + n->ofTypename = NULL; + n->constraints = NIL; + 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 + table_access_method_clause OptWith OnCommitOption OptTableSpace + { + CreateStmt *n = makeNode(CreateStmt); + + $7->relpersistence = $2; + n->relation = $7; + n->tableElts = $11; + n->inhRelations = list_make1($10); + n->partbound = $12; + n->partspec = $13; + n->ofTypename = NULL; + n->constraints = NIL; + n->accessMethod = $14; + n->options = $15; + n->oncommit = $16; + n->tablespacename = $17; + n->if_not_exists = true; + $$ = (Node *) n; + } + ; + +/* + * Redundancy here is needed to avoid shift/reduce conflicts, + * since TEMP is not a reserved word. See also OptTempTableName. + * + * NOTE: we accept both GLOBAL and LOCAL options. They currently do nothing, + * but future versions might consider GLOBAL to request SQL-spec-compliant + * temp table behavior, so warn about that. Since we have no modules the + * LOCAL keyword is really meaningless; furthermore, some other products + * implement LOCAL as meaning the same as our default temp table behavior, + * so we'll probably continue to treat LOCAL as a noise word. + */ +OptTemp: TEMPORARY { $$ = RELPERSISTENCE_TEMP; } + | TEMP { $$ = RELPERSISTENCE_TEMP; } + | LOCAL TEMPORARY { $$ = RELPERSISTENCE_TEMP; } + | LOCAL TEMP { $$ = RELPERSISTENCE_TEMP; } + | GLOBAL TEMPORARY + { + ereport(WARNING, + (errmsg("GLOBAL is deprecated in temporary table creation"), + parser_errposition(@1))); + $$ = RELPERSISTENCE_TEMP; + } + | GLOBAL TEMP + { + ereport(WARNING, + (errmsg("GLOBAL is deprecated in temporary table creation"), + parser_errposition(@1))); + $$ = RELPERSISTENCE_TEMP; + } + | UNLOGGED { $$ = RELPERSISTENCE_UNLOGGED; } + | /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; } + ; + +OptTableElementList: + TableElementList { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +OptTypedTableElementList: + '(' TypedTableElementList ')' { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +TableElementList: + TableElement + { + $$ = list_make1($1); + } + | TableElementList ',' TableElement + { + $$ = lappend($1, $3); + } + ; + +TypedTableElementList: + TypedTableElement + { + $$ = list_make1($1); + } + | TypedTableElementList ',' TypedTableElement + { + $$ = lappend($1, $3); + } + ; + +TableElement: + columnDef { $$ = $1; } + | TableLikeClause { $$ = $1; } + | TableConstraint { $$ = $1; } + ; + +TypedTableElement: + columnOptions { $$ = $1; } + | TableConstraint { $$ = $1; } + ; + +columnDef: ColId Typename opt_column_storage opt_column_compression create_generic_options ColQualList + { + ColumnDef *n = makeNode(ColumnDef); + + n->colname = $1; + n->typeName = $2; + n->storage_name = $3; + n->compression = $4; + n->inhcount = 0; + n->is_local = true; + n->is_not_null = false; + n->is_from_type = false; + n->storage = 0; + n->raw_default = NULL; + n->cooked_default = NULL; + n->collOid = InvalidOid; + n->fdwoptions = $5; + SplitColQualList($6, &n->constraints, &n->collClause, + yyscanner); + n->location = @1; + $$ = (Node *) n; + } + ; + +columnOptions: ColId ColQualList + { + ColumnDef *n = makeNode(ColumnDef); + + n->colname = $1; + n->typeName = NULL; + n->inhcount = 0; + n->is_local = true; + n->is_not_null = false; + n->is_from_type = false; + n->storage = 0; + n->raw_default = NULL; + n->cooked_default = NULL; + n->collOid = InvalidOid; + SplitColQualList($2, &n->constraints, &n->collClause, + yyscanner); + n->location = @1; + $$ = (Node *) n; + } + | ColId WITH OPTIONS ColQualList + { + ColumnDef *n = makeNode(ColumnDef); + + n->colname = $1; + n->typeName = NULL; + n->inhcount = 0; + n->is_local = true; + n->is_not_null = false; + n->is_from_type = false; + n->storage = 0; + n->raw_default = NULL; + n->cooked_default = NULL; + n->collOid = InvalidOid; + SplitColQualList($4, &n->constraints, &n->collClause, + yyscanner); + n->location = @1; + $$ = (Node *) n; + } + ; + +column_compression: + COMPRESSION ColId { $$ = $2; } + | COMPRESSION DEFAULT { $$ = pstrdup("default"); } + ; + +opt_column_compression: + column_compression { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +column_storage: + STORAGE ColId { $$ = $2; } + | STORAGE DEFAULT { $$ = pstrdup("default"); } + ; + +opt_column_storage: + column_storage { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +ColQualList: + ColQualList ColConstraint { $$ = lappend($1, $2); } + | /*EMPTY*/ { $$ = NIL; } + ; + +ColConstraint: + CONSTRAINT name ColConstraintElem + { + Constraint *n = castNode(Constraint, $3); + + n->conname = $2; + n->location = @1; + $$ = (Node *) n; + } + | ColConstraintElem { $$ = $1; } + | ConstraintAttr { $$ = $1; } + | COLLATE any_name + { + /* + * Note: the CollateClause is momentarily included in + * the list built by ColQualList, but we split it out + * again in SplitColQualList. + */ + CollateClause *n = makeNode(CollateClause); + + n->arg = NULL; + n->collname = $2; + n->location = @1; + $$ = (Node *) n; + } + ; + +/* DEFAULT NULL is already the default for Postgres. + * But define it here and carry it forward into the system + * to make it explicit. + * - thomas 1998-09-13 + * + * WITH NULL and NULL are not SQL-standard syntax elements, + * so leave them out. Use DEFAULT NULL to explicitly indicate + * that a column may have that value. WITH NULL leads to + * shift/reduce conflicts with WITH TIME ZONE anyway. + * - thomas 1999-01-08 + * + * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce + * conflict on NOT (since NOT might start a subsequent NOT NULL constraint, + * or be part of a_expr NOT LIKE or similar constructs). + */ +ColConstraintElem: + NOT NULL_P opt_no_inherit + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_NOTNULL; + n->location = @1; + n->is_no_inherit = $3; + n->is_enforced = true; + n->skip_validation = false; + n->initially_valid = true; + $$ = (Node *) n; + } + | NULL_P + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_NULL; + n->location = @1; + $$ = (Node *) n; + } + | UNIQUE opt_unique_null_treatment opt_definition OptConsTableSpace + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_UNIQUE; + n->location = @1; + n->nulls_not_distinct = !$2; + n->keys = NULL; + n->options = $3; + n->indexname = NULL; + n->indexspace = $4; + $$ = (Node *) n; + } + | PRIMARY KEY opt_definition OptConsTableSpace + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_PRIMARY; + n->location = @1; + n->keys = NULL; + n->options = $3; + n->indexname = NULL; + n->indexspace = $4; + $$ = (Node *) n; + } + | CHECK '(' a_expr ')' opt_no_inherit + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_CHECK; + n->location = @1; + n->is_no_inherit = $5; + n->raw_expr = $3; + n->cooked_expr = NULL; + n->is_enforced = true; + n->skip_validation = false; + n->initially_valid = true; + $$ = (Node *) n; + } + | DEFAULT b_expr + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_DEFAULT; + n->location = @1; + n->raw_expr = $2; + n->cooked_expr = NULL; + n->skip_validation = false; + n->initially_valid = true; + $$ = (Node *) n; + } + | GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_IDENTITY; + n->generated_when = $2; + n->options = $5; + n->location = @1; + $$ = (Node *) n; + } + | GENERATED generated_when AS '(' a_expr ')' opt_virtual_or_stored + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_GENERATED; + n->generated_when = $2; + n->raw_expr = $5; + n->cooked_expr = NULL; + n->generated_kind = $7; + 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); + + n->contype = CONSTR_FOREIGN; + n->location = @1; + n->pktable = $2; + n->fk_attrs = NIL; + n->pk_attrs = $3; + n->fk_matchtype = $4; + n->fk_upd_action = ($5)->updateAction->action; + n->fk_del_action = ($5)->deleteAction->action; + n->fk_del_set_cols = ($5)->deleteAction->cols; + n->is_enforced = true; + n->skip_validation = false; + n->initially_valid = true; + $$ = (Node *) n; + } + ; + +opt_unique_null_treatment: + NULLS_P DISTINCT { $$ = true; } + | NULLS_P NOT DISTINCT { $$ = false; } + | /*EMPTY*/ { $$ = true; } + ; + +generated_when: + ALWAYS { $$ = ATTRIBUTE_IDENTITY_ALWAYS; } + | BY DEFAULT { $$ = ATTRIBUTE_IDENTITY_BY_DEFAULT; } + ; + +opt_virtual_or_stored: + STORED { $$ = ATTRIBUTE_GENERATED_STORED; } + | VIRTUAL { $$ = ATTRIBUTE_GENERATED_VIRTUAL; } + | /*EMPTY*/ { $$ = ATTRIBUTE_GENERATED_VIRTUAL; } + ; + +/* + * ConstraintAttr represents constraint attributes, which we parse as if + * they were independent constraint clauses, in order to avoid shift/reduce + * conflicts (since NOT might start either an independent NOT NULL clause + * or an attribute). parse_utilcmd.c is responsible for attaching the + * attribute information to the preceding "real" constraint node, and for + * complaining if attribute clauses appear in the wrong place or wrong + * combinations. + * + * See also ConstraintAttributeSpec, which can be used in places where + * there is no parsing conflict. (Note: currently, NOT VALID and NO INHERIT + * are allowed clauses in ConstraintAttributeSpec, but not here. Someday we + * might need to allow them here too, but for the moment it doesn't seem + * useful in the statements that use ConstraintAttr.) + */ +ConstraintAttr: + DEFERRABLE + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_DEFERRABLE; + n->location = @1; + $$ = (Node *) n; + } + | NOT DEFERRABLE + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_NOT_DEFERRABLE; + n->location = @1; + $$ = (Node *) n; + } + | INITIALLY DEFERRED + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_DEFERRED; + n->location = @1; + $$ = (Node *) n; + } + | INITIALLY IMMEDIATE + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_IMMEDIATE; + n->location = @1; + $$ = (Node *) n; + } + | ENFORCED + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_ENFORCED; + n->location = @1; + $$ = (Node *) n; + } + | NOT ENFORCED + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_ATTR_NOT_ENFORCED; + n->location = @1; + $$ = (Node *) n; + } + ; + + +TableLikeClause: + LIKE qualified_name TableLikeOptionList + { + TableLikeClause *n = makeNode(TableLikeClause); + + n->relation = $2; + n->options = $3; + n->relationOid = InvalidOid; + $$ = (Node *) n; + } + ; + +TableLikeOptionList: + TableLikeOptionList INCLUDING TableLikeOption { $$ = $1 | $3; } + | TableLikeOptionList EXCLUDING TableLikeOption { $$ = $1 & ~$3; } + | /* EMPTY */ { $$ = 0; } + ; + +TableLikeOption: + COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; } + | COMPRESSION { $$ = CREATE_TABLE_LIKE_COMPRESSION; } + | 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; } + | ALL { $$ = CREATE_TABLE_LIKE_ALL; } + ; + + +/* ConstraintElem specifies constraint syntax which is not embedded into + * a column definition. ColConstraintElem specifies the embedded form. + * - thomas 1997-12-03 + */ +TableConstraint: + CONSTRAINT name ConstraintElem + { + Constraint *n = castNode(Constraint, $3); + + n->conname = $2; + n->location = @1; + $$ = (Node *) n; + } + | ConstraintElem { $$ = $1; } + ; + +ConstraintElem: + CHECK '(' a_expr ')' ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_CHECK; + n->location = @1; + n->raw_expr = $3; + n->cooked_expr = NULL; + processCASbits($5, @5, "CHECK", + NULL, NULL, &n->is_enforced, &n->skip_validation, + &n->is_no_inherit, yyscanner); + n->initially_valid = !n->skip_validation; + $$ = (Node *) n; + } + | NOT NULL_P ColId ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_NOTNULL; + n->location = @1; + n->keys = list_make1(makeString($3)); + processCASbits($4, @4, "NOT NULL", + NULL, NULL, NULL, &n->skip_validation, + &n->is_no_inherit, yyscanner); + n->initially_valid = !n->skip_validation; + $$ = (Node *) n; + } + | UNIQUE opt_unique_null_treatment '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace + ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_UNIQUE; + n->location = @1; + n->nulls_not_distinct = !$2; + n->keys = $4; + n->without_overlaps = $5; + n->including = $7; + n->options = $8; + n->indexname = NULL; + n->indexspace = $9; + processCASbits($10, @10, "UNIQUE", + &n->deferrable, &n->initdeferred, NULL, + NULL, NULL, yyscanner); + $$ = (Node *) n; + } + | UNIQUE ExistingIndex ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_UNIQUE; + n->location = @1; + n->keys = NIL; + n->including = NIL; + n->options = NIL; + n->indexname = $2; + n->indexspace = NULL; + processCASbits($3, @3, "UNIQUE", + &n->deferrable, &n->initdeferred, NULL, + NULL, NULL, yyscanner); + $$ = (Node *) n; + } + | PRIMARY KEY '(' columnList opt_without_overlaps ')' opt_c_include opt_definition OptConsTableSpace + ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_PRIMARY; + n->location = @1; + n->keys = $4; + n->without_overlaps = $5; + n->including = $7; + n->options = $8; + n->indexname = NULL; + n->indexspace = $9; + processCASbits($10, @10, "PRIMARY KEY", + &n->deferrable, &n->initdeferred, NULL, + NULL, NULL, yyscanner); + $$ = (Node *) n; + } + | PRIMARY KEY ExistingIndex ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_PRIMARY; + n->location = @1; + n->keys = NIL; + n->including = NIL; + n->options = NIL; + n->indexname = $3; + n->indexspace = NULL; + processCASbits($4, @4, "PRIMARY KEY", + &n->deferrable, &n->initdeferred, NULL, + NULL, NULL, yyscanner); + $$ = (Node *) n; + } + | EXCLUDE access_method_clause '(' ExclusionConstraintList ')' + opt_c_include opt_definition OptConsTableSpace OptWhereClause + ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_EXCLUSION; + n->location = @1; + n->access_method = $2; + n->exclusions = $4; + n->including = $6; + n->options = $7; + n->indexname = NULL; + n->indexspace = $8; + n->where_clause = $9; + processCASbits($10, @10, "EXCLUDE", + &n->deferrable, &n->initdeferred, NULL, + NULL, NULL, yyscanner); + $$ = (Node *) n; + } + | FOREIGN KEY '(' columnList optionalPeriodName ')' REFERENCES qualified_name + opt_column_and_period_list key_match key_actions ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_FOREIGN; + n->location = @1; + n->pktable = $8; + n->fk_attrs = $4; + if ($5) + { + n->fk_attrs = lappend(n->fk_attrs, $5); + n->fk_with_period = true; + } + n->pk_attrs = linitial($9); + if (lsecond($9)) + { + n->pk_attrs = lappend(n->pk_attrs, lsecond($9)); + n->pk_with_period = true; + } + n->fk_matchtype = $10; + n->fk_upd_action = ($11)->updateAction->action; + n->fk_del_action = ($11)->deleteAction->action; + n->fk_del_set_cols = ($11)->deleteAction->cols; + processCASbits($12, @12, "FOREIGN KEY", + &n->deferrable, &n->initdeferred, + &n->is_enforced, &n->skip_validation, NULL, + yyscanner); + n->initially_valid = !n->skip_validation; + $$ = (Node *) n; + } + ; + +/* + * DomainConstraint is separate from TableConstraint because the syntax for + * NOT NULL constraints is different. For table constraints, we need to + * accept a column name, but for domain constraints, we don't. (We could + * accept something like NOT NULL VALUE, but that seems weird.) CREATE DOMAIN + * (which uses ColQualList) has for a long time accepted NOT NULL without a + * column name, so it makes sense that ALTER DOMAIN (which uses + * DomainConstraint) does as well. None of these syntaxes are per SQL + * standard; we are just living with the bits of inconsistency that have built + * up over time. + */ +DomainConstraint: + CONSTRAINT name DomainConstraintElem + { + Constraint *n = castNode(Constraint, $3); + + n->conname = $2; + n->location = @1; + $$ = (Node *) n; + } + | DomainConstraintElem { $$ = $1; } + ; + +DomainConstraintElem: + CHECK '(' a_expr ')' ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_CHECK; + n->location = @1; + n->raw_expr = $3; + n->cooked_expr = NULL; + processCASbits($5, @5, "CHECK", + NULL, NULL, NULL, &n->skip_validation, + &n->is_no_inherit, yyscanner); + n->is_enforced = true; + n->initially_valid = !n->skip_validation; + $$ = (Node *) n; + } + | NOT NULL_P ConstraintAttributeSpec + { + Constraint *n = makeNode(Constraint); + + n->contype = CONSTR_NOTNULL; + n->location = @1; + n->keys = list_make1(makeString("value")); + /* no NOT VALID, NO INHERIT support */ + processCASbits($3, @3, "NOT NULL", + NULL, NULL, NULL, + NULL, NULL, yyscanner); + n->initially_valid = true; + $$ = (Node *) n; + } + ; + +opt_no_inherit: NO INHERIT { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + +opt_without_overlaps: + WITHOUT OVERLAPS { $$ = true; } + | /*EMPTY*/ { $$ = false; } + ; + +opt_column_list: + '(' columnList ')' { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +columnList: + columnElem { $$ = list_make1($1); } + | columnList ',' columnElem { $$ = lappend($1, $3); } + ; + +optionalPeriodName: + ',' PERIOD columnElem { $$ = $3; } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_column_and_period_list: + '(' columnList optionalPeriodName ')' { $$ = list_make2($2, $3); } + | /*EMPTY*/ { $$ = list_make2(NIL, NULL); } + ; + +columnElem: ColId + { + $$ = (Node *) makeString($1); + } + ; + +opt_c_include: INCLUDE '(' columnList ')' { $$ = $3; } + | /* EMPTY */ { $$ = NIL; } + ; + +key_match: MATCH FULL + { + $$ = FKCONSTR_MATCH_FULL; + } + | MATCH PARTIAL + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("MATCH PARTIAL not yet implemented"), + parser_errposition(@1))); + $$ = FKCONSTR_MATCH_PARTIAL; + } + | MATCH SIMPLE + { + $$ = FKCONSTR_MATCH_SIMPLE; + } + | /*EMPTY*/ + { + $$ = FKCONSTR_MATCH_SIMPLE; + } + ; + +ExclusionConstraintList: + ExclusionConstraintElem { $$ = list_make1($1); } + | ExclusionConstraintList ',' ExclusionConstraintElem + { $$ = lappend($1, $3); } + ; + +ExclusionConstraintElem: index_elem WITH any_operator + { + $$ = list_make2($1, $3); + } + /* allow OPERATOR() decoration for the benefit of ruleutils.c */ + | index_elem WITH OPERATOR '(' any_operator ')' + { + $$ = list_make2($1, $5); + } + ; + +OptWhereClause: + WHERE '(' a_expr ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NULL; } + ; + +key_actions: + key_update + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = $1; + n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction->action = FKCONSTR_ACTION_NOACTION; + n->deleteAction->cols = NIL; + $$ = n; + } + | key_delete + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction->action = FKCONSTR_ACTION_NOACTION; + n->updateAction->cols = NIL; + n->deleteAction = $1; + $$ = n; + } + | key_update key_delete + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = $1; + n->deleteAction = $2; + $$ = n; + } + | key_delete key_update + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = $2; + n->deleteAction = $1; + $$ = n; + } + | /*EMPTY*/ + { + KeyActions *n = palloc(sizeof(KeyActions)); + + n->updateAction = palloc(sizeof(KeyAction)); + n->updateAction->action = FKCONSTR_ACTION_NOACTION; + n->updateAction->cols = NIL; + n->deleteAction = palloc(sizeof(KeyAction)); + n->deleteAction->action = FKCONSTR_ACTION_NOACTION; + n->deleteAction->cols = NIL; + $$ = n; + } + ; + +key_update: ON UPDATE key_action + { + if (($3)->cols) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("a column list with %s is only supported for ON DELETE actions", + ($3)->action == FKCONSTR_ACTION_SETNULL ? "SET NULL" : "SET DEFAULT"), + parser_errposition(@1))); + $$ = $3; + } + ; + +key_delete: ON DELETE_P key_action + { + $$ = $3; + } + ; + +key_action: + NO ACTION + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_NOACTION; + n->cols = NIL; + $$ = n; + } + | RESTRICT + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_RESTRICT; + n->cols = NIL; + $$ = n; + } + | CASCADE + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_CASCADE; + n->cols = NIL; + $$ = n; + } + | SET NULL_P opt_column_list + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_SETNULL; + n->cols = $3; + $$ = n; + } + | SET DEFAULT opt_column_list + { + KeyAction *n = palloc(sizeof(KeyAction)); + + n->action = FKCONSTR_ACTION_SETDEFAULT; + n->cols = $3; + $$ = n; + } + ; + +OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; + +/* Optional partition key specification */ +OptPartitionSpec: PartitionSpec { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +PartitionSpec: PARTITION BY ColId '(' part_params ')' + { + PartitionSpec *n = makeNode(PartitionSpec); + + n->strategy = parsePartitionStrategy($3, @3, yyscanner); + n->partParams = $5; + n->location = @1; + + $$ = n; + } + ; + +part_params: part_elem { $$ = list_make1($1); } + | part_params ',' part_elem { $$ = lappend($1, $3); } + ; + +part_elem: ColId opt_collate opt_qualified_name + { + PartitionElem *n = makeNode(PartitionElem); + + n->name = $1; + n->expr = NULL; + n->collation = $2; + n->opclass = $3; + n->location = @1; + $$ = n; + } + | func_expr_windowless opt_collate opt_qualified_name + { + PartitionElem *n = makeNode(PartitionElem); + + n->name = NULL; + n->expr = $1; + n->collation = $2; + n->opclass = $3; + n->location = @1; + $$ = n; + } + | '(' a_expr ')' opt_collate opt_qualified_name + { + PartitionElem *n = makeNode(PartitionElem); + + n->name = NULL; + n->expr = $2; + n->collation = $4; + n->opclass = $5; + n->location = @1; + $$ = n; + } + ; + +table_access_method_clause: + USING name { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* WITHOUT OIDS is legacy only */ +OptWith: + WITH reloptions { $$ = $2; } + | WITHOUT OIDS { $$ = NIL; } + | /*EMPTY*/ { $$ = NIL; } + ; + +OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; } + | ON COMMIT DELETE_P ROWS { $$ = ONCOMMIT_DELETE_ROWS; } + | ON COMMIT PRESERVE ROWS { $$ = ONCOMMIT_PRESERVE_ROWS; } + | /*EMPTY*/ { $$ = ONCOMMIT_NOOP; } + ; + +OptTableSpace: TABLESPACE name { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; } + | /*EMPTY*/ { $$ = NULL; } + ; + +ExistingIndex: USING INDEX name { $$ = $3; } + ; + +/***************************************************************************** + * + * QUERY : + * CREATE STATISTICS [[IF NOT EXISTS] stats_name] [(stat types)] + * ON expression-list FROM from_list + * + * Note: the expectation here is that the clauses after ON are a subset of + * SELECT syntax, allowing for expressions and joined tables, and probably + * someday a WHERE clause. Much less than that is currently implemented, + * but the grammar accepts it and then we'll throw FEATURE_NOT_SUPPORTED + * errors as necessary at execution. + * + * Statistics name is optional unless IF NOT EXISTS is specified. + * + *****************************************************************************/ + +CreateStatsStmt: + CREATE STATISTICS opt_qualified_name + opt_name_list ON stats_params FROM from_list + { + CreateStatsStmt *n = makeNode(CreateStatsStmt); + + n->defnames = $3; + n->stat_types = $4; + n->exprs = $6; + n->relations = $8; + n->stxcomment = NULL; + n->if_not_exists = false; + $$ = (Node *) n; + } + | CREATE STATISTICS IF_P NOT EXISTS any_name + opt_name_list ON stats_params FROM from_list + { + CreateStatsStmt *n = makeNode(CreateStatsStmt); + + n->defnames = $6; + n->stat_types = $7; + n->exprs = $9; + n->relations = $11; + n->stxcomment = NULL; + n->if_not_exists = true; + $$ = (Node *) n; + } + ; + +/* + * Statistics attributes can be either simple column references, or arbitrary + * expressions in parens. For compatibility with index attributes permitted + * in CREATE INDEX, we allow an expression that's just a function call to be + * written without parens. + */ + +stats_params: stats_param { $$ = list_make1($1); } + | stats_params ',' stats_param { $$ = lappend($1, $3); } + ; + +stats_param: ColId + { + $$ = makeNode(StatsElem); + $$->name = $1; + $$->expr = NULL; + } + | func_expr_windowless + { + $$ = makeNode(StatsElem); + $$->name = NULL; + $$->expr = $1; + } + | '(' a_expr ')' + { + $$ = makeNode(StatsElem); + $$->name = NULL; + $$->expr = $2; + } + ; + +/***************************************************************************** + * + * QUERY : + * ALTER STATISTICS [IF EXISTS] stats_name + * SET STATISTICS + * + *****************************************************************************/ + +AlterStatsStmt: + ALTER STATISTICS any_name SET STATISTICS set_statistics_value + { + 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 set_statistics_value + { + AlterStatsStmt *n = makeNode(AlterStatsStmt); + + n->defnames = $5; + n->missing_ok = true; + n->stxstattarget = $8; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERY : + * CREATE TABLE relname AS SelectStmt [ WITH [NO] DATA ] + * + * + * Note: SELECT ... INTO is a now-deprecated alternative for this. + * + *****************************************************************************/ + +CreateAsStmt: + CREATE OptTemp TABLE create_as_target AS SelectStmt opt_with_data + { + CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + + ctas->query = $6; + ctas->into = $4; + ctas->objtype = OBJECT_TABLE; + ctas->is_select_into = false; + ctas->if_not_exists = false; + /* cram additional flags into the IntoClause */ + $4->rel->relpersistence = $2; + $4->skipData = !($7); + $$ = (Node *) ctas; + } + | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS SelectStmt opt_with_data + { + CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + + ctas->query = $9; + ctas->into = $7; + ctas->objtype = OBJECT_TABLE; + ctas->is_select_into = false; + ctas->if_not_exists = true; + /* cram additional flags into the IntoClause */ + $7->rel->relpersistence = $2; + $7->skipData = !($10); + $$ = (Node *) ctas; + } + ; + +create_as_target: + qualified_name opt_column_list table_access_method_clause + OptWith OnCommitOption OptTableSpace + { + $$ = makeNode(IntoClause); + $$->rel = $1; + $$->colNames = $2; + $$->accessMethod = $3; + $$->options = $4; + $$->onCommit = $5; + $$->tableSpaceName = $6; + $$->viewQuery = NULL; + $$->skipData = false; /* might get changed later */ + } + ; + +opt_with_data: + WITH DATA_P { $$ = true; } + | WITH NO DATA_P { $$ = false; } + | /*EMPTY*/ { $$ = true; } + ; + + +/***************************************************************************** + * + * QUERY : + * CREATE MATERIALIZED VIEW relname AS SelectStmt + * + *****************************************************************************/ + +CreateMatViewStmt: + CREATE OptNoLog MATERIALIZED VIEW create_mv_target AS SelectStmt opt_with_data + { + CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + + ctas->query = $7; + ctas->into = $5; + ctas->objtype = OBJECT_MATVIEW; + ctas->is_select_into = false; + ctas->if_not_exists = false; + /* cram additional flags into the IntoClause */ + $5->rel->relpersistence = $2; + $5->skipData = !($8); + $$ = (Node *) ctas; + } + | CREATE OptNoLog MATERIALIZED VIEW IF_P NOT EXISTS create_mv_target AS SelectStmt opt_with_data + { + CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + + ctas->query = $10; + ctas->into = $8; + ctas->objtype = OBJECT_MATVIEW; + ctas->is_select_into = false; + ctas->if_not_exists = true; + /* cram additional flags into the IntoClause */ + $8->rel->relpersistence = $2; + $8->skipData = !($11); + $$ = (Node *) ctas; + } + ; + +create_mv_target: + qualified_name opt_column_list table_access_method_clause opt_reloptions OptTableSpace + { + $$ = makeNode(IntoClause); + $$->rel = $1; + $$->colNames = $2; + $$->accessMethod = $3; + $$->options = $4; + $$->onCommit = ONCOMMIT_NOOP; + $$->tableSpaceName = $5; + $$->viewQuery = NULL; /* filled at analysis time */ + $$->skipData = false; /* might get changed later */ + } + ; + +OptNoLog: UNLOGGED { $$ = RELPERSISTENCE_UNLOGGED; } + | /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; } + ; + + +/***************************************************************************** + * + * QUERY : + * REFRESH MATERIALIZED VIEW qualified_name + * + *****************************************************************************/ + +RefreshMatViewStmt: + REFRESH MATERIALIZED VIEW opt_concurrently qualified_name opt_with_data + { + RefreshMatViewStmt *n = makeNode(RefreshMatViewStmt); + + n->concurrent = $4; + n->relation = $5; + n->skipData = !($6); + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * QUERY : + * CREATE SEQUENCE seqname + * ALTER SEQUENCE seqname + * + *****************************************************************************/ + +CreateSeqStmt: + CREATE OptTemp SEQUENCE qualified_name OptSeqOptList + { + CreateSeqStmt *n = makeNode(CreateSeqStmt); + + $4->relpersistence = $2; + n->sequence = $4; + n->options = $5; + n->ownerId = InvalidOid; + n->if_not_exists = false; + $$ = (Node *) n; + } + | CREATE OptTemp SEQUENCE IF_P NOT EXISTS qualified_name OptSeqOptList + { + CreateSeqStmt *n = makeNode(CreateSeqStmt); + + $7->relpersistence = $2; + n->sequence = $7; + n->options = $8; + n->ownerId = InvalidOid; + n->if_not_exists = true; + $$ = (Node *) n; + } + ; + +AlterSeqStmt: + ALTER SEQUENCE qualified_name SeqOptList + { + AlterSeqStmt *n = makeNode(AlterSeqStmt); + + n->sequence = $3; + n->options = $4; + n->missing_ok = false; + $$ = (Node *) n; + } + | ALTER SEQUENCE IF_P EXISTS qualified_name SeqOptList + { + AlterSeqStmt *n = makeNode(AlterSeqStmt); + + n->sequence = $5; + n->options = $6; + n->missing_ok = true; + $$ = (Node *) n; + } + + ; + +OptSeqOptList: SeqOptList { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +OptParenthesizedSeqOptList: '(' SeqOptList ')' { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +SeqOptList: SeqOptElem { $$ = list_make1($1); } + | SeqOptList SeqOptElem { $$ = lappend($1, $2); } + ; + +SeqOptElem: AS SimpleTypename + { + $$ = makeDefElem("as", (Node *) $2, @1); + } + | CACHE NumericOnly + { + $$ = makeDefElem("cache", (Node *) $2, @1); + } + | CYCLE + { + $$ = makeDefElem("cycle", (Node *) makeBoolean(true), @1); + } + | NO CYCLE + { + $$ = makeDefElem("cycle", (Node *) makeBoolean(false), @1); + } + | INCREMENT opt_by NumericOnly + { + $$ = makeDefElem("increment", (Node *) $3, @1); + } + | LOGGED + { + $$ = makeDefElem("logged", NULL, @1); + } + | MAXVALUE NumericOnly + { + $$ = makeDefElem("maxvalue", (Node *) $2, @1); + } + | MINVALUE NumericOnly + { + $$ = makeDefElem("minvalue", (Node *) $2, @1); + } + | NO MAXVALUE + { + $$ = makeDefElem("maxvalue", NULL, @1); + } + | NO MINVALUE + { + $$ = makeDefElem("minvalue", NULL, @1); + } + | OWNED BY any_name + { + $$ = makeDefElem("owned_by", (Node *) $3, @1); + } + | SEQUENCE NAME_P any_name + { + $$ = makeDefElem("sequence_name", (Node *) $3, @1); + } + | START opt_with NumericOnly + { + $$ = makeDefElem("start", (Node *) $3, @1); + } + | RESTART + { + $$ = makeDefElem("restart", NULL, @1); + } + | RESTART opt_with NumericOnly + { + $$ = makeDefElem("restart", (Node *) $3, @1); + } + | UNLOGGED + { + $$ = makeDefElem("unlogged", NULL, @1); + } + ; + +opt_by: BY + | /* EMPTY */ + ; + +NumericOnly: + FCONST { $$ = (Node *) makeFloat($1); } + | '+' FCONST { $$ = (Node *) makeFloat($2); } + | '-' FCONST + { + Float *f = makeFloat($2); + + doNegateFloat(f); + $$ = (Node *) f; + } + | SignedIconst { $$ = (Node *) makeInteger($1); } + ; + +NumericOnly_list: NumericOnly { $$ = list_make1($1); } + | NumericOnly_list ',' NumericOnly { $$ = lappend($1, $3); } + ; + +/***************************************************************************** + * + * QUERIES : + * CREATE [OR REPLACE] [TRUSTED] [PROCEDURAL] LANGUAGE ... + * DROP [PROCEDURAL] LANGUAGE ... + * + *****************************************************************************/ + +CreatePLangStmt: + CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name + { + /* + * We now interpret parameterless CREATE LANGUAGE as + * CREATE EXTENSION. "OR REPLACE" is silently translated + * to "IF NOT EXISTS", which isn't quite the same, but + * seems more useful than throwing an error. We just + * ignore TRUSTED, as the previous code would have too. + */ + CreateExtensionStmt *n = makeNode(CreateExtensionStmt); + + n->if_not_exists = $2; + n->extname = $6; + n->options = NIL; + $$ = (Node *) n; + } + | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name + HANDLER handler_name opt_inline_handler opt_validator + { + CreatePLangStmt *n = makeNode(CreatePLangStmt); + + n->replace = $2; + n->plname = $6; + n->plhandler = $8; + n->plinline = $9; + n->plvalidator = $10; + n->pltrusted = $3; + $$ = (Node *) n; + } + ; + +opt_trusted: + TRUSTED { $$ = true; } + | /*EMPTY*/ { $$ = false; } + ; + +/* This ought to be just func_name, but that causes reduce/reduce conflicts + * (CREATE LANGUAGE is the only place where func_name isn't followed by '('). + * Work around by using simple names, instead. + */ +handler_name: + name { $$ = list_make1(makeString($1)); } + | name attrs { $$ = lcons(makeString($1), $2); } + ; + +opt_inline_handler: + INLINE_P handler_name { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +validator_clause: + VALIDATOR handler_name { $$ = $2; } + | NO VALIDATOR { $$ = NIL; } + ; + +opt_validator: + validator_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +opt_procedural: + PROCEDURAL + | /*EMPTY*/ + ; + +/***************************************************************************** + * + * QUERY: + * CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/' + * + *****************************************************************************/ + +CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst opt_reloptions + { + CreateTableSpaceStmt *n = makeNode(CreateTableSpaceStmt); + + n->tablespacename = $3; + n->owner = $4; + n->location = $6; + n->options = $7; + $$ = (Node *) n; + } + ; + +OptTableSpaceOwner: OWNER RoleSpec { $$ = $2; } + | /*EMPTY */ { $$ = NULL; } + ; + +/***************************************************************************** + * + * QUERY : + * DROP TABLESPACE + * + * No need for drop behaviour as we cannot implement dependencies for + * objects in other databases; we can only support RESTRICT. + * + ****************************************************************************/ + +DropTableSpaceStmt: DROP TABLESPACE name + { + DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); + + n->tablespacename = $3; + n->missing_ok = false; + $$ = (Node *) n; + } + | DROP TABLESPACE IF_P EXISTS name + { + DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); + + n->tablespacename = $5; + n->missing_ok = true; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERY: + * CREATE EXTENSION extension + * [ WITH ] [ SCHEMA schema ] [ VERSION version ] + * + *****************************************************************************/ + +CreateExtensionStmt: CREATE EXTENSION name opt_with create_extension_opt_list + { + CreateExtensionStmt *n = makeNode(CreateExtensionStmt); + + n->extname = $3; + n->if_not_exists = false; + n->options = $5; + $$ = (Node *) n; + } + | CREATE EXTENSION IF_P NOT EXISTS name opt_with create_extension_opt_list + { + CreateExtensionStmt *n = makeNode(CreateExtensionStmt); + + n->extname = $6; + n->if_not_exists = true; + n->options = $8; + $$ = (Node *) n; + } + ; + +create_extension_opt_list: + create_extension_opt_list create_extension_opt_item + { $$ = lappend($1, $2); } + | /* EMPTY */ + { $$ = NIL; } + ; + +create_extension_opt_item: + SCHEMA name + { + $$ = makeDefElem("schema", (Node *) makeString($2), @1); + } + | VERSION_P NonReservedWord_or_Sconst + { + $$ = makeDefElem("new_version", (Node *) makeString($2), @1); + } + | FROM NonReservedWord_or_Sconst + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE EXTENSION ... FROM is no longer supported"), + parser_errposition(@1))); + } + | CASCADE + { + $$ = makeDefElem("cascade", (Node *) makeBoolean(true), @1); + } + ; + +/***************************************************************************** + * + * ALTER EXTENSION name UPDATE [ TO version ] + * + *****************************************************************************/ + +AlterExtensionStmt: ALTER EXTENSION name UPDATE alter_extension_opt_list + { + AlterExtensionStmt *n = makeNode(AlterExtensionStmt); + + n->extname = $3; + n->options = $5; + $$ = (Node *) n; + } + ; + +alter_extension_opt_list: + alter_extension_opt_list alter_extension_opt_item + { $$ = lappend($1, $2); } + | /* EMPTY */ + { $$ = NIL; } + ; + +alter_extension_opt_item: + TO NonReservedWord_or_Sconst + { + $$ = makeDefElem("new_version", (Node *) makeString($2), @1); + } + ; + +/***************************************************************************** + * + * ALTER EXTENSION name ADD/DROP object-identifier + * + *****************************************************************************/ + +AlterExtensionContentsStmt: + ALTER EXTENSION name add_drop object_type_name name + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = $5; + n->object = (Node *) makeString($6); + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop object_type_any_name any_name + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = $5; + n->object = (Node *) $6; + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_AGGREGATE; + n->object = (Node *) $6; + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')' + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_CAST; + n->object = (Node *) list_make2($7, $9); + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop DOMAIN_P Typename + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_DOMAIN; + n->object = (Node *) $6; + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop FUNCTION function_with_argtypes + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_FUNCTION; + n->object = (Node *) $6; + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop OPERATOR operator_with_argtypes + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_OPERATOR; + n->object = (Node *) $6; + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING name + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_OPCLASS; + n->object = (Node *) lcons(makeString($9), $7); + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING name + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_OPFAMILY; + n->object = (Node *) lcons(makeString($9), $7); + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop PROCEDURE function_with_argtypes + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_PROCEDURE; + n->object = (Node *) $6; + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop ROUTINE function_with_argtypes + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_ROUTINE; + n->object = (Node *) $6; + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop TRANSFORM FOR Typename LANGUAGE name + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_TRANSFORM; + n->object = (Node *) list_make2($7, makeString($9)); + $$ = (Node *) n; + } + | ALTER EXTENSION name add_drop TYPE_P Typename + { + AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt); + + n->extname = $3; + n->action = $4; + n->objtype = OBJECT_TYPE; + n->object = (Node *) $6; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERY: + * CREATE FOREIGN DATA WRAPPER name options + * + *****************************************************************************/ + +CreateFdwStmt: CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic_options + { + CreateFdwStmt *n = makeNode(CreateFdwStmt); + + n->fdwname = $5; + n->func_options = $6; + n->options = $7; + $$ = (Node *) n; + } + ; + +fdw_option: + HANDLER handler_name { $$ = makeDefElem("handler", (Node *) $2, @1); } + | NO HANDLER { $$ = makeDefElem("handler", NULL, @1); } + | VALIDATOR handler_name { $$ = makeDefElem("validator", (Node *) $2, @1); } + | NO VALIDATOR { $$ = makeDefElem("validator", NULL, @1); } + ; + +fdw_options: + fdw_option { $$ = list_make1($1); } + | fdw_options fdw_option { $$ = lappend($1, $2); } + ; + +opt_fdw_options: + fdw_options { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +/***************************************************************************** + * + * QUERY : + * ALTER FOREIGN DATA WRAPPER name options + * + ****************************************************************************/ + +AlterFdwStmt: ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_options + { + AlterFdwStmt *n = makeNode(AlterFdwStmt); + + n->fdwname = $5; + n->func_options = $6; + n->options = $7; + $$ = (Node *) n; + } + | ALTER FOREIGN DATA_P WRAPPER name fdw_options + { + AlterFdwStmt *n = makeNode(AlterFdwStmt); + + n->fdwname = $5; + n->func_options = $6; + n->options = NIL; + $$ = (Node *) n; + } + ; + +/* Options definition for CREATE FDW, SERVER and USER MAPPING */ +create_generic_options: + OPTIONS '(' generic_option_list ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NIL; } + ; + +generic_option_list: + generic_option_elem + { + $$ = list_make1($1); + } + | generic_option_list ',' generic_option_elem + { + $$ = lappend($1, $3); + } + ; + +/* Options definition for ALTER FDW, SERVER and USER MAPPING */ +alter_generic_options: + OPTIONS '(' alter_generic_option_list ')' { $$ = $3; } + ; + +alter_generic_option_list: + alter_generic_option_elem + { + $$ = list_make1($1); + } + | alter_generic_option_list ',' alter_generic_option_elem + { + $$ = lappend($1, $3); + } + ; + +alter_generic_option_elem: + generic_option_elem + { + $$ = $1; + } + | SET generic_option_elem + { + $$ = $2; + $$->defaction = DEFELEM_SET; + } + | ADD_P generic_option_elem + { + $$ = $2; + $$->defaction = DEFELEM_ADD; + } + | DROP generic_option_name + { + $$ = makeDefElemExtended(NULL, $2, NULL, DEFELEM_DROP, @2); + } + ; + +generic_option_elem: + generic_option_name generic_option_arg + { + $$ = makeDefElem($1, $2, @1); + } + ; + +generic_option_name: + ColLabel { $$ = $1; } + ; + +/* We could use def_arg here, but the spec only requires string literals */ +generic_option_arg: + Sconst { $$ = (Node *) makeString($1); } + ; + +/***************************************************************************** + * + * QUERY: + * CREATE SERVER name [TYPE] [VERSION] [OPTIONS] + * + *****************************************************************************/ + +CreateForeignServerStmt: CREATE SERVER name opt_type opt_foreign_server_version + FOREIGN DATA_P WRAPPER name create_generic_options + { + CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt); + + n->servername = $3; + n->servertype = $4; + n->version = $5; + n->fdwname = $9; + n->options = $10; + n->if_not_exists = false; + $$ = (Node *) n; + } + | CREATE SERVER IF_P NOT EXISTS name opt_type opt_foreign_server_version + FOREIGN DATA_P WRAPPER name create_generic_options + { + CreateForeignServerStmt *n = makeNode(CreateForeignServerStmt); + + n->servername = $6; + n->servertype = $7; + n->version = $8; + n->fdwname = $12; + n->options = $13; + n->if_not_exists = true; + $$ = (Node *) n; + } + ; + +opt_type: + TYPE_P Sconst { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + + +foreign_server_version: + VERSION_P Sconst { $$ = $2; } + | VERSION_P NULL_P { $$ = NULL; } + ; + +opt_foreign_server_version: + foreign_server_version { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +/***************************************************************************** + * + * QUERY : + * ALTER SERVER name [VERSION] [OPTIONS] + * + ****************************************************************************/ + +AlterForeignServerStmt: ALTER SERVER name foreign_server_version alter_generic_options + { + AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); + + n->servername = $3; + n->version = $4; + n->options = $5; + n->has_version = true; + $$ = (Node *) n; + } + | ALTER SERVER name foreign_server_version + { + AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); + + n->servername = $3; + n->version = $4; + n->has_version = true; + $$ = (Node *) n; + } + | ALTER SERVER name alter_generic_options + { + AlterForeignServerStmt *n = makeNode(AlterForeignServerStmt); + + n->servername = $3; + n->options = $4; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERY: + * CREATE FOREIGN TABLE relname (...) SERVER name (...) + * + *****************************************************************************/ + +CreateForeignTableStmt: + CREATE FOREIGN TABLE qualified_name + '(' OptTableElementList ')' + OptInherit SERVER name create_generic_options + { + CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + + $4->relpersistence = RELPERSISTENCE_PERMANENT; + n->base.relation = $4; + n->base.tableElts = $6; + n->base.inhRelations = $8; + n->base.ofTypename = NULL; + n->base.constraints = NIL; + n->base.options = NIL; + n->base.oncommit = ONCOMMIT_NOOP; + n->base.tablespacename = NULL; + n->base.if_not_exists = false; + /* FDW-specific data */ + n->servername = $10; + n->options = $11; + $$ = (Node *) n; + } + | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name + '(' OptTableElementList ')' + OptInherit SERVER name create_generic_options + { + CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + + $7->relpersistence = RELPERSISTENCE_PERMANENT; + n->base.relation = $7; + n->base.tableElts = $9; + n->base.inhRelations = $11; + n->base.ofTypename = NULL; + n->base.constraints = NIL; + n->base.options = NIL; + n->base.oncommit = ONCOMMIT_NOOP; + n->base.tablespacename = NULL; + n->base.if_not_exists = true; + /* FDW-specific data */ + n->servername = $13; + n->options = $14; + $$ = (Node *) n; + } + | CREATE FOREIGN TABLE qualified_name + PARTITION OF qualified_name OptTypedTableElementList PartitionBoundSpec + SERVER name create_generic_options + { + CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + + $4->relpersistence = RELPERSISTENCE_PERMANENT; + n->base.relation = $4; + n->base.inhRelations = list_make1($7); + n->base.tableElts = $8; + n->base.partbound = $9; + n->base.ofTypename = NULL; + n->base.constraints = NIL; + n->base.options = NIL; + n->base.oncommit = ONCOMMIT_NOOP; + n->base.tablespacename = NULL; + n->base.if_not_exists = false; + /* FDW-specific data */ + n->servername = $11; + n->options = $12; + $$ = (Node *) n; + } + | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name + PARTITION OF qualified_name OptTypedTableElementList PartitionBoundSpec + SERVER name create_generic_options + { + CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt); + + $7->relpersistence = RELPERSISTENCE_PERMANENT; + n->base.relation = $7; + n->base.inhRelations = list_make1($10); + n->base.tableElts = $11; + n->base.partbound = $12; + n->base.ofTypename = NULL; + n->base.constraints = NIL; + n->base.options = NIL; + n->base.oncommit = ONCOMMIT_NOOP; + n->base.tablespacename = NULL; + n->base.if_not_exists = true; + /* FDW-specific data */ + n->servername = $14; + n->options = $15; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERY: + * IMPORT FOREIGN SCHEMA remote_schema + * [ { LIMIT TO | EXCEPT } ( table_list ) ] + * FROM SERVER server_name INTO local_schema [ OPTIONS (...) ] + * + ****************************************************************************/ + +ImportForeignSchemaStmt: + IMPORT_P FOREIGN SCHEMA name import_qualification + FROM SERVER name INTO name create_generic_options + { + ImportForeignSchemaStmt *n = makeNode(ImportForeignSchemaStmt); + + n->server_name = $8; + n->remote_schema = $4; + n->local_schema = $10; + n->list_type = $5->type; + n->table_list = $5->table_names; + n->options = $11; + $$ = (Node *) n; + } + ; + +import_qualification_type: + LIMIT TO { $$ = FDW_IMPORT_SCHEMA_LIMIT_TO; } + | EXCEPT { $$ = FDW_IMPORT_SCHEMA_EXCEPT; } + ; + +import_qualification: + import_qualification_type '(' relation_expr_list ')' + { + ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + + n->type = $1; + n->table_names = $3; + $$ = n; + } + | /*EMPTY*/ + { + ImportQual *n = (ImportQual *) palloc(sizeof(ImportQual)); + n->type = FDW_IMPORT_SCHEMA_ALL; + n->table_names = NIL; + $$ = n; + } + ; + +/***************************************************************************** + * + * QUERY: + * CREATE USER MAPPING FOR auth_ident SERVER name [OPTIONS] + * + *****************************************************************************/ + +CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options + { + CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); + + n->user = $5; + n->servername = $7; + n->options = $8; + n->if_not_exists = false; + $$ = (Node *) n; + } + | CREATE USER MAPPING IF_P NOT EXISTS FOR auth_ident SERVER name create_generic_options + { + CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt); + + n->user = $8; + n->servername = $10; + n->options = $11; + n->if_not_exists = true; + $$ = (Node *) n; + } + ; + +/* User mapping authorization identifier */ +auth_ident: RoleSpec { $$ = $1; } + | USER { $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); } + ; + +/***************************************************************************** + * + * QUERY : + * DROP USER MAPPING FOR auth_ident SERVER name + * + * XXX you'd think this should have a CASCADE/RESTRICT option, even if it's + * only pro forma; but the SQL standard doesn't show one. + ****************************************************************************/ + +DropUserMappingStmt: DROP USER MAPPING FOR auth_ident SERVER name + { + DropUserMappingStmt *n = makeNode(DropUserMappingStmt); + + n->user = $5; + n->servername = $7; + n->missing_ok = false; + $$ = (Node *) n; + } + | DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name + { + DropUserMappingStmt *n = makeNode(DropUserMappingStmt); + + n->user = $7; + n->servername = $9; + n->missing_ok = true; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERY : + * ALTER USER MAPPING FOR auth_ident SERVER name OPTIONS + * + ****************************************************************************/ + +AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options + { + AlterUserMappingStmt *n = makeNode(AlterUserMappingStmt); + + n->user = $5; + n->servername = $7; + n->options = $8; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERIES: + * CREATE POLICY name ON table + * [AS { PERMISSIVE | RESTRICTIVE } ] + * [FOR { SELECT | INSERT | UPDATE | DELETE } ] + * [TO role, ...] + * [USING (qual)] [WITH CHECK (with check qual)] + * ALTER POLICY name ON table [TO role, ...] + * [USING (qual)] [WITH CHECK (with check qual)] + * + *****************************************************************************/ + +CreatePolicyStmt: + CREATE POLICY name ON qualified_name RowSecurityDefaultPermissive + RowSecurityDefaultForCmd RowSecurityDefaultToRole + RowSecurityOptionalExpr RowSecurityOptionalWithCheck + { + CreatePolicyStmt *n = makeNode(CreatePolicyStmt); + + n->policy_name = $3; + n->table = $5; + n->permissive = $6; + n->cmd_name = $7; + n->roles = $8; + n->qual = $9; + n->with_check = $10; + $$ = (Node *) n; + } + ; + +AlterPolicyStmt: + ALTER POLICY name ON qualified_name RowSecurityOptionalToRole + RowSecurityOptionalExpr RowSecurityOptionalWithCheck + { + AlterPolicyStmt *n = makeNode(AlterPolicyStmt); + + n->policy_name = $3; + n->table = $5; + n->roles = $6; + n->qual = $7; + n->with_check = $8; + $$ = (Node *) n; + } + ; + +RowSecurityOptionalExpr: + USING '(' a_expr ')' { $$ = $3; } + | /* EMPTY */ { $$ = NULL; } + ; + +RowSecurityOptionalWithCheck: + WITH CHECK '(' a_expr ')' { $$ = $4; } + | /* EMPTY */ { $$ = NULL; } + ; + +RowSecurityDefaultToRole: + TO role_list { $$ = $2; } + | /* EMPTY */ { $$ = list_make1(makeRoleSpec(ROLESPEC_PUBLIC, -1)); } + ; + +RowSecurityOptionalToRole: + TO role_list { $$ = $2; } + | /* EMPTY */ { $$ = NULL; } + ; + +RowSecurityDefaultPermissive: + AS IDENT + { + if (strcmp($2, "permissive") == 0) + $$ = true; + else if (strcmp($2, "restrictive") == 0) + $$ = false; + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized row security option \"%s\"", $2), + errhint("Only PERMISSIVE or RESTRICTIVE policies are supported currently."), + parser_errposition(@2))); + + } + | /* EMPTY */ { $$ = true; } + ; + +RowSecurityDefaultForCmd: + FOR row_security_cmd { $$ = $2; } + | /* EMPTY */ { $$ = "all"; } + ; + +row_security_cmd: + ALL { $$ = "all"; } + | SELECT { $$ = "select"; } + | INSERT { $$ = "insert"; } + | UPDATE { $$ = "update"; } + | DELETE_P { $$ = "delete"; } + ; + +/***************************************************************************** + * + * QUERY: + * CREATE ACCESS METHOD name 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 = $6; + $$ = (Node *) n; + } + ; + +am_type: + INDEX { $$ = AMTYPE_INDEX; } + | TABLE { $$ = AMTYPE_TABLE; } + ; + +/***************************************************************************** + * + * QUERIES : + * CREATE TRIGGER ... + * + *****************************************************************************/ + +CreateTrigStmt: + CREATE opt_or_replace TRIGGER name TriggerActionTime TriggerEvents ON + qualified_name TriggerReferencing TriggerForSpec TriggerWhen + EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' + { + CreateTrigStmt *n = makeNode(CreateTrigStmt); + + n->replace = $2; + n->isconstraint = false; + n->trigname = $4; + n->relation = $8; + n->funcname = $14; + n->args = $16; + n->row = $10; + n->timing = $5; + n->events = intVal(linitial($6)); + n->columns = (List *) lsecond($6); + n->whenClause = $11; + n->transitionRels = $9; + n->deferrable = false; + n->initdeferred = false; + n->constrrel = NULL; + $$ = (Node *) n; + } + | CREATE opt_or_replace CONSTRAINT TRIGGER name AFTER TriggerEvents ON + qualified_name OptConstrFromTable ConstraintAttributeSpec + FOR EACH ROW TriggerWhen + EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' + { + CreateTrigStmt *n = makeNode(CreateTrigStmt); + + n->replace = $2; + if (n->replace) /* not supported, see CreateTrigger */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE OR REPLACE CONSTRAINT TRIGGER is not supported"), + parser_errposition(@1))); + n->isconstraint = true; + n->trigname = $5; + n->relation = $9; + n->funcname = $18; + n->args = $20; + n->row = true; + n->timing = TRIGGER_TYPE_AFTER; + n->events = intVal(linitial($7)); + n->columns = (List *) lsecond($7); + n->whenClause = $15; + n->transitionRels = NIL; + processCASbits($11, @11, "TRIGGER", + &n->deferrable, &n->initdeferred, NULL, + NULL, NULL, yyscanner); + n->constrrel = $10; + $$ = (Node *) n; + } + ; + +TriggerActionTime: + BEFORE { $$ = TRIGGER_TYPE_BEFORE; } + | AFTER { $$ = TRIGGER_TYPE_AFTER; } + | INSTEAD OF { $$ = TRIGGER_TYPE_INSTEAD; } + ; + +TriggerEvents: + TriggerOneEvent + { $$ = $1; } + | TriggerEvents OR TriggerOneEvent + { + int events1 = intVal(linitial($1)); + int events2 = intVal(linitial($3)); + List *columns1 = (List *) lsecond($1); + List *columns2 = (List *) lsecond($3); + + if (events1 & events2) + parser_yyerror("duplicate trigger events specified"); + /* + * concat'ing the columns lists loses information about + * which columns went with which event, but so long as + * only UPDATE carries columns and we disallow multiple + * UPDATE items, it doesn't matter. Command execution + * should just ignore the columns for non-UPDATE events. + */ + $$ = list_make2(makeInteger(events1 | events2), + list_concat(columns1, columns2)); + } + ; + +TriggerOneEvent: + INSERT + { $$ = list_make2(makeInteger(TRIGGER_TYPE_INSERT), NIL); } + | DELETE_P + { $$ = list_make2(makeInteger(TRIGGER_TYPE_DELETE), NIL); } + | UPDATE + { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), NIL); } + | UPDATE OF columnList + { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), $3); } + | TRUNCATE + { $$ = list_make2(makeInteger(TRIGGER_TYPE_TRUNCATE), NIL); } + ; + +TriggerReferencing: + REFERENCING TriggerTransitions { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +TriggerTransitions: + TriggerTransition { $$ = list_make1($1); } + | TriggerTransitions TriggerTransition { $$ = lappend($1, $2); } + ; + +TriggerTransition: + TransitionOldOrNew TransitionRowOrTable opt_as TransitionRelName + { + TriggerTransition *n = makeNode(TriggerTransition); + + n->name = $4; + n->isNew = $1; + n->isTable = $2; + $$ = (Node *) n; + } + ; + +TransitionOldOrNew: + NEW { $$ = true; } + | OLD { $$ = false; } + ; + +TransitionRowOrTable: + TABLE { $$ = true; } + /* + * According to the standard, lack of a keyword here implies ROW. + * Support for that would require prohibiting ROW entirely here, + * reserving the keyword ROW, and/or requiring AS (instead of + * allowing it to be optional, as the standard specifies) as the + * next token. Requiring ROW seems cleanest and easiest to + * explain. + */ + | ROW { $$ = false; } + ; + +TransitionRelName: + ColId { $$ = $1; } + ; + +TriggerForSpec: + FOR TriggerForOptEach TriggerForType + { + $$ = $3; + } + | /* EMPTY */ + { + /* + * If ROW/STATEMENT not specified, default to + * STATEMENT, per SQL + */ + $$ = false; + } + ; + +TriggerForOptEach: + EACH + | /*EMPTY*/ + ; + +TriggerForType: + ROW { $$ = true; } + | STATEMENT { $$ = false; } + ; + +TriggerWhen: + WHEN '(' a_expr ')' { $$ = $3; } + | /*EMPTY*/ { $$ = NULL; } + ; + +FUNCTION_or_PROCEDURE: + FUNCTION + | PROCEDURE + ; + +TriggerFuncArgs: + TriggerFuncArg { $$ = list_make1($1); } + | TriggerFuncArgs ',' TriggerFuncArg { $$ = lappend($1, $3); } + | /*EMPTY*/ { $$ = NIL; } + ; + +TriggerFuncArg: + Iconst + { + $$ = (Node *) makeString(psprintf("%d", $1)); + } + | FCONST { $$ = (Node *) makeString($1); } + | Sconst { $$ = (Node *) makeString($1); } + | ColLabel { $$ = (Node *) makeString($1); } + ; + +OptConstrFromTable: + FROM qualified_name { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +ConstraintAttributeSpec: + /*EMPTY*/ + { $$ = 0; } + | ConstraintAttributeSpec ConstraintAttributeElem + { + /* + * We must complain about conflicting options. + * We could, but choose not to, complain about redundant + * options (ie, where $2's bit is already set in $1). + */ + int newspec = $1 | $2; + + /* special message for this case */ + if ((newspec & (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) == (CAS_NOT_DEFERRABLE | CAS_INITIALLY_DEFERRED)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"), + parser_errposition(@2))); + /* generic message for other conflicts */ + if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) || + (newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED) || + (newspec & (CAS_NOT_ENFORCED | CAS_ENFORCED)) == (CAS_NOT_ENFORCED | CAS_ENFORCED)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting constraint properties"), + parser_errposition(@2))); + $$ = newspec; + } + ; + +ConstraintAttributeElem: + NOT DEFERRABLE { $$ = CAS_NOT_DEFERRABLE; } + | DEFERRABLE { $$ = CAS_DEFERRABLE; } + | INITIALLY IMMEDIATE { $$ = CAS_INITIALLY_IMMEDIATE; } + | INITIALLY DEFERRED { $$ = CAS_INITIALLY_DEFERRED; } + | NOT VALID { $$ = CAS_NOT_VALID; } + | NO INHERIT { $$ = CAS_NO_INHERIT; } + | NOT ENFORCED { $$ = CAS_NOT_ENFORCED; } + | ENFORCED { $$ = CAS_ENFORCED; } + ; + + +/***************************************************************************** + * + * QUERIES : + * CREATE EVENT TRIGGER ... + * ALTER EVENT TRIGGER ... + * + *****************************************************************************/ + +CreateEventTrigStmt: + CREATE EVENT TRIGGER name ON ColLabel + EXECUTE FUNCTION_or_PROCEDURE func_name '(' ')' + { + CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt); + + n->trigname = $4; + n->eventname = $6; + n->whenclause = NULL; + n->funcname = $9; + $$ = (Node *) n; + } + | CREATE EVENT TRIGGER name ON ColLabel + WHEN event_trigger_when_list + EXECUTE FUNCTION_or_PROCEDURE func_name '(' ')' + { + CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt); + + n->trigname = $4; + n->eventname = $6; + n->whenclause = $8; + n->funcname = $11; + $$ = (Node *) n; + } + ; + +event_trigger_when_list: + event_trigger_when_item + { $$ = list_make1($1); } + | event_trigger_when_list AND event_trigger_when_item + { $$ = lappend($1, $3); } + ; + +event_trigger_when_item: + ColId IN_P '(' event_trigger_value_list ')' + { $$ = makeDefElem($1, (Node *) $4, @1); } + ; + +event_trigger_value_list: + SCONST + { $$ = list_make1(makeString($1)); } + | event_trigger_value_list ',' SCONST + { $$ = lappend($1, makeString($3)); } + ; + +AlterEventTrigStmt: + ALTER EVENT TRIGGER name enable_trigger + { + AlterEventTrigStmt *n = makeNode(AlterEventTrigStmt); + + n->trigname = $4; + n->tgenabled = $5; + $$ = (Node *) n; + } + ; + +enable_trigger: + ENABLE_P { $$ = TRIGGER_FIRES_ON_ORIGIN; } + | ENABLE_P REPLICA { $$ = TRIGGER_FIRES_ON_REPLICA; } + | ENABLE_P ALWAYS { $$ = TRIGGER_FIRES_ALWAYS; } + | DISABLE_P { $$ = TRIGGER_DISABLED; } + ; + +/***************************************************************************** + * + * QUERY : + * CREATE ASSERTION ... + * + *****************************************************************************/ + +CreateAssertionStmt: + CREATE ASSERTION any_name CHECK '(' a_expr ')' ConstraintAttributeSpec + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE ASSERTION is not yet implemented"), + parser_errposition(@1))); + + $$ = NULL; + } + ; + + +/***************************************************************************** + * + * QUERY : + * define (aggregate,operator,type) + * + *****************************************************************************/ + +DefineStmt: + CREATE opt_or_replace AGGREGATE func_name aggr_args definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_AGGREGATE; + n->oldstyle = false; + n->replace = $2; + n->defnames = $4; + n->args = $5; + n->definition = $6; + $$ = (Node *) n; + } + | 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->replace = $2; + n->defnames = $4; + n->args = NIL; + n->definition = $5; + $$ = (Node *) n; + } + | CREATE OPERATOR any_operator definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_OPERATOR; + n->oldstyle = false; + n->defnames = $3; + n->args = NIL; + n->definition = $4; + $$ = (Node *) n; + } + | CREATE TYPE_P any_name definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_TYPE; + n->oldstyle = false; + n->defnames = $3; + n->args = NIL; + n->definition = $4; + $$ = (Node *) n; + } + | CREATE TYPE_P any_name + { + /* Shell type (identified by lack of definition) */ + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_TYPE; + n->oldstyle = false; + n->defnames = $3; + n->args = NIL; + n->definition = NIL; + $$ = (Node *) n; + } + | CREATE TYPE_P any_name AS '(' OptTableFuncElementList ')' + { + CompositeTypeStmt *n = makeNode(CompositeTypeStmt); + + /* can't use qualified_name, sigh */ + n->typevar = makeRangeVarFromAnyName($3, @3, yyscanner); + n->coldeflist = $6; + $$ = (Node *) n; + } + | CREATE TYPE_P any_name AS ENUM_P '(' opt_enum_val_list ')' + { + CreateEnumStmt *n = makeNode(CreateEnumStmt); + + n->typeName = $3; + n->vals = $7; + $$ = (Node *) n; + } + | CREATE TYPE_P any_name AS RANGE definition + { + CreateRangeStmt *n = makeNode(CreateRangeStmt); + + n->typeName = $3; + n->params = $6; + $$ = (Node *) n; + } + | CREATE TEXT_P SEARCH PARSER any_name definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_TSPARSER; + n->args = NIL; + n->defnames = $5; + n->definition = $6; + $$ = (Node *) n; + } + | CREATE TEXT_P SEARCH DICTIONARY any_name definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_TSDICTIONARY; + n->args = NIL; + n->defnames = $5; + n->definition = $6; + $$ = (Node *) n; + } + | CREATE TEXT_P SEARCH TEMPLATE any_name definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_TSTEMPLATE; + n->args = NIL; + n->defnames = $5; + n->definition = $6; + $$ = (Node *) n; + } + | CREATE TEXT_P SEARCH CONFIGURATION any_name definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_TSCONFIGURATION; + n->args = NIL; + n->defnames = $5; + n->definition = $6; + $$ = (Node *) n; + } + | CREATE COLLATION any_name definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_COLLATION; + n->args = NIL; + n->defnames = $3; + n->definition = $4; + $$ = (Node *) n; + } + | CREATE COLLATION IF_P NOT EXISTS any_name definition + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_COLLATION; + n->args = NIL; + n->defnames = $6; + n->definition = $7; + n->if_not_exists = true; + $$ = (Node *) n; + } + | CREATE COLLATION any_name FROM any_name + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_COLLATION; + n->args = NIL; + n->defnames = $3; + n->definition = list_make1(makeDefElem("from", (Node *) $5, @5)); + $$ = (Node *) n; + } + | CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name + { + DefineStmt *n = makeNode(DefineStmt); + + n->kind = OBJECT_COLLATION; + n->args = NIL; + n->defnames = $6; + n->definition = list_make1(makeDefElem("from", (Node *) $8, @8)); + n->if_not_exists = true; + $$ = (Node *) n; + } + ; + +definition: '(' def_list ')' { $$ = $2; } + ; + +def_list: def_elem { $$ = list_make1($1); } + | def_list ',' def_elem { $$ = lappend($1, $3); } + ; + +def_elem: ColLabel '=' def_arg + { + $$ = makeDefElem($1, (Node *) $3, @1); + } + | ColLabel + { + $$ = makeDefElem($1, NULL, @1); + } + ; + +/* Note: any simple identifier will be returned as a type name! */ +def_arg: func_type { $$ = (Node *) $1; } + | reserved_keyword { $$ = (Node *) makeString(pstrdup($1)); } + | qual_all_Op { $$ = (Node *) $1; } + | NumericOnly { $$ = (Node *) $1; } + | Sconst { $$ = (Node *) makeString($1); } + | NONE { $$ = (Node *) makeString(pstrdup($1)); } + ; + +old_aggr_definition: '(' old_aggr_list ')' { $$ = $2; } + ; + +old_aggr_list: old_aggr_elem { $$ = list_make1($1); } + | old_aggr_list ',' old_aggr_elem { $$ = lappend($1, $3); } + ; + +/* + * Must use IDENT here to avoid reduce/reduce conflicts; fortunately none of + * the item names needed in old aggregate definitions are likely to become + * SQL keywords. + */ +old_aggr_elem: IDENT '=' def_arg + { + $$ = makeDefElem($1, (Node *) $3, @1); + } + ; + +opt_enum_val_list: + enum_val_list { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + +enum_val_list: Sconst + { $$ = list_make1(makeString($1)); } + | enum_val_list ',' Sconst + { $$ = lappend($1, makeString($3)); } + ; + +/***************************************************************************** + * + * ALTER TYPE enumtype ADD ... + * + *****************************************************************************/ + +AlterEnumStmt: + ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst + { + AlterEnumStmt *n = makeNode(AlterEnumStmt); + + n->typeName = $3; + n->oldVal = NULL; + n->newVal = $7; + n->newValNeighbor = NULL; + n->newValIsAfter = true; + n->skipIfNewValExists = $6; + $$ = (Node *) n; + } + | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst BEFORE Sconst + { + AlterEnumStmt *n = makeNode(AlterEnumStmt); + + n->typeName = $3; + n->oldVal = NULL; + n->newVal = $7; + n->newValNeighbor = $9; + n->newValIsAfter = false; + n->skipIfNewValExists = $6; + $$ = (Node *) n; + } + | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists Sconst AFTER Sconst + { + AlterEnumStmt *n = makeNode(AlterEnumStmt); + + n->typeName = $3; + n->oldVal = NULL; + n->newVal = $7; + n->newValNeighbor = $9; + n->newValIsAfter = true; + n->skipIfNewValExists = $6; + $$ = (Node *) n; + } + | ALTER TYPE_P any_name RENAME VALUE_P Sconst TO Sconst + { + AlterEnumStmt *n = makeNode(AlterEnumStmt); + + n->typeName = $3; + n->oldVal = $6; + n->newVal = $8; + n->newValNeighbor = NULL; + n->newValIsAfter = false; + n->skipIfNewValExists = false; + $$ = (Node *) n; + } + | ALTER TYPE_P any_name DROP VALUE_P Sconst + { + /* + * The following problems must be solved before this can be + * implemented: + * + * - There must be no instance of the target value in + * any table. + * + * - The value must not appear in any catalog metadata, + * such as stored view expressions or column defaults. + * + * - The value must not appear in any non-leaf page of a + * btree (and similar issues with other index types). + * This is problematic because a value could persist + * there long after it's gone from user-visible data. + * + * - Concurrent sessions must not be able to insert the + * value while the preceding conditions are being checked. + * + * - Possibly more... + */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("dropping an enum value is not implemented"), + parser_errposition(@4))); + } + ; + +opt_if_not_exists: IF_P NOT EXISTS { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + + +/***************************************************************************** + * + * QUERIES : + * CREATE OPERATOR CLASS ... + * CREATE OPERATOR FAMILY ... + * ALTER OPERATOR FAMILY ... + * DROP OPERATOR CLASS ... + * DROP OPERATOR FAMILY ... + * + *****************************************************************************/ + +CreateOpClassStmt: + CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename + USING name opt_opfamily AS opclass_item_list + { + CreateOpClassStmt *n = makeNode(CreateOpClassStmt); + + n->opclassname = $4; + n->isDefault = $5; + n->datatype = $8; + n->amname = $10; + n->opfamilyname = $11; + n->items = $13; + $$ = (Node *) n; + } + ; + +opclass_item_list: + opclass_item { $$ = list_make1($1); } + | opclass_item_list ',' opclass_item { $$ = lappend($1, $3); } + ; + +opclass_item: + OPERATOR Iconst any_operator opclass_purpose + { + CreateOpClassItem *n = makeNode(CreateOpClassItem); + ObjectWithArgs *owa = makeNode(ObjectWithArgs); + + owa->objname = $3; + owa->objargs = NIL; + n->itemtype = OPCLASS_ITEM_OPERATOR; + n->name = owa; + n->number = $2; + n->order_family = $4; + $$ = (Node *) n; + } + | OPERATOR Iconst operator_with_argtypes opclass_purpose + { + CreateOpClassItem *n = makeNode(CreateOpClassItem); + + n->itemtype = OPCLASS_ITEM_OPERATOR; + n->name = $3; + n->number = $2; + n->order_family = $4; + $$ = (Node *) n; + } + | FUNCTION Iconst function_with_argtypes + { + CreateOpClassItem *n = makeNode(CreateOpClassItem); + + n->itemtype = OPCLASS_ITEM_FUNCTION; + n->name = $3; + n->number = $2; + $$ = (Node *) n; + } + | FUNCTION Iconst '(' type_list ')' function_with_argtypes + { + CreateOpClassItem *n = makeNode(CreateOpClassItem); + + n->itemtype = OPCLASS_ITEM_FUNCTION; + n->name = $6; + n->number = $2; + n->class_args = $4; + $$ = (Node *) n; + } + | STORAGE Typename + { + CreateOpClassItem *n = makeNode(CreateOpClassItem); + + n->itemtype = OPCLASS_ITEM_STORAGETYPE; + n->storedtype = $2; + $$ = (Node *) n; + } + ; + +opt_default: DEFAULT { $$ = true; } + | /*EMPTY*/ { $$ = false; } + ; + +opt_opfamily: FAMILY any_name { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +opclass_purpose: FOR SEARCH { $$ = NIL; } + | FOR ORDER BY any_name { $$ = $4; } + | /*EMPTY*/ { $$ = NIL; } + ; + + +CreateOpFamilyStmt: + CREATE OPERATOR FAMILY any_name USING name + { + CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt); + + n->opfamilyname = $4; + n->amname = $6; + $$ = (Node *) n; + } + ; + +AlterOpFamilyStmt: + ALTER OPERATOR FAMILY any_name USING name ADD_P opclass_item_list + { + AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); + + n->opfamilyname = $4; + n->amname = $6; + n->isDrop = false; + n->items = $8; + $$ = (Node *) n; + } + | ALTER OPERATOR FAMILY any_name USING name DROP opclass_drop_list + { + AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt); + + n->opfamilyname = $4; + n->amname = $6; + n->isDrop = true; + n->items = $8; + $$ = (Node *) n; + } + ; + +opclass_drop_list: + opclass_drop { $$ = list_make1($1); } + | opclass_drop_list ',' opclass_drop { $$ = lappend($1, $3); } + ; + +opclass_drop: + OPERATOR Iconst '(' type_list ')' + { + CreateOpClassItem *n = makeNode(CreateOpClassItem); + + n->itemtype = OPCLASS_ITEM_OPERATOR; + n->number = $2; + n->class_args = $4; + $$ = (Node *) n; + } + | FUNCTION Iconst '(' type_list ')' + { + CreateOpClassItem *n = makeNode(CreateOpClassItem); + + n->itemtype = OPCLASS_ITEM_FUNCTION; + n->number = $2; + n->class_args = $4; + $$ = (Node *) n; + } + ; + + +DropOpClassStmt: + DROP OPERATOR CLASS any_name USING name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->objects = list_make1(lcons(makeString($6), $4)); + n->removeType = OBJECT_OPCLASS; + n->behavior = $7; + n->missing_ok = false; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP OPERATOR CLASS IF_P EXISTS any_name USING name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->objects = list_make1(lcons(makeString($8), $6)); + n->removeType = OBJECT_OPCLASS; + n->behavior = $9; + n->missing_ok = true; + n->concurrent = false; + $$ = (Node *) n; + } + ; + +DropOpFamilyStmt: + DROP OPERATOR FAMILY any_name USING name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->objects = list_make1(lcons(makeString($6), $4)); + n->removeType = OBJECT_OPFAMILY; + n->behavior = $7; + n->missing_ok = false; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP OPERATOR FAMILY IF_P EXISTS any_name USING name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->objects = list_make1(lcons(makeString($8), $6)); + n->removeType = OBJECT_OPFAMILY; + n->behavior = $9; + n->missing_ok = true; + n->concurrent = false; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * + * QUERY: + * + * DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ] + * REASSIGN OWNED BY username [, username ...] TO username + * + *****************************************************************************/ +DropOwnedStmt: + DROP OWNED BY role_list opt_drop_behavior + { + DropOwnedStmt *n = makeNode(DropOwnedStmt); + + n->roles = $4; + n->behavior = $5; + $$ = (Node *) n; + } + ; + +ReassignOwnedStmt: + REASSIGN OWNED BY role_list TO RoleSpec + { + ReassignOwnedStmt *n = makeNode(ReassignOwnedStmt); + + n->roles = $4; + n->newrole = $6; + $$ = (Node *) n; + } + ; + +/***************************************************************************** + * + * QUERY: + * + * DROP itemtype [ IF EXISTS ] itemname [, itemname ...] + * [ RESTRICT | CASCADE ] + * + *****************************************************************************/ + +DropStmt: DROP object_type_any_name IF_P EXISTS any_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = $2; + n->missing_ok = true; + n->objects = $5; + n->behavior = $6; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP object_type_any_name any_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = $2; + n->missing_ok = false; + n->objects = $3; + n->behavior = $4; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP drop_type_name IF_P EXISTS name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = $2; + n->missing_ok = true; + n->objects = $5; + n->behavior = $6; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP drop_type_name name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = $2; + n->missing_ok = false; + n->objects = $3; + n->behavior = $4; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP object_type_name_on_any_name name ON any_name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = $2; + n->objects = list_make1(lappend($5, makeString($3))); + n->behavior = $6; + n->missing_ok = false; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP object_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = $2; + n->objects = list_make1(lappend($7, makeString($5))); + n->behavior = $8; + n->missing_ok = true; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP TYPE_P type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = OBJECT_TYPE; + n->missing_ok = false; + n->objects = $3; + n->behavior = $4; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP TYPE_P IF_P EXISTS type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = OBJECT_TYPE; + n->missing_ok = true; + n->objects = $5; + n->behavior = $6; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP DOMAIN_P type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = OBJECT_DOMAIN; + n->missing_ok = false; + n->objects = $3; + n->behavior = $4; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP DOMAIN_P IF_P EXISTS type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = OBJECT_DOMAIN; + n->missing_ok = true; + n->objects = $5; + n->behavior = $6; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = OBJECT_INDEX; + n->missing_ok = false; + n->objects = $4; + n->behavior = $5; + n->concurrent = true; + $$ = (Node *) n; + } + | DROP INDEX CONCURRENTLY IF_P EXISTS any_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + + n->removeType = OBJECT_INDEX; + n->missing_ok = true; + n->objects = $6; + n->behavior = $7; + n->concurrent = true; + $$ = (Node *) n; + } + ; + +/* object types taking any_name/any_name_list */ +object_type_any_name: + TABLE { $$ = OBJECT_TABLE; } + | SEQUENCE { $$ = OBJECT_SEQUENCE; } + | VIEW { $$ = OBJECT_VIEW; } + | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } + | INDEX { $$ = OBJECT_INDEX; } + | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } + | COLLATION { $$ = OBJECT_COLLATION; } + | CONVERSION_P { $$ = OBJECT_CONVERSION; } + | STATISTICS { $$ = OBJECT_STATISTIC_EXT; } + | TEXT_P SEARCH PARSER { $$ = OBJECT_TSPARSER; } + | TEXT_P SEARCH DICTIONARY { $$ = OBJECT_TSDICTIONARY; } + | TEXT_P SEARCH TEMPLATE { $$ = OBJECT_TSTEMPLATE; } + | TEXT_P SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; } + ; + +/* + * object types taking name/name_list + * + * DROP handles some of them separately + */ + +object_type_name: + drop_type_name { $$ = $1; } + | DATABASE { $$ = OBJECT_DATABASE; } + | ROLE { $$ = OBJECT_ROLE; } + | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; } + | TABLESPACE { $$ = OBJECT_TABLESPACE; } + ; + +drop_type_name: + ACCESS METHOD { $$ = OBJECT_ACCESS_METHOD; } + | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } + | EXTENSION { $$ = OBJECT_EXTENSION; } + | FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; } + | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; } + | PUBLICATION { $$ = OBJECT_PUBLICATION; } + | SCHEMA { $$ = OBJECT_SCHEMA; } + | SERVER { $$ = OBJECT_FOREIGN_SERVER; } + ; + +/* object types attached to a table */ +object_type_name_on_any_name: + POLICY { $$ = OBJECT_POLICY; } + | RULE { $$ = OBJECT_RULE; } + | TRIGGER { $$ = OBJECT_TRIGGER; } + ; + +any_name_list: + any_name { $$ = list_make1($1); } + | any_name_list ',' any_name { $$ = lappend($1, $3); } + ; + +any_name: ColId { $$ = list_make1(makeString($1)); } + | ColId attrs { $$ = lcons(makeString($1), $2); } + ; + +attrs: '.' attr_name + { $$ = list_make1(makeString($2)); } + | attrs '.' attr_name + { $$ = lappend($1, makeString($3)); } + ; + +type_name_list: + Typename { $$ = list_make1($1); } + | type_name_list ',' Typename { $$ = lappend($1, $3); } + ; + +/***************************************************************************** + * + * QUERY: + * truncate table relname1, relname2, ... + * + *****************************************************************************/ + +TruncateStmt: + TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior + { + TruncateStmt *n = makeNode(TruncateStmt); + + n->relations = $3; + n->restart_seqs = $4; + n->behavior = $5; + $$ = (Node *) n; + } + ; + +opt_restart_seqs: + CONTINUE_P IDENTITY_P { $$ = false; } + | RESTART IDENTITY_P { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + +/***************************************************************************** + * + * COMMENT ON IS + * + *****************************************************************************/ + +CommentStmt: + COMMENT ON object_type_any_name any_name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = $3; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON COLUMN any_name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_COLUMN; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON object_type_name name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = $3; + n->object = (Node *) makeString($4); + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON TYPE_P Typename IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_TYPE; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON DOMAIN_P Typename IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_DOMAIN; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON AGGREGATE aggregate_with_argtypes IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_AGGREGATE; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON FUNCTION function_with_argtypes IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_FUNCTION; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON OPERATOR operator_with_argtypes IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_OPERATOR; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON CONSTRAINT name ON any_name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_TABCONSTRAINT; + n->object = (Node *) lappend($6, makeString($4)); + n->comment = $8; + $$ = (Node *) n; + } + | COMMENT ON CONSTRAINT name ON DOMAIN_P any_name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_DOMCONSTRAINT; + /* + * should use Typename not any_name in the production, but + * there's a shift/reduce conflict if we do that, so fix it + * up here. + */ + n->object = (Node *) list_make2(makeTypeNameFromNameList($7), makeString($4)); + n->comment = $9; + $$ = (Node *) n; + } + | COMMENT ON object_type_name_on_any_name name ON any_name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = $3; + n->object = (Node *) lappend($6, makeString($4)); + n->comment = $8; + $$ = (Node *) n; + } + | COMMENT ON PROCEDURE function_with_argtypes IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_PROCEDURE; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON ROUTINE function_with_argtypes IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_ROUTINE; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON TRANSFORM FOR Typename LANGUAGE name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_TRANSFORM; + n->object = (Node *) list_make2($5, makeString($7)); + n->comment = $9; + $$ = (Node *) n; + } + | COMMENT ON OPERATOR CLASS any_name USING name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_OPCLASS; + n->object = (Node *) lcons(makeString($7), $5); + n->comment = $9; + $$ = (Node *) n; + } + | COMMENT ON OPERATOR FAMILY any_name USING name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_OPFAMILY; + n->object = (Node *) lcons(makeString($7), $5); + n->comment = $9; + $$ = (Node *) n; + } + | COMMENT ON LARGE_P OBJECT_P NumericOnly IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_LARGEOBJECT; + n->object = (Node *) $5; + n->comment = $7; + $$ = (Node *) n; + } + | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + + n->objtype = OBJECT_CAST; + n->object = (Node *) list_make2($5, $7); + n->comment = $10; + $$ = (Node *) n; + } + ; + +comment_text: + Sconst { $$ = $1; } + | NULL_P { $$ = NULL; } + ; + + +/***************************************************************************** + * + * SECURITY LABEL [FOR ] ON IS