agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH 5/8] bloom fixes and tweaks 3+ messages / 3 participants [nested] [flat]
* [PATCH 5/8] bloom fixes and tweaks @ 2021-01-12 23:59 Tomas Vondra <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Tomas Vondra @ 2021-01-12 23:59 UTC (permalink / raw) --- doc/src/sgml/ref/create_index.sgml | 2 +- src/backend/access/brin/brin_bloom.c | 84 ++++++++++++++---------- src/test/regress/expected/brin_bloom.out | 14 ++-- src/test/regress/sql/brin_bloom.sql | 6 +- 4 files changed, 60 insertions(+), 46 deletions(-) diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index 8db10b7b1e..244e5834d8 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -573,7 +573,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class= equal to -1, the number of distinct non-null is assumed linear with the maximum possible number of tuples in the block range (about 290 rows per block). The default values is <literal>-0.1</literal>, and - the minimum number of distinct non-null values is <literal>128</literal>. + the minimum number of distinct non-null values is <literal>16</literal>. </para> </listitem> </varlistentry> diff --git a/src/backend/access/brin/brin_bloom.c b/src/backend/access/brin/brin_bloom.c index b7aa6d9f11..ffeb459d3e 100644 --- a/src/backend/access/brin/brin_bloom.c +++ b/src/backend/access/brin/brin_bloom.c @@ -8,12 +8,12 @@ * * A BRIN opclass summarizing page range into a bloom filter. * - * Bloom filters allow efficient test whether a given page range contains + * Bloom filters allow efficient testing whether a given page range contains * a particular value. Therefore, if we summarize each page range into a - * bloom filter, we can easily and cheaply test wheter it containst values + * bloom filter, we can easily and cheaply test wheter it contains values * we get later. * - * The index only supports equality operator, similarly to hash indexes. + * The index only supports equality operators, similarly to hash indexes. * BRIN bloom indexes are however much smaller, and support only bitmap * scans. * @@ -51,9 +51,9 @@ * the bloom filter. On the other hand, we want to keep the index as small * as possible - that's one of the basic advantages of BRIN indexes. * - * The number of distinct elements (in a page range) depends on the data, - * we can consider it fixed. This simplifies the trade-off to just false - * positive rate vs. size. + * Although the number of distinct elements (in a page range) depends on + * the data, we can consider it fixed. This simplifies the trade-off to + * just false positive rate vs. size. * * At the page range level, false positive rate is a probability the bloom * filter matches a random value. For the whole index (with sufficiently @@ -65,7 +65,7 @@ * the bitmap is inherently random, compression can't reliably help here. * To reduce the size of a filter (to fit to a page), we have to either * accept higher false positive rate (undesirable), or reduce the number - * of distinct items to be stored in the filter. We can't quite the input + * of distinct items to be stored in the filter. We can't alter the input * data, of course, but we may make the BRIN page ranges smaller - instead * of the default 128 pages (1MB) we may build index with 16-page ranges, * or something like that. This does help even for random data sets, as @@ -87,7 +87,8 @@ * not entirely clear how to distrubute the space between those columns. * * The current logic, implemented in brin_bloom_get_ndistinct, attempts to - * make some basic sizing decisions, based on the table ndistinct estimate. + * make some basic sizing decisions, based on the size of BRIN ranges, and + * the maximum number of rows per range. * * * sort vs. hash @@ -200,10 +201,20 @@ typedef struct BloomOptions /* * Allowed range and default value for the false positive range. The exact - * values are somewhat arbitrary. + * values are somewhat arbitrary, but were chosen considering the various + * parameters (size of filter vs. page size, etc.). + * + * The lower the false-positive rate, the more accurate the filter is, but + * it also gets larger - at some point this eliminates the main advantage + * of BRIN indexes, which is the tiny size. At 0.01% the index is about + * 10% of the table (assuming 290 distinct values per 8kB page). + * + * On the other hand, as the false-positive rate increases, larger part of + * the table has to be scanned due to mismatches - at 25% we're probably + * close to sequential scan being cheaper. */ -#define BLOOM_MIN_FALSE_POSITIVE_RATE 0.001 /* 0.1% fp rate */ -#define BLOOM_MAX_FALSE_POSITIVE_RATE 0.1 /* 10% fp rate */ +#define BLOOM_MIN_FALSE_POSITIVE_RATE 0.0001 /* 0.01% fp rate */ +#define BLOOM_MAX_FALSE_POSITIVE_RATE 0.25 /* 25% fp rate */ #define BLOOM_DEFAULT_FALSE_POSITIVE_RATE 0.01 /* 1% fp rate */ #define BloomGetNDistinctPerRange(opts) \ @@ -302,11 +313,21 @@ bloom_init(int ndistinct, double false_positive_rate) Assert(ndistinct > 0); Assert((false_positive_rate > 0) && (false_positive_rate < 1.0)); - m = ceil((ndistinct * log(false_positive_rate)) / log(1.0 / (pow(2.0, log(2.0))))); + /* sizing bloom filter: -(n * ln(p)) / (ln(2))^2 */ + m = ceil(- (ndistinct * log(false_positive_rate)) / pow(log(2.0), 2)); /* round m to whole bytes */ m = ((m + 7) / 8) * 8; + /* + * Reject filters that are obviously too large to store on a page. + * + * We do expect the bloom filter to eventually switch to hashing mode, + * and it's bound to be almost perfectly random, so not compressible. + */ + if ((m/8) > BLCKSZ) + elog(ERROR, "the bloom filter is too large (%d > %d)", (m/8), BLCKSZ); + /* * round(log(2.0) * m / ndistinct), but assume round() may not be * available on Windows @@ -315,16 +336,10 @@ bloom_init(int ndistinct, double false_positive_rate) k = (k - floor(k) >= 0.5) ? ceil(k) : floor(k); /* - * Allocate the bloom filter with a minimum size 64B (about 40B in the - * bitmap part). We require space at least for the header. - * - * XXX Maybe the 64B min size is not really needed? + * Allocate the bloom filter (initially it's just a header, we'll make + * it larger as needed). */ - len = Max(offsetof(BloomFilter, data), 64); - - /* Reject filters that are obviously too large to store on a page. */ - if (len > BLCKSZ) - elog(ERROR, "the bloom filter is too large (%zu > %d)", len, BLCKSZ); + len = offsetof(BloomFilter, data); filter = (BloomFilter *) palloc0(len); @@ -686,7 +701,7 @@ brin_bloom_opcinfo(PG_FUNCTION_ARGS) * brin_bloom_get_ndistinct * Determine the ndistinct value used to size bloom filter. * - * Tweak the ndistinct value based on the pagesPerRange value. First, + * Adjust the ndistinct value based on the pagesPerRange value. First, * if it's negative, it's assumed to be relative to maximum number of * tuples in the range (assuming each page gets MaxHeapTuplesPerPage * tuples, which is likely a significant over-estimate). We also clamp @@ -701,6 +716,10 @@ brin_bloom_opcinfo(PG_FUNCTION_ARGS) * and compute the expected number of distinct values in a range. But * that may be tricky due to data being sorted in various ways, so it * seems better to rely on the upper estimate. + * + * XXX We might also calculate a better estimate of rows per BRIN range, + * instead of using MaxHeapTuplesPerPage (which probably produces values + * much higher than reality). */ static int brin_bloom_get_ndistinct(BrinDesc *bdesc, BloomOptions *opts) @@ -738,11 +757,6 @@ brin_bloom_get_ndistinct(BrinDesc *bdesc, BloomOptions *opts) return (int) ndistinct; } -static double -brin_bloom_get_fp_rate(BrinDesc *bdesc, BloomOptions *opts) -{ - return BloomGetFalsePositiveRate(opts); -} /* * Examine the given index tuple (which contains partial status of a certain @@ -777,7 +791,7 @@ brin_bloom_add_value(PG_FUNCTION_ARGS) if (column->bv_allnulls) { filter = bloom_init(brin_bloom_get_ndistinct(bdesc, opts), - brin_bloom_get_fp_rate(bdesc, opts)); + BloomGetFalsePositiveRate(opts)); column->bv_values[0] = PointerGetDatum(filter); column->bv_allnulls = false; updated = true; @@ -949,7 +963,7 @@ brin_bloom_union(PG_FUNCTION_ARGS) * Cache and return inclusion opclass support procedure * * Return the procedure corresponding to the given function support number - * or null if it is not exists. + * or null if it does not exists. */ static FmgrInfo * bloom_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum) @@ -1050,11 +1064,8 @@ brin_bloom_summary_out(PG_FUNCTION_ARGS) initStringInfo(&str); appendStringInfoChar(&str, '{'); - /* - * XXX not sure the detoasting is necessary (probably not, this - * can only be in an index). - */ - filter = (BloomFilter *) PG_DETOAST_DATUM(PG_GETARG_BYTEA_PP(0)); + /* Detoasting not needed (this can only be in an index). */ + filter = (BloomFilter *) PG_GETARG_BYTEA_PP(0); if (BLOOM_IS_HASHED(filter)) { @@ -1063,9 +1074,12 @@ brin_bloom_summary_out(PG_FUNCTION_ARGS) } else { + /* + * XXX Maybe include the sorted/unsorted values? Seems a bit too + * much useless detail (internal hash values). + */ appendStringInfo(&str, "mode: sorted nvalues: %u nsorted: %u", filter->nvalues, filter->nsorted); - /* TODO include the sorted/unsorted values */ } appendStringInfoChar(&str, '}'); diff --git a/src/test/regress/expected/brin_bloom.out b/src/test/regress/expected/brin_bloom.out index 19b866283a..24ea5f6e42 100644 --- a/src/test/regress/expected/brin_bloom.out +++ b/src/test/regress/expected/brin_bloom.out @@ -58,17 +58,17 @@ CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( ); ERROR: value -1.1 out of bounds for option "n_distinct_per_range" DETAIL: Valid values are between "-1.000000" and "2147483647.000000". --- false_positive_rate must be between 0.001 and 1.0 +-- false_positive_rate must be between 0.0001 and 0.25 CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( - byteacol bytea_bloom_ops(false_positive_rate = 0.0009) + byteacol bytea_bloom_ops(false_positive_rate = 0.00009) ); -ERROR: value 0.0009 out of bounds for option "false_positive_rate" -DETAIL: Valid values are between "0.001000" and "0.100000". +ERROR: value 0.00009 out of bounds for option "false_positive_rate" +DETAIL: Valid values are between "0.000100" and "0.250000". CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( - byteacol bytea_bloom_ops(false_positive_rate = 0.11) + byteacol bytea_bloom_ops(false_positive_rate = 0.26) ); -ERROR: value 0.11 out of bounds for option "false_positive_rate" -DETAIL: Valid values are between "0.001000" and "0.100000". +ERROR: value 0.26 out of bounds for option "false_positive_rate" +DETAIL: Valid values are between "0.000100" and "0.250000". CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( byteacol bytea_bloom_ops, charcol char_bloom_ops, diff --git a/src/test/regress/sql/brin_bloom.sql b/src/test/regress/sql/brin_bloom.sql index 3c2ef56316..d587f3962f 100644 --- a/src/test/regress/sql/brin_bloom.sql +++ b/src/test/regress/sql/brin_bloom.sql @@ -59,12 +59,12 @@ FROM tenk1 ORDER BY thousand, tenthous LIMIT 25; CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( byteacol bytea_bloom_ops(n_distinct_per_range = -1.1) ); --- false_positive_rate must be between 0.001 and 1.0 +-- false_positive_rate must be between 0.0001 and 0.25 CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( - byteacol bytea_bloom_ops(false_positive_rate = 0.0009) + byteacol bytea_bloom_ops(false_positive_rate = 0.00009) ); CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( - byteacol bytea_bloom_ops(false_positive_rate = 0.11) + byteacol bytea_bloom_ops(false_positive_rate = 0.26) ); CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( -- 2.26.2 --------------CF71AF65F7C337C37C24B045 Content-Type: text/x-patch; charset=UTF-8; name="0006-add-sort_mode-opclass-parameter-20210112.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0006-add-sort_mode-opclass-parameter-20210112.patch" ^ permalink raw reply [nested|flat] 3+ messages in thread
* [PATCH v3 3/4] autoconf: Move export_dynamic determination to configure @ 2022-10-13 00:14 Andres Freund <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Andres Freund @ 2022-10-13 00:14 UTC (permalink / raw) Previously export_dynamic was set in src/makefiles/Makefile.$port. For solaris this required exporting with_gnu_ld. The determination of with_gnu_ld would be nontrivial to copy for meson PGXS compatibility. It's also nice to delete libtool.m4. This uses -Wl,--export-dynamic on all platforms, previously all platforms but FreeBSD used -Wl,-E. The likelihood of a name conflict seems lower with the longer spelling. Discussion: https://postgr.es/m/[email protected] --- config/c-compiler.m4 | 25 ++- config/libtool.m4 | 119 -------------- src/makefiles/Makefile.freebsd | 1 - src/makefiles/Makefile.linux | 1 - src/makefiles/Makefile.netbsd | 1 - src/makefiles/Makefile.openbsd | 1 - src/makefiles/Makefile.solaris | 4 - src/backend/Makefile | 12 +- aclocal.m4 | 1 - configure | 275 +++++++++++++-------------------- configure.ac | 8 +- src/Makefile.global.in | 2 +- 12 files changed, 141 insertions(+), 309 deletions(-) delete mode 100644 config/libtool.m4 diff --git a/config/c-compiler.m4 b/config/c-compiler.m4 index eb8cc8ce170..768df8b9fed 100644 --- a/config/c-compiler.m4 +++ b/config/c-compiler.m4 @@ -468,29 +468,38 @@ AC_DEFUN([PGAC_PROG_CXX_CFLAGS_OPT], -# PGAC_PROG_CC_LDFLAGS_OPT +# PGAC_PROG_CC_LD_VARFLAGS_OPT # ------------------------ # Given a string, check if the compiler supports the string as a -# command-line option. If it does, add the string to LDFLAGS. +# command-line option. If it does, add to the given variable. # 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 :-( -AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT], -[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_ldflags_$1])])dnl -AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar], +AC_DEFUN([PGAC_PROG_CC_LD_VARFLAGS_OPT], +[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_$1_$2])])dnl +AC_CACHE_CHECK([whether $CC supports $2, for $1], [Ac_cachevar], [pgac_save_LDFLAGS=$LDFLAGS -LDFLAGS="$pgac_save_LDFLAGS $1" -AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])], +LDFLAGS="$pgac_save_LDFLAGS $2" +AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $3 (); void (*fptr) () = $3;],[])], [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" + $1="${$1} $2" fi undefine([Ac_cachevar])dnl +])# PGAC_PROG_CC_LD_VARFLAGS_OPT + +# PGAC_PROG_CC_LDFLAGS_OPT +# ------------------------ +# Convenience wrapper around PGAC_PROG_CC_LD_VARFLAGS_OPT that adds to +# LDFLAGS. +AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT], +[PGAC_PROG_CC_LD_VARFLAGS_OPT(LDFLAGS, $1, $2) ])# PGAC_PROG_CC_LDFLAGS_OPT + # PGAC_HAVE_GCC__SYNC_CHAR_TAS # ---------------------------- # Check if the C compiler understands __sync_lock_test_and_set(char), diff --git a/config/libtool.m4 b/config/libtool.m4 deleted file mode 100644 index f6e426dbdf1..00000000000 --- a/config/libtool.m4 +++ /dev/null @@ -1,119 +0,0 @@ -## libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- -## Copyright (C) 1996-1999,2000 Free Software Foundation, Inc. -## Originally by Gordon Matzigkeit <[email protected]>, 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 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, write to the Free Software -## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -## -## 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. - -# No, PostgreSQL doesn't use libtool (yet), we just borrow stuff from it. -# This file was taken on 2000-10-20 from the multi-language branch (since -# that is the branch that PostgreSQL would most likely adopt anyway). -# --petere - -# ... bunch of stuff removed here ... - -# PGAC_PROG_LD - find the path to the GNU or non-GNU linker -AC_DEFUN([PGAC_PROG_LD], -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [[default=no]]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -dnl ###not for PostgreSQL### AC_REQUIRE([AC_CANONICAL_BUILD])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 GCC]) - 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. -changequote(,)dnl - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' -changequote([,])dnl - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(ac_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - ac_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - ac_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$ac_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -PGAC_PROG_LD_GNU -]) - -AC_DEFUN([PGAC_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then - ac_cv_prog_gnu_ld=yes -else - ac_cv_prog_gnu_ld=no -fi]) -with_gnu_ld=$ac_cv_prog_gnu_ld -]) - -# ... more stuff removed ... diff --git a/src/makefiles/Makefile.freebsd b/src/makefiles/Makefile.freebsd index db74a21568c..8a65d781354 100644 --- a/src/makefiles/Makefile.freebsd +++ b/src/makefiles/Makefile.freebsd @@ -1,4 +1,3 @@ -export_dynamic = -Wl,-export-dynamic rpath = -Wl,-R'$(rpathdir)' # extra stuff for $(with_temp_install) diff --git a/src/makefiles/Makefile.linux b/src/makefiles/Makefile.linux index 5a9451371ab..16d8249a111 100644 --- a/src/makefiles/Makefile.linux +++ b/src/makefiles/Makefile.linux @@ -1,4 +1,3 @@ -export_dynamic = -Wl,-E # Use --enable-new-dtags to generate DT_RUNPATH instead of DT_RPATH. # This allows LD_LIBRARY_PATH to still work when needed. rpath = -Wl,-rpath,'$(rpathdir)',--enable-new-dtags diff --git a/src/makefiles/Makefile.netbsd b/src/makefiles/Makefile.netbsd index 4f8e9ec2521..eb86e0b76e4 100644 --- a/src/makefiles/Makefile.netbsd +++ b/src/makefiles/Makefile.netbsd @@ -1,4 +1,3 @@ -export_dynamic = -Wl,-E rpath = -Wl,-R'$(rpathdir)' diff --git a/src/makefiles/Makefile.openbsd b/src/makefiles/Makefile.openbsd index 4f8e9ec2521..eb86e0b76e4 100644 --- a/src/makefiles/Makefile.openbsd +++ b/src/makefiles/Makefile.openbsd @@ -1,4 +1,3 @@ -export_dynamic = -Wl,-E rpath = -Wl,-R'$(rpathdir)' diff --git a/src/makefiles/Makefile.solaris b/src/makefiles/Makefile.solaris index 3de73ebc010..e2b386ac127 100644 --- a/src/makefiles/Makefile.solaris +++ b/src/makefiles/Makefile.solaris @@ -1,10 +1,6 @@ # src/makefiles/Makefile.solaris rpath = -Wl,-rpath,'$(rpathdir)' -ifeq ($(with_gnu_ld), yes) -export_dynamic = -Wl,-E -endif - # Rule for building a shared library from a single .o file %.so: %.o $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ diff --git a/src/backend/Makefile b/src/backend/Makefile index efd4d30a28d..c8d1de4f103 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -55,6 +55,8 @@ ifeq ($(with_systemd),yes) LIBS += -lsystemd endif +override LDFLAGS := $(LDFLAGS) $(LDFLAGS_EX) $(LDFLAGS_EX_BE) + ########################################################################## all: submake-libpgport submake-catalog-headers submake-utils-headers postgres $(POSTGRES_IMP) @@ -64,7 +66,7 @@ ifneq ($(PORTNAME), win32) ifneq ($(PORTNAME), aix) postgres: $(OBJS) - $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -o $@ + $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LIBS) -o $@ endif endif @@ -73,7 +75,7 @@ endif ifeq ($(PORTNAME), cygwin) postgres: $(OBJS) - $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) -Wl,--stack,$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@ + $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) -Wl,--stack,$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@ # libpostgres.a is actually built in the preceding rule, but we need this to # ensure it's newer than postgres; see notes in src/backend/parser/Makefile @@ -86,7 +88,7 @@ ifeq ($(PORTNAME), win32) LIBS += -lsecur32 postgres: $(OBJS) $(WIN32RES) - $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(WIN32RES) $(LDFLAGS) $(LDFLAGS_EX) -Wl,--stack=$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@$(X) + $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(WIN32RES) $(LDFLAGS) -Wl,--stack=$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@$(X) # libpostgres.a is actually built in the preceding rule, but we need this to # ensure it's newer than postgres; see notes in src/backend/parser/Makefile @@ -98,7 +100,7 @@ endif # win32 ifeq ($(PORTNAME), aix) postgres: $(POSTGRES_IMP) - $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(LDFLAGS) $(LDFLAGS_EX) -Wl,-bE:$(top_builddir)/src/backend/$(POSTGRES_IMP) $(LIBS) -Wl,-brtllib -o $@ + $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(LDFLAGS) -Wl,-bE:$(top_builddir)/src/backend/$(POSTGRES_IMP) $(LIBS) -Wl,-brtllib -o $@ # Linking to a single .o with -r is a lot faster than building a .a or passing # all objects to MKLDEXPORT. @@ -320,4 +322,4 @@ maintainer-clean: distclean # are up to date. It saves the time of doing all the submakes. .PHONY: quick quick: $(OBJS) - $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -o postgres + $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LIBS) -o postgres diff --git a/aclocal.m4 b/aclocal.m4 index 1c19c60c596..d05f8f9e3a8 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -4,7 +4,6 @@ m4_include([config/c-compiler.m4]) m4_include([config/c-library.m4]) m4_include([config/check_decls.m4]) m4_include([config/general.m4]) -m4_include([config/libtool.m4]) m4_include([config/llvm.m4]) m4_include([config/perl.m4]) m4_include([config/pkg.m4]) diff --git a/configure b/configure index d87b82dea92..f0faa1c2e87 100755 --- a/configure +++ b/configure @@ -629,6 +629,7 @@ ac_subst_vars='LTLIBOBJS vpath_build PG_SYSROOT PG_VERSION_NUM +LDFLAGS_EX_BE PROVE DBTOEPUB FOP @@ -691,7 +692,6 @@ AR STRIP_SHARED_LIB STRIP_STATIC_LIB STRIP -with_gnu_ld LDFLAGS_SL LDFLAGS_EX ZSTD_LIBS @@ -870,7 +870,6 @@ with_system_tzdata with_zlib with_lz4 with_zstd -with_gnu_ld with_ssl with_openssl enable_largefile @@ -1581,7 +1580,6 @@ Optional Packages: --without-zlib do not use Zlib --with-lz4 build with LZ4 support --with-zstd build with ZSTD support - --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-ssl=LIB use LIB for SSL/TLS support (openssl) --with-openssl obsolete spelling of --with-ssl=openssl @@ -9455,105 +9453,6 @@ LDFLAGS="$LDFLAGS $LIBDIRS" -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 -$as_echo_n "checking for ld used by GCC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case "$ac_prog" in - # Accept absolute paths. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${ac_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - ac_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - ac_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$ac_cv_path_LD" -if test -n "$LD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&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 ${ac_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then - ac_cv_prog_gnu_ld=yes -else - ac_cv_prog_gnu_ld=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gnu_ld" >&5 -$as_echo "$ac_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$ac_cv_prog_gnu_ld - - - - 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 @@ -19069,19 +18968,19 @@ else fi if test "$PORTNAME" = "darwin"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,-dead_strip_dylibs" >&5 -$as_echo_n "checking whether $CC supports -Wl,-dead_strip_dylibs... " >&6; } -if ${pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl, for LDFLAGS" >&5 +$as_echo_n "checking whether $CC supports -Wl, for LDFLAGS... " >&6; } +if ${pgac_cv_prog_cc_LDFLAGS__Wl+:} false; then : $as_echo_n "(cached) " >&6 else pgac_save_LDFLAGS=$LDFLAGS -LDFLAGS="$pgac_save_LDFLAGS -Wl,-dead_strip_dylibs" +LDFLAGS="$pgac_save_LDFLAGS -Wl" if test "$cross_compiling" = yes; then : - pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs="assuming no" + pgac_cv_prog_cc_LDFLAGS__Wl="assuming no" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -extern void $link_test_func (); void (*fptr) () = $link_test_func; +extern void -dead_strip_dylibs (); void (*fptr) () = -dead_strip_dylibs; int main () { @@ -19091,9 +18990,9 @@ main () } _ACEOF if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs=yes + pgac_cv_prog_cc_LDFLAGS__Wl=yes else - pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs=no + pgac_cv_prog_cc_LDFLAGS__Wl=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -19101,22 +19000,107 @@ fi LDFLAGS="$pgac_save_LDFLAGS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs" >&5 -$as_echo "$pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs" >&6; } -if test x"$pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs" = x"yes"; then - LDFLAGS="$LDFLAGS -Wl,-dead_strip_dylibs" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS__Wl" >&5 +$as_echo "$pgac_cv_prog_cc_LDFLAGS__Wl" >&6; } +if test x"$pgac_cv_prog_cc_LDFLAGS__Wl" = x"yes"; then + LDFLAGS="${LDFLAGS} -Wl" fi + elif test "$PORTNAME" = "openbsd"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,-Bdynamic" >&5 -$as_echo_n "checking whether $CC supports -Wl,-Bdynamic... " >&6; } -if ${pgac_cv_prog_cc_ldflags__Wl__Bdynamic+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl, for LDFLAGS" >&5 +$as_echo_n "checking whether $CC supports -Wl, for LDFLAGS... " >&6; } +if ${pgac_cv_prog_cc_LDFLAGS__Wl+:} false; then : $as_echo_n "(cached) " >&6 else pgac_save_LDFLAGS=$LDFLAGS -LDFLAGS="$pgac_save_LDFLAGS -Wl,-Bdynamic" +LDFLAGS="$pgac_save_LDFLAGS -Wl" if test "$cross_compiling" = yes; then : - pgac_cv_prog_cc_ldflags__Wl__Bdynamic="assuming no" + pgac_cv_prog_cc_LDFLAGS__Wl="assuming no" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +extern void -Bdynamic (); void (*fptr) () = -Bdynamic; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + pgac_cv_prog_cc_LDFLAGS__Wl=yes +else + pgac_cv_prog_cc_LDFLAGS__Wl=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +LDFLAGS="$pgac_save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS__Wl" >&5 +$as_echo "$pgac_cv_prog_cc_LDFLAGS__Wl" >&6; } +if test x"$pgac_cv_prog_cc_LDFLAGS__Wl" = x"yes"; then + LDFLAGS="${LDFLAGS} -Wl" +fi + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl, for LDFLAGS" >&5 +$as_echo_n "checking whether $CC supports -Wl, for LDFLAGS... " >&6; } +if ${pgac_cv_prog_cc_LDFLAGS__Wl+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_LDFLAGS=$LDFLAGS +LDFLAGS="$pgac_save_LDFLAGS -Wl" +if test "$cross_compiling" = yes; then : + pgac_cv_prog_cc_LDFLAGS__Wl="assuming no" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +extern void --as-needed (); void (*fptr) () = --as-needed; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + pgac_cv_prog_cc_LDFLAGS__Wl=yes +else + pgac_cv_prog_cc_LDFLAGS__Wl=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +LDFLAGS="$pgac_save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS__Wl" >&5 +$as_echo "$pgac_cv_prog_cc_LDFLAGS__Wl" >&6; } +if test x"$pgac_cv_prog_cc_LDFLAGS__Wl" = x"yes"; then + LDFLAGS="${LDFLAGS} -Wl" +fi + + +fi + +# For linkers that understand --export-dynamic, add that to the LDFLAGS_EX_BE +# (backend specific ldflags). One some platforms this will always fail (e.g., +# windows), but on others it depends on the choice of linker (e.g., solaris). +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,--export-dynamic, for LDFLAGS_EX_BE" >&5 +$as_echo_n "checking whether $CC supports -Wl,--export-dynamic, for LDFLAGS_EX_BE... " >&6; } +if ${pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_LDFLAGS=$LDFLAGS +LDFLAGS="$pgac_save_LDFLAGS -Wl,--export-dynamic" +if test "$cross_compiling" = yes; then : + pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic="assuming no" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -19130,9 +19114,9 @@ main () } _ACEOF if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_prog_cc_ldflags__Wl__Bdynamic=yes + pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic=yes else - pgac_cv_prog_cc_ldflags__Wl__Bdynamic=no + pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -19140,52 +19124,13 @@ fi LDFLAGS="$pgac_save_LDFLAGS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_ldflags__Wl__Bdynamic" >&5 -$as_echo "$pgac_cv_prog_cc_ldflags__Wl__Bdynamic" >&6; } -if test x"$pgac_cv_prog_cc_ldflags__Wl__Bdynamic" = x"yes"; then - LDFLAGS="$LDFLAGS -Wl,-Bdynamic" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic" >&5 +$as_echo "$pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic" >&6; } +if test x"$pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic" = x"yes"; then + LDFLAGS_EX_BE="${LDFLAGS_EX_BE} -Wl,--export-dynamic" fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,--as-needed" >&5 -$as_echo_n "checking whether $CC supports -Wl,--as-needed... " >&6; } -if ${pgac_cv_prog_cc_ldflags__Wl___as_needed+:} false; then : - $as_echo_n "(cached) " >&6 -else - pgac_save_LDFLAGS=$LDFLAGS -LDFLAGS="$pgac_save_LDFLAGS -Wl,--as-needed" -if test "$cross_compiling" = yes; then : - pgac_cv_prog_cc_ldflags__Wl___as_needed="assuming no" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -extern void $link_test_func (); void (*fptr) () = $link_test_func; -int -main () -{ - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_prog_cc_ldflags__Wl___as_needed=yes -else - pgac_cv_prog_cc_ldflags__Wl___as_needed=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -LDFLAGS="$pgac_save_LDFLAGS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_ldflags__Wl___as_needed" >&5 -$as_echo "$pgac_cv_prog_cc_ldflags__Wl___as_needed" >&6; } -if test x"$pgac_cv_prog_cc_ldflags__Wl___as_needed" = x"yes"; then - LDFLAGS="$LDFLAGS -Wl,--as-needed" -fi - -fi # Create compiler version string if test x"$GCC" = x"yes" ; then @@ -19872,7 +19817,7 @@ PostgreSQL config.status 16devel configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." diff --git a/configure.ac b/configure.ac index 77e5bef9e21..723fb736038 100644 --- a/configure.ac +++ b/configure.ac @@ -1128,8 +1128,6 @@ LDFLAGS="$LDFLAGS $LIBDIRS" AC_ARG_VAR(LDFLAGS_EX, [extra linker flags for linking executables only]) AC_ARG_VAR(LDFLAGS_SL, [extra linker flags for linking shared libraries only]) -PGAC_PROG_LD -AC_SUBST(with_gnu_ld) PGAC_CHECK_STRIP AC_CHECK_TOOL(AR, ar, ar) if test "$PORTNAME" = "win32"; then @@ -2368,6 +2366,12 @@ else PGAC_PROG_CC_LDFLAGS_OPT([-Wl,--as-needed], $link_test_func) fi +# For linkers that understand --export-dynamic, add that to the LDFLAGS_EX_BE +# (backend specific ldflags). One some platforms this will always fail (e.g., +# windows), but on others it depends on the choice of linker (e.g., solaris). +PGAC_PROG_CC_LD_VARFLAGS_OPT(LDFLAGS_EX_BE, [-Wl,--export-dynamic], $link_test_func) +AC_SUBST(LDFLAGS_EX_BE) + # Create compiler version string if test x"$GCC" = x"yes" ; then cc_string=`${CC} --version | sed q` diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 8107643578b..0d3c3e117fd 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -289,7 +289,6 @@ LDAP_LIBS_FE = @LDAP_LIBS_FE@ LDAP_LIBS_BE = @LDAP_LIBS_BE@ UUID_LIBS = @UUID_LIBS@ LLVM_LIBS=@LLVM_LIBS@ -with_gnu_ld = @with_gnu_ld@ # It's critical that within LDFLAGS, all -L switches pointing to build-tree # directories come before any -L switches pointing to external directories. @@ -313,6 +312,7 @@ endif LDFLAGS = $(LDFLAGS_INTERNAL) @LDFLAGS@ LDFLAGS_EX = @LDFLAGS_EX@ +LDFLAGS_EX_BE = @LDFLAGS_EX_BE@ # LDFLAGS_SL might have already been assigned by calling makefile LDFLAGS_SL += @LDFLAGS_SL@ WINDRES = @WINDRES@ -- 2.38.0 --72v5daafgeyrdmny Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0004-meson-Add-PGXS-compatibility.patch" ^ permalink raw reply [nested|flat] 3+ messages in thread
* [PATCH v6 1/7] Row pattern recognition patch for raw parser. @ 2023-09-12 05:22 Tatsuo Ishii <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Tatsuo Ishii @ 2023-09-12 05:22 UTC (permalink / raw) --- src/backend/parser/gram.y | 216 +++++++++++++++++++++++++++++--- src/include/nodes/parsenodes.h | 56 +++++++++ src/include/parser/kwlist.h | 8 ++ src/include/parser/parse_node.h | 1 + 4 files changed, 267 insertions(+), 14 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7d2032885e..70409cdc9a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -251,6 +251,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); DefElem *defelt; SortBy *sortby; WindowDef *windef; + RPCommonSyntax *rpcom; + RPSubsetItem *rpsubset; JoinExpr *jexpr; IndexElem *ielem; StatsElem *selem; @@ -453,8 +455,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); TriggerTransitions TriggerReferencing vacuum_relation_list opt_vacuum_relation_list drop_option_list pub_obj_list - -%type <node> opt_routine_body + row_pattern_measure_list row_pattern_definition_list + opt_row_pattern_subset_clause + row_pattern_subset_list row_pattern_subset_rhs + row_pattern +%type <rpsubset> row_pattern_subset_item +%type <node> opt_routine_body row_pattern_term %type <groupclause> group_clause %type <list> group_by_list %type <node> group_by_item empty_grouping_set rollup_clause cube_clause @@ -551,6 +557,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <range> relation_expr_opt_alias %type <node> tablesample_clause opt_repeatable_clause %type <target> target_el set_target insert_column_item + row_pattern_measure_item row_pattern_definition %type <str> generic_option_name %type <node> generic_option_arg @@ -633,6 +640,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <list> window_clause window_definition_list opt_partition_clause %type <windef> window_definition over_clause window_specification opt_frame_clause frame_extent frame_bound +%type <rpcom> opt_row_pattern_common_syntax opt_row_pattern_skip_to +%type <boolean> opt_row_pattern_initial_or_seek +%type <list> opt_row_pattern_measures %type <ival> opt_window_exclusion_clause %type <str> opt_existing_window_name %type <boolean> opt_if_not_exists @@ -659,7 +669,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); 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 @@ -702,7 +711,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); 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 + DEFERRABLE DEFERRED DEFINE DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP @@ -718,7 +727,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); 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 + INCLUDING INCREMENT INDENT INDEX INDEXES INHERIT INHERITS INITIAL INITIALLY INLINE_P INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION @@ -731,7 +740,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED - MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE METHOD + MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MEASURES MERGE METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NFC NFD NFKC NFKD NO NONE @@ -743,8 +752,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); ORDER ORDINALITY OTHERS OUT_P OUTER_P OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER - PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD - PLACING PLANS POLICY + PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PAST + PATTERN_P PERMUTE PLACING PLANS POLICY POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION @@ -755,12 +764,13 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); 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 + SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SEEK 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 STORED STRICT_P STRIP_P - SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER + SUBSCRIPTION SUBSET SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER TABLE TABLES TABLESAMPLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIES TIME TIMESTAMP TO TRAILING TRANSACTION TRANSFORM @@ -853,6 +863,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); */ %nonassoc UNBOUNDED /* ideally would have same precedence as IDENT */ %nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP +%nonassoc MEASURES AFTER INITIAL SEEK PATTERN_P %left Op OPERATOR /* multi-character ops and user-defined operators */ %left '+' '-' %left '*' '/' '%' @@ -15857,7 +15868,8 @@ over_clause: OVER window_specification ; window_specification: '(' opt_existing_window_name opt_partition_clause - opt_sort_clause opt_frame_clause ')' + opt_sort_clause opt_row_pattern_measures opt_frame_clause + opt_row_pattern_common_syntax ')' { WindowDef *n = makeNode(WindowDef); @@ -15865,10 +15877,12 @@ window_specification: '(' opt_existing_window_name opt_partition_clause n->refname = $2; n->partitionClause = $3; n->orderClause = $4; + n->rowPatternMeasures = $5; /* copy relevant fields of opt_frame_clause */ - n->frameOptions = $5->frameOptions; - n->startOffset = $5->startOffset; - n->endOffset = $5->endOffset; + n->frameOptions = $6->frameOptions; + n->startOffset = $6->startOffset; + n->endOffset = $6->endOffset; + n->rpCommonSyntax = $7; n->location = @1; $$ = n; } @@ -15892,6 +15906,31 @@ opt_partition_clause: PARTITION BY expr_list { $$ = $3; } | /*EMPTY*/ { $$ = NIL; } ; +/* + * ROW PATTERN_P MEASURES + */ +opt_row_pattern_measures: MEASURES row_pattern_measure_list { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +row_pattern_measure_list: + row_pattern_measure_item + { $$ = list_make1($1); } + | row_pattern_measure_list ',' row_pattern_measure_item + { $$ = lappend($1, $3); } + ; + +row_pattern_measure_item: + a_expr AS ColLabel + { + $$ = makeNode(ResTarget); + $$->name = $3; + $$->indirection = NIL; + $$->val = (Node *) $1; + $$->location = @1; + } + ; + /* * For frame clauses, we return a WindowDef, but only some fields are used: * frameOptions, startOffset, and endOffset. @@ -16051,6 +16090,139 @@ opt_window_exclusion_clause: | /*EMPTY*/ { $$ = 0; } ; +opt_row_pattern_common_syntax: +opt_row_pattern_skip_to opt_row_pattern_initial_or_seek + PATTERN_P '(' row_pattern ')' + opt_row_pattern_subset_clause + DEFINE row_pattern_definition_list + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = $1->rpSkipTo; + n->rpSkipVariable = $1->rpSkipVariable; + n->initial = $2; + n->rpPatterns = $5; + n->rpSubsetClause = $7; + n->rpDefs = $9; + $$ = n; + } + | /*EMPTY*/ { $$ = NULL; } + ; + +opt_row_pattern_skip_to: + AFTER MATCH SKIP TO NEXT ROW + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = ST_NEXT_ROW; + n->rpSkipVariable = NULL; + $$ = n; + } + | AFTER MATCH SKIP PAST LAST_P ROW + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = ST_PAST_LAST_ROW; + n->rpSkipVariable = NULL; + $$ = n; + } +/* + | AFTER MATCH SKIP TO FIRST_P ColId %prec FIRST_P + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = ST_FIRST_VARIABLE; + n->rpSkipVariable = $6; + $$ = n; + } + | AFTER MATCH SKIP TO LAST_P ColId %prec LAST_P + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = ST_LAST_VARIABLE; + n->rpSkipVariable = $6; + $$ = n; + } + * Shift/reduce + | AFTER MATCH SKIP TO ColId + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = ST_VARIABLE; + n->rpSkipVariable = $5; + $$ = n; + } +*/ + | /*EMPTY*/ + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + /* temporary set default to ST_NEXT_ROW */ + n->rpSkipTo = ST_PAST_LAST_ROW; + n->rpSkipVariable = NULL; + $$ = n; + } + ; + +opt_row_pattern_initial_or_seek: + INITIAL { $$ = true; } + | SEEK + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("SEEK is not supported"), + errhint("Use INITIAL."), + parser_errposition(@1))); + } + | /*EMPTY*/ { $$ = true; } + ; + +row_pattern: + row_pattern_term { $$ = list_make1($1); } + | row_pattern row_pattern_term { $$ = lappend($1, $2); } + ; + +row_pattern_term: + ColId { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "", (Node *)makeString($1), NULL, @1); } + | ColId '*' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", (Node *)makeString($1), NULL, @1); } + | ColId '+' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", (Node *)makeString($1), NULL, @1); } + | ColId '?' { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "?", (Node *)makeString($1), NULL, @1); } + ; + +opt_row_pattern_subset_clause: + SUBSET row_pattern_subset_list { $$ = $2; } + | /*EMPTY*/ { $$ = NIL; } + ; + +row_pattern_subset_list: + row_pattern_subset_item { $$ = list_make1($1); } + | row_pattern_subset_list ',' row_pattern_subset_item { $$ = lappend($1, $3); } + | /*EMPTY*/ { $$ = NIL; } + ; + +row_pattern_subset_item: ColId '=' '(' row_pattern_subset_rhs ')' + { + RPSubsetItem *n = makeNode(RPSubsetItem); + n->name = $1; + n->rhsVariable = $4; + $$ = n; + } + ; + +row_pattern_subset_rhs: + ColId { $$ = list_make1(makeStringConst($1, @1)); } + | row_pattern_subset_rhs ',' ColId { $$ = lappend($1, makeStringConst($3, @1)); } + | /*EMPTY*/ { $$ = NIL; } + ; + +row_pattern_definition_list: + row_pattern_definition { $$ = list_make1($1); } + | row_pattern_definition_list ',' row_pattern_definition { $$ = lappend($1, $3); } + ; + +row_pattern_definition: + ColId AS a_expr + { + $$ = makeNode(ResTarget); + $$->name = $1; + $$->indirection = NIL; + $$->val = (Node *) $3; + $$->location = @1; + } + ; /* * Supporting nonterminals for expressions. @@ -17146,6 +17318,7 @@ unreserved_keyword: | INDEXES | INHERIT | INHERITS + | INITIAL | INLINE_P | INPUT_P | INSENSITIVE @@ -17173,6 +17346,7 @@ unreserved_keyword: | MATCHED | MATERIALIZED | MAXVALUE + | MEASURES | MERGE | METHOD | MINUTE_P @@ -17215,6 +17389,9 @@ unreserved_keyword: | PARTITION | PASSING | PASSWORD + | PAST + | PATTERN_P + | PERMUTE | PLANS | POLICY | PRECEDING @@ -17265,6 +17442,7 @@ unreserved_keyword: | SEARCH | SECOND_P | SECURITY + | SEEK | SEQUENCE | SEQUENCES | SERIALIZABLE @@ -17290,6 +17468,7 @@ unreserved_keyword: | STRICT_P | STRIP_P | SUBSCRIPTION + | SUBSET | SUPPORT | SYSID | SYSTEM_P @@ -17477,6 +17656,7 @@ reserved_keyword: | CURRENT_USER | DEFAULT | DEFERRABLE + | DEFINE | DESC | DISTINCT | DO @@ -17639,6 +17819,7 @@ bare_label_keyword: | DEFAULTS | DEFERRABLE | DEFERRED + | DEFINE | DEFINER | DELETE_P | DELIMITER @@ -17714,6 +17895,7 @@ bare_label_keyword: | INDEXES | INHERIT | INHERITS + | INITIAL | INITIALLY | INLINE_P | INNER_P @@ -17763,6 +17945,7 @@ bare_label_keyword: | MATCHED | MATERIALIZED | MAXVALUE + | MEASURES | MERGE | METHOD | MINVALUE @@ -17816,6 +17999,9 @@ bare_label_keyword: | PARTITION | PASSING | PASSWORD + | PAST + | PATTERN_P + | PERMUTE | PLACING | PLANS | POLICY @@ -17872,6 +18058,7 @@ bare_label_keyword: | SCROLL | SEARCH | SECURITY + | SEEK | SELECT | SEQUENCE | SEQUENCES @@ -17903,6 +18090,7 @@ bare_label_keyword: | STRICT_P | STRIP_P | SUBSCRIPTION + | SUBSET | SUBSTRING | SUPPORT | SYMMETRIC diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index fef4c714b8..657651df1d 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -547,6 +547,44 @@ typedef struct SortBy int location; /* operator location, or -1 if none/unknown */ } SortBy; +/* + * AFTER MATCH row pattern skip to types in row pattern common syntax + */ +typedef enum RPSkipTo +{ + ST_NONE, /* AFTER MATCH omitted */ + ST_NEXT_ROW, /* SKIP TO NEXT ROW */ + ST_PAST_LAST_ROW, /* SKIP TO PAST LAST ROW */ + ST_FIRST_VARIABLE, /* SKIP TO FIRST variable name */ + ST_LAST_VARIABLE, /* SKIP TO LAST variable name */ + ST_VARIABLE /* SKIP TO variable name */ +} RPSkipTo; + +/* + * Row Pattern SUBSET clause item + */ +typedef struct RPSubsetItem +{ + NodeTag type; + char *name; /* Row Pattern SUBSET clause variable name */ + List *rhsVariable; /* Row Pattern SUBSET rhs variables (list of char *string) */ +} RPSubsetItem; + +/* + * RowPatternCommonSyntax - raw representation of row pattern common syntax + * + */ +typedef struct RPCommonSyntax +{ + NodeTag type; + RPSkipTo rpSkipTo; /* Row Pattern AFTER MATCH SKIP type */ + char *rpSkipVariable; /* Row Pattern Skip To variable name, if any */ + bool initial; /* true if <row pattern initial or seek> is initial */ + List *rpPatterns; /* PATTERN variables (list of A_Expr) */ + List *rpSubsetClause; /* row pattern subset clause (list of RPSubsetItem), if any */ + List *rpDefs; /* row pattern definitions clause (list of ResTarget) */ +} RPCommonSyntax; + /* * WindowDef - raw representation of WINDOW and OVER clauses * @@ -562,6 +600,8 @@ typedef struct WindowDef char *refname; /* referenced window name, if any */ List *partitionClause; /* PARTITION BY expression list */ List *orderClause; /* ORDER BY (list of SortBy) */ + List *rowPatternMeasures; /* row pattern measures (list of ResTarget) */ + RPCommonSyntax *rpCommonSyntax; /* row pattern common syntax */ int frameOptions; /* frame_clause options, see below */ Node *startOffset; /* expression for starting bound, if any */ Node *endOffset; /* expression for ending bound, if any */ @@ -1483,6 +1523,11 @@ typedef struct GroupingSet * the orderClause might or might not be copied (see copiedOrder); the framing * options are never copied, per spec. * + * "defineClause" is Row Pattern Recognition DEFINE clause (list of + * TargetEntry). TargetEntry.resname represents row pattern definition + * variable name. "patternVariable" and "patternRegexp" represents PATTERN + * clause. + * * The information relevant for the query jumbling is the partition clause * type and its bounds. */ @@ -1514,6 +1559,17 @@ typedef struct WindowClause Index winref; /* ID referenced by window functions */ /* did we copy orderClause from refname? */ bool copiedOrder pg_node_attr(query_jumble_ignore); + /* Row Pattern AFTER MACH SKIP clause */ + RPSkipTo rpSkipTo; /* Row Pattern Skip To type */ + bool initial; /* true if <row pattern initial or seek> is initial */ + /* Row Pattern DEFINE clause (list of TargetEntry) */ + List *defineClause; + /* Row Pattern DEFINE variable initial names (list of String) */ + List *defineInitial; + /* Row Pattern PATTERN variable name (list of String) */ + List *patternVariable; + /* Row Pattern PATTERN regular expression quantifier ('+' or ''. list of String) */ + List *patternRegexp; } WindowClause; /* diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 5984dcfa4b..2804333b53 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -128,6 +128,7 @@ 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("define", DEFINE, RESERVED_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) @@ -212,6 +213,7 @@ 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("initial", INITIAL, 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) @@ -265,6 +267,7 @@ 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("measures", MEASURES, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("merge", MERGE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD, AS_LABEL) @@ -326,6 +329,9 @@ 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("past", PAST, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("pattern", PATTERN_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("permute", PERMUTE, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD, BARE_LABEL) @@ -385,6 +391,7 @@ 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("seek", SEEK, 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) @@ -416,6 +423,7 @@ PG_KEYWORD("stored", STORED, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("subset", SUBSET, 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) diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h index f589112d5e..6640090910 100644 --- a/src/include/parser/parse_node.h +++ b/src/include/parser/parse_node.h @@ -51,6 +51,7 @@ typedef enum ParseExprKind EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */ EXPR_KIND_WINDOW_FRAME_ROWS, /* window frame clause with ROWS */ EXPR_KIND_WINDOW_FRAME_GROUPS, /* window frame clause with GROUPS */ + EXPR_KIND_RPR_DEFINE, /* DEFINE */ EXPR_KIND_SELECT_TARGET, /* SELECT target list item */ EXPR_KIND_INSERT_TARGET, /* INSERT target list item */ EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */ -- 2.25.1 ----Next_Part(Tue_Sep_12_15_18_43_2023_359)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v6-0002-Row-pattern-recognition-patch-parse-analysis.patch" ^ permalink raw reply [nested|flat] 3+ messages in thread
end of thread, other threads:[~2023-09-12 05:22 UTC | newest] Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2021-01-12 23:59 [PATCH 5/8] bloom fixes and tweaks Tomas Vondra <[email protected]> 2022-10-13 00:14 [PATCH v3 3/4] autoconf: Move export_dynamic determination to configure Andres Freund <[email protected]> 2023-09-12 05:22 [PATCH v6 1/7] Row pattern recognition patch for raw parser. Tatsuo Ishii <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox