agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH] implement trim_array 14+ messages / 7 participants [nested] [flat]
* [PATCH] implement trim_array @ 2021-02-16 17:38 Vik Fearing <[email protected]> 0 siblings, 0 replies; 14+ messages in thread From: Vik Fearing @ 2021-02-16 17:38 UTC (permalink / raw) --- doc/src/sgml/func.sgml | 18 ++++++++++++ src/backend/catalog/sql_features.txt | 2 +- src/backend/utils/adt/arrayfuncs.c | 42 ++++++++++++++++++++++++++++ src/include/catalog/pg_proc.dat | 5 ++++ src/test/regress/expected/arrays.out | 23 +++++++++++++++ src/test/regress/sql/arrays.sql | 19 +++++++++++++ 6 files changed, 108 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 08f08322ca..2aac87cf8d 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -17909,6 +17909,24 @@ SELECT NULLIF(value, '(none)') ... </para></entry> </row> + <row> + <entry role="func_table_entry"><para role="func_signature"> + <indexterm> + <primary>trim_array</primary> + </indexterm> + <function>trim_array</function> ( <parameter>array</parameter> <type>anyarray</type>, <parameter>n</parameter> <type>integer</type> ) + <returnvalue>anyarray</returnvalue> + </para> + <para> + Trims an array by removing the last <parameter>n</parameter> elements. + If the array is multidimensional, only the first dimension is trimmed. + </para> + <para> + <literal>trim_array(ARRAY[1,2,3,4,5,6], 2)</literal> + <returnvalue>{1,2,3,4}</returnvalue> + </para></entry> + </row> + <row> <entry role="func_table_entry"><para role="func_signature"> <indexterm> diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt index ab0895ce3c..32eed988ab 100644 --- a/src/backend/catalog/sql_features.txt +++ b/src/backend/catalog/sql_features.txt @@ -398,7 +398,7 @@ S301 Enhanced UNNEST YES S401 Distinct types based on array types NO S402 Distinct types based on distinct types NO S403 ARRAY_MAX_CARDINALITY NO -S404 TRIM_ARRAY NO +S404 TRIM_ARRAY YES T011 Timestamp in Information Schema NO T021 BINARY and VARBINARY data types NO T022 Advanced support for BINARY and VARBINARY data types NO diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index f7012cc5d9..d38a99f0b0 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -6631,3 +6631,45 @@ width_bucket_array_variable(Datum operand, return left; } + +/* + * Trim the right N elements from an array by calculating an appropriate slice. + * Only the first dimension is trimmed. + */ +Datum +trim_array(PG_FUNCTION_ARGS) +{ + ArrayType *v = PG_GETARG_ARRAYTYPE_P(0); + int n = PG_GETARG_INT32(1); + int array_length = ARR_DIMS(v)[0]; + int16 elmlen; + bool elmbyval; + char elmalign; + int lower[MAXDIM]; + int upper[MAXDIM]; + bool lowerProvided[MAXDIM]; + bool upperProvided[MAXDIM]; + Datum result; + + /* Throw an error if out of bounds */ + if (n < 0 || n > array_length) + ereport(ERROR, + (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), + errmsg("number of elements to trim must be between 0 and %d", array_length))); + + /* Set all the bounds as unprovided except the first upper bound */ + memset(lowerProvided, 0, sizeof(lowerProvided)); + memset(upperProvided, 0, sizeof(upperProvided)); + upper[0] = ARR_LBOUND(v)[0] + array_length - n - 1; + upperProvided[0] = true; + + /* Fetch the needed information about the element type */ + get_typlenbyvalalign(ARR_ELEMTYPE(v), &elmlen, &elmbyval, &elmalign); + + /* Get the slice */ + result = array_get_slice(PointerGetDatum(v), 1, + upper, lower, upperProvided, lowerProvided, + -1, elmlen, elmbyval, elmalign); + + PG_RETURN_DATUM(result); +} diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 1487710d59..8ab911238d 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1674,6 +1674,11 @@ proname => 'arraycontjoinsel', provolatile => 's', prorettype => 'float8', proargtypes => 'internal oid internal int2 internal', prosrc => 'arraycontjoinsel' }, +{ oid => '8819', + descr => 'trim an array down to n elements', + proname => 'trim_array', proisstrict => 't', provolatile => 'i', + prorettype => 'anyarray', proargtypes => 'anyarray int4', + prosrc => 'trim_array' }, { oid => '764', descr => 'large object import', proname => 'lo_import', provolatile => 'v', proparallel => 'u', diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out index 8bc7721e7d..fd3e4bfc49 100644 --- a/src/test/regress/expected/arrays.out +++ b/src/test/regress/expected/arrays.out @@ -2399,3 +2399,26 @@ SELECT width_bucket(5, ARRAY[3, 4, NULL]); ERROR: thresholds array must not contain NULLs SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]); ERROR: thresholds must be one-dimensional array +-- trim_array +CREATE TABLE trim_array_test (arr integer[]); +INSERT INTO trim_array_test +VALUES ('[-15:-10]={1,2,3,4,5,6}'), + ('{1,2,3,4,5,6}'), + ('[10:15]={1,2,3,4,5,6}'), + ('{{1,10},{2,20},{3,30},{4,40},{5,50},{6,60}}'); +SELECT arr, trim_array(arr, 2) +FROM trim_array_test +ORDER BY arr; + arr | trim_array +---------------------------------------------+------------------------------- + [-15:-10]={1,2,3,4,5,6} | {1,2,3,4} + {1,2,3,4,5,6} | {1,2,3,4} + [10:15]={1,2,3,4,5,6} | {1,2,3,4} + {{1,10},{2,20},{3,30},{4,40},{5,50},{6,60}} | {{1,10},{2,20},{3,30},{4,40}} +(4 rows) + +DROP TABLE trim_array_test; +VALUES (trim_array(ARRAY[1, 2, 3], -1)); -- fail +ERROR: number of elements to trim must be between 0 and 3 +VALUES (trim_array(ARRAY[1, 2, 3], 10)); -- fail +ERROR: number of elements to trim must be between 0 and 3 diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql index c40619a8d5..551cf5c5c9 100644 --- a/src/test/regress/sql/arrays.sql +++ b/src/test/regress/sql/arrays.sql @@ -722,3 +722,22 @@ SELECT width_bucket(5, '{}'); SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]); SELECT width_bucket(5, ARRAY[3, 4, NULL]); SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]); + + +-- trim_array + +CREATE TABLE trim_array_test (arr integer[]); +INSERT INTO trim_array_test +VALUES ('[-15:-10]={1,2,3,4,5,6}'), + ('{1,2,3,4,5,6}'), + ('[10:15]={1,2,3,4,5,6}'), + ('{{1,10},{2,20},{3,30},{4,40},{5,50},{6,60}}'); + +SELECT arr, trim_array(arr, 2) +FROM trim_array_test +ORDER BY arr; + +DROP TABLE trim_array_test; + +VALUES (trim_array(ARRAY[1, 2, 3], -1)); -- fail +VALUES (trim_array(ARRAY[1, 2, 3], 10)); -- fail -- 2.25.1 --------------CD3F9594D6239C85433F5ED4-- ^ permalink raw reply [nested|flat] 14+ messages in thread
* fixing typo in comment for restriction_is_or_clause @ 2022-10-24 17:19 Zhihong Yu <[email protected]> 0 siblings, 1 reply; 14+ messages in thread From: Zhihong Yu @ 2022-10-24 17:19 UTC (permalink / raw) To: PostgreSQL Developers <[email protected]> Hi, When I was looking at src/backend/optimizer/util/restrictinfo.c, I found a typo in one of the comments. I also took the chance to simplify the code a little bit. Please take a look at the patch. Thanks Attachments: [application/octet-stream] is-or.patch (676B, ../../CALNJ-vSP1-vpM7N8wMUQcofpQu6yMH5UXyyQ_bYuRC43bdZ9sQ@mail.gmail.com/3-is-or.patch) download | inline diff: diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index ef8df3d098..25c444d149 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -378,15 +378,12 @@ commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op) /* * restriction_is_or_clause * - * Returns t iff the restrictinfo node contains an 'or' clause. + * Returns true iff the restrictinfo node contains an 'or' clause. */ bool restriction_is_or_clause(RestrictInfo *restrictinfo) { - if (restrictinfo->orclause != NULL) - return true; - else - return false; + return (restrictinfo->orclause != NULL); } /* ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 02:05 John Naylor <[email protected]> parent: Zhihong Yu <[email protected]> 0 siblings, 1 reply; 14+ messages in thread From: John Naylor @ 2022-10-25 02:05 UTC (permalink / raw) To: Zhihong Yu <[email protected]>; +Cc: PostgreSQL Developers <[email protected]> On Tue, Oct 25, 2022 at 12:19 AM Zhihong Yu <[email protected]> wrote: > > Hi, > When I was looking at src/backend/optimizer/util/restrictinfo.c, I found a typo in one of the comments. Using "t" as an abbreviation for "true" was probably intentional, so not a typo. There is no doubt what the behavior is. > I also took the chance to simplify the code a little bit. It's perfectly clear and simple now, even if it doesn't win at "code golf". -- John Naylor EDB: http://www.enterprisedb.com ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 02:48 Richard Guo <[email protected]> parent: John Naylor <[email protected]> 0 siblings, 3 replies; 14+ messages in thread From: Richard Guo @ 2022-10-25 02:48 UTC (permalink / raw) To: John Naylor <[email protected]>; +Cc: Zhihong Yu <[email protected]>; PostgreSQL Developers <[email protected]> On Tue, Oct 25, 2022 at 10:05 AM John Naylor <[email protected]> wrote: > > On Tue, Oct 25, 2022 at 12:19 AM Zhihong Yu <[email protected]> wrote: > > > > Hi, > > When I was looking at src/backend/optimizer/util/restrictinfo.c, I found > a typo in one of the comments. > > Using "t" as an abbreviation for "true" was probably intentional, so not a > typo. There is no doubt what the behavior is. > > > I also took the chance to simplify the code a little bit. > > It's perfectly clear and simple now, even if it doesn't win at "code golf". > Agree with your point. Do you think we can further make the one-line function a macro or an inline function in the .h file? I think this function is called quite frequently during planning, so maybe doing that would bring a little bit of efficiency. Thanks Richard ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 02:58 Japin Li <[email protected]> parent: Richard Guo <[email protected]> 2 siblings, 1 reply; 14+ messages in thread From: Japin Li @ 2022-10-25 02:58 UTC (permalink / raw) To: Richard Guo <[email protected]>; +Cc: John Naylor <[email protected]>; Zhihong Yu <[email protected]>; [email protected] On Tue, 25 Oct 2022 at 10:48, Richard Guo <[email protected]> wrote: > On Tue, Oct 25, 2022 at 10:05 AM John Naylor <[email protected]> > wrote: > >> >> On Tue, Oct 25, 2022 at 12:19 AM Zhihong Yu <[email protected]> wrote: >> > >> > Hi, >> > When I was looking at src/backend/optimizer/util/restrictinfo.c, I found >> a typo in one of the comments. >> >> Using "t" as an abbreviation for "true" was probably intentional, so not a >> typo. There is no doubt what the behavior is. >> >> > I also took the chance to simplify the code a little bit. >> >> It's perfectly clear and simple now, even if it doesn't win at "code golf". >> > > Agree with your point. Do you think we can further make the one-line > function a macro or an inline function in the .h file? I think this > function is called quite frequently during planning, so maybe doing that > would bring a little bit of efficiency. > +1, same goes for restriction_is_securely_promotable. -- Regrads, Japin Li. ChengDu WenWu Information Technology Co.,Ltd. ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 03:07 Zhihong Yu <[email protected]> parent: Japin Li <[email protected]> 0 siblings, 1 reply; 14+ messages in thread From: Zhihong Yu @ 2022-10-25 03:07 UTC (permalink / raw) To: Japin Li <[email protected]>; +Cc: Richard Guo <[email protected]>; John Naylor <[email protected]>; [email protected] On Mon, Oct 24, 2022 at 7:58 PM Japin Li <[email protected]> wrote: > > On Tue, 25 Oct 2022 at 10:48, Richard Guo <[email protected]> wrote: > > On Tue, Oct 25, 2022 at 10:05 AM John Naylor < > [email protected]> > > wrote: > > > >> > >> On Tue, Oct 25, 2022 at 12:19 AM Zhihong Yu <[email protected]> wrote: > >> > > >> > Hi, > >> > When I was looking at src/backend/optimizer/util/restrictinfo.c, I > found > >> a typo in one of the comments. > >> > >> Using "t" as an abbreviation for "true" was probably intentional, so > not a > >> typo. There is no doubt what the behavior is. > >> > >> > I also took the chance to simplify the code a little bit. > >> > >> It's perfectly clear and simple now, even if it doesn't win at "code > golf". > >> > > > > Agree with your point. Do you think we can further make the one-line > > function a macro or an inline function in the .h file? I think this > > function is called quite frequently during planning, so maybe doing that > > would bring a little bit of efficiency. > > > > +1, same goes for restriction_is_securely_promotable. > > Hi, Thanks for the comments. Please take a look at patch v2. Attachments: [application/octet-stream] v2-is-or.patch (1.5K, ../../CALNJ-vSTpjFVwrf+fYTUSQjnjv1KoSOxziWsznN6sww9r0UJiw@mail.gmail.com/3-v2-is-or.patch) download | inline diff: diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index ef8df3d098..1c356e0809 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -378,15 +378,12 @@ commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op) /* * restriction_is_or_clause * - * Returns t iff the restrictinfo node contains an 'or' clause. + * Returns true iff the restrictinfo node contains an 'or' clause. */ -bool +inline bool restriction_is_or_clause(RestrictInfo *restrictinfo) { - if (restrictinfo->orclause != NULL) - return true; - else - return false; + return (restrictinfo->orclause != NULL); } /* @@ -395,7 +392,7 @@ restriction_is_or_clause(RestrictInfo *restrictinfo) * Returns true if it's okay to evaluate this clause "early", that is before * other restriction clauses attached to the specified relation. */ -bool +inline bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, RelOptInfo *rel) { @@ -403,11 +400,8 @@ restriction_is_securely_promotable(RestrictInfo *restrictinfo, * It's okay if there are no baserestrictinfo clauses for the rel that * would need to go before this one, *or* if this one is leakproof. */ - if (restrictinfo->security_level <= rel->baserestrict_min_security || - restrictinfo->leakproof) - return true; - else - return false; + return (restrictinfo->security_level <= rel->baserestrict_min_security || + restrictinfo->leakproof); } /* ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 03:46 Japin Li <[email protected]> parent: Zhihong Yu <[email protected]> 0 siblings, 1 reply; 14+ messages in thread From: Japin Li @ 2022-10-25 03:46 UTC (permalink / raw) To: Zhihong Yu <[email protected]>; +Cc: Richard Guo <[email protected]>; John Naylor <[email protected]>; [email protected] On Tue, 25 Oct 2022 at 11:07, Zhihong Yu <[email protected]> wrote: > Please take a look at patch v2. Maybe we should define those functions in headers. See patch v3. -- Regrads, Japin Li. ChengDu WenWu Information Technology Co.,Ltd. Attachments: [text/x-diff] v3-is-or.patch (2.9K, ../../MEYP282MB166954D2DF97D3796B81DB07B6319@MEYP282MB1669.AUSP282.PROD.OUTLOOK.COM/2-v3-is-or.patch) download | inline diff: diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index ef8df3d098..8a6812b4b1 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -375,41 +375,6 @@ commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op) return result; } -/* - * restriction_is_or_clause - * - * Returns t iff the restrictinfo node contains an 'or' clause. - */ -bool -restriction_is_or_clause(RestrictInfo *restrictinfo) -{ - if (restrictinfo->orclause != NULL) - return true; - else - return false; -} - -/* - * restriction_is_securely_promotable - * - * Returns true if it's okay to evaluate this clause "early", that is before - * other restriction clauses attached to the specified relation. - */ -bool -restriction_is_securely_promotable(RestrictInfo *restrictinfo, - RelOptInfo *rel) -{ - /* - * It's okay if there are no baserestrictinfo clauses for the rel that - * would need to go before this one, *or* if this one is leakproof. - */ - if (restrictinfo->security_level <= rel->baserestrict_min_security || - restrictinfo->leakproof) - return true; - else - return false; -} - /* * get_actual_clauses * diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index 6d30bd5e9d..dbfbebff48 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -31,9 +31,6 @@ extern RestrictInfo *make_restrictinfo(PlannerInfo *root, Relids outer_relids, Relids nullable_relids); extern RestrictInfo *commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op); -extern bool restriction_is_or_clause(RestrictInfo *restrictinfo); -extern bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, - RelOptInfo *rel); extern List *get_actual_clauses(List *restrictinfo_list); extern List *extract_actual_clauses(List *restrictinfo_list, bool pseudoconstant); @@ -46,4 +43,36 @@ extern bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer); +/* + * restriction_is_or_clause + * + * Returns true iff the restrictinfo node contains an 'or' clause. + */ +static inline bool +restriction_is_or_clause(RestrictInfo *restrictinfo) +{ + return (restrictinfo->orclause != NULL); +} + +/* + * restriction_is_securely_promotable + * + * Returns true if it's okay to evaluate this clause "early", that is before + * other restriction clauses attached to the specified relation. + */ +static inline bool +restriction_is_securely_promotable(RestrictInfo *restrictinfo, + RelOptInfo *rel) +{ + /* + * It's okay if there are no baserestrictinfo clauses for the rel that + * would need to go before this one, *or* if this one is leakproof. + */ + if (restrictinfo->security_level <= rel->baserestrict_min_security || + restrictinfo->leakproof) + return true; + else + return false; +} + #endif /* RESTRICTINFO_H */ ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 04:01 Richard Guo <[email protected]> parent: Japin Li <[email protected]> 0 siblings, 1 reply; 14+ messages in thread From: Richard Guo @ 2022-10-25 04:01 UTC (permalink / raw) To: Japin Li <[email protected]>; +Cc: Zhihong Yu <[email protected]>; John Naylor <[email protected]>; [email protected] On Tue, Oct 25, 2022 at 11:46 AM Japin Li <[email protected]> wrote: > > On Tue, 25 Oct 2022 at 11:07, Zhihong Yu <[email protected]> wrote: > > Please take a look at patch v2. > > Maybe we should define those functions in headers. See patch v3. Yes, putting them in .h file is better to me. For the v3 patch, we can do the same one-line trick for restriction_is_securely_promotable. Thanks Richard ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 05:40 Japin Li <[email protected]> parent: Richard Guo <[email protected]> 0 siblings, 0 replies; 14+ messages in thread From: Japin Li @ 2022-10-25 05:40 UTC (permalink / raw) To: Richard Guo <[email protected]>; +Cc: Zhihong Yu <[email protected]>; John Naylor <[email protected]>; [email protected] On Tue, 25 Oct 2022 at 12:01, Richard Guo <[email protected]> wrote: > On Tue, Oct 25, 2022 at 11:46 AM Japin Li <[email protected]> wrote: > >> >> On Tue, 25 Oct 2022 at 11:07, Zhihong Yu <[email protected]> wrote: >> > Please take a look at patch v2. >> >> Maybe we should define those functions in headers. See patch v3. > > > Yes, putting them in .h file is better to me. For the v3 patch, we can > do the same one-line trick for restriction_is_securely_promotable. > Fixed. Please consider the v4 for further review. -- Regrads, Japin Li. ChengDu WenWu Information Technology Co.,Ltd. Attachments: [text/x-diff] v4-is-or.patch (2.9K, ../../MEYP282MB166917CA266844532CE9E237B6319@MEYP282MB1669.AUSP282.PROD.OUTLOOK.COM/2-v4-is-or.patch) download | inline diff: diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index ef8df3d098..8a6812b4b1 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -375,41 +375,6 @@ commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op) return result; } -/* - * restriction_is_or_clause - * - * Returns t iff the restrictinfo node contains an 'or' clause. - */ -bool -restriction_is_or_clause(RestrictInfo *restrictinfo) -{ - if (restrictinfo->orclause != NULL) - return true; - else - return false; -} - -/* - * restriction_is_securely_promotable - * - * Returns true if it's okay to evaluate this clause "early", that is before - * other restriction clauses attached to the specified relation. - */ -bool -restriction_is_securely_promotable(RestrictInfo *restrictinfo, - RelOptInfo *rel) -{ - /* - * It's okay if there are no baserestrictinfo clauses for the rel that - * would need to go before this one, *or* if this one is leakproof. - */ - if (restrictinfo->security_level <= rel->baserestrict_min_security || - restrictinfo->leakproof) - return true; - else - return false; -} - /* * get_actual_clauses * diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index 6d30bd5e9d..b61707fd26 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -31,9 +31,6 @@ extern RestrictInfo *make_restrictinfo(PlannerInfo *root, Relids outer_relids, Relids nullable_relids); extern RestrictInfo *commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op); -extern bool restriction_is_or_clause(RestrictInfo *restrictinfo); -extern bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, - RelOptInfo *rel); extern List *get_actual_clauses(List *restrictinfo_list); extern List *extract_actual_clauses(List *restrictinfo_list, bool pseudoconstant); @@ -46,4 +43,33 @@ extern bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer); +/* + * restriction_is_or_clause + * + * Returns true iff the restrictinfo node contains an 'or' clause. + */ +static inline bool +restriction_is_or_clause(RestrictInfo *restrictinfo) +{ + return (restrictinfo->orclause != NULL); +} + +/* + * restriction_is_securely_promotable + * + * Returns true if it's okay to evaluate this clause "early", that is before + * other restriction clauses attached to the specified relation. + */ +static inline bool +restriction_is_securely_promotable(RestrictInfo *restrictinfo, + RelOptInfo *rel) +{ + /* + * It's okay if there are no baserestrictinfo clauses for the rel that + * would need to go before this one, *or* if this one is leakproof. + */ + return (restrictinfo->security_level <= rel->baserestrict_min_security || + restrictinfo->leakproof); +} + #endif /* RESTRICTINFO_H */ ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 06:25 John Naylor <[email protected]> parent: Richard Guo <[email protected]> 2 siblings, 1 reply; 14+ messages in thread From: John Naylor @ 2022-10-25 06:25 UTC (permalink / raw) To: Richard Guo <[email protected]>; +Cc: Zhihong Yu <[email protected]>; PostgreSQL Developers <[email protected]> On Tue, Oct 25, 2022 at 9:48 AM Richard Guo <[email protected]> wrote: > > > On Tue, Oct 25, 2022 at 10:05 AM John Naylor <[email protected]> wrote: >> >> It's perfectly clear and simple now, even if it doesn't win at "code golf". > > > Agree with your point. Do you think we can further make the one-line > function a macro or an inline function in the .h file? I think this > function is called quite frequently during planning, so maybe doing that > would bring a little bit of efficiency. My point was misunderstood, which is: I don't think we need to do anything at all here if the goal was purely about aesthetics. If the goal has now changed to efficiency, I have no opinion about that yet since no evidence has been presented. -- John Naylor EDB: http://www.enterprisedb.com ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 07:37 Alvaro Herrera <[email protected]> parent: Richard Guo <[email protected]> 2 siblings, 1 reply; 14+ messages in thread From: Alvaro Herrera @ 2022-10-25 07:37 UTC (permalink / raw) To: Richard Guo <[email protected]>; +Cc: John Naylor <[email protected]>; Zhihong Yu <[email protected]>; PostgreSQL Developers <[email protected]> On 2022-Oct-25, Richard Guo wrote: > Agree with your point. Do you think we can further make the one-line > function a macro or an inline function in the .h file? We can, but should we? > I think this function is called quite frequently during planning, so > maybe doing that would bring a little bit of efficiency. You'd need to measure it and show some gains. -- Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/ "Siempre hay que alimentar a los dioses, aunque la tierra esté seca" (Orual) ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 07:52 Richard Guo <[email protected]> parent: John Naylor <[email protected]> 0 siblings, 0 replies; 14+ messages in thread From: Richard Guo @ 2022-10-25 07:52 UTC (permalink / raw) To: John Naylor <[email protected]>; +Cc: Zhihong Yu <[email protected]>; PostgreSQL Developers <[email protected]> On Tue, Oct 25, 2022 at 2:25 PM John Naylor <[email protected]> wrote: > > On Tue, Oct 25, 2022 at 9:48 AM Richard Guo <[email protected]> > wrote: > > > > > > On Tue, Oct 25, 2022 at 10:05 AM John Naylor < > [email protected]> wrote: > >> > >> It's perfectly clear and simple now, even if it doesn't win at "code > golf". > > > > > > Agree with your point. Do you think we can further make the one-line > > function a macro or an inline function in the .h file? I think this > > function is called quite frequently during planning, so maybe doing that > > would bring a little bit of efficiency. > > My point was misunderstood, which is: I don't think we need to do anything > at all here if the goal was purely about aesthetics. > > If the goal has now changed to efficiency, I have no opinion about that > yet since no evidence has been presented. > Now I think I've got your point. Sorry for the misread. Your concern makes sense. When talking about efficiency we'd better attach some concrete proof, such as benchmark tests. Thanks Richard ^ permalink raw reply [nested|flat] 14+ messages in thread
* Re: fixing typo in comment for restriction_is_or_clause @ 2022-10-25 07:56 Richard Guo <[email protected]> parent: Alvaro Herrera <[email protected]> 0 siblings, 0 replies; 14+ messages in thread From: Richard Guo @ 2022-10-25 07:56 UTC (permalink / raw) To: Alvaro Herrera <[email protected]>; +Cc: John Naylor <[email protected]>; Zhihong Yu <[email protected]>; PostgreSQL Developers <[email protected]> On Tue, Oct 25, 2022 at 3:37 PM Alvaro Herrera <[email protected]> wrote: > On 2022-Oct-25, Richard Guo wrote: > > > Agree with your point. Do you think we can further make the one-line > > function a macro or an inline function in the .h file? > > We can, but should we? > > > I think this function is called quite frequently during planning, so > > maybe doing that would bring a little bit of efficiency. > > You'd need to measure it and show some gains. Yeah, that is what has to be done to make it happen. Thanks Richard ^ permalink raw reply [nested|flat] 14+ messages in thread
* [PATCH v23 1/8] Row pattern recognition patch for raw parser. @ 2024-10-25 03:56 Tatsuo Ishii <[email protected]> 0 siblings, 0 replies; 14+ messages in thread From: Tatsuo Ishii @ 2024-10-25 03:56 UTC (permalink / raw) --- src/backend/parser/gram.y | 221 ++++++++++++++++++++++++++++++-- src/include/nodes/parsenodes.h | 67 ++++++++++ src/include/parser/kwlist.h | 8 ++ src/include/parser/parse_node.h | 1 + 4 files changed, 286 insertions(+), 11 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index baca4059d2..ddfee6a652 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -664,6 +664,21 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); json_object_constructor_null_clause_opt json_array_constructor_null_clause_opt +%type <target> row_pattern_measure_item + row_pattern_definition +%type <node> opt_row_pattern_common_syntax + opt_row_pattern_skip_to + row_pattern_subset_item + row_pattern_term +%type <list> opt_row_pattern_measures + row_pattern_measure_list + row_pattern_definition_list + opt_row_pattern_subset_clause + row_pattern_subset_list + row_pattern_subset_rhs + row_pattern +%type <boolean> opt_row_pattern_initial_or_seek + first_or_last /* * Non-keyword token types. These are hard-wired into the "flex" lexer. @@ -707,7 +722,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 @@ -723,7 +738,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 @@ -736,7 +751,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 MERGE_ACTION METHOD + MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MEASURES 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 @@ -748,8 +763,9 @@ 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 PATH - PERIOD PLACING PLAN PLANS POLICY + PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PAST + PATH PATTERN_P PERIOD PERMUTE PLACING PLAN PLANS POLICY + POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION @@ -760,12 +776,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 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 + SUBSCRIPTION SUBSET 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 @@ -874,6 +891,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %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 + MEASURES AFTER INITIAL SEEK PATTERN_P %left Op OPERATOR /* multi-character ops and user-defined operators */ %left '+' '-' %left '*' '/' '%' @@ -16279,7 +16297,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); @@ -16287,10 +16306,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 = (RPCommonSyntax *)$7; n->location = @1; $$ = n; } @@ -16314,6 +16335,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. @@ -16473,6 +16519,143 @@ 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 = ((RPCommonSyntax *)$1)->rpSkipTo; + n->rpSkipVariable = ((RPCommonSyntax *)$1)->rpSkipVariable; + n->initial = $2; + n->rpPatterns = $5; + n->rpSubsetClause = $7; + n->rpDefs = $9; + $$ = (Node *) 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; + $$ = (Node *) n; + } + | AFTER MATCH SKIP PAST LAST_P ROW + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = ST_PAST_LAST_ROW; + n->rpSkipVariable = NULL; + $$ = (Node *) n; + } + | AFTER MATCH SKIP TO first_or_last ColId + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = $5? ST_FIRST_VARIABLE : ST_LAST_VARIABLE; + n->rpSkipVariable = $6; + $$ = (Node *) n; + } +/* + | AFTER MATCH SKIP TO LAST_P ColId %prec LAST_P + { + RPCommonSyntax *n = makeNode(RPCommonSyntax); + n->rpSkipTo = ST_LAST_VARIABLE; + n->rpSkipVariable = $6; + $$ = n; + } + | 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; + $$ = (Node *) n; + } + ; + +first_or_last: + FIRST_P { $$ = true; } + | LAST_P { $$ = false; } + ; + +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; + $$ = (Node *) 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. @@ -17683,6 +17866,7 @@ unreserved_keyword: | INDEXES | INHERIT | INHERITS + | INITIAL | INLINE_P | INPUT_P | INSENSITIVE @@ -17711,6 +17895,7 @@ unreserved_keyword: | MATCHED | MATERIALIZED | MAXVALUE + | MEASURES | MERGE | METHOD | MINUTE_P @@ -17755,8 +17940,11 @@ unreserved_keyword: | PARTITION | PASSING | PASSWORD + | PAST | PATH + | PATTERN_P | PERIOD + | PERMUTE | PLAN | PLANS | POLICY @@ -17808,6 +17996,7 @@ unreserved_keyword: | SEARCH | SECOND_P | SECURITY + | SEEK | SEQUENCE | SEQUENCES | SERIALIZABLE @@ -17835,6 +18024,7 @@ unreserved_keyword: | STRING_P | STRIP_P | SUBSCRIPTION + | SUBSET | SUPPORT | SYSID | SYSTEM_P @@ -18029,6 +18219,7 @@ reserved_keyword: | CURRENT_USER | DEFAULT | DEFERRABLE + | DEFINE | DESC | DISTINCT | DO @@ -18192,6 +18383,7 @@ bare_label_keyword: | DEFAULTS | DEFERRABLE | DEFERRED + | DEFINE | DEFINER | DELETE_P | DELIMITER @@ -18269,6 +18461,7 @@ bare_label_keyword: | INDEXES | INHERIT | INHERITS + | INITIAL | INITIALLY | INLINE_P | INNER_P @@ -18323,6 +18516,7 @@ bare_label_keyword: | MATCHED | MATERIALIZED | MAXVALUE + | MEASURES | MERGE | MERGE_ACTION | METHOD @@ -18379,8 +18573,11 @@ bare_label_keyword: | PARTITION | PASSING | PASSWORD + | PAST | PATH + | PATTERN_P | PERIOD + | PERMUTE | PLACING | PLAN | PLANS @@ -18438,6 +18635,7 @@ bare_label_keyword: | SCROLL | SEARCH | SECURITY + | SEEK | SELECT | SEQUENCE | SEQUENCES @@ -18471,6 +18669,7 @@ bare_label_keyword: | STRING_P | STRIP_P | SUBSCRIPTION + | SUBSET | SUBSTRING | SUPPORT | SYMMETRIC diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index b40b661ec8..685ca438b1 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -552,6 +552,48 @@ typedef struct SortBy ParseLoc 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 * @@ -567,6 +609,9 @@ 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 */ @@ -1530,6 +1575,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. */ @@ -1559,6 +1609,23 @@ 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 */ + char *rpSkipVariable; /* Row Pattern Skip To variable */ + 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 899d64ad55..f52d797615 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -129,6 +129,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) @@ -215,6 +216,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) @@ -273,6 +275,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("merge_action", MERGE_ACTION, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD, BARE_LABEL) @@ -337,8 +340,11 @@ 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("path", PATH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("pattern", PATTERN_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("period", PERIOD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("permute", PERMUTE, 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) @@ -399,6 +405,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) @@ -432,6 +439,7 @@ 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("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 2375e95c10..737f8a9e0e 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(Fri_Oct_25_13_04_53_2024_648)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v23-0002-Row-pattern-recognition-patch-parse-analysis.patch" ^ permalink raw reply [nested|flat] 14+ messages in thread
end of thread, other threads:[~2024-10-25 03:56 UTC | newest] Thread overview: 14+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2021-02-16 17:38 [PATCH] implement trim_array Vik Fearing <[email protected]> 2022-10-24 17:19 fixing typo in comment for restriction_is_or_clause Zhihong Yu <[email protected]> 2022-10-25 02:05 ` Re: fixing typo in comment for restriction_is_or_clause John Naylor <[email protected]> 2022-10-25 02:48 ` Re: fixing typo in comment for restriction_is_or_clause Richard Guo <[email protected]> 2022-10-25 02:58 ` Re: fixing typo in comment for restriction_is_or_clause Japin Li <[email protected]> 2022-10-25 03:07 ` Re: fixing typo in comment for restriction_is_or_clause Zhihong Yu <[email protected]> 2022-10-25 03:46 ` Re: fixing typo in comment for restriction_is_or_clause Japin Li <[email protected]> 2022-10-25 04:01 ` Re: fixing typo in comment for restriction_is_or_clause Richard Guo <[email protected]> 2022-10-25 05:40 ` Re: fixing typo in comment for restriction_is_or_clause Japin Li <[email protected]> 2022-10-25 06:25 ` Re: fixing typo in comment for restriction_is_or_clause John Naylor <[email protected]> 2022-10-25 07:52 ` Re: fixing typo in comment for restriction_is_or_clause Richard Guo <[email protected]> 2022-10-25 07:37 ` Re: fixing typo in comment for restriction_is_or_clause Alvaro Herrera <[email protected]> 2022-10-25 07:56 ` Re: fixing typo in comment for restriction_is_or_clause Richard Guo <[email protected]> 2024-10-25 03:56 [PATCH v23 1/8] 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