public inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH 3/8] Process all scan keys in existing BRIN opclasses
5+ messages / 5 participants
[nested] [flat]

* [PATCH 3/8] Process all scan keys in existing BRIN opclasses
@ 2021-03-04 23:45 Tomas Vondra <[email protected]>
  0 siblings, 0 replies; 5+ messages in thread

From: Tomas Vondra @ 2021-03-04 23:45 UTC (permalink / raw)

This modifies the existing BRIN opclasses (minmax, inclusion) although
those don't really benefit from this change. The primary purpose of this
is to allow more advanced opclases in the future.
---
 src/backend/access/brin/brin_inclusion.c | 140 ++++++++++++++++-------
 src/backend/access/brin/brin_minmax.c    |  92 ++++++++++++---
 src/include/catalog/pg_proc.dat          |   4 +-
 3 files changed, 177 insertions(+), 59 deletions(-)

diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c
index 12e5bddd1f..a260074c91 100644
--- a/src/backend/access/brin/brin_inclusion.c
+++ b/src/backend/access/brin/brin_inclusion.c
@@ -85,6 +85,8 @@ static FmgrInfo *inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno,
 										uint16 procnum);
 static FmgrInfo *inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno,
 												 Oid subtype, uint16 strategynum);
+static bool inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column,
+									 ScanKey key, Oid colloid);
 
 
 /*
@@ -251,6 +253,10 @@ brin_inclusion_add_value(PG_FUNCTION_ARGS)
 /*
  * BRIN inclusion consistent function
  *
+ * We inspect the IS NULL scan keys first, which allows us to make a decision
+ * without looking at the contents of the page range. Only when the page range
+ * matches all those keys, we check the regular scan keys.
+ *
  * All of the strategies are optional.
  */
 Datum
@@ -258,24 +264,31 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 {
 	BrinDesc   *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
 	BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
-	ScanKey		key = (ScanKey) PG_GETARG_POINTER(2);
-	Oid			colloid = PG_GET_COLLATION(),
-				subtype;
-	Datum		unionval;
-	AttrNumber	attno;
-	Datum		query;
-	FmgrInfo   *finfo;
-	Datum		result;
-
-	Assert(key->sk_attno == column->bv_attno);
+	ScanKey    *keys = (ScanKey *) PG_GETARG_POINTER(2);
+	int			nkeys = PG_GETARG_INT32(3);
+	Oid			colloid = PG_GET_COLLATION();
+	int			keyno;
+	bool		has_regular_keys = false;
 
-	/* Handle IS NULL/IS NOT NULL tests. */
-	if (key->sk_flags & SK_ISNULL)
+	/* Handle IS NULL/IS NOT NULL tests */
+	for (keyno = 0; keyno < nkeys; keyno++)
 	{
+		ScanKey		key = keys[keyno];
+
+		Assert(key->sk_attno == column->bv_attno);
+
+		/* Skip regular scan keys (and remember that we have some). */
+		if ((!key->sk_flags & SK_ISNULL))
+		{
+			has_regular_keys = true;
+			continue;
+		}
+
 		if (key->sk_flags & SK_SEARCHNULL)
 		{
 			if (column->bv_allnulls || column->bv_hasnulls)
-				PG_RETURN_BOOL(true);
+				continue;		/* this key is fine, continue */
+
 			PG_RETURN_BOOL(false);
 		}
 
@@ -284,7 +297,12 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 		 * only nulls.
 		 */
 		if (key->sk_flags & SK_SEARCHNOTNULL)
-			PG_RETURN_BOOL(!column->bv_allnulls);
+		{
+			if (column->bv_allnulls)
+				PG_RETURN_BOOL(false);
+
+			continue;
+		}
 
 		/*
 		 * Neither IS NULL nor IS NOT NULL was used; assume all indexable
@@ -293,7 +311,14 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 		PG_RETURN_BOOL(false);
 	}
 
-	/* If it is all nulls, it cannot possibly be consistent. */
+	/* If there are no regular keys, the page range is considered consistent. */
+	if (!has_regular_keys)
+		PG_RETURN_BOOL(true);
+
+	/*
+	 * If is all nulls, it cannot possibly be consistent (at this point we
+	 * know there are at least some regular scan keys).
+	 */
 	if (column->bv_allnulls)
 		PG_RETURN_BOOL(false);
 
@@ -301,10 +326,45 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 	if (DatumGetBool(column->bv_values[INCLUSION_UNMERGEABLE]))
 		PG_RETURN_BOOL(true);
 
-	attno = key->sk_attno;
-	subtype = key->sk_subtype;
-	query = key->sk_argument;
-	unionval = column->bv_values[INCLUSION_UNION];
+	/* Check that the range is consistent with all regular scan keys. */
+	for (keyno = 0; keyno < nkeys; keyno++)
+	{
+		ScanKey		key = keys[keyno];
+
+		/* Skip IS NULL/IS NOT NULL keys (already handled above). */
+		if (key->sk_flags & SK_ISNULL)
+			continue;
+
+		/*
+		 * When there are multiple scan keys, failure to meet the criteria for
+		 * a single one of them is enough to discard the range as a whole, so
+		 * break out of the loop as soon as a false return value is obtained.
+		 */
+		if (!inclusion_consistent_key(bdesc, column, key, colloid))
+			PG_RETURN_BOOL(false);
+	}
+
+	PG_RETURN_BOOL(true);
+}
+
+/*
+ * inclusion_consistent_key
+ *		Determine if the range is consistent with a single scan key.
+ */
+static bool
+inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
+						 Oid colloid)
+{
+	FmgrInfo   *finfo;
+	AttrNumber	attno = key->sk_attno;
+	Oid			subtype = key->sk_subtype;
+	Datum		query = key->sk_argument;
+	Datum		unionval = column->bv_values[INCLUSION_UNION];
+	Datum		result;
+
+	/* This should be called only for regular keys, not for IS [NOT] NULL. */
+	Assert(!(key->sk_flags & SK_ISNULL));
+
 	switch (key->sk_strategy)
 	{
 			/*
@@ -324,49 +384,49 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTOverRightStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		case RTOverLeftStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTRightStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		case RTOverRightStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTLeftStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		case RTRightStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTOverLeftStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		case RTBelowStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTOverAboveStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		case RTOverBelowStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTAboveStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		case RTOverAboveStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTBelowStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		case RTAboveStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTOverBelowStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 			/*
 			 * Overlap and contains strategies
@@ -384,7 +444,7 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													key->sk_strategy);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_DATUM(result);
+			return DatumGetBool(result);
 
 			/*
 			 * Contained by strategies
@@ -404,9 +464,9 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 													RTOverlapStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
 			if (DatumGetBool(result))
-				PG_RETURN_BOOL(true);
+				return true;
 
-			PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+			return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
 
 			/*
 			 * Adjacent strategy
@@ -423,12 +483,12 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 													RTOverlapStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
 			if (DatumGetBool(result))
-				PG_RETURN_BOOL(true);
+				return true;
 
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTAdjacentStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_DATUM(result);
+			return DatumGetBool(result);
 
 			/*
 			 * Basic comparison strategies
@@ -458,9 +518,9 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 													RTRightStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
 			if (!DatumGetBool(result))
-				PG_RETURN_BOOL(true);
+				return true;
 
-			PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+			return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
 
 		case RTSameStrategyNumber:
 		case RTEqualStrategyNumber:
@@ -468,30 +528,30 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
 													RTContainsStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
 			if (DatumGetBool(result))
-				PG_RETURN_BOOL(true);
+				return true;
 
-			PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+			return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
 
 		case RTGreaterEqualStrategyNumber:
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTLeftStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
 			if (!DatumGetBool(result))
-				PG_RETURN_BOOL(true);
+				return true;
 
-			PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+			return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
 
 		case RTGreaterStrategyNumber:
 			/* no need to check for empty elements */
 			finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
 													RTLeftStrategyNumber);
 			result = FunctionCall2Coll(finfo, colloid, unionval, query);
-			PG_RETURN_BOOL(!DatumGetBool(result));
+			return !DatumGetBool(result);
 
 		default:
 			/* shouldn't happen */
 			elog(ERROR, "invalid strategy number %d", key->sk_strategy);
-			PG_RETURN_BOOL(false);
+			return false;
 	}
 }
 
diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c
index 2ffbd9bf0d..e116084a02 100644
--- a/src/backend/access/brin/brin_minmax.c
+++ b/src/backend/access/brin/brin_minmax.c
@@ -30,6 +30,8 @@ typedef struct MinmaxOpaque
 
 static FmgrInfo *minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno,
 											  Oid subtype, uint16 strategynum);
+static bool minmax_consistent_key(BrinDesc *bdesc, BrinValues *column,
+								  ScanKey key, Oid colloid);
 
 
 Datum
@@ -140,29 +142,41 @@ brin_minmax_add_value(PG_FUNCTION_ARGS)
  * Given an index tuple corresponding to a certain page range and a scan key,
  * return whether the scan key is consistent with the index tuple's min/max
  * values.  Return true if so, false otherwise.
+ *
+ * We inspect the IS NULL scan keys first, which allows us to make a decision
+ * without looking at the contents of the page range. Only when the page range
+ * matches all those keys, we check the regular scan keys.
  */
 Datum
 brin_minmax_consistent(PG_FUNCTION_ARGS)
 {
 	BrinDesc   *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
 	BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
-	ScanKey		key = (ScanKey) PG_GETARG_POINTER(2);
-	Oid			colloid = PG_GET_COLLATION(),
-				subtype;
-	AttrNumber	attno;
-	Datum		value;
-	Datum		matches;
-	FmgrInfo   *finfo;
-
-	Assert(key->sk_attno == column->bv_attno);
+	ScanKey    *keys = (ScanKey *) PG_GETARG_POINTER(2);
+	int			nkeys = PG_GETARG_INT32(3);
+	Oid			colloid = PG_GET_COLLATION();
+	int			keyno;
+	bool		has_regular_keys = false;
 
 	/* handle IS NULL/IS NOT NULL tests */
-	if (key->sk_flags & SK_ISNULL)
+	for (keyno = 0; keyno < nkeys; keyno++)
 	{
+		ScanKey		key = keys[keyno];
+
+		Assert(key->sk_attno == column->bv_attno);
+
+		/* Skip regular scan keys (and remember that we have some). */
+		if ((!key->sk_flags & SK_ISNULL))
+		{
+			has_regular_keys = true;
+			continue;
+		}
+
 		if (key->sk_flags & SK_SEARCHNULL)
 		{
 			if (column->bv_allnulls || column->bv_hasnulls)
-				PG_RETURN_BOOL(true);
+				continue;		/* this key is fine, continue */
+
 			PG_RETURN_BOOL(false);
 		}
 
@@ -171,7 +185,12 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
 		 * only nulls.
 		 */
 		if (key->sk_flags & SK_SEARCHNOTNULL)
-			PG_RETURN_BOOL(!column->bv_allnulls);
+		{
+			if (column->bv_allnulls)
+				PG_RETURN_BOOL(false);
+
+			continue;
+		}
 
 		/*
 		 * Neither IS NULL nor IS NOT NULL was used; assume all indexable
@@ -180,13 +199,52 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
 		PG_RETURN_BOOL(false);
 	}
 
-	/* if the range is all empty, it cannot possibly be consistent */
+	/* If there are no regular keys, the page range is considered consistent. */
+	if (!has_regular_keys)
+		PG_RETURN_BOOL(true);
+
+	/*
+	 * If is all nulls, it cannot possibly be consistent (at this point we
+	 * know there are at least some regular scan keys).
+	 */
 	if (column->bv_allnulls)
 		PG_RETURN_BOOL(false);
 
-	attno = key->sk_attno;
-	subtype = key->sk_subtype;
-	value = key->sk_argument;
+	/* Check that the range is consistent with all scan keys. */
+	for (keyno = 0; keyno < nkeys; keyno++)
+	{
+		ScanKey		key = keys[keyno];
+
+		/* ignore IS NULL/IS NOT NULL tests handled above */
+		if (key->sk_flags & SK_ISNULL)
+			continue;
+
+		/*
+		 * When there are multiple scan keys, failure to meet the criteria for
+		 * a single one of them is enough to discard the range as a whole, so
+		 * break out of the loop as soon as a false return value is obtained.
+		 */
+		if (!minmax_consistent_key(bdesc, column, key, colloid))
+			PG_RETURN_DATUM(false);;
+	}
+
+	PG_RETURN_DATUM(true);
+}
+
+/*
+ * minmax_consistent_key
+ *		Determine if the range is consistent with a single scan key.
+ */
+static bool
+minmax_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
+					  Oid colloid)
+{
+	FmgrInfo   *finfo;
+	AttrNumber	attno = key->sk_attno;
+	Oid			subtype = key->sk_subtype;
+	Datum		value = key->sk_argument;
+	Datum		matches;
+
 	switch (key->sk_strategy)
 	{
 		case BTLessStrategyNumber:
@@ -229,7 +287,7 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
 			break;
 	}
 
-	PG_RETURN_DATUM(matches);
+	return DatumGetBool(matches);
 }
 
 /*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 59d2b71ca9..93bdb5ec83 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -8194,7 +8194,7 @@
   prosrc => 'brin_minmax_add_value' },
 { oid => '3385', descr => 'BRIN minmax support',
   proname => 'brin_minmax_consistent', prorettype => 'bool',
-  proargtypes => 'internal internal internal',
+  proargtypes => 'internal internal internal int4',
   prosrc => 'brin_minmax_consistent' },
 { oid => '3386', descr => 'BRIN minmax support',
   proname => 'brin_minmax_union', prorettype => 'bool',
@@ -8210,7 +8210,7 @@
   prosrc => 'brin_inclusion_add_value' },
 { oid => '4107', descr => 'BRIN inclusion support',
   proname => 'brin_inclusion_consistent', prorettype => 'bool',
-  proargtypes => 'internal internal internal',
+  proargtypes => 'internal internal internal int4',
   prosrc => 'brin_inclusion_consistent' },
 { oid => '4108', descr => 'BRIN inclusion support',
   proname => 'brin_inclusion_union', prorettype => 'bool',
-- 
2.26.2


--------------AC3FFB734F56C5F52D422EFC
Content-Type: text/x-patch; charset=UTF-8;
 name="0004-Move-IS-NOT-NULL-handling-from-BRIN-support-20210305.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="0004-Move-IS-NOT-NULL-handling-from-BRIN-support-20210305.pa";
 filename*1="tch"



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Support for dumping extended statistics
@ 2023-01-05 18:29 Hari krishna Maddileti <[email protected]>
  2023-01-07 02:39 ` Re: Support for dumping extended statistics Bruce Momjian <[email protected]>
  0 siblings, 1 reply; 5+ messages in thread

From: Hari krishna Maddileti @ 2023-01-05 18:29 UTC (permalink / raw)
  To: PostgreSQL Hackers <[email protected]>; [email protected] <[email protected]>

Hi Team,

In order to restore dumped extended statistics (stxdndistinct, stxddependencies, stxdmcv) we need to provide input functions to parse pg_distinct/pg_dependency/pg_mcv_list strings.

Today we get the ERROR "cannot accept a value of type pg_ndistinct/pg_dependencies/pg_mcv_list" when we try to do an insert of any type.

Approch tried:
- Using yacc grammar file (statistics_gram.y) to parse the input string to its internal format for the types pg_distinct and pg_dependencies
- We are just calling byteain() for serialized input text of type pg_mcv_list.

Currently the changes are working locally,  I would like to push the commit changes to upstream if there any usecase for postgres.   Would like to know if there any interest from postgres side.

Regards,
Hari Krishna


^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Support for dumping extended statistics
  2023-01-05 18:29 Support for dumping extended statistics Hari krishna Maddileti <[email protected]>
@ 2023-01-07 02:39 ` Bruce Momjian <[email protected]>
  2023-02-01 13:30   ` Re: Support for dumping extended statistics Tomas Vondra <[email protected]>
  0 siblings, 1 reply; 5+ messages in thread

From: Bruce Momjian @ 2023-01-07 02:39 UTC (permalink / raw)
  To: Hari krishna Maddileti <[email protected]>; +Cc: PostgreSQL Hackers <[email protected]>

On Thu, Jan  5, 2023 at 06:29:03PM +0000, Hari krishna Maddileti wrote:
> Hi Team,
> In order to restore dumped extended statistics (stxdndistinct,
> stxddependencies, stxdmcv) we need to provide input functions to parse
> pg_distinct/pg_dependency/pg_mcv_list strings.
> 
> Today we get the ERROR "cannot accept a value of type pg_ndistinct/
> pg_dependencies/pg_mcv_list" when we try to do an insert of any type.
> 
> Approch tried:
> 
> - Using yacc grammar file (statistics_gram.y) to parse the input string to its
> internal format for the types pg_distinct and pg_dependencies
> 
> - We are just calling byteain() for serialized input text of type pg_mcv_list.
> 
> Currently the changes are working locally,  I would like to push the commit
> changes to upstream if there any usecase for postgres.   Would like to know if
> there any interest from postgres side.

There is certainly interest in allowing the optimizer statistics to be
dumped and reloaded.  This could be used by pg_restore and pg_upgrade.

-- 
  Bruce Momjian  <[email protected]>        https://momjian.us
  EDB                                      https://enterprisedb.com

Embrace your flaws.  They make you human, rather than perfect,
which you will never be.






^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Support for dumping extended statistics
  2023-01-05 18:29 Support for dumping extended statistics Hari krishna Maddileti <[email protected]>
  2023-01-07 02:39 ` Re: Support for dumping extended statistics Bruce Momjian <[email protected]>
@ 2023-02-01 13:30   ` Tomas Vondra <[email protected]>
  2023-02-01 14:58     ` Re: Support for dumping extended statistics Tom Lane <[email protected]>
  0 siblings, 1 reply; 5+ messages in thread

From: Tomas Vondra @ 2023-02-01 13:30 UTC (permalink / raw)
  To: Bruce Momjian <[email protected]>; Hari krishna Maddileti <[email protected]>; +Cc: PostgreSQL Hackers <[email protected]>



On 1/7/23 03:39, Bruce Momjian wrote:
> On Thu, Jan  5, 2023 at 06:29:03PM +0000, Hari krishna Maddileti wrote:
>> Hi Team,
>> In order to restore dumped extended statistics (stxdndistinct,
>> stxddependencies, stxdmcv) we need to provide input functions to parse
>> pg_distinct/pg_dependency/pg_mcv_list strings.
>>
>> Today we get the ERROR "cannot accept a value of type pg_ndistinct/
>> pg_dependencies/pg_mcv_list" when we try to do an insert of any type.
>>
>> Approch tried:
>>
>> - Using yacc grammar file (statistics_gram.y) to parse the input string to its
>> internal format for the types pg_distinct and pg_dependencies
>>
>> - We are just calling byteain() for serialized input text of type pg_mcv_list.
>>
>> Currently the changes are working locally,  I would like to push the commit
>> changes to upstream if there any usecase for postgres.   Would like to know if
>> there any interest from postgres side.
> 
> There is certainly interest in allowing the optimizer statistics to be
> dumped and reloaded.  This could be used by pg_restore and pg_upgrade.
> 

Indeed, although I think it'd be better to deal with regular statistics
(which is what 99% of systems use). Furthermore, we should probably
think about differences between major versions - until now we could
change on-disk format of the statistics, because we have reset them.
It'd be silly to do dump on version X, and then fail to restore it on
(X+1) just because the statistics changed a bit.

So we need to be able to determine is the statistics has the correct
format/version, or what. And we need to do that for pg_upgrade.

At the very least we need an option to skip restoring statistics, or
something like that.

regards
-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company






^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Support for dumping extended statistics
  2023-01-05 18:29 Support for dumping extended statistics Hari krishna Maddileti <[email protected]>
  2023-01-07 02:39 ` Re: Support for dumping extended statistics Bruce Momjian <[email protected]>
  2023-02-01 13:30   ` Re: Support for dumping extended statistics Tomas Vondra <[email protected]>
@ 2023-02-01 14:58     ` Tom Lane <[email protected]>
  0 siblings, 0 replies; 5+ messages in thread

From: Tom Lane @ 2023-02-01 14:58 UTC (permalink / raw)
  To: Tomas Vondra <[email protected]>; +Cc: Bruce Momjian <[email protected]>; Hari krishna Maddileti <[email protected]>; PostgreSQL Hackers <[email protected]>

Tomas Vondra <[email protected]> writes:
> On 1/7/23 03:39, Bruce Momjian wrote:
>> There is certainly interest in allowing the optimizer statistics to be
>> dumped and reloaded.  This could be used by pg_restore and pg_upgrade.

> Indeed, although I think it'd be better to deal with regular statistics
> (which is what 99% of systems use). Furthermore, we should probably
> think about differences between major versions - until now we could
> change on-disk format of the statistics, because we have reset them.

Yeah, it's extremely odd to be proposing dump/reload for extended
stats when we don't yet have it for plain stats.  And yes, the main
stumbling block is that you need to have a plan for stats changing
across versions, or even just environmental issues.  For example,
what if the target DB doesn't use the same collation as the source?
That would affect string sorting and therefore at least partially
invalidate histograms for text columns.

I actually did some work on this, probably close to ten years ago
now, and came up with some hacks that didn't pass community review.
It'd be a good idea to dig up those old discussions if you want to
re-open the topic.

			regards, tom lane






^ permalink  raw  reply  [nested|flat] 5+ messages in thread


end of thread, other threads:[~2023-02-01 14:58 UTC | newest]

Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-03-04 23:45 [PATCH 3/8] Process all scan keys in existing BRIN opclasses Tomas Vondra <[email protected]>
2023-01-05 18:29 Support for dumping extended statistics Hari krishna Maddileti <[email protected]>
2023-01-07 02:39 ` Re: Support for dumping extended statistics Bruce Momjian <[email protected]>
2023-02-01 13:30   ` Re: Support for dumping extended statistics Tomas Vondra <[email protected]>
2023-02-01 14:58     ` Re: Support for dumping extended statistics Tom Lane <[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