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